deepsource-autofix-76c6eb20
Dan Gowans 2023-01-11 15:07:46 -05:00
parent 59b04c2b8f
commit 24067317c9
101 changed files with 3005 additions and 2575 deletions

View File

@ -12,6 +12,7 @@
"plugins": ["@typescript-eslint", "unicorn"],
"extends": [
"eslint:recommended",
"standard-with-typescript",
"plugin:import/recommended",
"plugin:import/typescript",
"plugin:node/recommended",
@ -21,6 +22,10 @@
],
"rules": {
"@typescript-eslint/no-extra-semi": "off",
"@typescript-eslint/no-non-null-assertion": "off",
"@typescript-eslint/restrict-plus-operands": "warn",
"@typescript-eslint/space-before-function-paren": "off",
"@typescript-eslint/strict-boolean-expressions": "warn",
"node/no-missing-import": "off",
"node/no-unpublished-import": "off",
"unicorn/consistent-function-scoping": "warn",

View File

@ -2,5 +2,6 @@
"trailingComma": "none",
"tabWidth": 2,
"semi": false,
"singleQuote": true
"singleQuote": true,
"bracketSpacing": true
}

18
app.js
View File

@ -30,13 +30,13 @@ import { getSafeRedirectURL } from './helpers/functions.authentication.js';
import debug from 'debug';
const debugApp = debug('lot-occupancy-system:app');
databaseInitializer.initializeDatabase();
const __dirname = '.';
const _dirname = '.';
export const app = express();
app.disable('X-Powered-By');
if (!configFunctions.getProperty('reverseProxy.disableEtag')) {
app.set('etag', false);
}
app.set('views', path.join(__dirname, 'views'));
app.set('views', path.join(_dirname, 'views'));
app.set('view engine', 'ejs');
if (!configFunctions.getProperty('reverseProxy.disableCompression')) {
app.use(compression());
@ -87,17 +87,20 @@ app.use(session({
}
}));
app.use((request, response, next) => {
if (request.cookies[sessionCookieName] && !request.session.user) {
if (Object.hasOwn(request.cookies, sessionCookieName) &&
!Object.hasOwn(request.session, 'user')) {
response.clearCookie(sessionCookieName);
}
next();
});
const sessionChecker = (request, response, next) => {
if (request.session.user && request.cookies[sessionCookieName]) {
return next();
if (Object.hasOwn(request.session, 'user') &&
Object.hasOwn(request.cookies, sessionCookieName)) {
next();
return;
}
const redirectUrl = getSafeRedirectURL(request.originalUrl);
return response.redirect(`${urlPrefix}/login?redirect=${encodeURIComponent(redirectUrl)}`);
response.redirect(`${urlPrefix}/login?redirect=${encodeURIComponent(redirectUrl)}`);
};
app.use((request, response, next) => {
response.locals.buildNumber = version;
@ -128,7 +131,8 @@ app.all(urlPrefix + '/keepAlive', (_request, response) => {
});
app.use(urlPrefix + '/login', routerLogin);
app.get(urlPrefix + '/logout', (request, response) => {
if (request.session.user && request.cookies[sessionCookieName]) {
if (Object.hasOwn(request.session, 'user') &&
Object.hasOwn(request.cookies, sessionCookieName)) {
request.session.destroy(() => {
response.clearCookie(sessionCookieName);
response.redirect(urlPrefix + '/');

61
app.ts
View File

@ -48,7 +48,7 @@ databaseInitializer.initializeDatabase()
* INITIALIZE APP
*/
const __dirname = '.'
const _dirname = '.'
export const app = express()
@ -59,7 +59,7 @@ if (!configFunctions.getProperty('reverseProxy.disableEtag')) {
}
// View engine setup
app.set('views', path.join(__dirname, 'views'))
app.set('views', path.join(_dirname, 'views'))
app.set('view engine', 'ejs')
if (!configFunctions.getProperty('reverseProxy.disableCompression')) {
@ -124,17 +124,27 @@ app.use(
express.static(path.join('node_modules', '@cityssm', 'bulma-webapp-js'))
)
app.use(urlPrefix + '/lib/fa', express.static(path.join('node_modules', '@fortawesome', 'fontawesome-free')))
app.use(
urlPrefix + '/lib/fa',
express.static(path.join('node_modules', '@fortawesome', 'fontawesome-free'))
)
app.use(urlPrefix + '/lib/leaflet', express.static(path.join('node_modules', 'leaflet', 'dist')))
app.use(
urlPrefix + '/lib/leaflet',
express.static(path.join('node_modules', 'leaflet', 'dist'))
)
app.use(urlPrefix + '/lib/randomcolor', express.static(path.join('node_modules', 'randomcolor')))
app.use(
urlPrefix + '/lib/randomcolor',
express.static(path.join('node_modules', 'randomcolor'))
)
/*
* SESSION MANAGEMENT
*/
const sessionCookieName: string = configFunctions.getProperty('session.cookieName')
const sessionCookieName: string =
configFunctions.getProperty('session.cookieName')
const FileStoreSession = FileStore(session)
@ -160,7 +170,10 @@ app.use(
// Clear cookie if no corresponding session
app.use((request, response, next) => {
if (request.cookies[sessionCookieName] && !request.session.user) {
if (
Object.hasOwn(request.cookies, sessionCookieName) &&
!Object.hasOwn(request.session, 'user')
) {
response.clearCookie(sessionCookieName)
}
@ -168,14 +181,24 @@ app.use((request, response, next) => {
})
// Redirect logged in users
const sessionChecker = (request: express.Request, response: express.Response, next: express.NextFunction) => {
if (request.session.user && request.cookies[sessionCookieName]) {
return next()
const sessionChecker = (
request: express.Request,
response: express.Response,
next: express.NextFunction
): void => {
if (
Object.hasOwn(request.session, 'user') &&
Object.hasOwn(request.cookies, sessionCookieName)
) {
next()
return
}
const redirectUrl = getSafeRedirectURL(request.originalUrl)
return response.redirect(`${urlPrefix}/login?redirect=${encodeURIComponent(redirectUrl)}`)
response.redirect(
`${urlPrefix}/login?redirect=${encodeURIComponent(redirectUrl)}`
)
}
/*
@ -196,7 +219,9 @@ app.use((request, response, next) => {
response.locals.stringFunctions = stringFns
response.locals.htmlFunctions = htmlFns
response.locals.urlPrefix = configFunctions.getProperty('reverseProxy.urlPrefix')
response.locals.urlPrefix = configFunctions.getProperty(
'reverseProxy.urlPrefix'
)
next()
})
@ -216,7 +241,12 @@ app.use(urlPrefix + '/lotOccupancies', sessionChecker, routerLotOccupancies)
app.use(urlPrefix + '/workOrders', sessionChecker, routerWorkOrders)
app.use(urlPrefix + '/reports', sessionChecker, routerReports)
app.use(urlPrefix + '/admin', sessionChecker, permissionHandlers.adminGetHandler, routerAdmin)
app.use(
urlPrefix + '/admin',
sessionChecker,
permissionHandlers.adminGetHandler,
routerAdmin
)
app.all(urlPrefix + '/keepAlive', (_request, response) => {
response.json(true)
@ -225,7 +255,10 @@ app.all(urlPrefix + '/keepAlive', (_request, response) => {
app.use(urlPrefix + '/login', routerLogin)
app.get(urlPrefix + '/logout', (request, response) => {
if (request.session.user && request.cookies[sessionCookieName]) {
if (
Object.hasOwn(request.session, 'user') &&
Object.hasOwn(request.cookies, sessionCookieName)
) {
request.session.destroy(() => {
response.clearCookie(sessionCookieName)
response.redirect(urlPrefix + '/')

View File

@ -1,21 +1,21 @@
import { app } from "../app.js";
import http from "node:http";
import * as configFunctions from "../helpers/functions.config.js";
import exitHook from "exit-hook";
import ntfyPublish from "@cityssm/ntfy-publish";
import Debug from "debug";
const debug = Debug("lot-occupancy-system:www");
import { app } from '../app.js';
import http from 'node:http';
import * as configFunctions from '../helpers/functions.config.js';
import exitHook from 'exit-hook';
import ntfyPublish from '@cityssm/ntfy-publish';
import Debug from 'debug';
const debug = Debug('lot-occupancy-system:www');
function onError(error) {
if (error.syscall !== "listen") {
if (error.syscall !== 'listen') {
throw error;
}
switch (error.code) {
case "EACCES": {
debug("Requires elevated privileges");
case 'EACCES': {
debug('Requires elevated privileges');
process.exit(1);
}
case "EADDRINUSE": {
debug("Port is already in use.");
case 'EADDRINUSE': {
debug('Port is already in use.');
process.exit(1);
}
default: {
@ -26,21 +26,21 @@ function onError(error) {
function onListening(server) {
const addr = server.address();
if (addr) {
const bind = typeof addr === "string" ? "pipe " + addr : "port " + addr.port.toString();
debug("Listening on " + bind);
const bind = typeof addr === 'string' ? 'pipe ' + addr : 'port ' + addr.port.toString();
debug('Listening on ' + bind);
}
}
const ntfyStartupConfig = configFunctions.getProperty("application.ntfyStartup");
const httpPort = configFunctions.getProperty("application.httpPort");
const ntfyStartupConfig = configFunctions.getProperty('application.ntfyStartup');
const httpPort = configFunctions.getProperty('application.httpPort');
const httpServer = http.createServer(app);
httpServer.listen(httpPort);
httpServer.on("error", onError);
httpServer.on("listening", () => {
httpServer.on('error', onError);
httpServer.on('listening', () => {
onListening(httpServer);
});
debug("HTTP listening on " + httpPort.toString());
debug('HTTP listening on ' + httpPort.toString());
exitHook(() => {
debug("Closing HTTP");
debug('Closing HTTP');
httpServer.close();
});
if (ntfyStartupConfig) {
@ -48,15 +48,15 @@ if (ntfyStartupConfig) {
const server = ntfyStartupConfig.server;
const ntfyStartupMessage = {
topic,
title: configFunctions.getProperty("application.applicationName"),
message: "Application Started",
tags: ["arrow_up"]
title: configFunctions.getProperty('application.applicationName'),
message: 'Application Started',
tags: ['arrow_up']
};
const ntfyShutdownMessage = {
topic,
title: configFunctions.getProperty("application.applicationName"),
message: "Application Shut Down",
tags: ["arrow_down"]
title: configFunctions.getProperty('application.applicationName'),
message: 'Application Shut Down',
tags: ['arrow_down']
};
if (server) {
ntfyStartupMessage.server = server;
@ -64,7 +64,7 @@ if (ntfyStartupConfig) {
}
await ntfyPublish(ntfyStartupMessage);
exitHook(() => {
debug("Sending ntfy notification");
ntfyPublish(ntfyShutdownMessage);
debug('Sending ntfy notification');
void ntfyPublish(ntfyShutdownMessage);
});
}

View File

@ -1,112 +1,113 @@
/* eslint-disable no-process-exit, unicorn/no-process-exit */
import { app } from "../app.js";
import { app } from '../app.js'
import http from "node:http";
import http from 'node:http'
import * as configFunctions from "../helpers/functions.config.js";
import * as configFunctions from '../helpers/functions.config.js'
import exitHook from "exit-hook";
import exitHook from 'exit-hook'
import ntfyPublish from "@cityssm/ntfy-publish";
import type * as ntfyTypes from "@cityssm/ntfy-publish/types";
import ntfyPublish from '@cityssm/ntfy-publish'
import type * as ntfyTypes from '@cityssm/ntfy-publish/types'
import Debug from "debug";
const debug = Debug("lot-occupancy-system:www");
import Debug from 'debug'
const debug = Debug('lot-occupancy-system:www')
interface ServerError extends Error {
syscall: string;
code: string;
syscall: string
code: string
}
function onError(error: ServerError) {
if (error.syscall !== "listen") {
throw error;
function onError(error: ServerError): void {
if (error.syscall !== 'listen') {
throw error
}
// handle specific listen errors with friendly messages
switch (error.code) {
// eslint-disable-next-line no-fallthrough
case 'EACCES': {
debug('Requires elevated privileges')
process.exit(1)
// break;
}
// handle specific listen errors with friendly messages
switch (error.code) {
// eslint-disable-next-line no-fallthrough
case "EACCES": {
debug("Requires elevated privileges");
process.exit(1);
// break;
}
// eslint-disable-next-line no-fallthrough
case "EADDRINUSE": {
debug("Port is already in use.");
process.exit(1);
// break;
}
// eslint-disable-next-line no-fallthrough
default: {
throw error;
}
// eslint-disable-next-line no-fallthrough
case 'EADDRINUSE': {
debug('Port is already in use.')
process.exit(1)
// break;
}
// eslint-disable-next-line no-fallthrough
default: {
throw error
}
}
}
function onListening(server: http.Server) {
const addr = server.address();
function onListening(server: http.Server): void {
const addr = server.address()
if (addr) {
const bind = typeof addr === "string" ? "pipe " + addr : "port " + addr.port.toString();
debug("Listening on " + bind);
}
if (addr) {
const bind =
typeof addr === 'string' ? 'pipe ' + addr : 'port ' + addr.port.toString()
debug('Listening on ' + bind)
}
}
/*
* Initialize HTTP
*/
const ntfyStartupConfig = configFunctions.getProperty("application.ntfyStartup");
const ntfyStartupConfig = configFunctions.getProperty('application.ntfyStartup')
const httpPort = configFunctions.getProperty("application.httpPort");
const httpPort = configFunctions.getProperty('application.httpPort')
const httpServer = http.createServer(app);
const httpServer = http.createServer(app)
httpServer.listen(httpPort);
httpServer.listen(httpPort)
httpServer.on("error", onError);
httpServer.on("listening", () => {
onListening(httpServer);
});
httpServer.on('error', onError)
httpServer.on('listening', () => {
onListening(httpServer)
})
debug("HTTP listening on " + httpPort.toString());
debug('HTTP listening on ' + httpPort.toString())
exitHook(() => {
debug("Closing HTTP");
httpServer.close();
});
debug('Closing HTTP')
httpServer.close()
})
if (ntfyStartupConfig) {
const topic = ntfyStartupConfig.topic;
const server = ntfyStartupConfig.server;
const topic = ntfyStartupConfig.topic
const server = ntfyStartupConfig.server
const ntfyStartupMessage: ntfyTypes.NtfyMessageOptions = {
topic,
title: configFunctions.getProperty("application.applicationName"),
message: "Application Started",
tags: ["arrow_up"]
};
const ntfyStartupMessage: ntfyTypes.NtfyMessageOptions = {
topic,
title: configFunctions.getProperty('application.applicationName'),
message: 'Application Started',
tags: ['arrow_up']
}
const ntfyShutdownMessage: ntfyTypes.NtfyMessageOptions = {
topic,
title: configFunctions.getProperty("application.applicationName"),
message: "Application Shut Down",
tags: ["arrow_down"]
};
const ntfyShutdownMessage: ntfyTypes.NtfyMessageOptions = {
topic,
title: configFunctions.getProperty('application.applicationName'),
message: 'Application Shut Down',
tags: ['arrow_down']
}
if (server) {
ntfyStartupMessage.server = server;
ntfyShutdownMessage.server = server;
}
if (server) {
ntfyStartupMessage.server = server
ntfyShutdownMessage.server = server
}
await ntfyPublish(ntfyStartupMessage);
await ntfyPublish(ntfyStartupMessage)
exitHook(() => {
debug("Sending ntfy notification");
ntfyPublish(ntfyShutdownMessage);
});
exitHook(() => {
debug('Sending ntfy notification')
void ntfyPublish(ntfyShutdownMessage)
})
}

View File

@ -1,51 +1,55 @@
import { testAdmin } from "../../../test/_globals.js";
import { logout, login, ajaxDelayMillis } from "../../support/index.js";
import * as configFunctions from "../../../helpers/functions.config.js";
describe("Admin - Fee Management", () => {
beforeEach("Loads page", () => {
import { testAdmin } from '../../../test/_globals.js';
import { logout, login, ajaxDelayMillis } from '../../support/index.js';
import * as configFunctions from '../../../helpers/functions.config.js';
describe('Admin - Fee Management', () => {
beforeEach('Loads page', () => {
logout();
login(testAdmin);
cy.visit("/admin/fees");
cy.location("pathname").should("equal", "/admin/fees");
cy.visit('/admin/fees');
cy.location('pathname').should('equal', '/admin/fees');
});
afterEach(logout);
it("Has no detectable accessibility issues", () => {
it('Has no detectable accessibility issues', () => {
cy.injectAxe();
cy.checkA11y();
});
it("Creates a new fee category", () => {
it('Creates a new fee category', () => {
cy.get("[data-cy='addFeeCategory']").click();
cy.get(".modal").should("be.visible");
cy.get('.modal').should('be.visible');
cy.injectAxe();
cy.checkA11y();
cy.fixture("fee.json").then((fee) => {
cy.fixture('fee.json').then((fee) => {
cy.get(".modal input[name='feeCategory']").type(fee.feeCategory);
cy.get(".modal button[type='submit']").click();
cy.wait(ajaxDelayMillis);
cy.get(".container--feeCategory .panel-heading .title").should("contain.text", fee.feeCategory);
cy.get('.container--feeCategory .panel-heading .title').should('contain.text', fee.feeCategory);
});
});
it("Creates a new fee", () => {
it('Creates a new fee', () => {
cy.get("[data-cy='addFee']").first().click();
cy.get(".modal").should("be.visible");
cy.get('.modal').should('be.visible');
cy.injectAxe();
cy.checkA11y();
cy.fixture("fee.json").then((fee) => {
cy.fixture('fee.json').then((fee) => {
cy.get(".modal input[name='feeName']").type(fee.feeName);
cy.get(".modal textarea[name='feeDescription']").type(fee.feeDescription);
cy.get(".modal input[name='feeAmount']").clear().type(fee.feeAmount.toString());
cy.get(".modal input[name='taxAmount']").should("be.disabled");
cy.get(".modal input[name='feeAmount']")
.clear()
.type(fee.feeAmount.toString());
cy.get(".modal input[name='taxAmount']").should('be.disabled');
cy.get(".modal input[name='taxPercentage']")
.invoke("val")
.should("equal", configFunctions.getProperty("settings.fees.taxPercentageDefault").toString());
cy.get(".modal input[name='quantityUnit']").should("be.disabled");
cy.get(".modal select[name='includeQuantity']").select("1");
.invoke('val')
.should('equal', configFunctions
.getProperty('settings.fees.taxPercentageDefault')
.toString());
cy.get(".modal input[name='quantityUnit']").should('be.disabled');
cy.get(".modal select[name='includeQuantity']").select('1');
cy.get(".modal input[name='quantityUnit']")
.should("not.be.disabled")
.should('not.be.disabled')
.type(fee.quantityUnit);
cy.get(".modal button[type='submit']").click();
cy.wait(ajaxDelayMillis);
cy.get(".container--fee a").should("contain.text", fee.feeName);
cy.get('.container--fee a').should('contain.text', fee.feeName);
});
});
});

View File

@ -1,88 +1,91 @@
/* eslint-disable unicorn/filename-case, promise/catch-or-return, promise/always-return */
/* eslint-disable unicorn/filename-case, promise/catch-or-return, promise/always-return, @typescript-eslint/no-non-null-assertion */
import { testAdmin } from "../../../test/_globals.js";
import { testAdmin } from '../../../test/_globals.js'
import { logout, login, ajaxDelayMillis } from "../../support/index.js";
import { logout, login, ajaxDelayMillis } from '../../support/index.js'
import * as configFunctions from "../../../helpers/functions.config.js";
import * as configFunctions from '../../../helpers/functions.config.js'
import type * as recordTypes from "../../../types/recordTypes";
import type * as recordTypes from '../../../types/recordTypes'
describe("Admin - Fee Management", () => {
beforeEach("Loads page", () => {
logout();
login(testAdmin);
cy.visit("/admin/fees");
cy.location("pathname").should("equal", "/admin/fees");
});
afterEach(logout);
describe('Admin - Fee Management', () => {
beforeEach('Loads page', () => {
logout()
login(testAdmin)
cy.visit('/admin/fees')
cy.location('pathname').should('equal', '/admin/fees')
})
it("Has no detectable accessibility issues", () => {
cy.injectAxe();
cy.checkA11y();
});
afterEach(logout)
it("Creates a new fee category", () => {
cy.get("[data-cy='addFeeCategory']").click();
it('Has no detectable accessibility issues', () => {
cy.injectAxe()
cy.checkA11y()
})
cy.get(".modal").should("be.visible");
it('Creates a new fee category', () => {
cy.get("[data-cy='addFeeCategory']").click()
cy.injectAxe();
cy.checkA11y();
cy.get('.modal').should('be.visible')
cy.fixture("fee.json").then((fee: recordTypes.Fee) => {
cy.get(".modal input[name='feeCategory']").type(fee.feeCategory);
cy.injectAxe()
cy.checkA11y()
cy.get(".modal button[type='submit']").click();
cy.fixture('fee.json').then((fee: recordTypes.Fee) => {
cy.get(".modal input[name='feeCategory']").type(fee.feeCategory!)
cy.wait(ajaxDelayMillis);
cy.get(".modal button[type='submit']").click()
cy.get(".container--feeCategory .panel-heading .title").should(
"contain.text",
fee.feeCategory
);
});
});
cy.wait(ajaxDelayMillis)
it("Creates a new fee", () => {
cy.get("[data-cy='addFee']").first().click();
cy.get('.container--feeCategory .panel-heading .title').should(
'contain.text',
fee.feeCategory
)
})
})
cy.get(".modal").should("be.visible");
it('Creates a new fee', () => {
cy.get("[data-cy='addFee']").first().click()
cy.injectAxe();
cy.checkA11y();
cy.get('.modal').should('be.visible')
cy.fixture("fee.json").then((fee: recordTypes.Fee) => {
cy.get(".modal input[name='feeName']").type(fee.feeName);
cy.injectAxe()
cy.checkA11y()
cy.get(".modal textarea[name='feeDescription']").type(fee.feeDescription);
cy.fixture('fee.json').then((fee: recordTypes.Fee) => {
cy.get(".modal input[name='feeName']").type(fee.feeName!)
cy.get(".modal input[name='feeAmount']").clear().type(fee.feeAmount.toString());
cy.get(".modal textarea[name='feeDescription']").type(fee.feeDescription!)
cy.get(".modal input[name='taxAmount']").should("be.disabled");
cy.get(".modal input[name='feeAmount']")
.clear()
.type(fee.feeAmount!.toString())
cy.get(".modal input[name='taxPercentage']")
.invoke("val")
.should(
"equal",
configFunctions.getProperty("settings.fees.taxPercentageDefault").toString()
);
cy.get(".modal input[name='taxAmount']").should('be.disabled')
cy.get(".modal input[name='quantityUnit']").should("be.disabled");
cy.get(".modal input[name='taxPercentage']")
.invoke('val')
.should(
'equal',
configFunctions
.getProperty('settings.fees.taxPercentageDefault')
.toString()
)
cy.get(".modal select[name='includeQuantity']").select("1");
cy.get(".modal input[name='quantityUnit']").should('be.disabled')
cy.get(".modal input[name='quantityUnit']")
.should("not.be.disabled")
.type(fee.quantityUnit);
cy.get(".modal select[name='includeQuantity']").select('1')
cy.get(".modal button[type='submit']").click();
cy.get(".modal input[name='quantityUnit']")
.should('not.be.disabled')
.type(fee.quantityUnit!)
cy.wait(ajaxDelayMillis);
cy.get(".modal button[type='submit']").click()
cy.get(".container--fee a").should("contain.text", fee.feeName);
});
});
});
cy.wait(ajaxDelayMillis)
cy.get('.container--fee a').should('contain.text', fee.feeName)
})
})
})

View File

@ -1,7 +1,7 @@
import { testUpdate } from "../../../test/_globals.js";
import { logout, login } from "../../support/index.js";
describe("Update - Lot Occupancies", () => {
beforeEach("Loads page", () => {
beforeEach(() => {
logout();
login(testUpdate);
});

View File

@ -3,14 +3,13 @@ import { testUpdate } from "../../../test/_globals.js";
import { logout, login } from "../../support/index.js";
describe("Update - Lot Occupancies", () => {
beforeEach("Loads page", () => {
beforeEach(() => {
logout();
login(testUpdate);
});
afterEach(logout);
it('Has a "Create" link on the Lot Occupancy Search', () => {
cy.visit("/lotOccupancies");
cy.location("pathname").should("equal", "/lotOccupancies");
@ -18,7 +17,6 @@ describe("Update - Lot Occupancies", () => {
});
describe("Update a New Lot Occupancy", () => {
it("Has no detectable accessibility issues", () => {
cy.visit("/lotOccupancies/new");
cy.injectAxe();

View File

@ -1,51 +1,61 @@
import { testUpdate } from "../../../test/_globals.js";
import { logout, login } from "../../support/index.js";
import * as configFunctions from "../../../helpers/functions.config.js";
describe("Update - Maps", () => {
beforeEach("Loads page", () => {
import { testUpdate } from '../../../test/_globals.js';
import { logout, login } from '../../support/index.js';
import * as configFunctions from '../../../helpers/functions.config.js';
describe('Update - Maps', () => {
beforeEach('Loads page', () => {
logout();
login(testUpdate);
});
afterEach(logout);
it('Has a "Create" link on the Map Search', () => {
cy.visit("/maps");
cy.location("pathname").should("equal", "/maps");
cy.get("a[href$='/maps/new']").should("exist");
cy.visit('/maps');
cy.location('pathname').should('equal', '/maps');
cy.get("a[href$='/maps/new']").should('exist');
});
it("Creates a new map", () => {
cy.visit("/maps/new");
cy.log("Check the accessibility");
it('Creates a new map', () => {
cy.visit('/maps/new');
cy.log('Check the accessibility');
cy.injectAxe();
cy.checkA11y();
cy.log("Populate the fields");
cy.fixture("map.json").then((mapJSON) => {
cy.log('Populate the fields');
cy.fixture('map.json').then((mapJSON) => {
cy.get("input[name='mapName']").clear().type(mapJSON.mapName);
cy.get("textarea[name='mapDescription']").clear().type(mapJSON.mapDescription);
cy.get("textarea[name='mapDescription']")
.clear()
.type(mapJSON.mapDescription);
cy.get("input[name='mapAddress1']").clear().type(mapJSON.mapAddress1);
cy.get("input[name='mapAddress2']").clear().type(mapJSON.mapAddress2);
cy.get("input[name='mapPostalCode']").clear().type(mapJSON.mapPostalCode);
cy.get("input[name='mapPhoneNumber']").clear().type(mapJSON.mapPhoneNumber);
cy.get("input[name='mapLatitude']").clear().type(mapJSON.mapLatitude.toString());
cy.get("input[name='mapLongitude']").clear().type(mapJSON.mapLongitude.toString());
cy.get("input[name='mapPhoneNumber']")
.clear()
.type(mapJSON.mapPhoneNumber);
cy.get("input[name='mapLatitude']")
.clear()
.type(mapJSON.mapLatitude.toString());
cy.get("input[name='mapLongitude']")
.clear()
.type(mapJSON.mapLongitude.toString());
});
cy.log("Ensure the default city and province are used");
cy.get("input[name='mapCity']").should("have.value", configFunctions.getProperty("settings.map.mapCityDefault"));
cy.get("input[name='mapProvince']").should("have.value", configFunctions.getProperty("settings.map.mapProvinceDefault"));
cy.log("Submit the form");
cy.get("#form--map").submit();
cy.log('Ensure the default city and province are used');
cy.get("input[name='mapCity']").should('have.value', configFunctions.getProperty('settings.map.mapCityDefault'));
cy.get("input[name='mapProvince']").should('have.value', configFunctions.getProperty('settings.map.mapProvinceDefault'));
cy.log('Submit the form');
cy.get('#form--map').submit();
cy.wait(1000);
cy.location("pathname").should("not.contain", "/new").should("contain", "/edit");
cy.fixture("map.json").then((mapJSON) => {
cy.get("input[name='mapName']").should("have.value", mapJSON.mapName);
cy.get("textarea[name='mapDescription']").should("have.value", mapJSON.mapDescription);
cy.get("input[name='mapAddress1']").should("have.value", mapJSON.mapAddress1);
cy.get("input[name='mapAddress2']").should("have.value", mapJSON.mapAddress2);
cy.get("input[name='mapCity']").should("have.value", configFunctions.getProperty("settings.map.mapCityDefault"));
cy.get("input[name='mapProvince']").should("have.value", configFunctions.getProperty("settings.map.mapProvinceDefault"));
cy.get("input[name='mapPostalCode']").should("have.value", mapJSON.mapPostalCode);
cy.get("input[name='mapPhoneNumber']").should("have.value", mapJSON.mapPhoneNumber);
cy.get("input[name='mapLatitude']").should("have.value", mapJSON.mapLatitude.toString());
cy.get("input[name='mapLongitude']").should("have.value", mapJSON.mapLongitude.toString());
cy.location('pathname')
.should('not.contain', '/new')
.should('contain', '/edit');
cy.fixture('map.json').then((mapJSON) => {
cy.get("input[name='mapName']").should('have.value', mapJSON.mapName);
cy.get("textarea[name='mapDescription']").should('have.value', mapJSON.mapDescription);
cy.get("input[name='mapAddress1']").should('have.value', mapJSON.mapAddress1);
cy.get("input[name='mapAddress2']").should('have.value', mapJSON.mapAddress2);
cy.get("input[name='mapCity']").should('have.value', configFunctions.getProperty('settings.map.mapCityDefault'));
cy.get("input[name='mapProvince']").should('have.value', configFunctions.getProperty('settings.map.mapProvinceDefault'));
cy.get("input[name='mapPostalCode']").should('have.value', mapJSON.mapPostalCode);
cy.get("input[name='mapPhoneNumber']").should('have.value', mapJSON.mapPhoneNumber);
cy.get("input[name='mapLatitude']").should('have.value', mapJSON.mapLatitude.toString());
cy.get("input[name='mapLongitude']").should('have.value', mapJSON.mapLongitude.toString());
});
});
});

View File

@ -1,97 +1,124 @@
import { testUpdate } from "../../../test/_globals.js";
/* eslint-disable @typescript-eslint/no-non-null-assertion */
import { logout, login } from "../../support/index.js";
import { testUpdate } from '../../../test/_globals.js'
import * as configFunctions from "../../../helpers/functions.config.js";
import { logout, login } from '../../support/index.js'
import type * as recordTypes from "../../../types/recordTypes";
import * as configFunctions from '../../../helpers/functions.config.js'
describe("Update - Maps", () => {
beforeEach("Loads page", () => {
logout();
login(testUpdate);
});
import type * as recordTypes from '../../../types/recordTypes'
afterEach(logout);
describe('Update - Maps', () => {
beforeEach('Loads page', () => {
logout()
login(testUpdate)
})
it('Has a "Create" link on the Map Search', () => {
cy.visit("/maps");
cy.location("pathname").should("equal", "/maps");
cy.get("a[href$='/maps/new']").should("exist");
});
afterEach(logout)
it("Creates a new map", () => {
cy.visit("/maps/new");
it('Has a "Create" link on the Map Search', () => {
cy.visit('/maps')
cy.location('pathname').should('equal', '/maps')
cy.get("a[href$='/maps/new']").should('exist')
})
cy.log("Check the accessibility");
it('Creates a new map', () => {
cy.visit('/maps/new')
cy.injectAxe();
cy.checkA11y();
cy.log('Check the accessibility')
cy.log("Populate the fields");
cy.injectAxe()
cy.checkA11y()
// eslint-disable-next-line promise/catch-or-return, promise/always-return
cy.fixture("map.json").then((mapJSON: recordTypes.Map) => {
cy.get("input[name='mapName']").clear().type(mapJSON.mapName);
cy.get("textarea[name='mapDescription']").clear().type(mapJSON.mapDescription);
cy.log('Populate the fields')
cy.get("input[name='mapAddress1']").clear().type(mapJSON.mapAddress1);
cy.get("input[name='mapAddress2']").clear().type(mapJSON.mapAddress2);
cy.get("input[name='mapPostalCode']").clear().type(mapJSON.mapPostalCode);
cy.get("input[name='mapPhoneNumber']").clear().type(mapJSON.mapPhoneNumber);
// eslint-disable-next-line promise/catch-or-return, promise/always-return
cy.fixture('map.json').then((mapJSON: recordTypes.Map) => {
cy.get("input[name='mapName']").clear().type(mapJSON.mapName!)
cy.get("textarea[name='mapDescription']")
.clear()
.type(mapJSON.mapDescription!)
cy.get("input[name='mapLatitude']").clear().type(mapJSON.mapLatitude.toString());
cy.get("input[name='mapLongitude']").clear().type(mapJSON.mapLongitude.toString());
});
cy.get("input[name='mapAddress1']").clear().type(mapJSON.mapAddress1!)
cy.get("input[name='mapAddress2']").clear().type(mapJSON.mapAddress2!)
cy.get("input[name='mapPostalCode']").clear().type(mapJSON.mapPostalCode!)
cy.get("input[name='mapPhoneNumber']")
.clear()
.type(mapJSON.mapPhoneNumber!)
cy.log("Ensure the default city and province are used");
cy.get("input[name='mapLatitude']")
.clear()
.type(mapJSON.mapLatitude!.toString())
cy.get("input[name='mapLongitude']")
.clear()
.type(mapJSON.mapLongitude!.toString())
})
cy.get("input[name='mapCity']").should(
"have.value",
configFunctions.getProperty("settings.map.mapCityDefault")
);
cy.log('Ensure the default city and province are used')
cy.get("input[name='mapProvince']").should(
"have.value",
configFunctions.getProperty("settings.map.mapProvinceDefault")
);
cy.get("input[name='mapCity']").should(
'have.value',
configFunctions.getProperty('settings.map.mapCityDefault')
)
cy.log("Submit the form");
cy.get("input[name='mapProvince']").should(
'have.value',
configFunctions.getProperty('settings.map.mapProvinceDefault')
)
cy.get("#form--map").submit();
cy.log('Submit the form')
cy.wait(1000);
cy.get('#form--map').submit()
cy.location("pathname").should("not.contain", "/new").should("contain", "/edit");
cy.wait(1000)
// eslint-disable-next-line promise/catch-or-return, promise/always-return
cy.fixture("map.json").then((mapJSON: recordTypes.Map) => {
cy.get("input[name='mapName']").should("have.value", mapJSON.mapName);
cy.get("textarea[name='mapDescription']").should("have.value", mapJSON.mapDescription);
cy.location('pathname')
.should('not.contain', '/new')
.should('contain', '/edit')
cy.get("input[name='mapAddress1']").should("have.value", mapJSON.mapAddress1);
cy.get("input[name='mapAddress2']").should("have.value", mapJSON.mapAddress2);
// eslint-disable-next-line promise/catch-or-return, promise/always-return
cy.fixture('map.json').then((mapJSON: recordTypes.Map) => {
cy.get("input[name='mapName']").should('have.value', mapJSON.mapName)
cy.get("textarea[name='mapDescription']").should(
'have.value',
mapJSON.mapDescription
)
cy.get("input[name='mapCity']").should(
"have.value",
configFunctions.getProperty("settings.map.mapCityDefault")
);
cy.get("input[name='mapProvince']").should(
"have.value",
configFunctions.getProperty("settings.map.mapProvinceDefault")
);
cy.get("input[name='mapAddress1']").should(
'have.value',
mapJSON.mapAddress1
)
cy.get("input[name='mapAddress2']").should(
'have.value',
mapJSON.mapAddress2
)
cy.get("input[name='mapPostalCode']").should("have.value", mapJSON.mapPostalCode);
cy.get("input[name='mapPhoneNumber']").should("have.value", mapJSON.mapPhoneNumber);
cy.get("input[name='mapCity']").should(
'have.value',
configFunctions.getProperty('settings.map.mapCityDefault')
)
cy.get("input[name='mapProvince']").should(
'have.value',
configFunctions.getProperty('settings.map.mapProvinceDefault')
)
cy.get("input[name='mapLatitude']").should(
"have.value",
mapJSON.mapLatitude.toString()
);
cy.get("input[name='mapLongitude']").should(
"have.value",
mapJSON.mapLongitude.toString()
);
});
});
});
cy.get("input[name='mapPostalCode']").should(
'have.value',
mapJSON.mapPostalCode
)
cy.get("input[name='mapPhoneNumber']").should(
'have.value',
mapJSON.mapPhoneNumber
)
cy.get("input[name='mapLatitude']").should(
'have.value',
mapJSON.mapLatitude!.toString()
)
cy.get("input[name='mapLongitude']").should(
'have.value',
mapJSON.mapLongitude!.toString()
)
})
})
})

View File

@ -4,33 +4,40 @@ config.aliases.occupancyStartDate = "Purchase Date";
config.aliases.externalReceiptNumber = "GP Receipt Number";
config.settings.lot.lotNamePattern =
/^[\dA-Z]{2}-(B[\dA-Z]+-)?(R[\dA-Z]+-)?(L[\dA-Z]+-)?G[\dA-Z]+(, Interment \d+)?$/;
config.settings.lot.lotNameHelpText =
"Two digit cemetery-Block-Range-Lot-Grave, Interment number\n" +
"ex. XX-BA-R41-L15-G3A, Interment 1";
config.settings.lot.lotNameHelpText = `Two digit cemetery-Block-Range-Lot-Grave, Interment number\n
ex. XX-BA-R41-L15-G3A, Interment 1`;
const numericPadding = "00000";
config.settings.lot.lotNameSortNameFunction = (lotName) => {
const numericPadding = "00000";
const lotNameSplit = lotName.toUpperCase().split("-");
const cleanLotNamePieces = [];
for (const lotNamePiece of lotNameSplit) {
let numericPiece = numericPadding;
let letterPiece = "";
for (const letter of lotNamePiece) {
if (letterPiece === "" && "0123456789".includes(letter)) {
numericPiece += letter;
try {
const lotNameSplit = lotName.toUpperCase().split("-");
const cleanLotNamePieces = [];
for (let lotNamePiece of lotNameSplit) {
if (cleanLotNamePieces.length === 0) {
cleanLotNamePieces.push(lotNamePiece);
continue;
}
else {
letterPiece += letter;
let numericPiece = numericPadding;
let letterPiece = "";
const firstLetter = lotNamePiece.charAt(0);
lotNamePiece = lotNamePiece.slice(1);
for (const letter of lotNamePiece) {
if (letterPiece === "" && "0123456789".includes(letter)) {
numericPiece += letter;
}
else {
letterPiece += letter;
}
}
cleanLotNamePieces.push(firstLetter + numericPiece.slice(-1 * numericPadding.length) + letterPiece);
}
cleanLotNamePieces.push(numericPiece.slice(-1 * numericPadding.length) + letterPiece);
return cleanLotNamePieces.join("-");
}
catch {
return lotName;
}
return cleanLotNamePieces.join("-");
};
config.settings.lotOccupancy.occupantCityDefault = "Sault Ste. Marie";
config.settings.lotOccupancy.prints = [
"pdf/ssm.cemetery.burialPermit",
"pdf/ssm.cemetery.contract"
];
config.settings.lotOccupancy.prints = ["pdf/ssm.cemetery.burialPermit", "pdf/ssm.cemetery.contract"];
config.settings.map.mapCityDefault = "Sault Ste. Marie";
config.settings.workOrders.workOrderNumberLength = 6;
config.settings.workOrders.workOrderMilestoneDateRecentBeforeDays = 7;

View File

@ -7,41 +7,51 @@ config.aliases.externalReceiptNumber = "GP Receipt Number";
config.settings.lot.lotNamePattern =
/^[\dA-Z]{2}-(B[\dA-Z]+-)?(R[\dA-Z]+-)?(L[\dA-Z]+-)?G[\dA-Z]+(, Interment \d+)?$/;
config.settings.lot.lotNameHelpText =
"Two digit cemetery-Block-Range-Lot-Grave, Interment number\n" +
"ex. XX-BA-R41-L15-G3A, Interment 1";
config.settings.lot.lotNameHelpText = `Two digit cemetery-Block-Range-Lot-Grave, Interment number\n
ex. XX-BA-R41-L15-G3A, Interment 1`;
const numericPadding = "00000";
config.settings.lot.lotNameSortNameFunction = (lotName) => {
const numericPadding = "00000";
try {
const lotNameSplit = lotName.toUpperCase().split("-");
const lotNameSplit = lotName.toUpperCase().split("-");
const cleanLotNamePieces: string[] = [];
const cleanLotNamePieces: string[] = [];
for (const lotNamePiece of lotNameSplit) {
let numericPiece = numericPadding;
let letterPiece = "";
for (const letter of lotNamePiece) {
if (letterPiece === "" && "0123456789".includes(letter)) {
numericPiece += letter;
} else {
letterPiece += letter;
for (let lotNamePiece of lotNameSplit) {
if (cleanLotNamePieces.length === 0) {
cleanLotNamePieces.push(lotNamePiece);
continue;
}
let numericPiece = numericPadding;
let letterPiece = "";
const firstLetter = lotNamePiece.charAt(0);
lotNamePiece = lotNamePiece.slice(1);
for (const letter of lotNamePiece) {
if (letterPiece === "" && "0123456789".includes(letter)) {
numericPiece += letter;
} else {
letterPiece += letter;
}
}
cleanLotNamePieces.push(
firstLetter + numericPiece.slice(-1 * numericPadding.length) + letterPiece
);
}
cleanLotNamePieces.push(numericPiece.slice(-1 * numericPadding.length) + letterPiece);
return cleanLotNamePieces.join("-");
} catch {
return lotName;
}
return cleanLotNamePieces.join("-");
};
config.settings.lotOccupancy.occupantCityDefault = "Sault Ste. Marie";
config.settings.lotOccupancy.prints = [
"pdf/ssm.cemetery.burialPermit",
"pdf/ssm.cemetery.contract"
];
config.settings.lotOccupancy.prints = ["pdf/ssm.cemetery.burialPermit", "pdf/ssm.cemetery.contract"];
config.settings.map.mapCityDefault = "Sault Ste. Marie";

View File

@ -1,3 +1,3 @@
import type { RequestHandler } from "express";
import type { RequestHandler } from 'express';
export declare const handler: RequestHandler;
export default handler;

View File

@ -1,6 +1,6 @@
import { addFee } from "../../helpers/lotOccupancyDB/addFee.js";
import { getFeeCategories } from "../../helpers/lotOccupancyDB/getFeeCategories.js";
export const handler = async (request, response) => {
import { addFee } from '../../helpers/lotOccupancyDB/addFee.js';
import { getFeeCategories } from '../../helpers/lotOccupancyDB/getFeeCategories.js';
export const handler = (request, response) => {
const feeId = addFee(request.body, request.session);
const feeCategories = getFeeCategories({}, {
includeFees: true

View File

@ -1,24 +1,24 @@
import type { RequestHandler } from "express";
import type { RequestHandler } from 'express'
import { addFee } from "../../helpers/lotOccupancyDB/addFee.js";
import { addFee } from '../../helpers/lotOccupancyDB/addFee.js'
import { getFeeCategories } from "../../helpers/lotOccupancyDB/getFeeCategories.js";
import { getFeeCategories } from '../../helpers/lotOccupancyDB/getFeeCategories.js'
export const handler: RequestHandler = async (request, response) => {
const feeId = addFee(request.body, request.session);
export const handler: RequestHandler = (request, response) => {
const feeId = addFee(request.body, request.session)
const feeCategories = getFeeCategories(
{},
{
includeFees: true
}
);
const feeCategories = getFeeCategories(
{},
{
includeFees: true
}
)
response.json({
success: true,
feeId,
feeCategories
});
};
response.json({
success: true,
feeId,
feeCategories
})
}
export default handler;
export default handler

View File

@ -1,3 +1,3 @@
import type { RequestHandler } from "express";
import type { RequestHandler } from 'express';
export declare const handler: RequestHandler;
export default handler;

View File

@ -1,7 +1,7 @@
import { updateRecord } from "../../helpers/lotOccupancyDB/updateRecord.js";
import { getWorkOrderTypes } from "../../helpers/functions.cache.js";
export const handler = async (request, response) => {
const success = updateRecord("WorkOrderTypes", request.body.workOrderTypeId, request.body.workOrderType, request.session);
import { updateRecord } from '../../helpers/lotOccupancyDB/updateRecord.js';
import { getWorkOrderTypes } from '../../helpers/functions.cache.js';
export const handler = (request, response) => {
const success = updateRecord('WorkOrderTypes', request.body.workOrderTypeId, request.body.workOrderType, request.session);
const workOrderTypes = getWorkOrderTypes();
response.json({
success,

View File

@ -1,22 +1,22 @@
import type { RequestHandler } from "express";
import type { RequestHandler } from 'express'
import { updateRecord } from "../../helpers/lotOccupancyDB/updateRecord.js";
import { getWorkOrderTypes } from "../../helpers/functions.cache.js";
import { updateRecord } from '../../helpers/lotOccupancyDB/updateRecord.js'
import { getWorkOrderTypes } from '../../helpers/functions.cache.js'
export const handler: RequestHandler = async (request, response) => {
const success = updateRecord(
"WorkOrderTypes",
request.body.workOrderTypeId,
request.body.workOrderType,
request.session
);
export const handler: RequestHandler = (request, response) => {
const success = updateRecord(
'WorkOrderTypes',
request.body.workOrderTypeId,
request.body.workOrderType,
request.session
)
const workOrderTypes = getWorkOrderTypes();
const workOrderTypes = getWorkOrderTypes()
response.json({
success,
workOrderTypes
});
};
response.json({
success,
workOrderTypes
})
}
export default handler;
export default handler

View File

@ -1,3 +1,3 @@
import type { RequestHandler } from "express";
import type { RequestHandler } from 'express';
export declare const handler: RequestHandler;
export default handler;

View File

@ -1,26 +1,26 @@
import ical, { ICalEventStatus } from "ical-generator";
import { getWorkOrderMilestones } from "../../helpers/lotOccupancyDB/getWorkOrderMilestones.js";
import * as configFunctions from "../../helpers/functions.config.js";
import { getPrintConfig } from "../../helpers/functions.print.js";
const calendarCompany = "cityssm.github.io";
const calendarProduct = configFunctions.getProperty("application.applicationName");
import ical, { ICalEventStatus } from 'ical-generator';
import { getWorkOrderMilestones } from '../../helpers/lotOccupancyDB/getWorkOrderMilestones.js';
import * as configFunctions from '../../helpers/functions.config.js';
import { getPrintConfig } from '../../helpers/functions.print.js';
const calendarCompany = 'cityssm.github.io';
const calendarProduct = configFunctions.getProperty('application.applicationName');
const timeStringSplitRegex = /[ :-]/;
function escapeHTML(stringToEscape) {
return stringToEscape.replace(/[^\d A-Za-z]/g, (c) => "&#" + c.codePointAt(0) + ";");
return stringToEscape.replace(/[^\d A-Za-z]/g, (c) => `&#${c.codePointAt(0)};`);
}
function getUrlRoot(request) {
return ("http://" +
return ('http://' +
request.hostname +
(configFunctions.getProperty("application.httpPort") === 80
? ""
: ":" + configFunctions.getProperty("application.httpPort")) +
configFunctions.getProperty("reverseProxy.urlPrefix"));
(configFunctions.getProperty('application.httpPort') === 80
? ''
: `:${configFunctions.getProperty('application.httpPort')}`) +
configFunctions.getProperty('reverseProxy.urlPrefix'));
}
function getWorkOrderUrl(request, milestone) {
return getUrlRoot(request) + "/workOrders/" + milestone.workOrderId;
return `${getUrlRoot(request)}/workOrders/${milestone.workOrderId}`;
}
function buildEventSummary(milestone) {
let summary = (milestone.workOrderMilestoneCompletionDate ? "✔ " : "") +
let summary = (milestone.workOrderMilestoneCompletionDate ? '✔ ' : '') +
(milestone.workOrderMilestoneTypeId
? milestone.workOrderMilestoneType
: milestone.workOrderMilestoneDescription).trim();
@ -29,121 +29,126 @@ function buildEventSummary(milestone) {
for (const occupant of lotOccupancy.lotOccupancyOccupants) {
occupantCount += 1;
if (occupantCount === 1) {
if (summary !== "") {
summary += ": ";
if (summary !== '') {
summary += ': ';
}
summary += occupant.occupantName;
}
}
}
if (occupantCount > 1) {
summary += " plus " + (occupantCount - 1);
summary += ' plus ' + (occupantCount - 1);
}
return summary;
}
function buildEventDescriptionHTML_occupancies(request, milestone) {
let descriptionHTML = "";
let descriptionHTML = '';
if (milestone.workOrderLotOccupancies.length > 0) {
const urlRoot = getUrlRoot(request);
descriptionHTML = `<h2>
Related ${escapeHTML(configFunctions.getProperty("aliases.occupancies"))}
</h2>
<table border="1">
<thead><tr>
<th>${escapeHTML(configFunctions.getProperty("aliases.occupancy"))} Type</th>
<th>${escapeHTML(configFunctions.getProperty("aliases.lot"))}</th>
<th>Start Date</th>
<th>End Date</th>
<th>${escapeHTML(configFunctions.getProperty("aliases.occupants"))}</th>
</tr></thead>
<tbody>`;
Related ${escapeHTML(configFunctions.getProperty('aliases.occupancies'))}
</h2>
<table border="1">
<thead><tr>
<th>${escapeHTML(configFunctions.getProperty('aliases.occupancy'))} Type</th>
<th>${escapeHTML(configFunctions.getProperty('aliases.lot'))}</th>
<th>Start Date</th>
<th>End Date</th>
<th>${escapeHTML(configFunctions.getProperty('aliases.occupants'))}</th>
</tr></thead>
<tbody>`;
for (const occupancy of milestone.workOrderLotOccupancies) {
descriptionHTML +=
`<tr>
<td>
<a href="${urlRoot}/lotOccupancies/${occupancy.lotOccupancyId}">
${escapeHTML(occupancy.occupancyType)}
</a>
</td>
<td>
${occupancy.lotName ? escapeHTML(occupancy.lotName) : "(Not Set)"}
</td>
<td>
${occupancy.occupancyStartDateString}
</td>` +
"<td>" +
(occupancy.occupancyEndDate ? occupancy.occupancyEndDateString : "(No End Date)") +
"</td>" +
"<td>";
descriptionHTML += `<tr>
<td>
<a href="${urlRoot}/lotOccupancies/${occupancy.lotOccupancyId}">
${escapeHTML(occupancy.occupancyType)}
</a>
</td>
<td>
${occupancy.lotName ? escapeHTML(occupancy.lotName) : '(Not Set)'}
</td>
<td>
${occupancy.occupancyStartDateString}
</td>
<td>
${occupancy.occupancyEndDate
? occupancy.occupancyEndDateString
: '(No End Date)'}
</td>
<td>`;
for (const occupant of occupancy.lotOccupancyOccupants) {
descriptionHTML +=
escapeHTML(occupant.lotOccupantType) +
": " +
': ' +
escapeHTML(occupant.occupantName) +
"<br />";
'<br />';
}
descriptionHTML += "</td></tr>";
descriptionHTML += '</td></tr>';
}
descriptionHTML += "</tbody></table>";
descriptionHTML += '</tbody></table>';
}
return descriptionHTML;
}
function buildEventDescriptionHTML_lots(request, milestone) {
let descriptionHTML = "";
let descriptionHTML = '';
if (milestone.workOrderLots.length > 0) {
const urlRoot = getUrlRoot(request);
descriptionHTML +=
"<h2>Related " +
escapeHTML(configFunctions.getProperty("aliases.lots")) +
"</h2>" +
'<h2>Related ' +
escapeHTML(configFunctions.getProperty('aliases.lots')) +
'</h2>' +
'<table border="1"><thead><tr>' +
`<th>
${escapeHTML(configFunctions.getProperty("aliases.lot"))} Type
${escapeHTML(configFunctions.getProperty('aliases.lot'))} Type
</th>
<th>
${escapeHTML(configFunctions.getProperty("aliases.map"))}
${escapeHTML(configFunctions.getProperty('aliases.map'))}
</th>
<th>
${escapeHTML(configFunctions.getProperty("aliases.lot"))} Type
${escapeHTML(configFunctions.getProperty('aliases.lot'))} Type
</th>` +
"<th>Status</th>" +
"</tr></thead>" +
"<tbody>";
'<th>Status</th>' +
'</tr></thead>' +
'<tbody>';
for (const lot of milestone.workOrderLots) {
descriptionHTML +=
"<tr>" +
("<td>" +
'<tr>' +
('<td>' +
'<a href="' +
urlRoot +
"/lots/" +
'/lots/' +
lot.lotId +
'">' +
escapeHTML(lot.lotName) +
"</a></td>") +
`<td>${escapeHTML(lot.mapName)}</td>` +
`<td>${escapeHTML(lot.lotType)}</td>` +
`<td>${escapeHTML(lot.lotStatus)}</td>` +
"</tr>";
escapeHTML(lot.lotName ?? '') +
'</a></td>') +
`<td>${escapeHTML(lot.mapName ?? '')}</td>` +
`<td>${escapeHTML(lot.lotType ?? '')}</td>` +
`<td>${escapeHTML(lot.lotStatus ?? '')}</td>` +
'</tr>';
}
descriptionHTML += "</tbody></table>";
descriptionHTML += '</tbody></table>';
}
return descriptionHTML;
}
function buildEventDescriptionHTML_prints(request, milestone) {
let descriptionHTML = "";
const prints = configFunctions.getProperty("settings.workOrders.prints");
let descriptionHTML = '';
const prints = configFunctions.getProperty('settings.workOrders.prints');
if (prints.length > 0) {
const urlRoot = getUrlRoot(request);
descriptionHTML += "<h2>Prints</h2>";
descriptionHTML += '<h2>Prints</h2>';
for (const printName of prints) {
const printConfig = getPrintConfig(printName);
if (printConfig) {
descriptionHTML +=
"<p>" +
'<p>' +
escapeHTML(printConfig.title) +
"<br />" +
(urlRoot + "/print/" + printName + "/?workOrderId=" + milestone.workOrderId) +
"</p>";
'<br />' +
(urlRoot +
'/print/' +
printName +
'/?workOrderId=' +
milestone.workOrderId) +
'</p>';
}
}
}
@ -152,9 +157,9 @@ function buildEventDescriptionHTML_prints(request, milestone) {
function buildEventDescriptionHTML(request, milestone) {
const workOrderUrl = getWorkOrderUrl(request, milestone);
let descriptionHTML = `<h1>Milestone Description</h1>
<p>${escapeHTML(milestone.workOrderMilestoneDescription)}</p>
<h2>Work Order #${milestone.workOrderNumber}</h2>
<p>${escapeHTML(milestone.workOrderDescription)}</p>
<p>${escapeHTML(milestone.workOrderMilestoneDescription ?? '')}</p>
<h2>Work Order #${milestone.workOrderNumber ?? ''}</h2>
<p>${escapeHTML(milestone.workOrderDescription ?? '')}</p>
<p>${workOrderUrl}</p>`;
descriptionHTML += buildEventDescriptionHTML_occupancies(request, milestone);
descriptionHTML += buildEventDescriptionHTML_lots(request, milestone);
@ -167,7 +172,7 @@ function buildEventCategoryList(milestone) {
categories.push(milestone.workOrderMilestoneType, milestone.workOrderType);
}
if (milestone.workOrderMilestoneCompletionDate) {
categories.push("Completed");
categories.push('Completed');
}
return categories;
}
@ -175,10 +180,10 @@ function buildEventLocation(milestone) {
const lotNames = [];
if (milestone.workOrderLots.length > 0) {
for (const lot of milestone.workOrderLots) {
lotNames.push(lot.mapName + ": " + lot.lotName);
lotNames.push(`${lot.mapName ?? ''}: ${lot.lotName ?? ''}`);
}
}
return lotNames.join(", ");
return lotNames.join(', ');
}
export const handler = (request, response) => {
const urlRoot = getUrlRoot(request);
@ -190,19 +195,19 @@ export const handler = (request, response) => {
workOrderMilestoneFilters.workOrderId = request.query.workOrderId;
}
else {
workOrderMilestoneFilters.workOrderMilestoneDateFilter = "recent";
workOrderMilestoneFilters.workOrderMilestoneDateFilter = 'recent';
}
const workOrderMilestones = getWorkOrderMilestones(workOrderMilestoneFilters, {
includeWorkOrders: true,
orderBy: "date"
orderBy: 'date'
});
const calendar = ical({
name: "Work Order Milestone Calendar",
url: urlRoot + "/workOrders"
name: 'Work Order Milestone Calendar',
url: urlRoot + '/workOrders'
});
if (request.query.workOrderId && workOrderMilestones.length > 0) {
calendar.name(`Work Order #${workOrderMilestones[0].workOrderNumber}`);
calendar.url(urlRoot + "/workOrders/" + workOrderMilestones[0].workOrderId);
calendar.url(urlRoot + '/workOrders/' + workOrderMilestones[0].workOrderId);
}
calendar.prodId({
company: calendarCompany,
@ -210,7 +215,7 @@ export const handler = (request, response) => {
});
for (const milestone of workOrderMilestones) {
const milestoneTimePieces = (milestone.workOrderMilestoneDateString +
" " +
' ' +
milestone.workOrderMilestoneTimeString).split(timeStringSplitRegex);
const milestoneDate = new Date(Number.parseInt(milestoneTimePieces[0], 10), Number.parseInt(milestoneTimePieces[1], 10) - 1, Number.parseInt(milestoneTimePieces[2], 10), Number.parseInt(milestoneTimePieces[3], 10), Number.parseInt(milestoneTimePieces[4], 10));
const milestoneEndDate = new Date(milestoneDate.getTime());
@ -253,13 +258,13 @@ export const handler = (request, response) => {
if (organizerSet) {
calendarEvent.createAttendee({
name: occupant.occupantName,
email: configFunctions.getProperty("settings.workOrders.calendarEmailAddress")
email: configFunctions.getProperty('settings.workOrders.calendarEmailAddress')
});
}
else {
calendarEvent.organizer({
name: occupant.occupantName,
email: configFunctions.getProperty("settings.workOrders.calendarEmailAddress")
email: configFunctions.getProperty('settings.workOrders.calendarEmailAddress')
});
organizerSet = true;
}
@ -269,7 +274,7 @@ export const handler = (request, response) => {
else {
calendarEvent.organizer({
name: milestone.recordCreate_userName,
email: configFunctions.getProperty("settings.workOrders.calendarEmailAddress")
email: configFunctions.getProperty('settings.workOrders.calendarEmailAddress')
});
}
}

View File

@ -1,413 +1,437 @@
/* eslint-disable unicorn/filename-case */
import ical, { ICalEventData, ICalEventStatus } from "ical-generator";
import ical, { ICalEventData, ICalEventStatus } from 'ical-generator'
import {
getWorkOrderMilestones,
WorkOrderMilestoneFilters
} from "../../helpers/lotOccupancyDB/getWorkOrderMilestones.js";
getWorkOrderMilestones,
WorkOrderMilestoneFilters
} from '../../helpers/lotOccupancyDB/getWorkOrderMilestones.js'
import type { RequestHandler, Request } from "express";
import type { RequestHandler, Request } from 'express'
import * as configFunctions from "../../helpers/functions.config.js";
import { getPrintConfig } from "../../helpers/functions.print.js";
import * as configFunctions from '../../helpers/functions.config.js'
import { getPrintConfig } from '../../helpers/functions.print.js'
import type * as recordTypes from "../../types/recordTypes";
import type * as recordTypes from '../../types/recordTypes'
const calendarCompany = "cityssm.github.io";
const calendarProduct = configFunctions.getProperty("application.applicationName");
const calendarCompany = 'cityssm.github.io'
const calendarProduct = configFunctions.getProperty(
'application.applicationName'
)
const timeStringSplitRegex = /[ :-]/;
const timeStringSplitRegex = /[ :-]/
function escapeHTML(stringToEscape: string) {
return stringToEscape.replace(/[^\d A-Za-z]/g, (c) => "&#" + c.codePointAt(0) + ";");
function escapeHTML(stringToEscape: string): string {
return stringToEscape.replace(
/[^\d A-Za-z]/g,
(c) => `&#${c.codePointAt(0)!};`
)
}
function getUrlRoot(request: Request): string {
return (
"http://" +
request.hostname +
(configFunctions.getProperty("application.httpPort") === 80
? ""
: ":" + configFunctions.getProperty("application.httpPort")) +
configFunctions.getProperty("reverseProxy.urlPrefix")
);
return (
'http://' +
request.hostname +
(configFunctions.getProperty('application.httpPort') === 80
? ''
: `:${configFunctions.getProperty('application.httpPort')}`) +
configFunctions.getProperty('reverseProxy.urlPrefix')
)
}
function getWorkOrderUrl(request: Request, milestone: recordTypes.WorkOrderMilestone) {
return getUrlRoot(request) + "/workOrders/" + milestone.workOrderId;
function getWorkOrderUrl(
request: Request,
milestone: recordTypes.WorkOrderMilestone
): string {
return `${getUrlRoot(request)}/workOrders/${milestone.workOrderId!}`
}
function buildEventSummary(milestone: recordTypes.WorkOrderMilestone): string {
let summary =
(milestone.workOrderMilestoneCompletionDate ? "✔ " : "") +
(milestone.workOrderMilestoneTypeId
? milestone.workOrderMilestoneType
: milestone.workOrderMilestoneDescription
).trim();
let summary =
(milestone.workOrderMilestoneCompletionDate ? '✔ ' : '') +
(milestone.workOrderMilestoneTypeId
? milestone.workOrderMilestoneType
: milestone.workOrderMilestoneDescription
).trim()
let occupantCount = 0;
let occupantCount = 0
for (const lotOccupancy of milestone.workOrderLotOccupancies) {
for (const occupant of lotOccupancy.lotOccupancyOccupants) {
occupantCount += 1;
for (const lotOccupancy of milestone.workOrderLotOccupancies!) {
for (const occupant of lotOccupancy.lotOccupancyOccupants!) {
occupantCount += 1
if (occupantCount === 1) {
if (summary !== "") {
summary += ": ";
}
summary += occupant.occupantName;
}
if (occupantCount === 1) {
if (summary !== '') {
summary += ': '
}
}
if (occupantCount > 1) {
summary += " plus " + (occupantCount - 1);
summary += occupant.occupantName
}
}
}
return summary;
if (occupantCount > 1) {
summary += ' plus ' + (occupantCount - 1)
}
return summary
}
function buildEventDescriptionHTML_occupancies(
request: Request,
milestone: recordTypes.WorkOrderMilestone
request: Request,
milestone: recordTypes.WorkOrderMilestone
): string {
let descriptionHTML = "";
let descriptionHTML = ''
if (milestone.workOrderLotOccupancies.length > 0) {
const urlRoot = getUrlRoot(request);
if (milestone.workOrderLotOccupancies!.length > 0) {
const urlRoot = getUrlRoot(request)
descriptionHTML = `<h2>
Related ${escapeHTML(configFunctions.getProperty("aliases.occupancies"))}
</h2>
<table border="1">
<thead><tr>
<th>${escapeHTML(configFunctions.getProperty("aliases.occupancy"))} Type</th>
<th>${escapeHTML(configFunctions.getProperty("aliases.lot"))}</th>
<th>Start Date</th>
<th>End Date</th>
<th>${escapeHTML(configFunctions.getProperty("aliases.occupants"))}</th>
</tr></thead>
<tbody>`;
descriptionHTML = `<h2>
Related ${escapeHTML(configFunctions.getProperty('aliases.occupancies'))}
</h2>
<table border="1">
<thead><tr>
<th>${escapeHTML(
configFunctions.getProperty('aliases.occupancy')
)} Type</th>
<th>${escapeHTML(configFunctions.getProperty('aliases.lot'))}</th>
<th>Start Date</th>
<th>End Date</th>
<th>${escapeHTML(configFunctions.getProperty('aliases.occupants'))}</th>
</tr></thead>
<tbody>`
for (const occupancy of milestone.workOrderLotOccupancies) {
descriptionHTML +=
`<tr>
<td>
<a href="${urlRoot}/lotOccupancies/${occupancy.lotOccupancyId}">
${escapeHTML(occupancy.occupancyType)}
</a>
</td>
<td>
${occupancy.lotName ? escapeHTML(occupancy.lotName) : "(Not Set)"}
</td>
<td>
${occupancy.occupancyStartDateString}
</td>` +
"<td>" +
(occupancy.occupancyEndDate ? occupancy.occupancyEndDateString : "(No End Date)") +
"</td>" +
"<td>";
for (const occupant of occupancy.lotOccupancyOccupants) {
descriptionHTML +=
escapeHTML(occupant.lotOccupantType) +
": " +
escapeHTML(occupant.occupantName) +
"<br />";
for (const occupancy of milestone.workOrderLotOccupancies!) {
descriptionHTML += `<tr>
<td>
<a href="${urlRoot}/lotOccupancies/${occupancy.lotOccupancyId!}">
${escapeHTML(occupancy.occupancyType!)}
</a>
</td>
<td>
${occupancy.lotName ? escapeHTML(occupancy.lotName) : '(Not Set)'}
</td>
<td>
${occupancy.occupancyStartDateString!}
</td>
<td>
${
occupancy.occupancyEndDate
? occupancy.occupancyEndDateString
: '(No End Date)'
}
</td>
<td>`
descriptionHTML += "</td></tr>";
}
for (const occupant of occupancy.lotOccupancyOccupants!) {
descriptionHTML +=
escapeHTML(occupant.lotOccupantType!) +
': ' +
escapeHTML(occupant.occupantName!) +
'<br />'
}
descriptionHTML += "</tbody></table>";
descriptionHTML += '</td></tr>'
}
return descriptionHTML;
descriptionHTML += '</tbody></table>'
}
return descriptionHTML
}
function buildEventDescriptionHTML_lots(
request: Request,
milestone: recordTypes.WorkOrderMilestone
request: Request,
milestone: recordTypes.WorkOrderMilestone
): string {
let descriptionHTML = "";
let descriptionHTML = ''
if (milestone.workOrderLots.length > 0) {
const urlRoot = getUrlRoot(request);
if (milestone.workOrderLots.length > 0) {
const urlRoot = getUrlRoot(request)
descriptionHTML +=
"<h2>Related " +
escapeHTML(configFunctions.getProperty("aliases.lots")) +
"</h2>" +
'<table border="1"><thead><tr>' +
`<th>
${escapeHTML(configFunctions.getProperty("aliases.lot"))} Type
descriptionHTML +=
'<h2>Related ' +
escapeHTML(configFunctions.getProperty('aliases.lots')) +
'</h2>' +
'<table border="1"><thead><tr>' +
`<th>
${escapeHTML(configFunctions.getProperty('aliases.lot'))} Type
</th>
<th>
${escapeHTML(configFunctions.getProperty("aliases.map"))}
${escapeHTML(configFunctions.getProperty('aliases.map'))}
</th>
<th>
${escapeHTML(configFunctions.getProperty("aliases.lot"))} Type
${escapeHTML(configFunctions.getProperty('aliases.lot'))} Type
</th>` +
"<th>Status</th>" +
"</tr></thead>" +
"<tbody>";
'<th>Status</th>' +
'</tr></thead>' +
'<tbody>'
for (const lot of milestone.workOrderLots) {
descriptionHTML +=
"<tr>" +
("<td>" +
'<a href="' +
urlRoot +
"/lots/" +
lot.lotId +
'">' +
escapeHTML(lot.lotName) +
"</a></td>") +
`<td>${escapeHTML(lot.mapName)}</td>` +
`<td>${escapeHTML(lot.lotType)}</td>` +
`<td>${escapeHTML(lot.lotStatus)}</td>` +
"</tr>";
}
descriptionHTML += "</tbody></table>";
for (const lot of milestone.workOrderLots!) {
descriptionHTML +=
'<tr>' +
('<td>' +
'<a href="' +
urlRoot +
'/lots/' +
lot.lotId +
'">' +
escapeHTML(lot.lotName ?? '') +
'</a></td>') +
`<td>${escapeHTML(lot.mapName ?? '')}</td>` +
`<td>${escapeHTML(lot.lotType ?? '')}</td>` +
`<td>${escapeHTML(lot.lotStatus ?? '')}</td>` +
'</tr>'
}
return descriptionHTML;
descriptionHTML += '</tbody></table>'
}
return descriptionHTML
}
function buildEventDescriptionHTML_prints(
request: Request,
milestone: recordTypes.WorkOrderMilestone
request: Request,
milestone: recordTypes.WorkOrderMilestone
): string {
let descriptionHTML = "";
let descriptionHTML = ''
const prints = configFunctions.getProperty("settings.workOrders.prints");
const prints = configFunctions.getProperty('settings.workOrders.prints')
if (prints.length > 0) {
const urlRoot = getUrlRoot(request);
if (prints.length > 0) {
const urlRoot = getUrlRoot(request)
descriptionHTML += "<h2>Prints</h2>";
descriptionHTML += '<h2>Prints</h2>'
for (const printName of prints) {
const printConfig = getPrintConfig(printName);
for (const printName of prints) {
const printConfig = getPrintConfig(printName)
if (printConfig) {
descriptionHTML +=
"<p>" +
escapeHTML(printConfig.title) +
"<br />" +
(urlRoot + "/print/" + printName + "/?workOrderId=" + milestone.workOrderId) +
"</p>";
}
}
if (printConfig) {
descriptionHTML +=
'<p>' +
escapeHTML(printConfig.title) +
'<br />' +
(urlRoot +
'/print/' +
printName +
'/?workOrderId=' +
milestone.workOrderId) +
'</p>'
}
}
}
return descriptionHTML;
return descriptionHTML
}
function buildEventDescriptionHTML(
request: Request,
milestone: recordTypes.WorkOrderMilestone
request: Request,
milestone: recordTypes.WorkOrderMilestone
): string {
const workOrderUrl = getWorkOrderUrl(request, milestone);
const workOrderUrl = getWorkOrderUrl(request, milestone)
let descriptionHTML = `<h1>Milestone Description</h1>
<p>${escapeHTML(milestone.workOrderMilestoneDescription)}</p>
<h2>Work Order #${milestone.workOrderNumber}</h2>
<p>${escapeHTML(milestone.workOrderDescription)}</p>
<p>${workOrderUrl}</p>`;
let descriptionHTML = `<h1>Milestone Description</h1>
<p>${escapeHTML(milestone.workOrderMilestoneDescription ?? '')}</p>
<h2>Work Order #${milestone.workOrderNumber ?? ''}</h2>
<p>${escapeHTML(milestone.workOrderDescription ?? '')}</p>
<p>${workOrderUrl}</p>`
descriptionHTML += buildEventDescriptionHTML_occupancies(request, milestone);
descriptionHTML += buildEventDescriptionHTML_lots(request, milestone);
descriptionHTML += buildEventDescriptionHTML_prints(request, milestone);
descriptionHTML += buildEventDescriptionHTML_occupancies(request, milestone)
descriptionHTML += buildEventDescriptionHTML_lots(request, milestone)
descriptionHTML += buildEventDescriptionHTML_prints(request, milestone)
return descriptionHTML;
return descriptionHTML
}
function buildEventCategoryList(milestone: recordTypes.WorkOrderMilestone): string[] {
const categories: string[] = [];
function buildEventCategoryList(
milestone: recordTypes.WorkOrderMilestone
): string[] {
const categories: string[] = []
if (milestone.workOrderMilestoneTypeId) {
categories.push(milestone.workOrderMilestoneType, milestone.workOrderType);
}
if (milestone.workOrderMilestoneTypeId) {
categories.push(milestone.workOrderMilestoneType, milestone.workOrderType)
}
if (milestone.workOrderMilestoneCompletionDate) {
categories.push("Completed");
}
if (milestone.workOrderMilestoneCompletionDate) {
categories.push('Completed')
}
return categories;
return categories
}
function buildEventLocation(milestone: recordTypes.WorkOrderMilestone): string {
const lotNames = [];
const lotNames: string[] = []
if (milestone.workOrderLots.length > 0) {
for (const lot of milestone.workOrderLots) {
lotNames.push(lot.mapName + ": " + lot.lotName);
}
if (milestone.workOrderLots!.length > 0) {
for (const lot of milestone.workOrderLots!) {
lotNames.push(`${lot.mapName ?? ''}: ${lot.lotName ?? ''}`)
}
return lotNames.join(", ");
}
return lotNames.join(', ')
}
export const handler: RequestHandler = (request, response) => {
const urlRoot = getUrlRoot(request);
const urlRoot = getUrlRoot(request)
/*
* Get work order milestones
*/
/*
* Get work order milestones
*/
const workOrderMilestoneFilters: WorkOrderMilestoneFilters = {
workOrderTypeIds: request.query.workOrderTypeIds as string,
workOrderMilestoneTypeIds: request.query.workOrderMilestoneTypeIds as string
};
const workOrderMilestoneFilters: WorkOrderMilestoneFilters = {
workOrderTypeIds: request.query.workOrderTypeIds as string,
workOrderMilestoneTypeIds: request.query.workOrderMilestoneTypeIds as string
}
if (request.query.workOrderId) {
workOrderMilestoneFilters.workOrderId = request.query.workOrderId as string;
} else {
workOrderMilestoneFilters.workOrderMilestoneDateFilter = "recent";
if (request.query.workOrderId) {
workOrderMilestoneFilters.workOrderId = request.query.workOrderId as string
} else {
workOrderMilestoneFilters.workOrderMilestoneDateFilter = 'recent'
}
const workOrderMilestones = getWorkOrderMilestones(
workOrderMilestoneFilters,
{
includeWorkOrders: true,
orderBy: 'date'
}
)
/*
* Create calendar object
*/
const calendar = ical({
name: 'Work Order Milestone Calendar',
url: urlRoot + '/workOrders'
})
if (request.query.workOrderId && workOrderMilestones.length > 0) {
calendar.name(`Work Order #${workOrderMilestones[0].workOrderNumber}`)
calendar.url(urlRoot + '/workOrders/' + workOrderMilestones[0].workOrderId)
}
calendar.prodId({
company: calendarCompany,
product: calendarProduct
})
/*
* Loop through milestones
*/
for (const milestone of workOrderMilestones) {
const milestoneTimePieces = (
milestone.workOrderMilestoneDateString +
' ' +
milestone.workOrderMilestoneTimeString
).split(timeStringSplitRegex)
const milestoneDate = new Date(
Number.parseInt(milestoneTimePieces[0], 10),
Number.parseInt(milestoneTimePieces[1], 10) - 1,
Number.parseInt(milestoneTimePieces[2], 10),
Number.parseInt(milestoneTimePieces[3], 10),
Number.parseInt(milestoneTimePieces[4], 10)
)
const milestoneEndDate = new Date(milestoneDate.getTime())
milestoneEndDate.setHours(milestoneEndDate.getHours() + 1)
// Build summary (title in Outlook)
const summary = buildEventSummary(milestone)
// Build URL
const workOrderUrl = getWorkOrderUrl(request, milestone)
// Create event
const eventData: ICalEventData = {
start: milestoneDate,
created: new Date(milestone.recordCreate_timeMillis),
stamp: new Date(milestone.recordCreate_timeMillis),
lastModified: new Date(
Math.max(
milestone.recordUpdate_timeMillis,
milestone.workOrderRecordUpdate_timeMillis
)
),
allDay: !milestone.workOrderMilestoneTime,
summary,
url: workOrderUrl
}
const workOrderMilestones = getWorkOrderMilestones(workOrderMilestoneFilters, {
includeWorkOrders: true,
orderBy: "date"
});
/*
* Create calendar object
*/
const calendar = ical({
name: "Work Order Milestone Calendar",
url: urlRoot + "/workOrders"
});
if (request.query.workOrderId && workOrderMilestones.length > 0) {
calendar.name(`Work Order #${workOrderMilestones[0].workOrderNumber}`);
calendar.url(urlRoot + "/workOrders/" + workOrderMilestones[0].workOrderId);
if (!eventData.allDay) {
eventData.end = milestoneEndDate
}
calendar.prodId({
company: calendarCompany,
product: calendarProduct
});
const calendarEvent = calendar.createEvent(eventData)
/*
* Loop through milestones
*/
// Build description
for (const milestone of workOrderMilestones) {
const milestoneTimePieces = (
milestone.workOrderMilestoneDateString +
" " +
milestone.workOrderMilestoneTimeString
).split(timeStringSplitRegex);
const descriptionHTML = buildEventDescriptionHTML(request, milestone)
const milestoneDate = new Date(
Number.parseInt(milestoneTimePieces[0], 10),
Number.parseInt(milestoneTimePieces[1], 10) - 1,
Number.parseInt(milestoneTimePieces[2], 10),
Number.parseInt(milestoneTimePieces[3], 10),
Number.parseInt(milestoneTimePieces[4], 10)
);
calendarEvent.description({
plain: workOrderUrl,
html: descriptionHTML
})
const milestoneEndDate = new Date(milestoneDate.getTime());
milestoneEndDate.setHours(milestoneEndDate.getHours() + 1);
// Set status
// Build summary (title in Outlook)
if (milestone.workOrderMilestoneCompletionDate) {
calendarEvent.status(ICalEventStatus.CONFIRMED)
}
const summary = buildEventSummary(milestone);
// Add categories
// Build URL
const categories = buildEventCategoryList(milestone)
for (const category of categories) {
calendarEvent.createCategory({
name: category
})
}
const workOrderUrl = getWorkOrderUrl(request, milestone);
// Set location
// Create event
const location = buildEventLocation(milestone)
calendarEvent.location(location)
const eventData: ICalEventData = {
start: milestoneDate,
created: new Date(milestone.recordCreate_timeMillis),
stamp: new Date(milestone.recordCreate_timeMillis),
lastModified: new Date(
Math.max(
milestone.recordUpdate_timeMillis,
milestone.workOrderRecordUpdate_timeMillis
)
),
allDay: !milestone.workOrderMilestoneTime,
summary,
url: workOrderUrl
};
// Set organizer / attendees
if (!eventData.allDay) {
eventData.end = milestoneEndDate;
}
const calendarEvent = calendar.createEvent(eventData);
// Build description
const descriptionHTML = buildEventDescriptionHTML(request, milestone);
calendarEvent.description({
plain: workOrderUrl,
html: descriptionHTML
});
// Set status
if (milestone.workOrderMilestoneCompletionDate) {
calendarEvent.status(ICalEventStatus.CONFIRMED);
}
// Add categories
const categories = buildEventCategoryList(milestone);
for (const category of categories) {
calendarEvent.createCategory({
name: category
});
}
// Set location
const location = buildEventLocation(milestone);
calendarEvent.location(location);
// Set organizer / attendees
if (milestone.workOrderLotOccupancies.length > 0) {
let organizerSet = false;
for (const lotOccupancy of milestone.workOrderLotOccupancies) {
for (const occupant of lotOccupancy.lotOccupancyOccupants) {
if (organizerSet) {
calendarEvent.createAttendee({
name: occupant.occupantName,
email: configFunctions.getProperty(
"settings.workOrders.calendarEmailAddress"
)
});
} else {
calendarEvent.organizer({
name: occupant.occupantName,
email: configFunctions.getProperty(
"settings.workOrders.calendarEmailAddress"
)
});
organizerSet = true;
}
}
}
} else {
if (milestone.workOrderLotOccupancies.length > 0) {
let organizerSet = false
for (const lotOccupancy of milestone.workOrderLotOccupancies) {
for (const occupant of lotOccupancy.lotOccupancyOccupants) {
if (organizerSet) {
calendarEvent.createAttendee({
name: occupant.occupantName,
email: configFunctions.getProperty(
'settings.workOrders.calendarEmailAddress'
)
})
} else {
calendarEvent.organizer({
name: milestone.recordCreate_userName,
email: configFunctions.getProperty("settings.workOrders.calendarEmailAddress")
});
name: occupant.occupantName,
email: configFunctions.getProperty(
'settings.workOrders.calendarEmailAddress'
)
})
organizerSet = true
}
}
}
} else {
calendarEvent.organizer({
name: milestone.recordCreate_userName,
email: configFunctions.getProperty(
'settings.workOrders.calendarEmailAddress'
)
})
}
}
calendar.serve(response);
};
calendar.serve(response)
}
export default handler;
export default handler

View File

@ -1,3 +1,3 @@
import type { RequestHandler } from "express";
import type { RequestHandler } from 'express';
export declare const handler: RequestHandler;
export default handler;

View File

@ -1,12 +1,12 @@
import { getLotOccupantTypes, getLotStatuses, getLotTypes, getOccupancyTypePrintsById, getOccupancyTypes, getWorkOrderTypes } from "../../helpers/functions.cache.js";
import * as configFunctions from "../../helpers/functions.config.js";
import { getLotOccupancy } from "../../helpers/lotOccupancyDB/getLotOccupancy.js";
import { getMaps } from "../../helpers/lotOccupancyDB/getMaps.js";
import { getLotOccupantTypes, getLotStatuses, getLotTypes, getOccupancyTypePrintsById, getOccupancyTypes, getWorkOrderTypes } from '../../helpers/functions.cache.js';
import * as configFunctions from '../../helpers/functions.config.js';
import { getLotOccupancy } from '../../helpers/lotOccupancyDB/getLotOccupancy.js';
import { getMaps } from '../../helpers/lotOccupancyDB/getMaps.js';
export const handler = (request, response) => {
const lotOccupancy = getLotOccupancy(request.params.lotOccupancyId);
if (!lotOccupancy) {
return response.redirect(configFunctions.getProperty("reverseProxy.urlPrefix") +
"/lotOccupancies/?error=lotOccupancyIdNotFound");
response.redirect(`${configFunctions.getProperty('reverseProxy.urlPrefix')}/lotOccupancies/?error=lotOccupancyIdNotFound`);
return;
}
const occupancyTypePrints = getOccupancyTypePrintsById(lotOccupancy.occupancyTypeId);
const occupancyTypes = getOccupancyTypes();
@ -15,8 +15,8 @@ export const handler = (request, response) => {
const lotStatuses = getLotStatuses();
const maps = getMaps();
const workOrderTypes = getWorkOrderTypes();
return response.render("lotOccupancy-edit", {
headTitle: `${configFunctions.getProperty("aliases.occupancy")} Update`,
response.render('lotOccupancy-edit', {
headTitle: `${configFunctions.getProperty('aliases.occupancy')} Update`,
lotOccupancy,
occupancyTypePrints,
occupancyTypes,

View File

@ -1,52 +1,56 @@
import type { RequestHandler } from "express";
import type { RequestHandler } from 'express'
import {
getLotOccupantTypes,
getLotStatuses,
getLotTypes,
getOccupancyTypePrintsById,
getOccupancyTypes,
getWorkOrderTypes
} from "../../helpers/functions.cache.js";
getLotOccupantTypes,
getLotStatuses,
getLotTypes,
getOccupancyTypePrintsById,
getOccupancyTypes,
getWorkOrderTypes
} from '../../helpers/functions.cache.js'
import * as configFunctions from "../../helpers/functions.config.js";
import * as configFunctions from '../../helpers/functions.config.js'
import { getLotOccupancy } from "../../helpers/lotOccupancyDB/getLotOccupancy.js";
import { getMaps } from "../../helpers/lotOccupancyDB/getMaps.js";
import { getLotOccupancy } from '../../helpers/lotOccupancyDB/getLotOccupancy.js'
import { getMaps } from '../../helpers/lotOccupancyDB/getMaps.js'
export const handler: RequestHandler = (request, response) => {
const lotOccupancy = getLotOccupancy(request.params.lotOccupancyId);
const lotOccupancy = getLotOccupancy(request.params.lotOccupancyId)
if (!lotOccupancy) {
return response.redirect(
configFunctions.getProperty("reverseProxy.urlPrefix") +
"/lotOccupancies/?error=lotOccupancyIdNotFound"
);
}
if (!lotOccupancy) {
response.redirect(
`${configFunctions.getProperty(
'reverseProxy.urlPrefix'
)}/lotOccupancies/?error=lotOccupancyIdNotFound`
)
return
}
const occupancyTypePrints = getOccupancyTypePrintsById(lotOccupancy.occupancyTypeId);
const occupancyTypePrints = getOccupancyTypePrintsById(
lotOccupancy.occupancyTypeId!
)
const occupancyTypes = getOccupancyTypes();
const lotOccupantTypes = getLotOccupantTypes();
const lotTypes = getLotTypes();
const lotStatuses = getLotStatuses();
const maps = getMaps();
const workOrderTypes = getWorkOrderTypes();
const occupancyTypes = getOccupancyTypes()
const lotOccupantTypes = getLotOccupantTypes()
const lotTypes = getLotTypes()
const lotStatuses = getLotStatuses()
const maps = getMaps()
const workOrderTypes = getWorkOrderTypes()
return response.render("lotOccupancy-edit", {
headTitle: `${configFunctions.getProperty("aliases.occupancy")} Update`,
lotOccupancy,
occupancyTypePrints,
response.render('lotOccupancy-edit', {
headTitle: `${configFunctions.getProperty('aliases.occupancy')} Update`,
lotOccupancy,
occupancyTypePrints,
occupancyTypes,
lotOccupantTypes,
lotTypes,
lotStatuses,
maps,
workOrderTypes,
occupancyTypes,
lotOccupantTypes,
lotTypes,
lotStatuses,
maps,
workOrderTypes,
isCreate: false
});
};
isCreate: false
})
}
export default handler;
export default handler

View File

@ -1,3 +1,3 @@
import type { RequestHandler } from "express";
import type { RequestHandler } from 'express';
export declare const handler: RequestHandler;
export default handler;

View File

@ -1,15 +1,16 @@
import { getOccupancyTypePrintsById } from "../../helpers/functions.cache.js";
import * as configFunctions from "../../helpers/functions.config.js";
import { getLotOccupancy } from "../../helpers/lotOccupancyDB/getLotOccupancy.js";
import { getOccupancyTypePrintsById } from '../../helpers/functions.cache.js';
import * as configFunctions from '../../helpers/functions.config.js';
import { getLotOccupancy } from '../../helpers/lotOccupancyDB/getLotOccupancy.js';
export const handler = (request, response) => {
const lotOccupancy = getLotOccupancy(request.params.lotOccupancyId);
if (!lotOccupancy) {
return response.redirect(configFunctions.getProperty("reverseProxy.urlPrefix") +
"/lotOccupancies/?error=lotOccupancyIdNotFound");
response.redirect(configFunctions.getProperty('reverseProxy.urlPrefix') +
'/lotOccupancies/?error=lotOccupancyIdNotFound');
return;
}
const occupancyTypePrints = getOccupancyTypePrintsById(lotOccupancy.occupancyTypeId);
return response.render("lotOccupancy-view", {
headTitle: `${configFunctions.getProperty("aliases.occupancy")} View`,
response.render('lotOccupancy-view', {
headTitle: `${configFunctions.getProperty('aliases.occupancy')} View`,
lotOccupancy,
occupancyTypePrints
});

View File

@ -1,27 +1,30 @@
import type { RequestHandler } from "express";
import { getOccupancyTypePrintsById } from "../../helpers/functions.cache.js";
import type { RequestHandler } from 'express'
import { getOccupancyTypePrintsById } from '../../helpers/functions.cache.js'
import * as configFunctions from "../../helpers/functions.config.js";
import * as configFunctions from '../../helpers/functions.config.js'
import { getLotOccupancy } from "../../helpers/lotOccupancyDB/getLotOccupancy.js";
import { getLotOccupancy } from '../../helpers/lotOccupancyDB/getLotOccupancy.js'
export const handler: RequestHandler = (request, response) => {
const lotOccupancy = getLotOccupancy(request.params.lotOccupancyId);
const lotOccupancy = getLotOccupancy(request.params.lotOccupancyId)
if (!lotOccupancy) {
return response.redirect(
configFunctions.getProperty("reverseProxy.urlPrefix") +
"/lotOccupancies/?error=lotOccupancyIdNotFound"
);
}
if (!lotOccupancy) {
response.redirect(
configFunctions.getProperty('reverseProxy.urlPrefix') +
'/lotOccupancies/?error=lotOccupancyIdNotFound'
)
return
}
const occupancyTypePrints = getOccupancyTypePrintsById(lotOccupancy.occupancyTypeId);
const occupancyTypePrints = getOccupancyTypePrintsById(
lotOccupancy.occupancyTypeId!
)
return response.render("lotOccupancy-view", {
headTitle: `${configFunctions.getProperty("aliases.occupancy")} View`,
lotOccupancy,
occupancyTypePrints
});
};
response.render('lotOccupancy-view', {
headTitle: `${configFunctions.getProperty('aliases.occupancy')} View`,
lotOccupancy,
occupancyTypePrints
})
}
export default handler;
export default handler

View File

@ -1,3 +1,3 @@
import type { RequestHandler } from "express";
import type { RequestHandler } from 'express';
export declare const handler: RequestHandler;
export default handler;

View File

@ -1,5 +1,5 @@
import { getLotOccupancy } from "../../helpers/lotOccupancyDB/getLotOccupancy.js";
import { getFeeCategories } from "../../helpers/lotOccupancyDB/getFeeCategories.js";
import { getLotOccupancy } from '../../helpers/lotOccupancyDB/getLotOccupancy.js';
import { getFeeCategories } from '../../helpers/lotOccupancyDB/getFeeCategories.js';
export const handler = (request, response) => {
const lotOccupancyId = request.body.lotOccupancyId;
const lotOccupancy = getLotOccupancy(lotOccupancyId);

View File

@ -1,27 +1,27 @@
import type { RequestHandler } from "express";
import type { RequestHandler } from 'express'
import { getLotOccupancy } from "../../helpers/lotOccupancyDB/getLotOccupancy.js";
import { getLotOccupancy } from '../../helpers/lotOccupancyDB/getLotOccupancy.js'
import { getFeeCategories } from "../../helpers/lotOccupancyDB/getFeeCategories.js";
import { getFeeCategories } from '../../helpers/lotOccupancyDB/getFeeCategories.js'
export const handler: RequestHandler = (request, response) => {
const lotOccupancyId = request.body.lotOccupancyId;
const lotOccupancyId = request.body.lotOccupancyId
const lotOccupancy = getLotOccupancy(lotOccupancyId);
const lotOccupancy = getLotOccupancy(lotOccupancyId)!
const feeCategories = getFeeCategories(
{
occupancyTypeId: lotOccupancy.occupancyTypeId,
lotTypeId: lotOccupancy.lotTypeId
},
{
includeFees: true
}
);
const feeCategories = getFeeCategories(
{
occupancyTypeId: lotOccupancy.occupancyTypeId,
lotTypeId: lotOccupancy.lotTypeId
},
{
includeFees: true
}
)
response.json({
feeCategories
});
};
response.json({
feeCategories
})
}
export default handler;
export default handler

View File

@ -1,3 +1,3 @@
import type { RequestHandler } from "express";
import type { RequestHandler } from 'express';
export declare const handler: RequestHandler;
export default handler;

View File

@ -1,8 +1,8 @@
import { getOccupancyTypeById, getAllOccupancyTypeFields } from "../../helpers/functions.cache.js";
export const handler = async (request, response) => {
import { getOccupancyTypeById, getAllOccupancyTypeFields } from '../../helpers/functions.cache.js';
export const handler = (request, response) => {
const occupancyTypeFields = getAllOccupancyTypeFields();
const result = getOccupancyTypeById(Number.parseInt(request.body.occupancyTypeId, 10));
occupancyTypeFields.push(...result.occupancyTypeFields);
occupancyTypeFields.push(...(result.occupancyTypeFields ?? []));
response.json({
occupancyTypeFields
});

View File

@ -1,17 +1,22 @@
import type { RequestHandler } from "express";
import type { RequestHandler } from 'express'
import { getOccupancyTypeById, getAllOccupancyTypeFields } from "../../helpers/functions.cache.js";
import {
getOccupancyTypeById,
getAllOccupancyTypeFields
} from '../../helpers/functions.cache.js'
export const handler: RequestHandler = async (request, response) => {
const occupancyTypeFields = getAllOccupancyTypeFields();
export const handler: RequestHandler = (request, response) => {
const occupancyTypeFields = getAllOccupancyTypeFields()
const result = getOccupancyTypeById(Number.parseInt(request.body.occupancyTypeId, 10));
const result = getOccupancyTypeById(
Number.parseInt(request.body.occupancyTypeId, 10)
)!
occupancyTypeFields.push(...result.occupancyTypeFields);
occupancyTypeFields.push(...(result.occupancyTypeFields ?? []))
response.json({
occupancyTypeFields
});
};
response.json({
occupancyTypeFields
})
}
export default handler;
export default handler

View File

@ -1,3 +1,3 @@
import type { RequestHandler } from "express";
import type { RequestHandler } from 'express';
export declare const handler: RequestHandler;
export default handler;

View File

@ -1,5 +1,5 @@
import { getLotTypeById } from "../../helpers/functions.cache.js";
export const handler = async (request, response) => {
import { getLotTypeById } from '../../helpers/functions.cache.js';
export const handler = (request, response) => {
const lotType = getLotTypeById(Number.parseInt(request.body.lotTypeId, 10));
response.json({
lotTypeFields: lotType.lotTypeFields

View File

@ -1,13 +1,13 @@
import type { RequestHandler } from "express";
import type { RequestHandler } from 'express'
import { getLotTypeById } from "../../helpers/functions.cache.js";
import { getLotTypeById } from '../../helpers/functions.cache.js'
export const handler: RequestHandler = async (request, response) => {
const lotType = getLotTypeById(Number.parseInt(request.body.lotTypeId, 10));
export const handler: RequestHandler = (request, response) => {
const lotType = getLotTypeById(Number.parseInt(request.body.lotTypeId, 10))!
response.json({
lotTypeFields: lotType.lotTypeFields
});
};
response.json({
lotTypeFields: lotType.lotTypeFields
})
}
export default handler;
export default handler

View File

@ -1,3 +1,3 @@
import type { RequestHandler } from "express";
import type { RequestHandler } from 'express';
export declare const handler: RequestHandler;
export default handler;

View File

@ -1,5 +1,5 @@
import { getReportData } from "../../helpers/lotOccupancyDB/getReportData.js";
import papaparse from "papaparse";
import { getReportData } from '../../helpers/lotOccupancyDB/getReportData.js';
import papaparse from 'papaparse';
export const handler = (request, response) => {
const reportName = request.params.reportName;
let rows;
@ -12,12 +12,12 @@ export const handler = (request, response) => {
if (!rows) {
return response.status(404).json({
success: false,
message: "Report Not Found"
message: 'Report Not Found'
});
}
const csv = papaparse.unparse(rows);
response.setHeader("Content-Disposition", "attachment; filename=" + reportName + "-" + Date.now().toString() + ".csv");
response.setHeader("Content-Type", "text/csv");
response.setHeader('Content-Disposition', 'attachment; filename=' + reportName + '-' + Date.now().toString() + '.csv');
response.setHeader('Content-Type', 'text/csv');
response.send(csv);
};
export default handler;

View File

@ -1,38 +1,41 @@
import type { RequestHandler } from "express";
import type { RequestHandler } from 'express'
import { getReportData, ReportParameters } from "../../helpers/lotOccupancyDB/getReportData.js";
import {
getReportData,
ReportParameters
} from '../../helpers/lotOccupancyDB/getReportData.js'
import papaparse from "papaparse";
import papaparse from 'papaparse'
export const handler: RequestHandler = (request, response) => {
const reportName = request.params.reportName;
const reportName = request.params.reportName
let rows: unknown[];
let rows: unknown[] | undefined
switch (reportName) {
default: {
rows = getReportData(reportName, request.query as ReportParameters);
break;
}
switch (reportName) {
default: {
rows = getReportData(reportName, request.query as ReportParameters)
break
}
}
if (!rows) {
return response.status(404).json({
success: false,
message: "Report Not Found"
});
}
if (!rows) {
return response.status(404).json({
success: false,
message: 'Report Not Found'
})
}
const csv = papaparse.unparse(rows);
const csv = papaparse.unparse(rows)
response.setHeader(
"Content-Disposition",
"attachment; filename=" + reportName + "-" + Date.now().toString() + ".csv"
);
response.setHeader(
'Content-Disposition',
'attachment; filename=' + reportName + '-' + Date.now().toString() + '.csv'
)
response.setHeader("Content-Type", "text/csv");
response.setHeader('Content-Type', 'text/csv')
response.send(csv);
};
response.send(csv)
}
export default handler;
export default handler

View File

@ -1,3 +1,3 @@
import type { RequestHandler } from "express";
import type { RequestHandler } from 'express';
export declare const handler: RequestHandler;
export default handler;

View File

@ -1,6 +1,6 @@
import { getLotStatuses, getWorkOrderMilestoneTypes, getWorkOrderTypes } from "../../helpers/functions.cache.js";
import * as configFunctions from "../../helpers/functions.config.js";
import { getWorkOrder } from "../../helpers/lotOccupancyDB/getWorkOrder.js";
import { getLotStatuses, getWorkOrderMilestoneTypes, getWorkOrderTypes } from '../../helpers/functions.cache.js';
import * as configFunctions from '../../helpers/functions.config.js';
import { getWorkOrder } from '../../helpers/lotOccupancyDB/getWorkOrder.js';
export const handler = (request, response) => {
const workOrder = getWorkOrder(request.params.workOrderId, {
includeLotsAndLotOccupancies: true,
@ -8,20 +8,22 @@ export const handler = (request, response) => {
includeMilestones: true
});
if (!workOrder) {
return response.redirect(configFunctions.getProperty("reverseProxy.urlPrefix") +
"/workOrders/?error=workOrderIdNotFound");
response.redirect(configFunctions.getProperty('reverseProxy.urlPrefix') +
'/workOrders/?error=workOrderIdNotFound');
return;
}
if (workOrder.workOrderCloseDate) {
return response.redirect(configFunctions.getProperty("reverseProxy.urlPrefix") +
"/workOrders/" +
response.redirect(configFunctions.getProperty('reverseProxy.urlPrefix') +
'/workOrders/' +
workOrder.workOrderId.toString() +
"/?error=workOrderIsClosed");
'/?error=workOrderIsClosed');
return;
}
const workOrderTypes = getWorkOrderTypes();
const workOrderMilestoneTypes = getWorkOrderMilestoneTypes();
const lotStatuses = getLotStatuses();
response.render("workOrder-edit", {
headTitle: "Work Order #" + workOrder.workOrderNumber,
response.render('workOrder-edit', {
headTitle: `Work Order #${workOrder.workOrderNumber}`,
workOrder,
isCreate: false,
workOrderTypes,

View File

@ -1,52 +1,54 @@
import type { RequestHandler } from "express";
import type { RequestHandler } from 'express'
import {
getLotStatuses,
getWorkOrderMilestoneTypes,
getWorkOrderTypes
} from "../../helpers/functions.cache.js";
getLotStatuses,
getWorkOrderMilestoneTypes,
getWorkOrderTypes
} from '../../helpers/functions.cache.js'
import * as configFunctions from "../../helpers/functions.config.js";
import * as configFunctions from '../../helpers/functions.config.js'
import { getWorkOrder } from "../../helpers/lotOccupancyDB/getWorkOrder.js";
import { getWorkOrder } from '../../helpers/lotOccupancyDB/getWorkOrder.js'
export const handler: RequestHandler = (request, response) => {
const workOrder = getWorkOrder(request.params.workOrderId, {
includeLotsAndLotOccupancies: true,
includeComments: true,
includeMilestones: true
});
const workOrder = getWorkOrder(request.params.workOrderId, {
includeLotsAndLotOccupancies: true,
includeComments: true,
includeMilestones: true
})
if (!workOrder) {
return response.redirect(
configFunctions.getProperty("reverseProxy.urlPrefix") +
"/workOrders/?error=workOrderIdNotFound"
);
}
if (!workOrder) {
response.redirect(
configFunctions.getProperty('reverseProxy.urlPrefix') +
'/workOrders/?error=workOrderIdNotFound'
)
return
}
if (workOrder.workOrderCloseDate) {
return response.redirect(
configFunctions.getProperty("reverseProxy.urlPrefix") +
"/workOrders/" +
workOrder.workOrderId.toString() +
"/?error=workOrderIsClosed"
);
}
if (workOrder.workOrderCloseDate) {
response.redirect(
configFunctions.getProperty('reverseProxy.urlPrefix') +
'/workOrders/' +
workOrder.workOrderId!.toString() +
'/?error=workOrderIsClosed'
)
return
}
const workOrderTypes = getWorkOrderTypes();
const workOrderTypes = getWorkOrderTypes()
const workOrderMilestoneTypes = getWorkOrderMilestoneTypes();
const workOrderMilestoneTypes = getWorkOrderMilestoneTypes()
const lotStatuses = getLotStatuses();
const lotStatuses = getLotStatuses()
response.render("workOrder-edit", {
headTitle: "Work Order #" + workOrder.workOrderNumber,
workOrder,
isCreate: false,
workOrderTypes,
workOrderMilestoneTypes,
lotStatuses
});
};
response.render('workOrder-edit', {
headTitle: `Work Order #${workOrder.workOrderNumber!}`,
workOrder,
isCreate: false,
workOrderTypes,
workOrderMilestoneTypes,
lotStatuses
})
}
export default handler;
export default handler

View File

@ -1,5 +1,5 @@
import * as recordTypes from "../types/recordTypes";
import * as recordTypes from '../types/recordTypes';
export declare function regenerateApiKey(userName: string): Promise<void>;
export declare function getApiKey(userName: string): Promise<string>;
export declare function getApiKeyFromSession(session: recordTypes.PartialSession): Promise<string>;
export declare function getUserNameFromApiKey(apiKey: string): Promise<string>;
export declare function getUserNameFromApiKey(apiKey: string): Promise<string | undefined>;

View File

@ -1,12 +1,12 @@
import fs from "node:fs/promises";
import { v4 as uuidv4 } from "uuid";
import Debug from "debug";
const debug = Debug("lot-occupancy-system:functions.api");
const apiKeyPath = "data/apiKeys.json";
import fs from 'node:fs/promises';
import { v4 as uuidv4 } from 'uuid';
import Debug from 'debug';
const debug = Debug('lot-occupancy-system:functions.api');
const apiKeyPath = 'data/apiKeys.json';
let apiKeys;
async function loadApiKeys() {
try {
const fileData = await fs.readFile(apiKeyPath, "utf8");
const fileData = await fs.readFile(apiKeyPath, 'utf8');
apiKeys = JSON.parse(fileData);
}
catch (error) {
@ -16,14 +16,14 @@ async function loadApiKeys() {
}
async function saveApiKeys() {
try {
await fs.writeFile(apiKeyPath, JSON.stringify(apiKeys), "utf8");
await fs.writeFile(apiKeyPath, JSON.stringify(apiKeys), 'utf8');
}
catch (error) {
debug(error);
}
}
function generateApiKey(apiKeyPrefix) {
return apiKeyPrefix + "-" + uuidv4() + "-" + Date.now();
return apiKeyPrefix + '-' + uuidv4() + '-' + Date.now();
}
export async function regenerateApiKey(userName) {
apiKeys[userName] = generateApiKey(userName);

View File

@ -1,66 +1,70 @@
import fs from "node:fs/promises";
import { v4 as uuidv4 } from "uuid";
import fs from 'node:fs/promises'
import { v4 as uuidv4 } from 'uuid'
import Debug from "debug";
import Debug from 'debug'
import * as recordTypes from "../types/recordTypes";
import * as recordTypes from '../types/recordTypes'
const debug = Debug("lot-occupancy-system:functions.api");
const debug = Debug('lot-occupancy-system:functions.api')
const apiKeyPath = "data/apiKeys.json";
let apiKeys: { [userName: string]: string };
const apiKeyPath = 'data/apiKeys.json'
let apiKeys: Record<string, string>
async function loadApiKeys() {
try {
const fileData = await fs.readFile(apiKeyPath, "utf8");
apiKeys = JSON.parse(fileData);
} catch (error) {
debug(error);
apiKeys = {};
}
}
async function saveApiKeys() {
try {
await fs.writeFile(apiKeyPath, JSON.stringify(apiKeys), "utf8");
} catch (error) {
debug(error);
}
}
function generateApiKey(apiKeyPrefix: string) {
return apiKeyPrefix + "-" + uuidv4() + "-" + Date.now();
}
export async function regenerateApiKey(userName: string) {
apiKeys[userName] = generateApiKey(userName);
await saveApiKeys();
}
export async function getApiKey(userName: string) {
if (!apiKeys) {
await loadApiKeys();
}
if (!apiKeys[userName]) {
await regenerateApiKey(userName);
}
return apiKeys[userName];
}
export async function getApiKeyFromSession(session: recordTypes.PartialSession) {
return await getApiKey(session.user.userName);
}
export async function getUserNameFromApiKey(apiKey: string) {
if (!apiKeys) {
await loadApiKeys();
}
for (const [userName, currentApiKey] of Object.entries(apiKeys)) {
if (apiKey === currentApiKey) {
return userName;
}
async function loadApiKeys(): Promise<void> {
try {
const fileData = await fs.readFile(apiKeyPath, 'utf8')
apiKeys = JSON.parse(fileData)
} catch (error) {
debug(error)
apiKeys = {}
}
}
async function saveApiKeys(): Promise<void> {
try {
await fs.writeFile(apiKeyPath, JSON.stringify(apiKeys), 'utf8')
} catch (error) {
debug(error)
}
}
function generateApiKey(apiKeyPrefix: string): string {
return apiKeyPrefix + '-' + uuidv4() + '-' + Date.now()
}
export async function regenerateApiKey(userName: string): Promise<void> {
apiKeys[userName] = generateApiKey(userName)
await saveApiKeys()
}
export async function getApiKey(userName: string): Promise<string> {
if (!apiKeys) {
await loadApiKeys()
}
if (!apiKeys[userName]) {
await regenerateApiKey(userName)
}
return apiKeys[userName]
}
export async function getApiKeyFromSession(
session: recordTypes.PartialSession
): Promise<string> {
return await getApiKey(session.user!.userName)
}
export async function getUserNameFromApiKey(
apiKey: string
): Promise<string | undefined> {
if (!apiKeys) {
await loadApiKeys()
}
for (const [userName, currentApiKey] of Object.entries(apiKeys)) {
if (apiKey === currentApiKey) {
return userName
}
}
}

View File

@ -13,7 +13,7 @@ async function authenticateViaActiveDirectory(userName, password) {
resolve(auth);
});
}
catch (_a) {
catch {
resolve(false);
}
});

View File

@ -1,21 +1,21 @@
import type * as recordTypes from "../types/recordTypes";
import type * as recordTypes from '../types/recordTypes';
export declare function getLotOccupantTypes(): recordTypes.LotOccupantType[];
export declare function getLotOccupantTypeById(lotOccupantTypeId: number): recordTypes.LotOccupantType;
export declare function getLotOccupantTypeByLotOccupantType(lotOccupantType: string): recordTypes.LotOccupantType;
export declare function getLotOccupantTypeById(lotOccupantTypeId: number): recordTypes.LotOccupantType | undefined;
export declare function getLotOccupantTypeByLotOccupantType(lotOccupantType: string): recordTypes.LotOccupantType | undefined;
export declare function getLotStatuses(): recordTypes.LotStatus[];
export declare function getLotStatusById(lotStatusId: number): recordTypes.LotStatus;
export declare function getLotStatusByLotStatus(lotStatus: string): recordTypes.LotStatus;
export declare function getLotStatusById(lotStatusId: number): recordTypes.LotStatus | undefined;
export declare function getLotStatusByLotStatus(lotStatus: string): recordTypes.LotStatus | undefined;
export declare function getLotTypes(): recordTypes.LotType[];
export declare function getLotTypeById(lotTypeId: number): recordTypes.LotType;
export declare function getLotTypesByLotType(lotType: string): recordTypes.LotType;
export declare function getLotTypeById(lotTypeId: number): recordTypes.LotType | undefined;
export declare function getLotTypesByLotType(lotType: string): recordTypes.LotType | undefined;
export declare function getOccupancyTypes(): recordTypes.OccupancyType[];
export declare function getAllOccupancyTypeFields(): recordTypes.OccupancyTypeField[];
export declare function getOccupancyTypeById(occupancyTypeId: number): recordTypes.OccupancyType;
export declare function getOccupancyTypeByOccupancyType(occupancyTypeString: string): recordTypes.OccupancyType;
export declare function getOccupancyTypeById(occupancyTypeId: number): recordTypes.OccupancyType | undefined;
export declare function getOccupancyTypeByOccupancyType(occupancyTypeString: string): recordTypes.OccupancyType | undefined;
export declare function getOccupancyTypePrintsById(occupancyTypeId: number): string[];
export declare function getWorkOrderTypes(): recordTypes.WorkOrderType[];
export declare function getWorkOrderTypeById(workOrderTypeId: number): recordTypes.WorkOrderType;
export declare function getWorkOrderTypeById(workOrderTypeId: number): recordTypes.WorkOrderType | undefined;
export declare function getWorkOrderMilestoneTypes(): recordTypes.WorkOrderMilestoneType[];
export declare function getWorkOrderMilestoneTypeByWorkOrderMilestoneTypeId(workOrderMilestoneTypeId: number): recordTypes.WorkOrderMilestoneType;
export declare function getWorkOrderMilestoneTypeByWorkOrderMilestoneType(workOrderMilestoneTypeString: string): recordTypes.WorkOrderMilestoneType;
export declare function getWorkOrderMilestoneTypeByWorkOrderMilestoneTypeId(workOrderMilestoneTypeId: number): recordTypes.WorkOrderMilestoneType | undefined;
export declare function getWorkOrderMilestoneTypeByWorkOrderMilestoneType(workOrderMilestoneTypeString: string): recordTypes.WorkOrderMilestoneType | undefined;
export declare function clearCacheByTableName(tableName: string): void;

View File

@ -1,11 +1,11 @@
import * as configFunctions from "./functions.config.js";
import { getLotOccupantTypes as getLotOccupantTypesFromDatabase } from "./lotOccupancyDB/getLotOccupantTypes.js";
import { getLotStatuses as getLotStatusesFromDatabase } from "./lotOccupancyDB/getLotStatuses.js";
import { getLotTypes as getLotTypesFromDatabase } from "./lotOccupancyDB/getLotTypes.js";
import { getOccupancyTypes as getOccupancyTypesFromDatabase } from "./lotOccupancyDB/getOccupancyTypes.js";
import { getOccupancyTypeFields as getOccupancyTypeFieldsFromDatabase } from "./lotOccupancyDB/getOccupancyTypeFields.js";
import { getWorkOrderTypes as getWorkOrderTypesFromDatabase } from "./lotOccupancyDB/getWorkOrderTypes.js";
import { getWorkOrderMilestoneTypes as getWorkOrderMilestoneTypesFromDatabase } from "./lotOccupancyDB/getWorkOrderMilestoneTypes.js";
import * as configFunctions from './functions.config.js';
import { getLotOccupantTypes as getLotOccupantTypesFromDatabase } from './lotOccupancyDB/getLotOccupantTypes.js';
import { getLotStatuses as getLotStatusesFromDatabase } from './lotOccupancyDB/getLotStatuses.js';
import { getLotTypes as getLotTypesFromDatabase } from './lotOccupancyDB/getLotTypes.js';
import { getOccupancyTypes as getOccupancyTypesFromDatabase } from './lotOccupancyDB/getOccupancyTypes.js';
import { getOccupancyTypeFields as getOccupancyTypeFieldsFromDatabase } from './lotOccupancyDB/getOccupancyTypeFields.js';
import { getWorkOrderTypes as getWorkOrderTypesFromDatabase } from './lotOccupancyDB/getWorkOrderTypes.js';
import { getWorkOrderMilestoneTypes as getWorkOrderMilestoneTypesFromDatabase } from './lotOccupancyDB/getWorkOrderMilestoneTypes.js';
let lotOccupantTypes;
export function getLotOccupantTypes() {
if (!lotOccupantTypes) {
@ -23,7 +23,8 @@ export function getLotOccupantTypeByLotOccupantType(lotOccupantType) {
const cachedLotOccupantTypes = getLotOccupantTypes();
const lotOccupantTypeLowerCase = lotOccupantType.toLowerCase();
return cachedLotOccupantTypes.find((currentLotOccupantType) => {
return currentLotOccupantType.lotOccupantType.toLowerCase() === lotOccupantTypeLowerCase;
return (currentLotOccupantType.lotOccupantType.toLowerCase() ===
lotOccupantTypeLowerCase);
});
}
function clearLotOccupantTypesCache() {
@ -99,16 +100,18 @@ export function getOccupancyTypeByOccupancyType(occupancyTypeString) {
const cachedOccupancyTypes = getOccupancyTypes();
const occupancyTypeLowerCase = occupancyTypeString.toLowerCase();
return cachedOccupancyTypes.find((currentOccupancyType) => {
return currentOccupancyType.occupancyType.toLowerCase() === occupancyTypeLowerCase;
return (currentOccupancyType.occupancyType.toLowerCase() ===
occupancyTypeLowerCase);
});
}
export function getOccupancyTypePrintsById(occupancyTypeId) {
const occupancyType = getOccupancyTypeById(occupancyTypeId);
if (!occupancyType || occupancyType.occupancyTypePrints.length === 0) {
if (!occupancyType ||
(occupancyType.occupancyTypePrints ?? []).length === 0) {
return [];
}
if (occupancyType.occupancyTypePrints.includes("*")) {
return configFunctions.getProperty("settings.lotOccupancy.prints");
if (occupancyType.occupancyTypePrints.includes('*')) {
return configFunctions.getProperty('settings.lotOccupancy.prints');
}
return occupancyType.occupancyTypePrints;
}
@ -142,7 +145,8 @@ export function getWorkOrderMilestoneTypes() {
export function getWorkOrderMilestoneTypeByWorkOrderMilestoneTypeId(workOrderMilestoneTypeId) {
const cachedWorkOrderMilestoneTypes = getWorkOrderMilestoneTypes();
return cachedWorkOrderMilestoneTypes.find((currentWorkOrderMilestoneType) => {
return currentWorkOrderMilestoneType.workOrderMilestoneTypeId === workOrderMilestoneTypeId;
return (currentWorkOrderMilestoneType.workOrderMilestoneTypeId ===
workOrderMilestoneTypeId);
});
}
export function getWorkOrderMilestoneTypeByWorkOrderMilestoneType(workOrderMilestoneTypeString) {
@ -158,30 +162,30 @@ function clearWorkOrderMilestoneTypesCache() {
}
export function clearCacheByTableName(tableName) {
switch (tableName) {
case "LotOccupantTypes": {
case 'LotOccupantTypes': {
clearLotOccupantTypesCache();
break;
}
case "LotStatuses": {
case 'LotStatuses': {
clearLotStatusesCache();
break;
}
case "LotTypes":
case "LotTypeFields": {
case 'LotTypes':
case 'LotTypeFields': {
clearLotTypesCache();
break;
}
case "OccupancyTypes":
case "OccupancyTypeFields":
case "OccupancyTypePrints": {
case 'OccupancyTypes':
case 'OccupancyTypeFields':
case 'OccupancyTypePrints': {
clearOccupancyTypesCache();
break;
}
case "WorkOrderMilestoneTypes": {
case 'WorkOrderMilestoneTypes': {
clearWorkOrderMilestoneTypesCache();
break;
}
case "WorkOrderTypes": {
case 'WorkOrderTypes': {
clearWorkOrderTypesCache();
break;
}

View File

@ -1,285 +1,320 @@
import * as configFunctions from "./functions.config.js";
import * as configFunctions from './functions.config.js'
import { getLotOccupantTypes as getLotOccupantTypesFromDatabase } from "./lotOccupancyDB/getLotOccupantTypes.js";
import { getLotOccupantTypes as getLotOccupantTypesFromDatabase } from './lotOccupancyDB/getLotOccupantTypes.js'
import { getLotStatuses as getLotStatusesFromDatabase } from "./lotOccupancyDB/getLotStatuses.js";
import { getLotStatuses as getLotStatusesFromDatabase } from './lotOccupancyDB/getLotStatuses.js'
import { getLotTypes as getLotTypesFromDatabase } from "./lotOccupancyDB/getLotTypes.js";
import { getLotTypes as getLotTypesFromDatabase } from './lotOccupancyDB/getLotTypes.js'
import { getOccupancyTypes as getOccupancyTypesFromDatabase } from "./lotOccupancyDB/getOccupancyTypes.js";
import { getOccupancyTypeFields as getOccupancyTypeFieldsFromDatabase } from "./lotOccupancyDB/getOccupancyTypeFields.js";
import { getOccupancyTypes as getOccupancyTypesFromDatabase } from './lotOccupancyDB/getOccupancyTypes.js'
import { getOccupancyTypeFields as getOccupancyTypeFieldsFromDatabase } from './lotOccupancyDB/getOccupancyTypeFields.js'
import { getWorkOrderTypes as getWorkOrderTypesFromDatabase } from "./lotOccupancyDB/getWorkOrderTypes.js";
import { getWorkOrderTypes as getWorkOrderTypesFromDatabase } from './lotOccupancyDB/getWorkOrderTypes.js'
import { getWorkOrderMilestoneTypes as getWorkOrderMilestoneTypesFromDatabase } from "./lotOccupancyDB/getWorkOrderMilestoneTypes.js";
import { getWorkOrderMilestoneTypes as getWorkOrderMilestoneTypesFromDatabase } from './lotOccupancyDB/getWorkOrderMilestoneTypes.js'
import type * as recordTypes from "../types/recordTypes";
import type * as recordTypes from '../types/recordTypes'
/*
* Lot Occupant Types
*/
let lotOccupantTypes: recordTypes.LotOccupantType[] | undefined;
let lotOccupantTypes: recordTypes.LotOccupantType[] | undefined
export function getLotOccupantTypes() {
if (!lotOccupantTypes) {
lotOccupantTypes = getLotOccupantTypesFromDatabase();
}
export function getLotOccupantTypes(): recordTypes.LotOccupantType[] {
if (!lotOccupantTypes) {
lotOccupantTypes = getLotOccupantTypesFromDatabase()
}
return lotOccupantTypes;
return lotOccupantTypes
}
export function getLotOccupantTypeById(lotOccupantTypeId: number) {
const cachedLotOccupantTypes = getLotOccupantTypes();
export function getLotOccupantTypeById(
lotOccupantTypeId: number
): recordTypes.LotOccupantType | undefined {
const cachedLotOccupantTypes = getLotOccupantTypes()
return cachedLotOccupantTypes.find((currentLotOccupantType) => {
return currentLotOccupantType.lotOccupantTypeId === lotOccupantTypeId;
});
return cachedLotOccupantTypes.find((currentLotOccupantType) => {
return currentLotOccupantType.lotOccupantTypeId === lotOccupantTypeId
})
}
export function getLotOccupantTypeByLotOccupantType(lotOccupantType: string) {
const cachedLotOccupantTypes = getLotOccupantTypes();
export function getLotOccupantTypeByLotOccupantType(
lotOccupantType: string
): recordTypes.LotOccupantType | undefined {
const cachedLotOccupantTypes = getLotOccupantTypes()
const lotOccupantTypeLowerCase = lotOccupantType.toLowerCase();
const lotOccupantTypeLowerCase = lotOccupantType.toLowerCase()
return cachedLotOccupantTypes.find((currentLotOccupantType) => {
return currentLotOccupantType.lotOccupantType.toLowerCase() === lotOccupantTypeLowerCase;
});
return cachedLotOccupantTypes.find((currentLotOccupantType) => {
return (
currentLotOccupantType.lotOccupantType.toLowerCase() ===
lotOccupantTypeLowerCase
)
})
}
function clearLotOccupantTypesCache() {
lotOccupantTypes = undefined;
function clearLotOccupantTypesCache(): void {
lotOccupantTypes = undefined
}
/*
* Lot Statuses
*/
let lotStatuses: recordTypes.LotStatus[] | undefined;
let lotStatuses: recordTypes.LotStatus[] | undefined
export function getLotStatuses() {
if (!lotStatuses) {
lotStatuses = getLotStatusesFromDatabase();
}
export function getLotStatuses(): recordTypes.LotStatus[] {
if (!lotStatuses) {
lotStatuses = getLotStatusesFromDatabase()
}
return lotStatuses;
return lotStatuses
}
export function getLotStatusById(lotStatusId: number) {
const cachedLotStatuses = getLotStatuses();
export function getLotStatusById(
lotStatusId: number
): recordTypes.LotStatus | undefined {
const cachedLotStatuses = getLotStatuses()
return cachedLotStatuses.find((currentLotStatus) => {
return currentLotStatus.lotStatusId === lotStatusId;
});
return cachedLotStatuses.find((currentLotStatus) => {
return currentLotStatus.lotStatusId === lotStatusId
})
}
export function getLotStatusByLotStatus(lotStatus: string) {
const cachedLotStatuses = getLotStatuses();
export function getLotStatusByLotStatus(
lotStatus: string
): recordTypes.LotStatus | undefined {
const cachedLotStatuses = getLotStatuses()
const lotStatusLowerCase = lotStatus.toLowerCase();
const lotStatusLowerCase = lotStatus.toLowerCase()
return cachedLotStatuses.find((currentLotStatus) => {
return currentLotStatus.lotStatus.toLowerCase() === lotStatusLowerCase;
});
return cachedLotStatuses.find((currentLotStatus) => {
return currentLotStatus.lotStatus.toLowerCase() === lotStatusLowerCase
})
}
function clearLotStatusesCache() {
lotStatuses = undefined;
function clearLotStatusesCache(): void {
lotStatuses = undefined
}
/*
* Lot Types
*/
let lotTypes: recordTypes.LotType[] | undefined;
let lotTypes: recordTypes.LotType[] | undefined
export function getLotTypes() {
if (!lotTypes) {
lotTypes = getLotTypesFromDatabase();
}
export function getLotTypes(): recordTypes.LotType[] {
if (!lotTypes) {
lotTypes = getLotTypesFromDatabase()
}
return lotTypes;
return lotTypes
}
export function getLotTypeById(lotTypeId: number) {
const cachedLotTypes = getLotTypes();
export function getLotTypeById(
lotTypeId: number
): recordTypes.LotType | undefined {
const cachedLotTypes = getLotTypes()
return cachedLotTypes.find((currentLotType) => {
return currentLotType.lotTypeId === lotTypeId;
});
return cachedLotTypes.find((currentLotType) => {
return currentLotType.lotTypeId === lotTypeId
})
}
export function getLotTypesByLotType(lotType: string) {
const cachedLotTypes = getLotTypes();
export function getLotTypesByLotType(
lotType: string
): recordTypes.LotType | undefined {
const cachedLotTypes = getLotTypes()
const lotTypeLowerCase = lotType.toLowerCase();
const lotTypeLowerCase = lotType.toLowerCase()
return cachedLotTypes.find((currentLotType) => {
return currentLotType.lotType.toLowerCase() === lotTypeLowerCase;
});
return cachedLotTypes.find((currentLotType) => {
return currentLotType.lotType.toLowerCase() === lotTypeLowerCase
})
}
function clearLotTypesCache() {
lotTypes = undefined;
function clearLotTypesCache(): void {
lotTypes = undefined
}
/*
* Occupancy Types
*/
let occupancyTypes: recordTypes.OccupancyType[] | undefined;
let allOccupancyTypeFields: recordTypes.OccupancyTypeField[] | undefined;
let occupancyTypes: recordTypes.OccupancyType[] | undefined
let allOccupancyTypeFields: recordTypes.OccupancyTypeField[] | undefined
export function getOccupancyTypes() {
if (!occupancyTypes) {
occupancyTypes = getOccupancyTypesFromDatabase();
}
export function getOccupancyTypes(): recordTypes.OccupancyType[] {
if (!occupancyTypes) {
occupancyTypes = getOccupancyTypesFromDatabase()
}
return occupancyTypes;
return occupancyTypes
}
export function getAllOccupancyTypeFields() {
if (!allOccupancyTypeFields) {
allOccupancyTypeFields = getOccupancyTypeFieldsFromDatabase();
}
return allOccupancyTypeFields;
export function getAllOccupancyTypeFields(): recordTypes.OccupancyTypeField[] {
if (!allOccupancyTypeFields) {
allOccupancyTypeFields = getOccupancyTypeFieldsFromDatabase()
}
return allOccupancyTypeFields
}
export function getOccupancyTypeById(occupancyTypeId: number) {
const cachedOccupancyTypes = getOccupancyTypes();
export function getOccupancyTypeById(
occupancyTypeId: number
): recordTypes.OccupancyType | undefined {
const cachedOccupancyTypes = getOccupancyTypes()
return cachedOccupancyTypes.find((currentOccupancyType) => {
return currentOccupancyType.occupancyTypeId === occupancyTypeId;
});
return cachedOccupancyTypes.find((currentOccupancyType) => {
return currentOccupancyType.occupancyTypeId === occupancyTypeId
})
}
export function getOccupancyTypeByOccupancyType(occupancyTypeString: string) {
const cachedOccupancyTypes = getOccupancyTypes();
export function getOccupancyTypeByOccupancyType(
occupancyTypeString: string
): recordTypes.OccupancyType | undefined {
const cachedOccupancyTypes = getOccupancyTypes()
const occupancyTypeLowerCase = occupancyTypeString.toLowerCase();
const occupancyTypeLowerCase = occupancyTypeString.toLowerCase()
return cachedOccupancyTypes.find((currentOccupancyType) => {
return currentOccupancyType.occupancyType.toLowerCase() === occupancyTypeLowerCase;
});
return cachedOccupancyTypes.find((currentOccupancyType) => {
return (
currentOccupancyType.occupancyType.toLowerCase() ===
occupancyTypeLowerCase
)
})
}
export function getOccupancyTypePrintsById(occupancyTypeId: number): string[] {
const occupancyType = getOccupancyTypeById(occupancyTypeId);
const occupancyType = getOccupancyTypeById(occupancyTypeId)
if (!occupancyType || occupancyType.occupancyTypePrints.length === 0) {
return [];
}
if (
!occupancyType ||
(occupancyType.occupancyTypePrints ?? []).length === 0
) {
return []
}
if (occupancyType.occupancyTypePrints.includes("*")) {
return configFunctions.getProperty("settings.lotOccupancy.prints");
}
if (occupancyType.occupancyTypePrints!.includes('*')) {
return configFunctions.getProperty('settings.lotOccupancy.prints')
}
return occupancyType.occupancyTypePrints;
return occupancyType.occupancyTypePrints!
}
function clearOccupancyTypesCache() {
occupancyTypes = undefined;
allOccupancyTypeFields = undefined;
function clearOccupancyTypesCache(): void {
occupancyTypes = undefined
allOccupancyTypeFields = undefined
}
/*
* Work Order Types
*/
let workOrderTypes: recordTypes.WorkOrderType[] | undefined;
let workOrderTypes: recordTypes.WorkOrderType[] | undefined
export function getWorkOrderTypes() {
if (!workOrderTypes) {
workOrderTypes = getWorkOrderTypesFromDatabase();
}
export function getWorkOrderTypes(): recordTypes.WorkOrderType[] {
if (!workOrderTypes) {
workOrderTypes = getWorkOrderTypesFromDatabase()
}
return workOrderTypes;
return workOrderTypes
}
export function getWorkOrderTypeById(workOrderTypeId: number) {
const cachedWorkOrderTypes = getWorkOrderTypes();
export function getWorkOrderTypeById(
workOrderTypeId: number
): recordTypes.WorkOrderType | undefined {
const cachedWorkOrderTypes = getWorkOrderTypes()
return cachedWorkOrderTypes.find((currentWorkOrderType) => {
return currentWorkOrderType.workOrderTypeId === workOrderTypeId;
});
return cachedWorkOrderTypes.find((currentWorkOrderType) => {
return currentWorkOrderType.workOrderTypeId === workOrderTypeId
})
}
function clearWorkOrderTypesCache() {
workOrderTypes = undefined;
function clearWorkOrderTypesCache(): void {
workOrderTypes = undefined
}
/*
* Work Order Milestone Types
*/
let workOrderMilestoneTypes: recordTypes.WorkOrderMilestoneType[] | undefined;
let workOrderMilestoneTypes: recordTypes.WorkOrderMilestoneType[] | undefined
export function getWorkOrderMilestoneTypes() {
if (!workOrderMilestoneTypes) {
workOrderMilestoneTypes = getWorkOrderMilestoneTypesFromDatabase();
export function getWorkOrderMilestoneTypes(): recordTypes.WorkOrderMilestoneType[] {
if (!workOrderMilestoneTypes) {
workOrderMilestoneTypes = getWorkOrderMilestoneTypesFromDatabase()
}
return workOrderMilestoneTypes
}
export function getWorkOrderMilestoneTypeByWorkOrderMilestoneTypeId(
workOrderMilestoneTypeId: number
): recordTypes.WorkOrderMilestoneType | undefined {
const cachedWorkOrderMilestoneTypes = getWorkOrderMilestoneTypes()
return cachedWorkOrderMilestoneTypes.find((currentWorkOrderMilestoneType) => {
return (
currentWorkOrderMilestoneType.workOrderMilestoneTypeId ===
workOrderMilestoneTypeId
)
})
}
export function getWorkOrderMilestoneTypeByWorkOrderMilestoneType(
workOrderMilestoneTypeString: string
): recordTypes.WorkOrderMilestoneType | undefined {
const cachedWorkOrderMilestoneTypes = getWorkOrderMilestoneTypes()
const workOrderMilestoneTypeLowerCase =
workOrderMilestoneTypeString.toLowerCase()
return cachedWorkOrderMilestoneTypes.find((currentWorkOrderMilestoneType) => {
return (
currentWorkOrderMilestoneType.workOrderMilestoneType.toLowerCase() ===
workOrderMilestoneTypeLowerCase
)
})
}
function clearWorkOrderMilestoneTypesCache(): void {
workOrderMilestoneTypes = undefined
}
export function clearCacheByTableName(tableName: string): void {
switch (tableName) {
case 'LotOccupantTypes': {
clearLotOccupantTypesCache()
break
}
return workOrderMilestoneTypes;
}
export function getWorkOrderMilestoneTypeByWorkOrderMilestoneTypeId(workOrderMilestoneTypeId: number) {
const cachedWorkOrderMilestoneTypes = getWorkOrderMilestoneTypes();
return cachedWorkOrderMilestoneTypes.find((currentWorkOrderMilestoneType) => {
return currentWorkOrderMilestoneType.workOrderMilestoneTypeId === workOrderMilestoneTypeId;
});
}
export function getWorkOrderMilestoneTypeByWorkOrderMilestoneType(workOrderMilestoneTypeString: string) {
const cachedWorkOrderMilestoneTypes = getWorkOrderMilestoneTypes();
const workOrderMilestoneTypeLowerCase = workOrderMilestoneTypeString.toLowerCase();
return cachedWorkOrderMilestoneTypes.find((currentWorkOrderMilestoneType) => {
return (
currentWorkOrderMilestoneType.workOrderMilestoneType.toLowerCase() ===
workOrderMilestoneTypeLowerCase
);
});
}
function clearWorkOrderMilestoneTypesCache() {
workOrderMilestoneTypes = undefined;
}
export function clearCacheByTableName(tableName: string) {
switch (tableName) {
case "LotOccupantTypes": {
clearLotOccupantTypesCache();
break;
}
case "LotStatuses": {
clearLotStatusesCache();
break;
}
case "LotTypes":
case "LotTypeFields": {
clearLotTypesCache();
break;
}
case "OccupancyTypes":
case "OccupancyTypeFields":
case "OccupancyTypePrints": {
clearOccupancyTypesCache();
break;
}
case "WorkOrderMilestoneTypes": {
clearWorkOrderMilestoneTypesCache();
break;
}
case "WorkOrderTypes": {
clearWorkOrderTypesCache();
break;
}
case 'LotStatuses': {
clearLotStatusesCache()
break
}
case 'LotTypes':
case 'LotTypeFields': {
clearLotTypesCache()
break
}
case 'OccupancyTypes':
case 'OccupancyTypeFields':
case 'OccupancyTypePrints': {
clearOccupancyTypesCache()
break
}
case 'WorkOrderMilestoneTypes': {
clearWorkOrderMilestoneTypesCache()
break
}
case 'WorkOrderTypes': {
clearWorkOrderTypesCache()
break
}
}
}

View File

@ -1,11 +1,11 @@
import faIcons from "font-awesome-v5-icons";
import faIcons from 'font-awesome-v5-icons';
let solidIcons = [];
export async function getSolidIconClasses() {
if (solidIcons.length === 0) {
const allIcons = await faIcons.getListByKeys(["name", "styles"]);
const allIcons = await faIcons.getListByKeys(['name', 'styles']);
const list = [];
for (const icon of allIcons) {
if (icon.styles.includes("solid")) {
if ((icon.styles ?? []).includes('solid')) {
list.push(icon.name);
}
}

View File

@ -1,21 +1,21 @@
import faIcons from "font-awesome-v5-icons";
import faIcons from 'font-awesome-v5-icons'
let solidIcons: string[] = [];
let solidIcons: string[] = []
export async function getSolidIconClasses() {
if (solidIcons.length === 0) {
const allIcons = await faIcons.getListByKeys(["name", "styles"]);
export async function getSolidIconClasses(): Promise<string[]> {
if (solidIcons.length === 0) {
const allIcons = await faIcons.getListByKeys(['name', 'styles'])
const list: string[] = [];
const list: string[] = []
for (const icon of allIcons) {
if (icon.styles.includes("solid")) {
list.push(icon.name);
}
}
solidIcons = list;
for (const icon of allIcons) {
if ((icon.styles ?? []).includes('solid')) {
list.push(icon.name!)
}
}
return solidIcons;
solidIcons = list
}
return solidIcons
}

View File

@ -1,15 +1,10 @@
declare type LotNameSearchType = "startsWith" | "endsWith" | "";
export declare function getLotNameWhereClause(lotName: string, lotNameSearchType: LotNameSearchType, lotsTableAlias?: string): {
declare type LotNameSearchType = 'startsWith' | 'endsWith' | '';
interface WhereClauseReturn {
sqlWhereClause: string;
sqlParameters: any[];
};
declare type OccupancyTime = "" | "current" | "past" | "future";
export declare function getOccupancyTimeWhereClause(occupancyTime: OccupancyTime, lotOccupanciesTableAlias?: string): {
sqlWhereClause: string;
sqlParameters: any[];
};
export declare function getOccupantNameWhereClause(occupantName: string, tableAlias?: string): {
sqlWhereClause: string;
sqlParameters: any[];
};
sqlParameters: unknown[];
}
export declare function getLotNameWhereClause(lotName: string, lotNameSearchType: LotNameSearchType, lotsTableAlias?: string): WhereClauseReturn;
declare type OccupancyTime = '' | 'current' | 'past' | 'future';
export declare function getOccupancyTimeWhereClause(occupancyTime: OccupancyTime, lotOccupanciesTableAlias?: string): WhereClauseReturn;
export declare function getOccupantNameWhereClause(occupantName: string, tableAlias?: string): WhereClauseReturn;
export {};

View File

@ -1,23 +1,24 @@
import { dateToInteger } from "@cityssm/expressjs-server-js/dateTimeFns.js";
export function getLotNameWhereClause(lotName, lotNameSearchType, lotsTableAlias = "l") {
let sqlWhereClause = "";
import { dateToInteger } from '@cityssm/expressjs-server-js/dateTimeFns.js';
export function getLotNameWhereClause(lotName, lotNameSearchType, lotsTableAlias = 'l') {
let sqlWhereClause = '';
const sqlParameters = [];
if (lotName) {
if (lotName !== '') {
switch (lotNameSearchType) {
case "startsWith": {
sqlWhereClause += " and " + lotsTableAlias + ".lotName like ? || '%'";
case 'startsWith': {
sqlWhereClause += ' and ' + lotsTableAlias + ".lotName like ? || '%'";
sqlParameters.push(lotName);
break;
}
case "endsWith": {
sqlWhereClause += " and " + lotsTableAlias + ".lotName like '%' || ?";
case 'endsWith': {
sqlWhereClause += ' and ' + lotsTableAlias + ".lotName like '%' || ?";
sqlParameters.push(lotName);
break;
}
default: {
const lotNamePieces = lotName.toLowerCase().split(" ");
const lotNamePieces = lotName.toLowerCase().split(' ');
for (const lotNamePiece of lotNamePieces) {
sqlWhereClause += " and instr(lower(" + lotsTableAlias + ".lotName), ?)";
sqlWhereClause +=
' and instr(lower(' + lotsTableAlias + '.lotName), ?)';
sqlParameters.push(lotNamePiece);
}
}
@ -28,31 +29,33 @@ export function getLotNameWhereClause(lotName, lotNameSearchType, lotsTableAlias
sqlParameters
};
}
export function getOccupancyTimeWhereClause(occupancyTime, lotOccupanciesTableAlias = "o") {
let sqlWhereClause = "";
export function getOccupancyTimeWhereClause(occupancyTime, lotOccupanciesTableAlias = 'o') {
let sqlWhereClause = '';
const sqlParameters = [];
if (occupancyTime) {
if (occupancyTime !== '') {
const currentDateString = dateToInteger(new Date());
switch (occupancyTime) {
case "current": {
case 'current': {
sqlWhereClause +=
" and " +
' and ' +
lotOccupanciesTableAlias +
".occupancyStartDate <= ? and (" +
'.occupancyStartDate <= ? and (' +
lotOccupanciesTableAlias +
".occupancyEndDate is null or " +
'.occupancyEndDate is null or ' +
lotOccupanciesTableAlias +
".occupancyEndDate >= ?)";
'.occupancyEndDate >= ?)';
sqlParameters.push(currentDateString, currentDateString);
break;
}
case "past": {
sqlWhereClause += " and " + lotOccupanciesTableAlias + ".occupancyEndDate < ?";
case 'past': {
sqlWhereClause +=
' and ' + lotOccupanciesTableAlias + '.occupancyEndDate < ?';
sqlParameters.push(currentDateString);
break;
}
case "future": {
sqlWhereClause += " and " + lotOccupanciesTableAlias + ".occupancyStartDate > ?";
case 'future': {
sqlWhereClause +=
' and ' + lotOccupanciesTableAlias + '.occupancyStartDate > ?';
sqlParameters.push(currentDateString);
break;
}
@ -63,13 +66,13 @@ export function getOccupancyTimeWhereClause(occupancyTime, lotOccupanciesTableAl
sqlParameters
};
}
export function getOccupantNameWhereClause(occupantName, tableAlias = "o") {
let sqlWhereClause = "";
export function getOccupantNameWhereClause(occupantName, tableAlias = 'o') {
let sqlWhereClause = '';
const sqlParameters = [];
if (occupantName) {
const occupantNamePieces = occupantName.toLowerCase().split(" ");
if (occupantName !== '') {
const occupantNamePieces = occupantName.toLowerCase().split(' ');
for (const occupantNamePiece of occupantNamePieces) {
sqlWhereClause += " and instr(lower(" + tableAlias + ".occupantName), ?)";
sqlWhereClause += ' and instr(lower(' + tableAlias + '.occupantName), ?)';
sqlParameters.push(occupantNamePiece);
}
}

View File

@ -1,103 +1,114 @@
import { dateToInteger } from "@cityssm/expressjs-server-js/dateTimeFns.js";
import { dateToInteger } from '@cityssm/expressjs-server-js/dateTimeFns.js'
type LotNameSearchType = "startsWith" | "endsWith" | "";
type LotNameSearchType = 'startsWith' | 'endsWith' | ''
interface WhereClauseReturn {
sqlWhereClause: string
sqlParameters: unknown[]
}
export function getLotNameWhereClause(
lotName: string,
lotNameSearchType: LotNameSearchType,
lotsTableAlias = "l"
) {
let sqlWhereClause = "";
const sqlParameters = [];
lotName: string,
lotNameSearchType: LotNameSearchType,
lotsTableAlias = 'l'
): WhereClauseReturn {
let sqlWhereClause = ''
const sqlParameters: unknown[] = []
if (lotName) {
switch (lotNameSearchType) {
case "startsWith": {
sqlWhereClause += " and " + lotsTableAlias + ".lotName like ? || '%'";
sqlParameters.push(lotName);
break;
}
case "endsWith": {
sqlWhereClause += " and " + lotsTableAlias + ".lotName like '%' || ?";
sqlParameters.push(lotName);
break;
}
default: {
const lotNamePieces = lotName.toLowerCase().split(" ");
for (const lotNamePiece of lotNamePieces) {
sqlWhereClause += " and instr(lower(" + lotsTableAlias + ".lotName), ?)";
sqlParameters.push(lotNamePiece);
}
}
if (lotName !== '') {
switch (lotNameSearchType) {
case 'startsWith': {
sqlWhereClause += ' and ' + lotsTableAlias + ".lotName like ? || '%'"
sqlParameters.push(lotName)
break
}
case 'endsWith': {
sqlWhereClause += ' and ' + lotsTableAlias + ".lotName like '%' || ?"
sqlParameters.push(lotName)
break
}
default: {
const lotNamePieces = lotName.toLowerCase().split(' ')
for (const lotNamePiece of lotNamePieces) {
sqlWhereClause +=
' and instr(lower(' + lotsTableAlias + '.lotName), ?)'
sqlParameters.push(lotNamePiece)
}
}
}
}
return {
sqlWhereClause,
sqlParameters
};
return {
sqlWhereClause,
sqlParameters
}
}
type OccupancyTime = "" | "current" | "past" | "future";
type OccupancyTime = '' | 'current' | 'past' | 'future'
export function getOccupancyTimeWhereClause(
occupancyTime: OccupancyTime,
lotOccupanciesTableAlias = "o"
) {
let sqlWhereClause = "";
const sqlParameters = [];
occupancyTime: OccupancyTime,
lotOccupanciesTableAlias = 'o'
): WhereClauseReturn {
let sqlWhereClause = ''
const sqlParameters: unknown[] = []
if (occupancyTime) {
const currentDateString = dateToInteger(new Date());
if (occupancyTime !== '') {
const currentDateString = dateToInteger(new Date())
switch (occupancyTime) {
case "current": {
sqlWhereClause +=
" and " +
lotOccupanciesTableAlias +
".occupancyStartDate <= ? and (" +
lotOccupanciesTableAlias +
".occupancyEndDate is null or " +
lotOccupanciesTableAlias +
".occupancyEndDate >= ?)";
sqlParameters.push(currentDateString, currentDateString);
break;
}
switch (occupancyTime) {
case 'current': {
sqlWhereClause +=
' and ' +
lotOccupanciesTableAlias +
'.occupancyStartDate <= ? and (' +
lotOccupanciesTableAlias +
'.occupancyEndDate is null or ' +
lotOccupanciesTableAlias +
'.occupancyEndDate >= ?)'
sqlParameters.push(currentDateString, currentDateString)
break
}
case "past": {
sqlWhereClause += " and " + lotOccupanciesTableAlias + ".occupancyEndDate < ?";
sqlParameters.push(currentDateString);
break;
}
case 'past': {
sqlWhereClause +=
' and ' + lotOccupanciesTableAlias + '.occupancyEndDate < ?'
sqlParameters.push(currentDateString)
break
}
case "future": {
sqlWhereClause += " and " + lotOccupanciesTableAlias + ".occupancyStartDate > ?";
sqlParameters.push(currentDateString);
break;
}
}
case 'future': {
sqlWhereClause +=
' and ' + lotOccupanciesTableAlias + '.occupancyStartDate > ?'
sqlParameters.push(currentDateString)
break
}
}
}
return {
sqlWhereClause,
sqlParameters
};
return {
sqlWhereClause,
sqlParameters
}
}
export function getOccupantNameWhereClause(occupantName: string, tableAlias = "o") {
let sqlWhereClause = "";
const sqlParameters = [];
export function getOccupantNameWhereClause(
occupantName: string,
tableAlias = 'o'
): WhereClauseReturn {
let sqlWhereClause = ''
const sqlParameters: unknown[] = []
if (occupantName) {
const occupantNamePieces = occupantName.toLowerCase().split(" ");
for (const occupantNamePiece of occupantNamePieces) {
sqlWhereClause += " and instr(lower(" + tableAlias + ".occupantName), ?)";
sqlParameters.push(occupantNamePiece);
}
if (occupantName !== '') {
const occupantNamePieces = occupantName.toLowerCase().split(' ')
for (const occupantNamePiece of occupantNamePieces) {
sqlWhereClause += ' and instr(lower(' + tableAlias + '.occupantName), ?)'
sqlParameters.push(occupantNamePiece)
}
}
return {
sqlWhereClause,
sqlParameters
};
return {
sqlWhereClause,
sqlParameters
}
}

View File

@ -1,24 +1,21 @@
import { getUserNameFromApiKey } from "./functions.api.js";
import * as configFunctions from "./functions.config.js";
export function userIsAdmin(request) {
var _a;
const user = (_a = request.session) === null || _a === void 0 ? void 0 : _a.user;
const user = request.session?.user;
if (!user || !user.userProperties) {
return false;
}
return user.userProperties.isAdmin;
}
export function userCanUpdate(request) {
var _a;
const user = (_a = request.session) === null || _a === void 0 ? void 0 : _a.user;
const user = request.session?.user;
if (!user || !user.userProperties) {
return false;
}
return user.userProperties.canUpdate;
}
export async function apiKeyIsValid(request) {
var _a;
const apiKey = (_a = request.params) === null || _a === void 0 ? void 0 : _a.apiKey;
const apiKey = request.params?.apiKey;
if (!apiKey) {
return false;
}

View File

@ -1,4 +1,4 @@
import type * as recordTypes from "../../types/recordTypes";
import type * as recordTypes from '../../types/recordTypes';
interface AddFeeForm {
feeCategoryId: string;
feeName: string;
@ -9,9 +9,9 @@ interface AddFeeForm {
feeFunction?: string;
taxAmount?: string;
taxPercentage?: string;
includeQuantity: "" | "1";
includeQuantity: '' | '1';
quantityUnit?: string;
isRequired: "" | "1";
isRequired: '' | '1';
orderNumber?: number;
}
export declare function addFee(feeForm: AddFeeForm, requestSession: recordTypes.PartialSession): number;

View File

@ -1,21 +1,21 @@
import sqlite from "better-sqlite3";
import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js";
import sqlite from 'better-sqlite3';
import { lotOccupancyDB as databasePath } from '../../data/databasePaths.js';
export function addFee(feeForm, requestSession) {
const database = sqlite(databasePath);
const rightNowMillis = Date.now();
const result = database
.prepare(`insert into Fees (
feeCategoryId,
feeName, feeDescription,
occupancyTypeId, lotTypeId,
feeAmount, feeFunction,
taxAmount, taxPercentage,
includeQuantity, quantityUnit,
isRequired, orderNumber,
recordCreate_userName, recordCreate_timeMillis,
recordUpdate_userName, recordUpdate_timeMillis)
values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`)
.run(feeForm.feeCategoryId, feeForm.feeName, feeForm.feeDescription, feeForm.occupancyTypeId || undefined, feeForm.lotTypeId || undefined, feeForm.feeAmount || undefined, feeForm.feeFunction || undefined, feeForm.taxAmount || undefined, feeForm.taxPercentage || undefined, feeForm.includeQuantity ? 1 : 0, feeForm.quantityUnit, feeForm.isRequired ? 1 : 0, feeForm.orderNumber || -1, requestSession.user.userName, rightNowMillis, requestSession.user.userName, rightNowMillis);
feeCategoryId,
feeName, feeDescription,
occupancyTypeId, lotTypeId,
feeAmount, feeFunction,
taxAmount, taxPercentage,
includeQuantity, quantityUnit,
isRequired, orderNumber,
recordCreate_userName, recordCreate_timeMillis,
recordUpdate_userName, recordUpdate_timeMillis)
values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`)
.run(feeForm.feeCategoryId, feeForm.feeName, feeForm.feeDescription, feeForm.occupancyTypeId ?? undefined, feeForm.lotTypeId ?? undefined, feeForm.feeAmount ?? undefined, feeForm.feeFunction ?? undefined, feeForm.taxAmount ?? undefined, feeForm.taxPercentage ?? undefined, (feeForm.includeQuantity ?? '') === '' ? 0 : 1, feeForm.quantityUnit, (feeForm.isRequired ?? '') === '' ? 0 : 1, feeForm.orderNumber ?? -1, requestSession.user.userName, rightNowMillis, requestSession.user.userName, rightNowMillis);
database.close();
return result.lastInsertRowid;
}

View File

@ -1,66 +1,71 @@
import sqlite from "better-sqlite3";
import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js";
/* eslint-disable @typescript-eslint/no-non-null-assertion */
import type * as recordTypes from "../../types/recordTypes";
import sqlite from 'better-sqlite3'
import { lotOccupancyDB as databasePath } from '../../data/databasePaths.js'
import type * as recordTypes from '../../types/recordTypes'
interface AddFeeForm {
feeCategoryId: string;
feeName: string;
feeDescription: string;
occupancyTypeId?: string;
lotTypeId?: string;
feeAmount?: string;
feeFunction?: string;
taxAmount?: string;
taxPercentage?: string;
includeQuantity: "" | "1";
quantityUnit?: string;
isRequired: "" | "1";
orderNumber?: number;
feeCategoryId: string
feeName: string
feeDescription: string
occupancyTypeId?: string
lotTypeId?: string
feeAmount?: string
feeFunction?: string
taxAmount?: string
taxPercentage?: string
includeQuantity: '' | '1'
quantityUnit?: string
isRequired: '' | '1'
orderNumber?: number
}
export function addFee(feeForm: AddFeeForm, requestSession: recordTypes.PartialSession): number {
const database = sqlite(databasePath);
export function addFee(
feeForm: AddFeeForm,
requestSession: recordTypes.PartialSession
): number {
const database = sqlite(databasePath)
const rightNowMillis = Date.now();
const rightNowMillis = Date.now()
const result = database
.prepare(
`insert into Fees (
feeCategoryId,
feeName, feeDescription,
occupancyTypeId, lotTypeId,
feeAmount, feeFunction,
taxAmount, taxPercentage,
includeQuantity, quantityUnit,
isRequired, orderNumber,
recordCreate_userName, recordCreate_timeMillis,
recordUpdate_userName, recordUpdate_timeMillis)
values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
)
.run(
feeForm.feeCategoryId,
feeForm.feeName,
feeForm.feeDescription,
feeForm.occupancyTypeId || undefined,
feeForm.lotTypeId || undefined,
feeForm.feeAmount || undefined,
feeForm.feeFunction || undefined,
feeForm.taxAmount || undefined,
feeForm.taxPercentage || undefined,
feeForm.includeQuantity ? 1 : 0,
feeForm.quantityUnit,
feeForm.isRequired ? 1 : 0,
feeForm.orderNumber || -1,
requestSession.user.userName,
rightNowMillis,
requestSession.user.userName,
rightNowMillis
);
const result = database
.prepare(
`insert into Fees (
feeCategoryId,
feeName, feeDescription,
occupancyTypeId, lotTypeId,
feeAmount, feeFunction,
taxAmount, taxPercentage,
includeQuantity, quantityUnit,
isRequired, orderNumber,
recordCreate_userName, recordCreate_timeMillis,
recordUpdate_userName, recordUpdate_timeMillis)
values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
)
.run(
feeForm.feeCategoryId,
feeForm.feeName,
feeForm.feeDescription,
feeForm.occupancyTypeId ?? undefined,
feeForm.lotTypeId ?? undefined,
feeForm.feeAmount ?? undefined,
feeForm.feeFunction ?? undefined,
feeForm.taxAmount ?? undefined,
feeForm.taxPercentage ?? undefined,
(feeForm.includeQuantity ?? '') === '' ? 0 : 1,
feeForm.quantityUnit,
(feeForm.isRequired ?? '') === '' ? 0 : 1,
feeForm.orderNumber ?? -1,
requestSession.user!.userName,
rightNowMillis,
requestSession.user!.userName,
rightNowMillis
)
database.close();
database.close()
return result.lastInsertRowid as number;
return result.lastInsertRowid as number
}
export default addFee;
export default addFee

View File

@ -1,4 +1,4 @@
import type * as recordTypes from "../../types/recordTypes";
import type * as recordTypes from '../../types/recordTypes';
interface AddLotForm {
lotName: string;
lotTypeId: string | number;

View File

@ -1,6 +1,6 @@
import sqlite from "better-sqlite3";
import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js";
import { addOrUpdateLotField } from "./addOrUpdateLotField.js";
import sqlite from 'better-sqlite3';
import { lotOccupancyDB as databasePath } from '../../data/databasePaths.js';
import { addOrUpdateLotField } from './addOrUpdateLotField.js';
export function addLot(lotForm, requestSession) {
const database = sqlite(databasePath);
const rightNowMillis = Date.now();
@ -12,12 +12,12 @@ export function addLot(lotForm, requestSession) {
recordCreate_userName, recordCreate_timeMillis,
recordUpdate_userName, recordUpdate_timeMillis)
values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`)
.run(lotForm.lotName, lotForm.lotTypeId, lotForm.lotStatusId === "" ? undefined : lotForm.lotStatusId, lotForm.mapId === "" ? undefined : lotForm.mapId, lotForm.mapKey, lotForm.lotLatitude === "" ? undefined : lotForm.lotLatitude, lotForm.lotLongitude === "" ? undefined : lotForm.lotLongitude, requestSession.user.userName, rightNowMillis, requestSession.user.userName, rightNowMillis);
.run(lotForm.lotName, lotForm.lotTypeId, lotForm.lotStatusId === '' ? undefined : lotForm.lotStatusId, lotForm.mapId === '' ? undefined : lotForm.mapId, lotForm.mapKey, lotForm.lotLatitude === '' ? undefined : lotForm.lotLatitude, lotForm.lotLongitude === '' ? undefined : lotForm.lotLongitude, requestSession.user.userName, rightNowMillis, requestSession.user.userName, rightNowMillis);
const lotId = result.lastInsertRowid;
const lotTypeFieldIds = (lotForm.lotTypeFieldIds || "").split(",");
const lotTypeFieldIds = (lotForm.lotTypeFieldIds ?? '').split(',');
for (const lotTypeFieldId of lotTypeFieldIds) {
const lotFieldValue = lotForm["lotFieldValue_" + lotTypeFieldId];
if (lotFieldValue && lotFieldValue !== "") {
const lotFieldValue = lotForm['lotFieldValue_' + lotTypeFieldId];
if (lotFieldValue && lotFieldValue !== '') {
addOrUpdateLotField({
lotId,
lotTypeFieldId,

View File

@ -1,78 +1,81 @@
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 { addOrUpdateLotField } from "./addOrUpdateLotField.js";
import { addOrUpdateLotField } from './addOrUpdateLotField.js'
import type * as recordTypes from "../../types/recordTypes";
import type * as recordTypes from '../../types/recordTypes'
interface AddLotForm {
lotName: string;
lotTypeId: string | number;
lotStatusId: string | number;
lotName: string
lotTypeId: string | number
lotStatusId: string | number
mapId: string | number;
mapKey: string;
mapId: string | number
mapKey: string
lotLatitude: string;
lotLongitude: string;
lotLatitude: string
lotLongitude: string
lotTypeFieldIds?: string;
[lotFieldValue_lotTypeFieldId: string]: unknown;
lotTypeFieldIds?: string
[lotFieldValue_lotTypeFieldId: string]: unknown
}
export function addLot(lotForm: AddLotForm, requestSession: recordTypes.PartialSession): number {
const database = sqlite(databasePath);
export function addLot(
lotForm: AddLotForm,
requestSession: recordTypes.PartialSession
): number {
const database = sqlite(databasePath)
const rightNowMillis = Date.now();
const rightNowMillis = Date.now()
const result = database
.prepare(
`insert into Lots (
const result = database
.prepare(
`insert into Lots (
lotName, lotTypeId, lotStatusId,
mapId, mapKey,
lotLatitude, lotLongitude,
recordCreate_userName, recordCreate_timeMillis,
recordUpdate_userName, recordUpdate_timeMillis)
values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
)
.run(
lotForm.lotName,
lotForm.lotTypeId,
lotForm.lotStatusId === "" ? undefined : lotForm.lotStatusId,
lotForm.mapId === "" ? undefined : lotForm.mapId,
lotForm.mapKey,
lotForm.lotLatitude === "" ? undefined : lotForm.lotLatitude,
lotForm.lotLongitude === "" ? undefined : lotForm.lotLongitude,
requestSession.user.userName,
rightNowMillis,
requestSession.user.userName,
rightNowMillis
);
)
.run(
lotForm.lotName,
lotForm.lotTypeId,
lotForm.lotStatusId === '' ? undefined : lotForm.lotStatusId,
lotForm.mapId === '' ? undefined : lotForm.mapId,
lotForm.mapKey,
lotForm.lotLatitude === '' ? undefined : lotForm.lotLatitude,
lotForm.lotLongitude === '' ? undefined : lotForm.lotLongitude,
requestSession.user!.userName,
rightNowMillis,
requestSession.user!.userName,
rightNowMillis
)
const lotId = result.lastInsertRowid as number;
const lotId = result.lastInsertRowid as number
const lotTypeFieldIds = (lotForm.lotTypeFieldIds || "").split(",");
const lotTypeFieldIds = (lotForm.lotTypeFieldIds ?? '').split(',')
for (const lotTypeFieldId of lotTypeFieldIds) {
const lotFieldValue = lotForm["lotFieldValue_" + lotTypeFieldId] as string;
for (const lotTypeFieldId of lotTypeFieldIds) {
const lotFieldValue = lotForm['lotFieldValue_' + lotTypeFieldId] as string
if (lotFieldValue && lotFieldValue !== "") {
addOrUpdateLotField(
{
lotId,
lotTypeFieldId,
lotFieldValue
},
requestSession,
database
);
}
if (lotFieldValue && lotFieldValue !== '') {
addOrUpdateLotField(
{
lotId,
lotTypeFieldId,
lotFieldValue
},
requestSession,
database
)
}
}
database.close();
database.close()
return lotId;
return lotId
}
export default addLot;
export default addLot

View File

@ -1,4 +1,4 @@
import type * as recordTypes from "../../types/recordTypes";
import type * as recordTypes from '../../types/recordTypes';
interface AddLotCommentForm {
lotId: string;
lotComment: string;

View File

@ -1,6 +1,6 @@
import sqlite from "better-sqlite3";
import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js";
import * as dateTimeFunctions from "@cityssm/expressjs-server-js/dateTimeFns.js";
import sqlite from 'better-sqlite3';
import { lotOccupancyDB as databasePath } from '../../data/databasePaths.js';
import * as dateTimeFunctions from '@cityssm/expressjs-server-js/dateTimeFns.js';
export function addLotComment(lotCommentForm, requestSession) {
const database = sqlite(databasePath);
const rightNow = new Date();

View File

@ -1,47 +1,47 @@
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 dateTimeFunctions from "@cityssm/expressjs-server-js/dateTimeFns.js";
import * as dateTimeFunctions from '@cityssm/expressjs-server-js/dateTimeFns.js'
import type * as recordTypes from "../../types/recordTypes";
import type * as recordTypes from '../../types/recordTypes'
interface AddLotCommentForm {
lotId: string;
lotComment: string;
lotId: string
lotComment: string
}
export function addLotComment(
lotCommentForm: AddLotCommentForm,
requestSession: recordTypes.PartialSession
lotCommentForm: AddLotCommentForm,
requestSession: recordTypes.PartialSession
): number {
const database = sqlite(databasePath);
const database = sqlite(databasePath)
const rightNow = new Date();
const rightNow = new Date()
const result = database
.prepare(
`insert into LotComments (
const result = database
.prepare(
`insert into LotComments (
lotId,
lotCommentDate, lotCommentTime, lotComment,
recordCreate_userName, recordCreate_timeMillis,
recordUpdate_userName, recordUpdate_timeMillis)
values (?, ?, ?, ?, ?, ?, ?, ?)`
)
.run(
lotCommentForm.lotId,
dateTimeFunctions.dateToInteger(rightNow),
dateTimeFunctions.dateToTimeInteger(rightNow),
lotCommentForm.lotComment,
requestSession.user.userName,
rightNow.getTime(),
requestSession.user.userName,
rightNow.getTime()
);
)
.run(
lotCommentForm.lotId,
dateTimeFunctions.dateToInteger(rightNow),
dateTimeFunctions.dateToTimeInteger(rightNow),
lotCommentForm.lotComment,
requestSession.user!.userName,
rightNow.getTime(),
requestSession.user!.userName,
rightNow.getTime()
)
database.close();
database.close()
return result.lastInsertRowid as number;
return result.lastInsertRowid as number
}
export default addLotComment;
export default addLotComment

View File

@ -1,5 +1,5 @@
import sqlite from "better-sqlite3";
import type * as recordTypes from "../../types/recordTypes";
import sqlite from 'better-sqlite3';
import type * as recordTypes from '../../types/recordTypes';
interface AddLotOccupancyForm {
occupancyTypeId: string | number;
lotId: string | number;

View File

@ -1,10 +1,10 @@
import sqlite from "better-sqlite3";
import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js";
import * as dateTimeFunctions from "@cityssm/expressjs-server-js/dateTimeFns.js";
import { addOrUpdateLotOccupancyField } from "./addOrUpdateLotOccupancyField.js";
import { addLotOccupancyOccupant } from "./addLotOccupancyOccupant.js";
import sqlite from 'better-sqlite3';
import { lotOccupancyDB as databasePath } from '../../data/databasePaths.js';
import * as dateTimeFunctions from '@cityssm/expressjs-server-js/dateTimeFns.js';
import { addOrUpdateLotOccupancyField } from './addOrUpdateLotOccupancyField.js';
import { addLotOccupancyOccupant } from './addLotOccupancyOccupant.js';
export function addLotOccupancy(lotOccupancyForm, requestSession, connectedDatabase) {
const database = connectedDatabase || sqlite(databasePath);
const database = connectedDatabase ?? sqlite(databasePath);
const rightNowMillis = Date.now();
const occupancyStartDate = dateTimeFunctions.dateStringToInteger(lotOccupancyForm.occupancyStartDateString);
if (occupancyStartDate <= 0) {
@ -12,19 +12,19 @@ export function addLotOccupancy(lotOccupancyForm, requestSession, connectedDatab
}
const result = database
.prepare(`insert into LotOccupancies (
occupancyTypeId, lotId,
occupancyStartDate, occupancyEndDate,
recordCreate_userName, recordCreate_timeMillis,
recordUpdate_userName, recordUpdate_timeMillis)
values (?, ?, ?, ?, ?, ?, ?, ?)`)
.run(lotOccupancyForm.occupancyTypeId, lotOccupancyForm.lotId === "" ? undefined : lotOccupancyForm.lotId, occupancyStartDate, lotOccupancyForm.occupancyEndDateString === ""
occupancyTypeId, lotId,
occupancyStartDate, occupancyEndDate,
recordCreate_userName, recordCreate_timeMillis,
recordUpdate_userName, recordUpdate_timeMillis)
values (?, ?, ?, ?, ?, ?, ?, ?)`)
.run(lotOccupancyForm.occupancyTypeId, lotOccupancyForm.lotId === '' ? undefined : lotOccupancyForm.lotId, occupancyStartDate, lotOccupancyForm.occupancyEndDateString === ''
? undefined
: dateTimeFunctions.dateStringToInteger(lotOccupancyForm.occupancyEndDateString), requestSession.user.userName, rightNowMillis, requestSession.user.userName, rightNowMillis);
const lotOccupancyId = result.lastInsertRowid;
const occupancyTypeFieldIds = (lotOccupancyForm.occupancyTypeFieldIds || "").split(",");
const occupancyTypeFieldIds = (lotOccupancyForm.occupancyTypeFieldIds ?? '').split(',');
for (const occupancyTypeFieldId of occupancyTypeFieldIds) {
const lotOccupancyFieldValue = lotOccupancyForm["lotOccupancyFieldValue_" + occupancyTypeFieldId];
if (lotOccupancyFieldValue && lotOccupancyFieldValue !== "") {
const lotOccupancyFieldValue = lotOccupancyForm['lotOccupancyFieldValue_' + occupancyTypeFieldId];
if (lotOccupancyFieldValue && lotOccupancyFieldValue !== '') {
addOrUpdateLotOccupancyField({
lotOccupancyId,
occupancyTypeFieldId,

View File

@ -1,122 +1,127 @@
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 dateTimeFunctions from "@cityssm/expressjs-server-js/dateTimeFns.js";
import * as dateTimeFunctions from '@cityssm/expressjs-server-js/dateTimeFns.js'
import { addOrUpdateLotOccupancyField } from "./addOrUpdateLotOccupancyField.js";
import { addLotOccupancyOccupant } from "./addLotOccupancyOccupant.js";
import { addOrUpdateLotOccupancyField } from './addOrUpdateLotOccupancyField.js'
import { addLotOccupancyOccupant } from './addLotOccupancyOccupant.js'
import type * as recordTypes from "../../types/recordTypes";
import type * as recordTypes from '../../types/recordTypes'
interface AddLotOccupancyForm {
occupancyTypeId: string | number;
lotId: string | number;
occupancyTypeId: string | number
lotId: string | number
occupancyStartDateString: string;
occupancyEndDateString: string;
occupancyStartDateString: string
occupancyEndDateString: string
occupancyTypeFieldIds?: string;
[lotOccupancyFieldValue_occupancyTypeFieldId: string]: unknown;
occupancyTypeFieldIds?: string
[lotOccupancyFieldValue_occupancyTypeFieldId: string]: unknown
lotOccupantTypeId?: string;
occupantName?: string;
occupantAddress1?: string;
occupantAddress2?: string;
occupantCity?: string;
occupantProvince?: string;
occupantPostalCode?: string;
occupantPhoneNumber?: string;
occupantEmailAddress?: string;
occupantComment?: string;
lotOccupantTypeId?: string
occupantName?: string
occupantAddress1?: string
occupantAddress2?: string
occupantCity?: string
occupantProvince?: string
occupantPostalCode?: string
occupantPhoneNumber?: string
occupantEmailAddress?: string
occupantComment?: string
}
export function addLotOccupancy(
lotOccupancyForm: AddLotOccupancyForm,
requestSession: recordTypes.PartialSession,
connectedDatabase?: sqlite.Database
lotOccupancyForm: AddLotOccupancyForm,
requestSession: recordTypes.PartialSession,
connectedDatabase?: sqlite.Database
): number {
const database = connectedDatabase || sqlite(databasePath);
const database = connectedDatabase ?? sqlite(databasePath)
const rightNowMillis = Date.now();
const rightNowMillis = Date.now()
const occupancyStartDate = dateTimeFunctions.dateStringToInteger(
lotOccupancyForm.occupancyStartDateString
);
const occupancyStartDate = dateTimeFunctions.dateStringToInteger(
lotOccupancyForm.occupancyStartDateString
)
if (occupancyStartDate <= 0) {
console.error(lotOccupancyForm);
if (occupancyStartDate <= 0) {
console.error(lotOccupancyForm)
}
/* eslint-disable @typescript-eslint/indent */
const result = database
.prepare(
`insert into LotOccupancies (
occupancyTypeId, lotId,
occupancyStartDate, occupancyEndDate,
recordCreate_userName, recordCreate_timeMillis,
recordUpdate_userName, recordUpdate_timeMillis)
values (?, ?, ?, ?, ?, ?, ?, ?)`
)
.run(
lotOccupancyForm.occupancyTypeId,
lotOccupancyForm.lotId === '' ? undefined : lotOccupancyForm.lotId,
occupancyStartDate,
lotOccupancyForm.occupancyEndDateString === ''
? undefined
: dateTimeFunctions.dateStringToInteger(
lotOccupancyForm.occupancyEndDateString
),
requestSession.user!.userName,
rightNowMillis,
requestSession.user!.userName,
rightNowMillis
)
const lotOccupancyId = result.lastInsertRowid as number
const occupancyTypeFieldIds = (
lotOccupancyForm.occupancyTypeFieldIds ?? ''
).split(',')
for (const occupancyTypeFieldId of occupancyTypeFieldIds) {
const lotOccupancyFieldValue = lotOccupancyForm[
'lotOccupancyFieldValue_' + occupancyTypeFieldId
] as string
if (lotOccupancyFieldValue && lotOccupancyFieldValue !== '') {
addOrUpdateLotOccupancyField(
{
lotOccupancyId,
occupancyTypeFieldId,
lotOccupancyFieldValue
},
requestSession,
database
)
}
}
const result = database
.prepare(
`insert into LotOccupancies (
occupancyTypeId, lotId,
occupancyStartDate, occupancyEndDate,
recordCreate_userName, recordCreate_timeMillis,
recordUpdate_userName, recordUpdate_timeMillis)
values (?, ?, ?, ?, ?, ?, ?, ?)`
)
.run(
lotOccupancyForm.occupancyTypeId,
lotOccupancyForm.lotId === "" ? undefined : lotOccupancyForm.lotId,
occupancyStartDate,
lotOccupancyForm.occupancyEndDateString === ""
? undefined
: dateTimeFunctions.dateStringToInteger(lotOccupancyForm.occupancyEndDateString),
requestSession.user.userName,
rightNowMillis,
requestSession.user.userName,
rightNowMillis
);
if (lotOccupancyForm.lotOccupantTypeId) {
addLotOccupancyOccupant(
{
lotOccupancyId,
lotOccupantTypeId: lotOccupancyForm.lotOccupantTypeId,
occupantName: lotOccupancyForm.occupantName!,
occupantAddress1: lotOccupancyForm.occupantAddress1!,
occupantAddress2: lotOccupancyForm.occupantAddress2!,
occupantCity: lotOccupancyForm.occupantCity!,
occupantProvince: lotOccupancyForm.occupantProvince!,
occupantPostalCode: lotOccupancyForm.occupantPostalCode!,
occupantPhoneNumber: lotOccupancyForm.occupantPhoneNumber!,
occupantEmailAddress: lotOccupancyForm.occupantEmailAddress!,
occupantComment: lotOccupancyForm.occupantComment!
},
requestSession,
database
)
}
const lotOccupancyId = result.lastInsertRowid as number;
if (!connectedDatabase) {
database.close()
}
const occupancyTypeFieldIds = (lotOccupancyForm.occupancyTypeFieldIds || "").split(",");
for (const occupancyTypeFieldId of occupancyTypeFieldIds) {
const lotOccupancyFieldValue = lotOccupancyForm[
"lotOccupancyFieldValue_" + occupancyTypeFieldId
] as string;
if (lotOccupancyFieldValue && lotOccupancyFieldValue !== "") {
addOrUpdateLotOccupancyField(
{
lotOccupancyId,
occupancyTypeFieldId,
lotOccupancyFieldValue
},
requestSession,
database
);
}
}
if (lotOccupancyForm.lotOccupantTypeId) {
addLotOccupancyOccupant(
{
lotOccupancyId,
lotOccupantTypeId: lotOccupancyForm.lotOccupantTypeId,
occupantName: lotOccupancyForm.occupantName,
occupantAddress1: lotOccupancyForm.occupantAddress1,
occupantAddress2: lotOccupancyForm.occupantAddress2,
occupantCity: lotOccupancyForm.occupantCity,
occupantProvince: lotOccupancyForm.occupantProvince,
occupantPostalCode: lotOccupancyForm.occupantPostalCode,
occupantPhoneNumber: lotOccupancyForm.occupantPhoneNumber,
occupantEmailAddress: lotOccupancyForm.occupantEmailAddress,
occupantComment: lotOccupancyForm.occupantComment
},
requestSession,
database
);
}
if (!connectedDatabase) {
database.close();
}
return lotOccupancyId;
return lotOccupancyId
}
export default addLotOccupancy;
export default addLotOccupancy

View File

@ -1,4 +1,4 @@
import type * as recordTypes from "../../types/recordTypes";
import type * as recordTypes from '../../types/recordTypes';
interface AddLotOccupancyCommentForm {
lotOccupancyId: string | number;
lotOccupancyCommentDateString?: string;

View File

@ -1,13 +1,13 @@
import sqlite from "better-sqlite3";
import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js";
import { dateStringToInteger, dateToInteger, dateToTimeInteger, timeStringToInteger } from "@cityssm/expressjs-server-js/dateTimeFns.js";
import sqlite from 'better-sqlite3';
import { lotOccupancyDB as databasePath } from '../../data/databasePaths.js';
import { dateStringToInteger, dateToInteger, dateToTimeInteger, timeStringToInteger } from '@cityssm/expressjs-server-js/dateTimeFns.js';
export function addLotOccupancyComment(commentForm, requestSession) {
const rightNow = new Date();
let lotOccupancyCommentDate;
let lotOccupancyCommentTime;
if (commentForm.lotOccupancyCommentDateString) {
lotOccupancyCommentDate = dateStringToInteger(commentForm.lotOccupancyCommentDateString);
lotOccupancyCommentTime = timeStringToInteger(commentForm.lotOccupancyCommentTimeString);
lotOccupancyCommentTime = timeStringToInteger(commentForm.lotOccupancyCommentTimeString ?? '');
}
else {
lotOccupancyCommentDate = dateToInteger(rightNow);

View File

@ -1,66 +1,70 @@
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 {
dateStringToInteger,
dateToInteger,
dateToTimeInteger,
timeStringToInteger
} from "@cityssm/expressjs-server-js/dateTimeFns.js";
dateStringToInteger,
dateToInteger,
dateToTimeInteger,
timeStringToInteger
} from '@cityssm/expressjs-server-js/dateTimeFns.js'
import type * as recordTypes from "../../types/recordTypes";
import type * as recordTypes from '../../types/recordTypes'
interface AddLotOccupancyCommentForm {
lotOccupancyId: string | number;
lotOccupancyCommentDateString?: string;
lotOccupancyCommentTimeString?: string;
lotOccupancyComment: string;
lotOccupancyId: string | number
lotOccupancyCommentDateString?: string
lotOccupancyCommentTimeString?: string
lotOccupancyComment: string
}
export function addLotOccupancyComment(
commentForm: AddLotOccupancyCommentForm,
requestSession: recordTypes.PartialSession
commentForm: AddLotOccupancyCommentForm,
requestSession: recordTypes.PartialSession
): number {
const rightNow = new Date();
const rightNow = new Date()
let lotOccupancyCommentDate: number;
let lotOccupancyCommentTime: number;
let lotOccupancyCommentDate: number
let lotOccupancyCommentTime: number
if (commentForm.lotOccupancyCommentDateString) {
lotOccupancyCommentDate = dateStringToInteger(commentForm.lotOccupancyCommentDateString);
lotOccupancyCommentTime = timeStringToInteger(commentForm.lotOccupancyCommentTimeString);
} else {
lotOccupancyCommentDate = dateToInteger(rightNow);
lotOccupancyCommentTime = dateToTimeInteger(rightNow);
}
if (commentForm.lotOccupancyCommentDateString) {
lotOccupancyCommentDate = dateStringToInteger(
commentForm.lotOccupancyCommentDateString
)
lotOccupancyCommentTime = timeStringToInteger(
commentForm.lotOccupancyCommentTimeString ?? ''
)
} else {
lotOccupancyCommentDate = dateToInteger(rightNow)
lotOccupancyCommentTime = dateToTimeInteger(rightNow)
}
const database = sqlite(databasePath);
const database = sqlite(databasePath)
const result = database
.prepare(
`insert into LotOccupancyComments (
const result = database
.prepare(
`insert into LotOccupancyComments (
lotOccupancyId,
lotOccupancyCommentDate, lotOccupancyCommentTime,
lotOccupancyComment,
recordCreate_userName, recordCreate_timeMillis,
recordUpdate_userName, recordUpdate_timeMillis)
values (?, ?, ?, ?, ?, ?, ?, ?)`
)
.run(
commentForm.lotOccupancyId,
lotOccupancyCommentDate,
lotOccupancyCommentTime,
commentForm.lotOccupancyComment,
requestSession.user.userName,
rightNow.getTime(),
requestSession.user.userName,
rightNow.getTime()
);
)
.run(
commentForm.lotOccupancyId,
lotOccupancyCommentDate,
lotOccupancyCommentTime,
commentForm.lotOccupancyComment,
requestSession.user!.userName,
rightNow.getTime(),
requestSession.user!.userName,
rightNow.getTime()
)
database.close();
database.close()
return result.lastInsertRowid as number;
return result.lastInsertRowid as number
}
export default addLotOccupancyComment;
export default addLotOccupancyComment

View File

@ -1,4 +1,4 @@
import type * as recordTypes from "../../types/recordTypes";
import type * as recordTypes from '../../types/recordTypes';
interface AddLotOccupancyFeeForm {
lotOccupancyId: number | string;
feeId: number | string;

View File

@ -1,8 +1,8 @@
import sqlite from "better-sqlite3";
import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js";
import { calculateFeeAmount, calculateTaxAmount } from "../functions.fee.js";
import { getFee } from "./getFee.js";
import { getLotOccupancy } from "./getLotOccupancy.js";
import sqlite from 'better-sqlite3';
import { lotOccupancyDB as databasePath } from '../../data/databasePaths.js';
import { calculateFeeAmount, calculateTaxAmount } from '../functions.fee.js';
import { getFee } from './getFee.js';
import { getLotOccupancy } from './getLotOccupancy.js';
export function addLotOccupancyFee(lotOccupancyFeeForm, requestSession) {
const database = sqlite(databasePath);
const rightNowMillis = Date.now();
@ -10,13 +10,13 @@ export function addLotOccupancyFee(lotOccupancyFeeForm, requestSession) {
let taxAmount;
if (lotOccupancyFeeForm.feeAmount) {
feeAmount =
typeof lotOccupancyFeeForm.feeAmount === "string"
typeof lotOccupancyFeeForm.feeAmount === 'string'
? Number.parseFloat(lotOccupancyFeeForm.feeAmount)
: feeAmount;
: 0;
taxAmount =
typeof lotOccupancyFeeForm.taxAmount === "string"
typeof lotOccupancyFeeForm.taxAmount === 'string'
? Number.parseFloat(lotOccupancyFeeForm.taxAmount)
: taxAmount;
: 0;
}
else {
const lotOccupancy = getLotOccupancy(lotOccupancyFeeForm.lotOccupancyId);
@ -39,7 +39,8 @@ export function addLotOccupancyFee(lotOccupancyFeeForm, requestSession) {
and feeId = ?`)
.run(lotOccupancyFeeForm.lotOccupancyId, lotOccupancyFeeForm.feeId);
}
else if (record.feeAmount === feeAmount && record.taxAmount === taxAmount) {
else if (record.feeAmount === feeAmount &&
record.taxAmount === taxAmount) {
database
.prepare(`update LotOccupancyFees
set quantity = quantity + ?,
@ -52,18 +53,18 @@ export function addLotOccupancyFee(lotOccupancyFeeForm, requestSession) {
return true;
}
else {
const quantity = typeof lotOccupancyFeeForm.quantity === "string"
const quantity = typeof lotOccupancyFeeForm.quantity === 'string'
? Number.parseFloat(lotOccupancyFeeForm.quantity)
: lotOccupancyFeeForm.quantity;
database
.prepare(`update LotOccupancyFees
set feeAmount = (feeAmount * quantity) + ?,
taxAmount = (taxAmount * quantity) + ?,
quantity = 1,
recordUpdate_userName = ?,
recordUpdate_timeMillis = ?
where lotOccupancyId = ?
and feeId = ?`)
set feeAmount = (feeAmount * quantity) + ?,
taxAmount = (taxAmount * quantity) + ?,
quantity = 1,
recordUpdate_userName = ?,
recordUpdate_timeMillis = ?
where lotOccupancyId = ?
and feeId = ?`)
.run(feeAmount * quantity, taxAmount * quantity, requestSession.user.userName, rightNowMillis, lotOccupancyFeeForm.lotOccupancyId, lotOccupancyFeeForm.feeId);
database.close();
return true;

View File

@ -1,154 +1,157 @@
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 { calculateFeeAmount, calculateTaxAmount } from "../functions.fee.js";
import { calculateFeeAmount, calculateTaxAmount } from '../functions.fee.js'
import { getFee } from "./getFee.js";
import { getFee } from './getFee.js'
import { getLotOccupancy } from "./getLotOccupancy.js";
import { getLotOccupancy } from './getLotOccupancy.js'
import type * as recordTypes from "../../types/recordTypes";
import type * as recordTypes from '../../types/recordTypes'
interface AddLotOccupancyFeeForm {
lotOccupancyId: number | string;
feeId: number | string;
quantity: number | string;
feeAmount?: number | string;
taxAmount?: number | string;
lotOccupancyId: number | string
feeId: number | string
quantity: number | string
feeAmount?: number | string
taxAmount?: number | string
}
export function addLotOccupancyFee(
lotOccupancyFeeForm: AddLotOccupancyFeeForm,
requestSession: recordTypes.PartialSession
lotOccupancyFeeForm: AddLotOccupancyFeeForm,
requestSession: recordTypes.PartialSession
): boolean {
const database = sqlite(databasePath);
const database = sqlite(databasePath)
const rightNowMillis = Date.now();
const rightNowMillis = Date.now()
// Calculate fee and tax (if not set)
let feeAmount: number;
let taxAmount: number;
// Calculate fee and tax (if not set)
let feeAmount: number
let taxAmount: number
if (lotOccupancyFeeForm.feeAmount) {
feeAmount =
typeof lotOccupancyFeeForm.feeAmount === "string"
? Number.parseFloat(lotOccupancyFeeForm.feeAmount)
: feeAmount;
taxAmount =
typeof lotOccupancyFeeForm.taxAmount === "string"
? Number.parseFloat(lotOccupancyFeeForm.taxAmount)
: taxAmount;
} else {
const lotOccupancy = getLotOccupancy(lotOccupancyFeeForm.lotOccupancyId);
const fee = getFee(lotOccupancyFeeForm.feeId);
if (lotOccupancyFeeForm.feeAmount) {
feeAmount =
typeof lotOccupancyFeeForm.feeAmount === 'string'
? Number.parseFloat(lotOccupancyFeeForm.feeAmount)
: 0
taxAmount =
typeof lotOccupancyFeeForm.taxAmount === 'string'
? Number.parseFloat(lotOccupancyFeeForm.taxAmount)
: 0
} else {
const lotOccupancy = getLotOccupancy(lotOccupancyFeeForm.lotOccupancyId)!
const fee = getFee(lotOccupancyFeeForm.feeId)
feeAmount = calculateFeeAmount(fee, lotOccupancy);
taxAmount = calculateTaxAmount(fee, feeAmount);
}
feeAmount = calculateFeeAmount(fee, lotOccupancy)
taxAmount = calculateTaxAmount(fee, feeAmount)
}
// Check if record already exists
const record: {
feeAmount?: number;
taxAmount?: number;
recordDelete_timeMillis?: number;
} = database
.prepare(
`select feeAmount, taxAmount, recordDelete_timeMillis
// Check if record already exists
const record: {
feeAmount?: number
taxAmount?: number
recordDelete_timeMillis?: number
} = database
.prepare(
`select feeAmount, taxAmount, recordDelete_timeMillis
from LotOccupancyFees
where lotOccupancyId = ?
and feeId = ?`
)
.get(lotOccupancyFeeForm.lotOccupancyId, lotOccupancyFeeForm.feeId);
)
.get(lotOccupancyFeeForm.lotOccupancyId, lotOccupancyFeeForm.feeId)
if (record) {
if (record.recordDelete_timeMillis) {
database
.prepare(
`delete from LotOccupancyFees
if (record) {
if (record.recordDelete_timeMillis) {
database
.prepare(
`delete from LotOccupancyFees
where recordDelete_timeMillis is not null
and lotOccupancyId = ?
and feeId = ?`
)
.run(lotOccupancyFeeForm.lotOccupancyId, lotOccupancyFeeForm.feeId);
} else if (record.feeAmount === feeAmount && record.taxAmount === taxAmount) {
database
.prepare(
`update LotOccupancyFees
)
.run(lotOccupancyFeeForm.lotOccupancyId, lotOccupancyFeeForm.feeId)
} else if (
record.feeAmount === feeAmount &&
record.taxAmount === taxAmount
) {
database
.prepare(
`update LotOccupancyFees
set quantity = quantity + ?,
recordUpdate_userName = ?,
recordUpdate_timeMillis = ?
where lotOccupancyId = ?
and feeId = ?`
)
.run(
lotOccupancyFeeForm.quantity,
requestSession.user.userName,
rightNowMillis,
lotOccupancyFeeForm.lotOccupancyId,
lotOccupancyFeeForm.feeId
);
)
.run(
lotOccupancyFeeForm.quantity,
requestSession.user!.userName,
rightNowMillis,
lotOccupancyFeeForm.lotOccupancyId,
lotOccupancyFeeForm.feeId
)
database.close();
database.close()
return true;
} else {
const quantity =
typeof lotOccupancyFeeForm.quantity === "string"
? Number.parseFloat(lotOccupancyFeeForm.quantity)
: lotOccupancyFeeForm.quantity;
return true
} else {
const quantity =
typeof lotOccupancyFeeForm.quantity === 'string'
? Number.parseFloat(lotOccupancyFeeForm.quantity)
: lotOccupancyFeeForm.quantity
database
.prepare(
`update LotOccupancyFees
set feeAmount = (feeAmount * quantity) + ?,
taxAmount = (taxAmount * quantity) + ?,
quantity = 1,
recordUpdate_userName = ?,
recordUpdate_timeMillis = ?
where lotOccupancyId = ?
and feeId = ?`
)
.run(
feeAmount * quantity,
taxAmount * quantity,
requestSession.user.userName,
rightNowMillis,
lotOccupancyFeeForm.lotOccupancyId,
lotOccupancyFeeForm.feeId
);
database.close();
return true;
}
}
// Create new record
const result = database
database
.prepare(
`insert into LotOccupancyFees (
`update LotOccupancyFees
set feeAmount = (feeAmount * quantity) + ?,
taxAmount = (taxAmount * quantity) + ?,
quantity = 1,
recordUpdate_userName = ?,
recordUpdate_timeMillis = ?
where lotOccupancyId = ?
and feeId = ?`
)
.run(
feeAmount * quantity,
taxAmount * quantity,
requestSession.user!.userName,
rightNowMillis,
lotOccupancyFeeForm.lotOccupancyId,
lotOccupancyFeeForm.feeId
)
database.close()
return true
}
}
// Create new record
const result = database
.prepare(
`insert into LotOccupancyFees (
lotOccupancyId, feeId,
quantity, feeAmount, taxAmount,
recordCreate_userName, recordCreate_timeMillis,
recordUpdate_userName, recordUpdate_timeMillis)
values (?, ?, ?, ?, ?, ?, ?, ?, ?)`
)
.run(
lotOccupancyFeeForm.lotOccupancyId,
lotOccupancyFeeForm.feeId,
lotOccupancyFeeForm.quantity,
feeAmount,
taxAmount,
requestSession.user.userName,
rightNowMillis,
requestSession.user.userName,
rightNowMillis
);
)
.run(
lotOccupancyFeeForm.lotOccupancyId,
lotOccupancyFeeForm.feeId,
lotOccupancyFeeForm.quantity,
feeAmount,
taxAmount,
requestSession.user!.userName,
rightNowMillis,
requestSession.user!.userName,
rightNowMillis
)
database.close();
database.close()
return result.changes > 0;
return result.changes > 0
}
export default addLotOccupancyFee;
export default addLotOccupancyFee

View File

@ -1,5 +1,5 @@
import sqlite from "better-sqlite3";
import type * as recordTypes from "../../types/recordTypes";
import sqlite from 'better-sqlite3';
import type * as recordTypes from '../../types/recordTypes';
interface AddLotOccupancyOccupantForm {
lotOccupancyId: string | number;
lotOccupantTypeId: string | number;

View File

@ -1,7 +1,7 @@
import sqlite from "better-sqlite3";
import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js";
import sqlite from 'better-sqlite3';
import { lotOccupancyDB as databasePath } from '../../data/databasePaths.js';
export function addLotOccupancyOccupant(lotOccupancyOccupantForm, requestSession, connectedDatabase) {
const database = connectedDatabase || sqlite(databasePath);
const database = connectedDatabase ?? sqlite(databasePath);
let lotOccupantIndex = 0;
const maxIndexResult = database
.prepare(`select lotOccupantIndex
@ -26,7 +26,7 @@ export function addLotOccupancyOccupant(lotOccupancyOccupantForm, requestSession
recordCreate_userName, recordCreate_timeMillis,
recordUpdate_userName, recordUpdate_timeMillis)
values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`)
.run(lotOccupancyOccupantForm.lotOccupancyId, lotOccupantIndex, lotOccupancyOccupantForm.occupantName, lotOccupancyOccupantForm.occupantAddress1, lotOccupancyOccupantForm.occupantAddress2, lotOccupancyOccupantForm.occupantCity, lotOccupancyOccupantForm.occupantProvince, lotOccupancyOccupantForm.occupantPostalCode, lotOccupancyOccupantForm.occupantPhoneNumber, lotOccupancyOccupantForm.occupantEmailAddress, lotOccupancyOccupantForm.occupantComment || "", lotOccupancyOccupantForm.lotOccupantTypeId, requestSession.user.userName, rightNowMillis, requestSession.user.userName, rightNowMillis);
.run(lotOccupancyOccupantForm.lotOccupancyId, lotOccupantIndex, lotOccupancyOccupantForm.occupantName, lotOccupancyOccupantForm.occupantAddress1, lotOccupancyOccupantForm.occupantAddress2, lotOccupancyOccupantForm.occupantCity, lotOccupancyOccupantForm.occupantProvince, lotOccupancyOccupantForm.occupantPostalCode, lotOccupancyOccupantForm.occupantPhoneNumber, lotOccupancyOccupantForm.occupantEmailAddress, lotOccupancyOccupantForm.occupantComment ?? '', lotOccupancyOccupantForm.lotOccupantTypeId, requestSession.user.userName, rightNowMillis, requestSession.user.userName, rightNowMillis);
if (!connectedDatabase) {
database.close();
}

View File

@ -1,51 +1,51 @@
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 type * as recordTypes from "../../types/recordTypes";
import type * as recordTypes from '../../types/recordTypes'
interface AddLotOccupancyOccupantForm {
lotOccupancyId: string | number;
lotOccupantTypeId: string | number;
occupantName: string;
occupantAddress1: string;
occupantAddress2: string;
occupantCity: string;
occupantProvince: string;
occupantPostalCode: string;
occupantPhoneNumber: string;
occupantEmailAddress: string;
occupantComment?: string;
lotOccupancyId: string | number
lotOccupantTypeId: string | number
occupantName: string
occupantAddress1: string
occupantAddress2: string
occupantCity: string
occupantProvince: string
occupantPostalCode: string
occupantPhoneNumber: string
occupantEmailAddress: string
occupantComment?: string
}
export function addLotOccupancyOccupant(
lotOccupancyOccupantForm: AddLotOccupancyOccupantForm,
requestSession: recordTypes.PartialSession,
connectedDatabase?: sqlite.Database
lotOccupancyOccupantForm: AddLotOccupancyOccupantForm,
requestSession: recordTypes.PartialSession,
connectedDatabase?: sqlite.Database
): number {
const database = connectedDatabase || sqlite(databasePath);
const database = connectedDatabase ?? sqlite(databasePath)
let lotOccupantIndex = 0;
let lotOccupantIndex = 0
const maxIndexResult = database
.prepare(
`select lotOccupantIndex
const maxIndexResult = database
.prepare(
`select lotOccupantIndex
from LotOccupancyOccupants
where lotOccupancyId = ?
order by lotOccupantIndex desc
limit 1`
)
.get(lotOccupancyOccupantForm.lotOccupancyId);
)
.get(lotOccupancyOccupantForm.lotOccupancyId)
if (maxIndexResult) {
lotOccupantIndex = maxIndexResult.lotOccupantIndex + 1;
}
if (maxIndexResult) {
lotOccupantIndex = maxIndexResult.lotOccupantIndex + 1
}
const rightNowMillis = Date.now();
const rightNowMillis = Date.now()
database
.prepare(
`insert into LotOccupancyOccupants (
database
.prepare(
`insert into LotOccupancyOccupants (
lotOccupancyId, lotOccupantIndex,
occupantName,
occupantAddress1, occupantAddress2,
@ -56,31 +56,31 @@ export function addLotOccupancyOccupant(
recordCreate_userName, recordCreate_timeMillis,
recordUpdate_userName, recordUpdate_timeMillis)
values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
)
.run(
lotOccupancyOccupantForm.lotOccupancyId,
lotOccupantIndex,
lotOccupancyOccupantForm.occupantName,
lotOccupancyOccupantForm.occupantAddress1,
lotOccupancyOccupantForm.occupantAddress2,
lotOccupancyOccupantForm.occupantCity,
lotOccupancyOccupantForm.occupantProvince,
lotOccupancyOccupantForm.occupantPostalCode,
lotOccupancyOccupantForm.occupantPhoneNumber,
lotOccupancyOccupantForm.occupantEmailAddress,
lotOccupancyOccupantForm.occupantComment || "",
lotOccupancyOccupantForm.lotOccupantTypeId,
requestSession.user.userName,
rightNowMillis,
requestSession.user.userName,
rightNowMillis
);
)
.run(
lotOccupancyOccupantForm.lotOccupancyId,
lotOccupantIndex,
lotOccupancyOccupantForm.occupantName,
lotOccupancyOccupantForm.occupantAddress1,
lotOccupancyOccupantForm.occupantAddress2,
lotOccupancyOccupantForm.occupantCity,
lotOccupancyOccupantForm.occupantProvince,
lotOccupancyOccupantForm.occupantPostalCode,
lotOccupancyOccupantForm.occupantPhoneNumber,
lotOccupancyOccupantForm.occupantEmailAddress,
lotOccupancyOccupantForm.occupantComment ?? '',
lotOccupancyOccupantForm.lotOccupantTypeId,
requestSession.user!.userName,
rightNowMillis,
requestSession.user!.userName,
rightNowMillis
)
if (!connectedDatabase) {
database.close();
}
if (!connectedDatabase) {
database.close()
}
return lotOccupantIndex;
return lotOccupantIndex
}
export default addLotOccupancyOccupant;
export default addLotOccupancyOccupant

View File

@ -1,4 +1,4 @@
import type * as recordTypes from "../../types/recordTypes";
import type * as recordTypes from '../../types/recordTypes';
interface AddLotOccupancyTransactionForm {
lotOccupancyId: string | number;
transactionDateString?: string;

View File

@ -1,6 +1,6 @@
import sqlite from "better-sqlite3";
import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js";
import { dateStringToInteger, dateToInteger, dateToTimeInteger, timeStringToInteger } from "@cityssm/expressjs-server-js/dateTimeFns.js";
import sqlite from 'better-sqlite3';
import { lotOccupancyDB as databasePath } from '../../data/databasePaths.js';
import { dateStringToInteger, dateToInteger, dateToTimeInteger, timeStringToInteger } from '@cityssm/expressjs-server-js/dateTimeFns.js';
export function addLotOccupancyTransaction(lotOccupancyTransactionForm, requestSession) {
const database = sqlite(databasePath);
let transactionIndex = 0;

View File

@ -1,84 +1,84 @@
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 {
dateStringToInteger,
dateToInteger,
dateToTimeInteger,
timeStringToInteger
} from "@cityssm/expressjs-server-js/dateTimeFns.js";
dateStringToInteger,
dateToInteger,
dateToTimeInteger,
timeStringToInteger
} from '@cityssm/expressjs-server-js/dateTimeFns.js'
import type * as recordTypes from "../../types/recordTypes";
import type * as recordTypes from '../../types/recordTypes'
interface AddLotOccupancyTransactionForm {
lotOccupancyId: string | number;
transactionDateString?: string;
transactionTimeString?: string;
transactionAmount: string | number;
externalReceiptNumber: string;
transactionNote: string;
lotOccupancyId: string | number
transactionDateString?: string
transactionTimeString?: string
transactionAmount: string | number
externalReceiptNumber: string
transactionNote: string
}
export function addLotOccupancyTransaction(
lotOccupancyTransactionForm: AddLotOccupancyTransactionForm,
requestSession: recordTypes.PartialSession
lotOccupancyTransactionForm: AddLotOccupancyTransactionForm,
requestSession: recordTypes.PartialSession
): number {
const database = sqlite(databasePath);
const database = sqlite(databasePath)
let transactionIndex = 0;
let transactionIndex = 0
const maxIndexResult = database
.prepare(
`select transactionIndex
const maxIndexResult: { transactionIndex: number } | undefined = database
.prepare(
`select transactionIndex
from LotOccupancyTransactions
where lotOccupancyId = ?
order by transactionIndex desc
limit 1`
)
.get(lotOccupancyTransactionForm.lotOccupancyId);
)
.get(lotOccupancyTransactionForm.lotOccupancyId)
if (maxIndexResult) {
transactionIndex = maxIndexResult.transactionIndex + 1;
}
if (maxIndexResult) {
transactionIndex = maxIndexResult.transactionIndex + 1
}
const rightNow = new Date();
const rightNow = new Date()
const transactionDate = lotOccupancyTransactionForm.transactionDateString
? dateStringToInteger(lotOccupancyTransactionForm.transactionDateString)
: dateToInteger(rightNow);
const transactionDate = lotOccupancyTransactionForm.transactionDateString
? dateStringToInteger(lotOccupancyTransactionForm.transactionDateString)
: dateToInteger(rightNow)
const transactionTime = lotOccupancyTransactionForm.transactionTimeString
? timeStringToInteger(lotOccupancyTransactionForm.transactionTimeString)
: dateToTimeInteger(rightNow);
const transactionTime = lotOccupancyTransactionForm.transactionTimeString
? timeStringToInteger(lotOccupancyTransactionForm.transactionTimeString)
: dateToTimeInteger(rightNow)
database
.prepare(
`insert into LotOccupancyTransactions (
database
.prepare(
`insert into LotOccupancyTransactions (
lotOccupancyId, transactionIndex,
transactionDate, transactionTime,
transactionAmount, externalReceiptNumber, transactionNote,
recordCreate_userName, recordCreate_timeMillis,
recordUpdate_userName, recordUpdate_timeMillis)
values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
)
.run(
lotOccupancyTransactionForm.lotOccupancyId,
transactionIndex,
transactionDate,
transactionTime,
lotOccupancyTransactionForm.transactionAmount,
lotOccupancyTransactionForm.externalReceiptNumber,
lotOccupancyTransactionForm.transactionNote,
requestSession.user.userName,
rightNow.getTime(),
requestSession.user.userName,
rightNow.getTime()
);
)
.run(
lotOccupancyTransactionForm.lotOccupancyId,
transactionIndex,
transactionDate,
transactionTime,
lotOccupancyTransactionForm.transactionAmount,
lotOccupancyTransactionForm.externalReceiptNumber,
lotOccupancyTransactionForm.transactionNote,
requestSession.user!.userName,
rightNow.getTime(),
requestSession.user!.userName,
rightNow.getTime()
)
database.close();
database.close()
return transactionIndex;
return transactionIndex
}
export default addLotOccupancyTransaction;
export default addLotOccupancyTransaction

View File

@ -1,4 +1,4 @@
import type * as recordTypes from "../../types/recordTypes";
import type * as recordTypes from '../../types/recordTypes';
interface AddLotOccupantTypeForm {
lotOccupantType: string;
fontAwesomeIconClass?: string;

View File

@ -1,6 +1,6 @@
import sqlite from "better-sqlite3";
import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js";
import { clearCacheByTableName } from "../functions.cache.js";
import sqlite from 'better-sqlite3';
import { lotOccupancyDB as databasePath } from '../../data/databasePaths.js';
import { clearCacheByTableName } from '../functions.cache.js';
export function addLotOccupantType(lotOccupantTypeForm, requestSession) {
const database = sqlite(databasePath);
const rightNowMillis = Date.now();
@ -10,9 +10,9 @@ export function addLotOccupantType(lotOccupantTypeForm, requestSession) {
recordCreate_userName, recordCreate_timeMillis,
recordUpdate_userName, recordUpdate_timeMillis)
values (?, ?, ?, ?, ?, ?, ?)`)
.run(lotOccupantTypeForm.lotOccupantType, lotOccupantTypeForm.fontAwesomeIconClass || "", lotOccupantTypeForm.orderNumber || -1, requestSession.user.userName, rightNowMillis, requestSession.user.userName, rightNowMillis);
.run(lotOccupantTypeForm.lotOccupantType, lotOccupantTypeForm.fontAwesomeIconClass ?? '', lotOccupantTypeForm.orderNumber ?? -1, requestSession.user.userName, rightNowMillis, requestSession.user.userName, rightNowMillis);
database.close();
clearCacheByTableName("LotOccupantTypes");
clearCacheByTableName('LotOccupantTypes');
return result.lastInsertRowid;
}
export default addLotOccupantType;

View File

@ -1,47 +1,47 @@
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 type * as recordTypes from "../../types/recordTypes";
import { clearCacheByTableName } from "../functions.cache.js";
import type * as recordTypes from '../../types/recordTypes'
import { clearCacheByTableName } from '../functions.cache.js'
interface AddLotOccupantTypeForm {
lotOccupantType: string;
fontAwesomeIconClass?: string;
orderNumber?: number;
lotOccupantType: string
fontAwesomeIconClass?: string
orderNumber?: number
}
export function addLotOccupantType(
lotOccupantTypeForm: AddLotOccupantTypeForm,
requestSession: recordTypes.PartialSession
lotOccupantTypeForm: AddLotOccupantTypeForm,
requestSession: recordTypes.PartialSession
): number {
const database = sqlite(databasePath);
const database = sqlite(databasePath)
const rightNowMillis = Date.now();
const rightNowMillis = Date.now()
const result = database
.prepare(
`insert into LotOccupantTypes (
const result = database
.prepare(
`insert into LotOccupantTypes (
lotOccupantType, fontAwesomeIconClass, orderNumber,
recordCreate_userName, recordCreate_timeMillis,
recordUpdate_userName, recordUpdate_timeMillis)
values (?, ?, ?, ?, ?, ?, ?)`
)
.run(
lotOccupantTypeForm.lotOccupantType,
lotOccupantTypeForm.fontAwesomeIconClass || "",
lotOccupantTypeForm.orderNumber || -1,
requestSession.user.userName,
rightNowMillis,
requestSession.user.userName,
rightNowMillis
);
)
.run(
lotOccupantTypeForm.lotOccupantType,
lotOccupantTypeForm.fontAwesomeIconClass ?? '',
lotOccupantTypeForm.orderNumber ?? -1,
requestSession.user!.userName,
rightNowMillis,
requestSession.user!.userName,
rightNowMillis
)
database.close();
database.close()
clearCacheByTableName("LotOccupantTypes");
clearCacheByTableName('LotOccupantTypes')
return result.lastInsertRowid as number;
return result.lastInsertRowid as number
}
export default addLotOccupantType;
export default addLotOccupantType

View File

@ -1,4 +1,4 @@
import type * as recordTypes from "../../types/recordTypes";
import type * as recordTypes from '../../types/recordTypes';
interface AddLotTypeFieldForm {
lotTypeId: string | number;
lotTypeField: string;

View File

@ -1,6 +1,6 @@
import sqlite from "better-sqlite3";
import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js";
import { clearCacheByTableName } from "../functions.cache.js";
import sqlite from 'better-sqlite3';
import { lotOccupancyDB as databasePath } from '../../data/databasePaths.js';
import { clearCacheByTableName } from '../functions.cache.js';
export function addLotTypeField(lotTypeFieldForm, requestSession) {
const database = sqlite(databasePath);
const rightNowMillis = Date.now();
@ -13,9 +13,9 @@ export function addLotTypeField(lotTypeFieldForm, requestSession) {
recordCreate_userName, recordCreate_timeMillis,
recordUpdate_userName, recordUpdate_timeMillis)
values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`)
.run(lotTypeFieldForm.lotTypeId, lotTypeFieldForm.lotTypeField, lotTypeFieldForm.lotTypeFieldValues || "", lotTypeFieldForm.isRequired ? 1 : 0, lotTypeFieldForm.pattern || "", lotTypeFieldForm.minimumLength || 0, lotTypeFieldForm.maximumLength || 100, lotTypeFieldForm.orderNumber || -1, requestSession.user.userName, rightNowMillis, requestSession.user.userName, rightNowMillis);
.run(lotTypeFieldForm.lotTypeId, lotTypeFieldForm.lotTypeField, lotTypeFieldForm.lotTypeFieldValues ?? '', lotTypeFieldForm.isRequired === '' ? 0 : 1, lotTypeFieldForm.pattern ?? '', lotTypeFieldForm.minimumLength ?? 0, lotTypeFieldForm.maximumLength ?? 100, lotTypeFieldForm.orderNumber ?? -1, requestSession.user.userName, rightNowMillis, requestSession.user.userName, rightNowMillis);
database.close();
clearCacheByTableName("LotTypeFields");
clearCacheByTableName('LotTypeFields');
return result.lastInsertRowid;
}
export default addLotTypeField;

View File

@ -1,33 +1,33 @@
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 type * as recordTypes from "../../types/recordTypes";
import type * as recordTypes from '../../types/recordTypes'
interface AddLotTypeFieldForm {
lotTypeId: string | number;
lotTypeField: string;
lotTypeFieldValues?: string;
isRequired?: string;
pattern?: string;
minimumLength: string | number;
maximumLength: string | number;
orderNumber?: number;
lotTypeId: string | number
lotTypeField: string
lotTypeFieldValues?: string
isRequired?: string
pattern?: string
minimumLength: string | number
maximumLength: string | number
orderNumber?: number
}
export function addLotTypeField(
lotTypeFieldForm: AddLotTypeFieldForm,
requestSession: recordTypes.PartialSession
lotTypeFieldForm: AddLotTypeFieldForm,
requestSession: recordTypes.PartialSession
): number {
const database = sqlite(databasePath);
const database = sqlite(databasePath)
const rightNowMillis = Date.now();
const rightNowMillis = Date.now()
const result = database
.prepare(
`insert into LotTypeFields (
const result = database
.prepare(
`insert into LotTypeFields (
lotTypeId, lotTypeField, lotTypeFieldValues,
isRequired, pattern,
minimumLength, maximumLength,
@ -35,27 +35,27 @@ export function addLotTypeField(
recordCreate_userName, recordCreate_timeMillis,
recordUpdate_userName, recordUpdate_timeMillis)
values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
)
.run(
lotTypeFieldForm.lotTypeId,
lotTypeFieldForm.lotTypeField,
lotTypeFieldForm.lotTypeFieldValues || "",
lotTypeFieldForm.isRequired ? 1 : 0,
lotTypeFieldForm.pattern || "",
lotTypeFieldForm.minimumLength || 0,
lotTypeFieldForm.maximumLength || 100,
lotTypeFieldForm.orderNumber || -1,
requestSession.user.userName,
rightNowMillis,
requestSession.user.userName,
rightNowMillis
);
)
.run(
lotTypeFieldForm.lotTypeId,
lotTypeFieldForm.lotTypeField,
lotTypeFieldForm.lotTypeFieldValues ?? '',
lotTypeFieldForm.isRequired === '' ? 0 : 1,
lotTypeFieldForm.pattern ?? '',
lotTypeFieldForm.minimumLength ?? 0,
lotTypeFieldForm.maximumLength ?? 100,
lotTypeFieldForm.orderNumber ?? -1,
requestSession.user!.userName,
rightNowMillis,
requestSession.user!.userName,
rightNowMillis
)
database.close();
database.close()
clearCacheByTableName("LotTypeFields");
clearCacheByTableName('LotTypeFields')
return result.lastInsertRowid as number;
return result.lastInsertRowid as number
}
export default addLotTypeField;
export default addLotTypeField

View File

@ -1,4 +1,4 @@
import type * as recordTypes from "../../types/recordTypes";
import type * as recordTypes from '../../types/recordTypes';
interface AddMapForm {
mapName: string;
mapDescription: string;

View File

@ -1,19 +1,19 @@
import sqlite from "better-sqlite3";
import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js";
import sqlite from 'better-sqlite3';
import { lotOccupancyDB as databasePath } from '../../data/databasePaths.js';
export function addMap(mapForm, requestSession) {
const database = sqlite(databasePath);
const rightNowMillis = Date.now();
const result = database
.prepare(`insert into Maps (
mapName, mapDescription,
mapSVG, mapLatitude, mapLongitude,
mapAddress1, mapAddress2,
mapCity, mapProvince, mapPostalCode,
mapPhoneNumber,
recordCreate_userName, recordCreate_timeMillis,
recordUpdate_userName, recordUpdate_timeMillis)
values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`)
.run(mapForm.mapName, mapForm.mapDescription, mapForm.mapSVG, mapForm.mapLatitude === "" ? undefined : mapForm.mapLatitude, mapForm.mapLongitude === "" ? undefined : mapForm.mapLongitude, mapForm.mapAddress1, mapForm.mapAddress2, mapForm.mapCity, mapForm.mapProvince, mapForm.mapPostalCode, mapForm.mapPhoneNumber, requestSession.user.userName, rightNowMillis, requestSession.user.userName, rightNowMillis);
mapName, mapDescription,
mapSVG, mapLatitude, mapLongitude,
mapAddress1, mapAddress2,
mapCity, mapProvince, mapPostalCode,
mapPhoneNumber,
recordCreate_userName, recordCreate_timeMillis,
recordUpdate_userName, recordUpdate_timeMillis)
values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`)
.run(mapForm.mapName, mapForm.mapDescription, mapForm.mapSVG, mapForm.mapLatitude === '' ? undefined : mapForm.mapLatitude, mapForm.mapLongitude === '' ? undefined : mapForm.mapLongitude, mapForm.mapAddress1, mapForm.mapAddress2, mapForm.mapCity, mapForm.mapProvince, mapForm.mapPostalCode, mapForm.mapPhoneNumber, requestSession.user.userName, rightNowMillis, requestSession.user.userName, rightNowMillis);
database.close();
return result.lastInsertRowid;
}

View File

@ -1,61 +1,64 @@
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 type * as recordTypes from "../../types/recordTypes";
import type * as recordTypes from '../../types/recordTypes'
interface AddMapForm {
mapName: string;
mapDescription: string;
mapSVG: string;
mapLatitude: string;
mapLongitude: string;
mapAddress1: string;
mapAddress2: string;
mapCity: string;
mapProvince: string;
mapPostalCode: string;
mapPhoneNumber: string;
mapName: string
mapDescription: string
mapSVG: string
mapLatitude: string
mapLongitude: string
mapAddress1: string
mapAddress2: string
mapCity: string
mapProvince: string
mapPostalCode: string
mapPhoneNumber: string
}
export function addMap(mapForm: AddMapForm, requestSession: recordTypes.PartialSession): number {
const database = sqlite(databasePath);
export function addMap(
mapForm: AddMapForm,
requestSession: recordTypes.PartialSession
): number {
const database = sqlite(databasePath)
const rightNowMillis = Date.now();
const rightNowMillis = Date.now()
const result = database
.prepare(
`insert into Maps (
mapName, mapDescription,
mapSVG, mapLatitude, mapLongitude,
mapAddress1, mapAddress2,
mapCity, mapProvince, mapPostalCode,
mapPhoneNumber,
recordCreate_userName, recordCreate_timeMillis,
recordUpdate_userName, recordUpdate_timeMillis)
values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
)
.run(
mapForm.mapName,
mapForm.mapDescription,
mapForm.mapSVG,
mapForm.mapLatitude === "" ? undefined : mapForm.mapLatitude,
mapForm.mapLongitude === "" ? undefined : mapForm.mapLongitude,
mapForm.mapAddress1,
mapForm.mapAddress2,
mapForm.mapCity,
mapForm.mapProvince,
mapForm.mapPostalCode,
mapForm.mapPhoneNumber,
requestSession.user.userName,
rightNowMillis,
requestSession.user.userName,
rightNowMillis
);
const result = database
.prepare(
`insert into Maps (
mapName, mapDescription,
mapSVG, mapLatitude, mapLongitude,
mapAddress1, mapAddress2,
mapCity, mapProvince, mapPostalCode,
mapPhoneNumber,
recordCreate_userName, recordCreate_timeMillis,
recordUpdate_userName, recordUpdate_timeMillis)
values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
)
.run(
mapForm.mapName,
mapForm.mapDescription,
mapForm.mapSVG,
mapForm.mapLatitude === '' ? undefined : mapForm.mapLatitude,
mapForm.mapLongitude === '' ? undefined : mapForm.mapLongitude,
mapForm.mapAddress1,
mapForm.mapAddress2,
mapForm.mapCity,
mapForm.mapProvince,
mapForm.mapPostalCode,
mapForm.mapPhoneNumber,
requestSession.user!.userName,
rightNowMillis,
requestSession.user!.userName,
rightNowMillis
)
database.close();
database.close()
return result.lastInsertRowid as number;
return result.lastInsertRowid as number
}
export default addMap;
export default addMap

View File

@ -1,4 +1,4 @@
import sqlite from "better-sqlite3";
import type * as recordTypes from "../../types/recordTypes";
export declare function getLotOccupancy(lotOccupancyId: number | string, connectedDatabase?: sqlite.Database): recordTypes.LotOccupancy;
import sqlite from 'better-sqlite3';
import type * as recordTypes from '../../types/recordTypes';
export declare function getLotOccupancy(lotOccupancyId: number | string, connectedDatabase?: sqlite.Database): recordTypes.LotOccupancy | undefined;
export default getLotOccupancy;

View File

@ -1,18 +1,18 @@
import sqlite from "better-sqlite3";
import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js";
import { dateIntegerToString } from "@cityssm/expressjs-server-js/dateTimeFns.js";
import { getLotOccupancyOccupants } from "./getLotOccupancyOccupants.js";
import { getLotOccupancyComments } from "./getLotOccupancyComments.js";
import { getLotOccupancyFields } from "./getLotOccupancyFields.js";
import { getLotOccupancyFees } from "./getLotOccupancyFees.js";
import { getLotOccupancyTransactions } from "./getLotOccupancyTransactions.js";
import { getWorkOrders } from "./getWorkOrders.js";
import sqlite from 'better-sqlite3';
import { lotOccupancyDB as databasePath } from '../../data/databasePaths.js';
import { dateIntegerToString } from '@cityssm/expressjs-server-js/dateTimeFns.js';
import { getLotOccupancyOccupants } from './getLotOccupancyOccupants.js';
import { getLotOccupancyComments } from './getLotOccupancyComments.js';
import { getLotOccupancyFields } from './getLotOccupancyFields.js';
import { getLotOccupancyFees } from './getLotOccupancyFees.js';
import { getLotOccupancyTransactions } from './getLotOccupancyTransactions.js';
import { getWorkOrders } from './getWorkOrders.js';
export function getLotOccupancy(lotOccupancyId, connectedDatabase) {
const database = connectedDatabase ||
const database = connectedDatabase ??
sqlite(databasePath, {
readonly: true
});
database.function("userFn_dateIntegerToString", dateIntegerToString);
database.function('userFn_dateIntegerToString', dateIntegerToString);
const lotOccupancy = database
.prepare(`select o.lotOccupancyId,
o.occupancyTypeId, t.occupancyType,

View File

@ -1,33 +1,33 @@
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 { getLotOccupancyOccupants } from "./getLotOccupancyOccupants.js";
import { getLotOccupancyComments } from "./getLotOccupancyComments.js";
import { getLotOccupancyFields } from "./getLotOccupancyFields.js";
import { getLotOccupancyFees } from "./getLotOccupancyFees.js";
import { getLotOccupancyTransactions } from "./getLotOccupancyTransactions.js";
import { getWorkOrders } from "./getWorkOrders.js";
import { getLotOccupancyOccupants } from './getLotOccupancyOccupants.js'
import { getLotOccupancyComments } from './getLotOccupancyComments.js'
import { getLotOccupancyFields } from './getLotOccupancyFields.js'
import { getLotOccupancyFees } from './getLotOccupancyFees.js'
import { getLotOccupancyTransactions } from './getLotOccupancyTransactions.js'
import { getWorkOrders } from './getWorkOrders.js'
import type * as recordTypes from "../../types/recordTypes";
import type * as recordTypes from '../../types/recordTypes'
export function getLotOccupancy(
lotOccupancyId: number | string,
connectedDatabase?: sqlite.Database
): recordTypes.LotOccupancy {
const database =
connectedDatabase ||
sqlite(databasePath, {
readonly: true
});
lotOccupancyId: number | string,
connectedDatabase?: sqlite.Database
): recordTypes.LotOccupancy | undefined {
const database =
connectedDatabase ??
sqlite(databasePath, {
readonly: true
})
database.function("userFn_dateIntegerToString", dateIntegerToString);
database.function('userFn_dateIntegerToString', dateIntegerToString)
const lotOccupancy: recordTypes.LotOccupancy = database
.prepare(
`select o.lotOccupancyId,
const lotOccupancy: recordTypes.LotOccupancy | undefined = database
.prepare(
`select o.lotOccupancyId,
o.occupancyTypeId, t.occupancyType,
o.lotId, l.lotName, l.lotTypeId,
l.mapId, m.mapName,
@ -40,36 +40,48 @@ export function getLotOccupancy(
left join Maps m on l.mapId = m.mapId
where o.recordDelete_timeMillis is null
and o.lotOccupancyId = ?`
)
.get(lotOccupancyId);
)
.get(lotOccupancyId)
if (lotOccupancy) {
lotOccupancy.lotOccupancyFields = getLotOccupancyFields(lotOccupancyId, database);
lotOccupancy.lotOccupancyOccupants = getLotOccupancyOccupants(lotOccupancyId, database);
lotOccupancy.lotOccupancyComments = getLotOccupancyComments(lotOccupancyId, database);
lotOccupancy.lotOccupancyFees = getLotOccupancyFees(lotOccupancyId, database);
lotOccupancy.lotOccupancyTransactions = getLotOccupancyTransactions(
lotOccupancyId,
database
);
if (lotOccupancy) {
lotOccupancy.lotOccupancyFields = getLotOccupancyFields(
lotOccupancyId,
database
)
lotOccupancy.lotOccupancyOccupants = getLotOccupancyOccupants(
lotOccupancyId,
database
)
lotOccupancy.lotOccupancyComments = getLotOccupancyComments(
lotOccupancyId,
database
)
lotOccupancy.lotOccupancyFees = getLotOccupancyFees(
lotOccupancyId,
database
)
lotOccupancy.lotOccupancyTransactions = getLotOccupancyTransactions(
lotOccupancyId,
database
)
lotOccupancy.workOrders = getWorkOrders(
{
lotOccupancyId
},
{
limit: -1,
offset: 0
},
database
).workOrders;
}
lotOccupancy.workOrders = getWorkOrders(
{
lotOccupancyId
},
{
limit: -1,
offset: 0
},
database
).workOrders
}
if (!connectedDatabase) {
database.close();
}
if (!connectedDatabase) {
database.close()
}
return lotOccupancy;
return lotOccupancy
}
export default getLotOccupancy;
export default getLotOccupancy

215
package-lock.json generated
View File

@ -78,6 +78,7 @@
"cypress": "^12.3.0",
"cypress-axe": "^1.2.0",
"eslint": "^8.31.0",
"eslint-config-standard-with-typescript": "^26.0.0",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^6.1.1",
@ -2442,6 +2443,16 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/builtins": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/builtins/-/builtins-5.0.1.tgz",
"integrity": "sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==",
"dev": true,
"peer": true,
"dependencies": {
"semver": "^7.0.0"
}
},
"node_modules/bulma": {
"version": "0.9.4",
"resolved": "https://registry.npmjs.org/bulma/-/bulma-0.9.4.tgz",
@ -4020,6 +4031,50 @@
"url": "https://opencollective.com/eslint"
}
},
"node_modules/eslint-config-standard": {
"version": "17.0.0",
"resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-17.0.0.tgz",
"integrity": "sha512-/2ks1GKyqSOkH7JFvXJicu0iMpoojkwB+f5Du/1SC0PtBL+s8v30k9njRZ21pm2drKYm2342jFnGWzttxPmZVg==",
"dev": true,
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
],
"peerDependencies": {
"eslint": "^8.0.1",
"eslint-plugin-import": "^2.25.2",
"eslint-plugin-n": "^15.0.0",
"eslint-plugin-promise": "^6.0.0"
}
},
"node_modules/eslint-config-standard-with-typescript": {
"version": "26.0.0",
"resolved": "https://registry.npmjs.org/eslint-config-standard-with-typescript/-/eslint-config-standard-with-typescript-26.0.0.tgz",
"integrity": "sha512-TluIWunQo76qp4MHyYIaTT+sN2q2v/jTeE3Dj4rXsSbx27GOUEOujhJaAL3v9dHVQelAK13gZ5Jy9IWnWCyFrg==",
"dev": true,
"dependencies": {
"@typescript-eslint/parser": "^5.0.0",
"eslint-config-standard": "17.0.0"
},
"peerDependencies": {
"@typescript-eslint/eslint-plugin": "^5.0.0",
"eslint": "^8.0.1",
"eslint-plugin-import": "^2.25.2",
"eslint-plugin-n": "^15.0.0",
"eslint-plugin-promise": "^6.0.0",
"typescript": "*"
}
},
"node_modules/eslint-import-resolver-node": {
"version": "0.3.6",
"resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz",
@ -4158,6 +4213,78 @@
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
"dev": true
},
"node_modules/eslint-plugin-n": {
"version": "15.6.1",
"resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-15.6.1.tgz",
"integrity": "sha512-R9xw9OtCRxxaxaszTQmQAlPgM+RdGjaL1akWuY/Fv9fRAi8Wj4CUKc6iYVG8QNRjRuo8/BqVYIpfqberJUEacA==",
"dev": true,
"peer": true,
"dependencies": {
"builtins": "^5.0.1",
"eslint-plugin-es": "^4.1.0",
"eslint-utils": "^3.0.0",
"ignore": "^5.1.1",
"is-core-module": "^2.11.0",
"minimatch": "^3.1.2",
"resolve": "^1.22.1",
"semver": "^7.3.8"
},
"engines": {
"node": ">=12.22.0"
},
"funding": {
"url": "https://github.com/sponsors/mysticatea"
},
"peerDependencies": {
"eslint": ">=7.0.0"
}
},
"node_modules/eslint-plugin-n/node_modules/eslint-plugin-es": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-4.1.0.tgz",
"integrity": "sha512-GILhQTnjYE2WorX5Jyi5i4dz5ALWxBIdQECVQavL6s7cI76IZTDWleTHkxz/QT3kvcs2QlGHvKLYsSlPOlPXnQ==",
"dev": true,
"peer": true,
"dependencies": {
"eslint-utils": "^2.0.0",
"regexpp": "^3.0.0"
},
"engines": {
"node": ">=8.10.0"
},
"funding": {
"url": "https://github.com/sponsors/mysticatea"
},
"peerDependencies": {
"eslint": ">=4.19.1"
}
},
"node_modules/eslint-plugin-n/node_modules/eslint-plugin-es/node_modules/eslint-utils": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz",
"integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==",
"dev": true,
"peer": true,
"dependencies": {
"eslint-visitor-keys": "^1.1.0"
},
"engines": {
"node": ">=6"
},
"funding": {
"url": "https://github.com/sponsors/mysticatea"
}
},
"node_modules/eslint-plugin-n/node_modules/eslint-visitor-keys": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz",
"integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==",
"dev": true,
"peer": true,
"engines": {
"node": ">=4"
}
},
"node_modules/eslint-plugin-node": {
"version": "11.1.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz",
@ -7032,9 +7159,9 @@
}
},
"node_modules/is-core-module": {
"version": "2.9.0",
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz",
"integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==",
"version": "2.11.0",
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz",
"integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==",
"dev": true,
"dependencies": {
"has": "^1.0.3"
@ -14465,6 +14592,16 @@
"integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==",
"dev": true
},
"builtins": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/builtins/-/builtins-5.0.1.tgz",
"integrity": "sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==",
"dev": true,
"peer": true,
"requires": {
"semver": "^7.0.0"
}
},
"bulma": {
"version": "0.9.4",
"resolved": "https://registry.npmjs.org/bulma/-/bulma-0.9.4.tgz",
@ -15761,6 +15898,23 @@
}
}
},
"eslint-config-standard": {
"version": "17.0.0",
"resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-17.0.0.tgz",
"integrity": "sha512-/2ks1GKyqSOkH7JFvXJicu0iMpoojkwB+f5Du/1SC0PtBL+s8v30k9njRZ21pm2drKYm2342jFnGWzttxPmZVg==",
"dev": true,
"requires": {}
},
"eslint-config-standard-with-typescript": {
"version": "26.0.0",
"resolved": "https://registry.npmjs.org/eslint-config-standard-with-typescript/-/eslint-config-standard-with-typescript-26.0.0.tgz",
"integrity": "sha512-TluIWunQo76qp4MHyYIaTT+sN2q2v/jTeE3Dj4rXsSbx27GOUEOujhJaAL3v9dHVQelAK13gZ5Jy9IWnWCyFrg==",
"dev": true,
"requires": {
"@typescript-eslint/parser": "^5.0.0",
"eslint-config-standard": "17.0.0"
}
},
"eslint-import-resolver-node": {
"version": "0.3.6",
"resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz",
@ -15877,6 +16031,55 @@
}
}
},
"eslint-plugin-n": {
"version": "15.6.1",
"resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-15.6.1.tgz",
"integrity": "sha512-R9xw9OtCRxxaxaszTQmQAlPgM+RdGjaL1akWuY/Fv9fRAi8Wj4CUKc6iYVG8QNRjRuo8/BqVYIpfqberJUEacA==",
"dev": true,
"peer": true,
"requires": {
"builtins": "^5.0.1",
"eslint-plugin-es": "^4.1.0",
"eslint-utils": "^3.0.0",
"ignore": "^5.1.1",
"is-core-module": "^2.11.0",
"minimatch": "^3.1.2",
"resolve": "^1.22.1",
"semver": "^7.3.8"
},
"dependencies": {
"eslint-plugin-es": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-4.1.0.tgz",
"integrity": "sha512-GILhQTnjYE2WorX5Jyi5i4dz5ALWxBIdQECVQavL6s7cI76IZTDWleTHkxz/QT3kvcs2QlGHvKLYsSlPOlPXnQ==",
"dev": true,
"peer": true,
"requires": {
"eslint-utils": "^2.0.0",
"regexpp": "^3.0.0"
},
"dependencies": {
"eslint-utils": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz",
"integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==",
"dev": true,
"peer": true,
"requires": {
"eslint-visitor-keys": "^1.1.0"
}
}
}
},
"eslint-visitor-keys": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz",
"integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==",
"dev": true,
"peer": true
}
}
},
"eslint-plugin-node": {
"version": "11.1.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz",
@ -17998,9 +18201,9 @@
}
},
"is-core-module": {
"version": "2.9.0",
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz",
"integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==",
"version": "2.11.0",
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz",
"integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==",
"dev": true,
"requires": {
"has": "^1.0.3"

View File

@ -1,117 +1,118 @@
{
"name": "lot-occupancy-system",
"version": "1.0.0-alpha.6",
"type": "module",
"description": "A system for managing the occupancy of lots. (i.e. Cemetery management)",
"exports": "./app.js",
"engines": {
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
},
"scripts": {
"build:version": "npx genversion --es6 --semi version.js",
"init:cemetery": "cross-env NODE_ENV=dev DEBUG=lot-occupancy-system:* node ./helpers/initializer.database.cemetery.js",
"init:cemetery:test": "cross-env NODE_ENV=dev DEBUG=lot-occupancy-system:* TEST_DATABASES=true node ./helpers/initializer.database.cemetery.js",
"start": "cross-env NODE_ENV=production node ./bin/www",
"dev:test": "cross-env NODE_ENV=dev DEBUG=lot-occupancy-system:* TEST_DATABASES=true nodemon ./bin/www.js",
"dev:live": "cross-env NODE_ENV=dev DEBUG=lot-occupancy-system:* nodemon ./bin/www.js",
"cy:open": "cypress open --config-file cypress.config.ts",
"cy:run": "cypress run --config-file cypress.config.ts",
"test": "cross-env NODE_ENV=dev DEBUG=lot-occupancy-system:* TEST_DATABASES=true mocha --timeout 30000 --exit",
"coverage": "cross-env NODE_ENV=dev DEBUG=lot-occupancy-system:* TEST_DATABASES=true c8 --reporter=lcov --reporter=text --reporter=text-summary mocha --timeout 30000 --exit",
"temp:legacy:importFromCsv": "cross-env NODE_ENV=dev DEBUG=lot-occupancy-system:* TEST_DATABASES=true node ./temp/legacy.importFromCsv.js",
"temp:so:exportMaps": "node ./temp/so.exportMaps.js"
},
"repository": {
"type": "git",
"url": "git+https://github.com/cityssm/lot-occupancy-manager.git"
},
"author": "The Corporation of the City of Sault Ste. Marie",
"license": "MIT",
"bugs": {
"url": "https://github.com/cityssm/lot-occupancy-manager/issues"
},
"homepage": "https://github.com/cityssm/lot-occupancy-manager#readme",
"private": true,
"dependencies": {
"@cityssm/bulma-js": "^0.4.0",
"@cityssm/bulma-webapp-js": "^1.5.0",
"@cityssm/date-diff": "^2.2.3",
"@cityssm/expressjs-server-js": "^2.3.3",
"@cityssm/ntfy-publish": "^0.2.1",
"@cityssm/pdf-puppeteer": "^2.0.0-beta.1",
"@fortawesome/fontawesome-free": "^5.15.4",
"activedirectory2": "^2.1.0",
"better-sqlite3": "^8.0.1",
"bulma-calendar": "^6.1.18",
"camelcase": "^7.0.1",
"compression": "^1.7.4",
"cookie-parser": "^1.4.6",
"cross-env": "^7.0.3",
"csurf": "^1.11.0",
"debug": "^4.3.4",
"ejs": "^3.1.8",
"exit-hook": "^3.1.4",
"express": "^4.18.2",
"express-rate-limit": "^6.7.0",
"express-session": "^1.17.3",
"font-awesome-v5-icons": "^1.3.0",
"http-errors": "^2.0.0",
"ical-generator": "^3.6.1",
"leaflet": "^1.9.3",
"papaparse": "^5.3.2",
"randomcolor": "^0.6.2",
"session-file-store": "^1.5.0",
"uuid": "^9.0.0"
},
"devDependencies": {
"@cityssm/bulma-a11y": "^0.4.0",
"@cityssm/bulma-sticky-table": "^2.0.1",
"@cityssm/bulma-webapp-css": "^0.12.0",
"@cityssm/fa-glow": "^0.1.0",
"@cityssm/mssql-multi-pool": "^2.2.0",
"@cityssm/simple-fa5-checkbox": "^0.2.1",
"@types/activedirectory2": "^1.2.3",
"@types/better-sqlite3": "^7.6.3",
"@types/compression": "^1.7.2",
"@types/cookie-parser": "^1.4.3",
"@types/csurf": "^1.11.2",
"@types/debug": "^4.1.7",
"@types/ejs": "^3.1.1",
"@types/express": "^4.17.15",
"@types/express-session": "^1.17.5",
"@types/gulp": "^4.0.10",
"@types/gulp-changed": "^0.0.35",
"@types/gulp-minify": "^3.1.1",
"@types/gulp-sass": "^5.0.0",
"@types/http-errors": "^2.0.1",
"@types/leaflet": "^1.9.0",
"@types/mocha": "^10.0.1",
"@types/node-windows": "^0.1.2",
"@types/papaparse": "^5.3.7",
"@types/randomcolor": "^0.5.7",
"@types/session-file-store": "^1.2.2",
"@types/uuid": "^9.0.0",
"@typescript-eslint/eslint-plugin": "^5.48.1",
"@typescript-eslint/parser": "^5.48.1",
"bulma": "^0.9.4",
"bulma-divider": "^0.2.0",
"bulma-helpers": "^0.4.3",
"bulma-steps": "^2.2.1",
"bulma-switch": "^2.0.4",
"bulma-tooltip": "^3.0.2",
"cypress": "^12.3.0",
"cypress-axe": "^1.2.0",
"eslint": "^8.31.0",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^6.1.1",
"eslint-plugin-unicorn": "^45.0.2",
"gulp": "^4.0.2",
"gulp-changed": "^4.0.3",
"gulp-include": "^2.4.1",
"gulp-minify": "^3.1.0",
"gulp-sass": "^5.1.0",
"nodemon": "^2.0.20",
"sass": "^1.57.1"
}
"name": "lot-occupancy-system",
"version": "1.0.0-alpha.6",
"type": "module",
"description": "A system for managing the occupancy of lots. (i.e. Cemetery management)",
"exports": "./app.js",
"engines": {
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
},
"scripts": {
"build:version": "npx genversion --es6 --semi version.js",
"init:cemetery": "cross-env NODE_ENV=dev DEBUG=lot-occupancy-system:* node ./helpers/initializer.database.cemetery.js",
"init:cemetery:test": "cross-env NODE_ENV=dev DEBUG=lot-occupancy-system:* TEST_DATABASES=true node ./helpers/initializer.database.cemetery.js",
"start": "cross-env NODE_ENV=production node ./bin/www",
"dev:test": "cross-env NODE_ENV=dev DEBUG=lot-occupancy-system:* TEST_DATABASES=true nodemon ./bin/www.js",
"dev:live": "cross-env NODE_ENV=dev DEBUG=lot-occupancy-system:* nodemon ./bin/www.js",
"cy:open": "cypress open --config-file cypress.config.ts",
"cy:run": "cypress run --config-file cypress.config.ts",
"test": "cross-env NODE_ENV=dev DEBUG=lot-occupancy-system:* TEST_DATABASES=true mocha --timeout 30000 --exit",
"coverage": "cross-env NODE_ENV=dev DEBUG=lot-occupancy-system:* TEST_DATABASES=true c8 --reporter=lcov --reporter=text --reporter=text-summary mocha --timeout 30000 --exit",
"temp:legacy:importFromCsv": "cross-env NODE_ENV=dev DEBUG=lot-occupancy-system:* TEST_DATABASES=true node ./temp/legacy.importFromCsv.js",
"temp:so:exportMaps": "node ./temp/so.exportMaps.js"
},
"repository": {
"type": "git",
"url": "git+https://github.com/cityssm/lot-occupancy-manager.git"
},
"author": "The Corporation of the City of Sault Ste. Marie",
"license": "MIT",
"bugs": {
"url": "https://github.com/cityssm/lot-occupancy-manager/issues"
},
"homepage": "https://github.com/cityssm/lot-occupancy-manager#readme",
"private": true,
"dependencies": {
"@cityssm/bulma-js": "^0.4.0",
"@cityssm/bulma-webapp-js": "^1.5.0",
"@cityssm/date-diff": "^2.2.3",
"@cityssm/expressjs-server-js": "^2.3.3",
"@cityssm/ntfy-publish": "^0.2.1",
"@cityssm/pdf-puppeteer": "^2.0.0-beta.1",
"@fortawesome/fontawesome-free": "^5.15.4",
"activedirectory2": "^2.1.0",
"better-sqlite3": "^8.0.1",
"bulma-calendar": "^6.1.18",
"camelcase": "^7.0.1",
"compression": "^1.7.4",
"cookie-parser": "^1.4.6",
"cross-env": "^7.0.3",
"csurf": "^1.11.0",
"debug": "^4.3.4",
"ejs": "^3.1.8",
"exit-hook": "^3.1.4",
"express": "^4.18.2",
"express-rate-limit": "^6.7.0",
"express-session": "^1.17.3",
"font-awesome-v5-icons": "^1.3.0",
"http-errors": "^2.0.0",
"ical-generator": "^3.6.1",
"leaflet": "^1.9.3",
"papaparse": "^5.3.2",
"randomcolor": "^0.6.2",
"session-file-store": "^1.5.0",
"uuid": "^9.0.0"
},
"devDependencies": {
"@cityssm/bulma-a11y": "^0.4.0",
"@cityssm/bulma-sticky-table": "^2.0.1",
"@cityssm/bulma-webapp-css": "^0.12.0",
"@cityssm/fa-glow": "^0.1.0",
"@cityssm/mssql-multi-pool": "^2.2.0",
"@cityssm/simple-fa5-checkbox": "^0.2.1",
"@types/activedirectory2": "^1.2.3",
"@types/better-sqlite3": "^7.6.3",
"@types/compression": "^1.7.2",
"@types/cookie-parser": "^1.4.3",
"@types/csurf": "^1.11.2",
"@types/debug": "^4.1.7",
"@types/ejs": "^3.1.1",
"@types/express": "^4.17.15",
"@types/express-session": "^1.17.5",
"@types/gulp": "^4.0.10",
"@types/gulp-changed": "^0.0.35",
"@types/gulp-minify": "^3.1.1",
"@types/gulp-sass": "^5.0.0",
"@types/http-errors": "^2.0.1",
"@types/leaflet": "^1.9.0",
"@types/mocha": "^10.0.1",
"@types/node-windows": "^0.1.2",
"@types/papaparse": "^5.3.7",
"@types/randomcolor": "^0.5.7",
"@types/session-file-store": "^1.2.2",
"@types/uuid": "^9.0.0",
"@typescript-eslint/eslint-plugin": "^5.48.1",
"@typescript-eslint/parser": "^5.48.1",
"bulma": "^0.9.4",
"bulma-divider": "^0.2.0",
"bulma-helpers": "^0.4.3",
"bulma-steps": "^2.2.1",
"bulma-switch": "^2.0.4",
"bulma-tooltip": "^3.0.2",
"cypress": "^12.3.0",
"cypress-axe": "^1.2.0",
"eslint": "^8.31.0",
"eslint-config-standard-with-typescript": "^26.0.0",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^6.1.1",
"eslint-plugin-unicorn": "^45.0.2",
"gulp": "^4.0.2",
"gulp-changed": "^4.0.3",
"gulp-include": "^2.4.1",
"gulp-minify": "^3.1.0",
"gulp-sass": "^5.1.0",
"nodemon": "^2.0.20",
"sass": "^1.57.1"
}
}

View File

@ -26,13 +26,13 @@ async function importMaps() {
});
}
}
catch (_a) {
catch {
}
finally {
try {
pool.close();
}
catch (_b) {
catch {
}
}
}

View File

@ -16,7 +16,7 @@ describe("lot-occupancy-system", () => {
try {
httpServer.close();
}
catch (_a) {
catch {
}
});
it("Ensure server starts on port " + portNumber.toString(), () => {

View File

@ -1,15 +1,3 @@
var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); }
var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) {
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
var g = generator.apply(thisArg, _arguments || []), i, q = [];
return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i;
function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }
function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }
function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
function fulfill(value) { resume("next", value); }
function reject(value) { resume("throw", value); }
function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }
};
export const testView = "*testView";
export const testUpdate = "*testUpdate";
export const testAdmin = "*testAdmin";
@ -37,7 +25,7 @@ export const fakeAdminSession = {
user: undefined
};
export const fakeRequest = {
[Symbol.asyncIterator]() { return __asyncGenerator(this, arguments, function* _a() { }); },
async *[Symbol.asyncIterator]() { },
_destroy: undefined,
_read: undefined,
aborted: undefined,

View File

@ -1,6 +1,6 @@
{
"compilerOptions": {
"target": "es2017",
"target": "es2022",
"module": "es2022",
"moduleResolution": "Node",
"isolatedModules": false,
@ -11,7 +11,8 @@
"allowSyntheticDefaultImports": true,
"resolveJsonModule": true,
"esModuleInterop": true,
"skipLibCheck": true
"skipLibCheck": true,
"strictNullChecks": true
},
"compileOnSave": true,
"buildOnSave": true,

View File

@ -258,11 +258,11 @@ export interface UserProperties {
isAdmin: boolean;
apiKey: string;
}
declare module "express-session" {
declare module 'express-session' {
interface Session {
user: User;
user?: User;
}
}
export interface PartialSession {
user: User;
user?: User;
}

Some files were not shown because too many files have changed in this diff Show More