major refactoring in progress

**broken**
deepsource-autofix-76c6eb20
Dan Gowans 2025-02-21 15:48:28 -05:00
parent ad098bfa12
commit 0ea7494b8c
558 changed files with 3147 additions and 4188 deletions

View File

@ -1,18 +0,0 @@
version: "2"
checks:
file-lines:
config:
threshold: 1500
method-complexity:
config:
threshold: 20
method-lines:
config:
threshold: 500
exclude_patterns:
- "cypress/"
- "**/node_modules/"
- "temp/"
- "test/"
- "**/*.d.ts"
- "**/*.js"

View File

@ -1,3 +0,0 @@
**/*.d.ts
**/*.ejs
**/*.js

View File

@ -1,72 +0,0 @@
name: Coverage Testing
on: [workflow_dispatch, push, pull_request]
permissions: read-all
jobs:
Coverage:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
node: [ 18, 20, 21 ]
env:
CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }}
DEEPSOURCE_DSN: ${{ secrets.DEEPSOURCE_DSN }}
name: Node ${{ matrix.node }}
steps:
- uses: actions/checkout@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
- name: Install Application
run: |
npm ci
npm install -g mocha c8 cypress@13
- name: Copy Test Config
run: cp ./data/config.testing.js ./data/config.js
- name: Test Application Startup
run: npm run test:startup
- name: Code Climate (Before)
if: ${{ github.event_name != 'pull_request' && env.CC_TEST_REPORTER_ID != '' && matrix.node == 20 }}
run: |
curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./codeclimate-test-reporter
chmod +x codeclimate-test-reporter
./codeclimate-test-reporter before-build
- name: Verify Cypress
run: cypress verify
env:
CYPRESS_VERIFY_TIMEOUT: 600000
- name: Run Coverage Testing
run: c8 --reporter=lcov --reporter=text --reporter=text-summary mocha --timeout 10000 --exit
- name: Code Climate (After)
if: ${{ github.event_name != 'pull_request' && env.CC_TEST_REPORTER_ID != '' && matrix.node == 20 }}
run: |
./codeclimate-test-reporter after-build -t lcov --exit-code $?
- name: Codecov
if: ${{ github.event_name != 'pull_request' && env.CODECOV_TOKEN != '' && matrix.node == 20 }}
run: |
curl -Os https://uploader.codecov.io/latest/linux/codecov
chmod +x codecov
./codecov -t ${CODECOV_TOKEN}
- name: DeepSource
if: ${{ github.event_name != 'pull_request' && env.DEEPSOURCE_DSN != '' && matrix.node == 20 }}
run: |
# Install deepsource CLI
curl https://deepsource.io/cli | sh
# From the root directory, run the report coverage command
./bin/deepsource report --analyzer test-coverage --key javascript --value-file ./coverage/lcov.info

View File

@ -1,6 +1,6 @@
MIT License
# MIT License
Copyright (c) 2023 The City of Sault Ste. Marie
Copyright (c) 2025 The City of Sault Ste. Marie
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@ -1,27 +1,13 @@
# Lot Occupancy System
# Sunrise Cemetery Management System (CMS)
[![DeepSource](https://app.deepsource.com/gh/cityssm/lot-occupancy-system.svg/?label=active+issues&show_trend=true&token=8rYoZ1g7FoZHstfQmOzvlBn7)](https://app.deepsource.com/gh/cityssm/lot-occupancy-system/)
[![Maintainability](https://api.codeclimate.com/v1/badges/11a8975b332f66e6eec7/maintainability)](https://codeclimate.com/github/cityssm/lot-occupancy-system/maintainability)
[![codecov](https://codecov.io/gh/cityssm/lot-occupancy-system/branch/main/graph/badge.svg?token=1M38ZVCLKE)](https://codecov.io/gh/cityssm/lot-occupancy-system)
[![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/cityssm/lot-occupancy-system/coverage.yml?branch=main)](https://github.com/cityssm/lot-occupancy-system/actions/workflows/coverage.yml)
[![lot-occupancy-system](https://img.shields.io/endpoint?url=https://cloud.cypress.io/badge/simple/xya1fn&style=flat&logo=cypress)](https://cloud.cypress.io/projects/xya1fn/runs)
🚧 **In development** 🚧
**In development**
**A web-based application that allows cemetery managers to manage their cemetery records**
![Lot View](docs/images/lotView.png)
A system for managing the occupancy of lots.
Built with **cemetery management** in mind, but flexible enough to handle marinas and campgrounds as well.
[**User Documentation**](docs/) (In The Works)
## Key Features
**Maps are optional!**<br />
Many systems of this type start with a map, and drill down into the data from it.
This can result in a huge amount of effort to get started.
This system can run "out-of-the-box" without maps, with the option to add them when it makes sense.
This is a major refactoring of the
[Lot Occupancy System](https://github.com/cityssm/lot-occupancy-system),
originally built with multiple focuses. This fork reworks the project to focus exculsively
on cemetery management.
## About this Project

View File

@ -1,2 +1,2 @@
theme: jekyll-theme-cayman
title: Lot Occupancy System
title: Sunrise Cemetery Management System

11
app.js
View File

@ -10,11 +10,12 @@ import session from 'express-session';
import createError from 'http-errors';
import FileStore from 'session-file-store';
import { useTestDatabases } from './data/databasePaths.js';
import { DEBUG_NAMESPACE } from './debug.config.js';
import * as permissionHandlers from './handlers/permissions.js';
import { getSafeRedirectURL } from './helpers/functions.authentication.js';
import * as configFunctions from './helpers/functions.config.js';
import * as configFunctions from './helpers/config.helpers.js';
import * as printFunctions from './helpers/functions.print.js';
import { initializeDatabase } from './helpers/initializer.database.js';
import { initializeDatabase } from './helpers/helpers.database.js';
import routerAdmin from './routes/admin.js';
import routerApi from './routes/api.js';
import routerDashboard from './routes/dashboard.js';
@ -26,11 +27,11 @@ import routerPrint from './routes/print.js';
import routerReports from './routes/reports.js';
import routerWorkOrders from './routes/workOrders.js';
import { version } from './version.js';
const debug = Debug(`lot-occupancy-system:app:${process.pid}`);
const debug = Debug(`${DEBUG_NAMESPACE}:app:${process.pid}`);
/*
* INITIALIZE THE DATABASE
*/
initializeDatabase();
await initializeDatabase();
/*
* INITIALIZE APP
*/
@ -88,7 +89,7 @@ const FileStoreSession = FileStore(session);
app.use(session({
store: new FileStoreSession({
path: './data/sessions',
logFn: Debug(`lot-occupancy-system:session:${process.pid}`),
logFn: Debug(`${DEBUG_NAMESPACE}:session:${process.pid}`),
retries: 20
}),
name: sessionCookieName,

17
app.ts
View File

@ -12,11 +12,12 @@ import createError from 'http-errors'
import FileStore from 'session-file-store'
import { useTestDatabases } from './data/databasePaths.js'
import { DEBUG_NAMESPACE } from './debug.config.js'
import * as permissionHandlers from './handlers/permissions.js'
import { getSafeRedirectURL } from './helpers/functions.authentication.js'
import * as configFunctions from './helpers/functions.config.js'
import * as configFunctions from './helpers/config.helpers.js'
import * as printFunctions from './helpers/functions.print.js'
import { initializeDatabase } from './helpers/initializer.database.js'
import { initializeDatabase } from './helpers/helpers.database.js'
import routerAdmin from './routes/admin.js'
import routerApi from './routes/api.js'
import routerDashboard from './routes/dashboard.js'
@ -29,13 +30,13 @@ import routerReports from './routes/reports.js'
import routerWorkOrders from './routes/workOrders.js'
import { version } from './version.js'
const debug = Debug(`lot-occupancy-system:app:${process.pid}`)
const debug = Debug(`${DEBUG_NAMESPACE}:app:${process.pid}`)
/*
* INITIALIZE THE DATABASE
*/
initializeDatabase()
await initializeDatabase()
/*
* INITIALIZE APP
@ -150,7 +151,7 @@ app.use(
session({
store: new FileStoreSession({
path: './data/sessions',
logFn: Debug(`lot-occupancy-system:session:${process.pid}`),
logFn: Debug(`${DEBUG_NAMESPACE}:session:${process.pid}`),
retries: 20
}),
name: sessionCookieName,
@ -227,11 +228,7 @@ app.get(`${urlPrefix}/`, sessionChecker, (_request, response) => {
app.use(`${urlPrefix}/dashboard`, sessionChecker, routerDashboard)
app.use(
`${urlPrefix}/api/:apiKey`,
permissionHandlers.apiGetHandler,
routerApi
)
app.use(`${urlPrefix}/api/:apiKey`, permissionHandlers.apiGetHandler, routerApi)
app.use(`${urlPrefix}/print`, sessionChecker, routerPrint)
app.use(`${urlPrefix}/maps`, sessionChecker, routerMaps)

View File

@ -6,8 +6,9 @@ import ntfyPublish from '@cityssm/ntfy-publish';
import { secondsToMillis } from '@cityssm/to-millis';
import Debug from 'debug';
import exitHook from 'exit-hook';
import { getConfigProperty } from '../helpers/functions.config.js';
const debug = Debug(`lot-occupancy-system:www:${process.pid}`);
import { DEBUG_NAMESPACE } from '../debug.config.js';
import { getConfigProperty } from '../helpers/config.helpers.js';
const debug = Debug(`${DEBUG_NAMESPACE}:www:${process.pid}`);
const directoryName = path.dirname(fileURLToPath(import.meta.url));
const processCount = Math.min(getConfigProperty('application.maximumProcesses'), os.cpus().length);
process.title = `${getConfigProperty('application.applicationName')} (Primary)`;

View File

@ -8,10 +8,11 @@ import { secondsToMillis } from '@cityssm/to-millis'
import Debug from 'debug'
import exitHook from 'exit-hook'
import { getConfigProperty } from '../helpers/functions.config.js'
import { DEBUG_NAMESPACE } from '../debug.config.js'
import { getConfigProperty } from '../helpers/config.helpers.js'
import type { WorkerMessage } from '../types/applicationTypes.js'
const debug = Debug(`lot-occupancy-system:www:${process.pid}`)
const debug = Debug(`${DEBUG_NAMESPACE}:www:${process.pid}`)
const directoryName = path.dirname(fileURLToPath(import.meta.url))

View File

@ -4,8 +4,9 @@ import http from 'node:http';
import Debug from 'debug';
import exitHook from 'exit-hook';
import { app } from '../app.js';
import { getConfigProperty } from '../helpers/functions.config.js';
const debug = Debug(`lot-occupancy-system:wwwProcess:${process.pid}`);
import { DEBUG_NAMESPACE } from '../debug.config.js';
import { getConfigProperty } from '../helpers/config.helpers.js';
const debug = Debug(`${DEBUG_NAMESPACE}:wwwProcess:${process.pid}`);
function onError(error) {
if (error.syscall !== 'listen') {
throw error;

View File

@ -7,9 +7,10 @@ import Debug from 'debug'
import exitHook from 'exit-hook'
import { app } from '../app.js'
import { getConfigProperty } from '../helpers/functions.config.js'
import { DEBUG_NAMESPACE } from '../debug.config.js'
import { getConfigProperty } from '../helpers/config.helpers.js'
const debug = Debug(`lot-occupancy-system:wwwProcess:${process.pid}`)
const debug = Debug(`${DEBUG_NAMESPACE}:wwwProcess:${process.pid}`)
interface ServerError extends Error {
syscall: string
@ -57,9 +58,7 @@ function onListening(server: http.Server): void {
* Initialize HTTP
*/
process.title = `${getConfigProperty(
'application.applicationName'
)} (Worker)`
process.title = `${getConfigProperty('application.applicationName')} (Worker)`
const httpPort = getConfigProperty('application.httpPort')

View File

@ -1,4 +1,4 @@
import { getConfigProperty } from '../../../helpers/functions.config.js';
import { getConfigProperty } from '../../../helpers/config.helpers.js';
import { testAdmin } from '../../../test/_globals.js';
import { ajaxDelayMillis, login, logout } from '../../support/index.js';
describe('Admin - Fee Management', () => {

View File

@ -1,4 +1,4 @@
import { getConfigProperty } from '../../../helpers/functions.config.js'
import { getConfigProperty } from '../../../helpers/config.helpers.js'
import { testAdmin } from '../../../test/_globals.js'
import type { Fee } from '../../../types/recordTypes.js'
import { ajaxDelayMillis, login, logout } from '../../support/index.js'

View File

@ -1,4 +1,4 @@
import { getConfigProperty } from '../../../helpers/functions.config.js';
import { getConfigProperty } from '../../../helpers/config.helpers.js';
import { testUpdate } from '../../../test/_globals.js';
import { login, logout } from '../../support/index.js';
describe('Update - Maps', () => {

View File

@ -1,4 +1,4 @@
import { getConfigProperty } from '../../../helpers/functions.config.js'
import { getConfigProperty } from '../../../helpers/config.helpers.js'
import { testUpdate } from '../../../test/_globals.js'
import type { MapRecord } from '../../../types/recordTypes.js'
import { login, logout } from '../../support/index.js'

View File

@ -0,0 +1 @@
export {};

View File

@ -5,3 +5,4 @@ describe('Keep Alive', () => {
});
});
});
export {};

View File

@ -6,9 +6,8 @@ export const config = {
aliases: {},
settings: {
fees: {},
map: {},
lot: {},
lotOccupancy: {},
cemeteries: {},
contracts: {},
workOrders: {},
adminCleanup: {},
printPdf: {},

View File

@ -8,9 +8,8 @@ export const config: Config = {
aliases: {},
settings: {
fees: {},
map: {},
lot: {},
lotOccupancy: {},
cemeteries: {},
contracts: {},
workOrders: {},
adminCleanup: {},
printPdf: {},

View File

@ -0,0 +1,6 @@
import { config as baseConfig } from './config.base.js';
export const config = Object.assign({}, baseConfig);
config.settings.contracts.provinceDefault = 'ON';
config.settings.cemeteries.provinceDefault = 'ON';
config.settings.fees.taxPercentageDefault = 13;
export default config;

View File

@ -0,0 +1,11 @@
import { config as baseConfig } from './config.base.js'
export const config = Object.assign({}, baseConfig)
config.settings.contracts.provinceDefault = 'ON'
config.settings.cemeteries.provinceDefault = 'ON'
config.settings.fees.taxPercentageDefault = 13
export default config

View File

@ -0,0 +1,17 @@
import { config as cemeteryConfig } from './config.baseOntario.js';
export const config = { ...cemeteryConfig };
config.aliases.externalReceiptNumber = 'GP Receipt Number';
config.settings.contracts.cityDefault = 'Sault Ste. Marie';
config.settings.contracts.prints = [
'pdf/ssm.cemetery.burialPermit',
'pdf/ssm.cemetery.contract'
];
config.settings.cemeteries.cityDefault = 'Sault Ste. Marie';
config.settings.workOrders.workOrderNumberLength = 6;
config.settings.workOrders.workOrderMilestoneDateRecentBeforeDays = 7;
config.settings.workOrders.workOrderMilestoneDateRecentAfterDays = 30;
config.settings.dynamicsGP = {
integrationIsEnabled: true,
lookupOrder: ['diamond/cashReceipt', 'diamond/extendedInvoice']
};
export default config;

View File

@ -0,0 +1,26 @@
import type { Config } from '../types/configTypes.js'
import { config as cemeteryConfig } from './config.baseOntario.js'
export const config: Config = { ...cemeteryConfig }
config.aliases.externalReceiptNumber = 'GP Receipt Number'
config.settings.contracts.cityDefault = 'Sault Ste. Marie'
config.settings.contracts.prints = [
'pdf/ssm.cemetery.burialPermit',
'pdf/ssm.cemetery.contract'
]
config.settings.cemeteries.cityDefault = 'Sault Ste. Marie'
config.settings.workOrders.workOrderNumberLength = 6
config.settings.workOrders.workOrderMilestoneDateRecentBeforeDays = 7
config.settings.workOrders.workOrderMilestoneDateRecentAfterDays = 30
config.settings.dynamicsGP = {
integrationIsEnabled: true,
lookupOrder: ['diamond/cashReceipt', 'diamond/extendedInvoice']
}
export default config

View File

@ -1,19 +0,0 @@
import { config as baseConfig } from './config.base.js';
export const config = { ...baseConfig };
config.application = {
applicationName: 'Cemetery Management System',
backgroundURL: '/images/cemetery-background.jpg',
logoURL: '/images/cemetery-logo.svg'
};
config.aliases.lot = 'Burial Site';
config.aliases.lots = 'Burial Sites';
config.aliases.map = 'Cemetery';
config.aliases.maps = 'Cemeteries';
config.aliases.occupancy = 'Contract';
config.aliases.occupancies = 'Contracts';
config.aliases.occupant = 'Customer';
config.aliases.occupants = 'Customers';
config.aliases.workOrderOpenDate = 'Order Date';
config.aliases.workOrderCloseDate = 'Completion Date';
config.settings.lotOccupancy.occupancyEndDateIsRequired = false;
export default config;

View File

@ -1,6 +0,0 @@
import { config as cemeteryConfig } from './config.cemetery.js';
export const config = Object.assign({}, cemeteryConfig);
config.settings.lotOccupancy.occupantProvinceDefault = 'ON';
config.settings.map.mapProvinceDefault = 'ON';
config.settings.fees.taxPercentageDefault = 13;
export default config;

View File

@ -1,11 +0,0 @@
import { config as cemeteryConfig } from './config.cemetery.js'
export const config = Object.assign({}, cemeteryConfig)
config.settings.lotOccupancy.occupantProvinceDefault = 'ON'
config.settings.map.mapProvinceDefault = 'ON'
config.settings.fees.taxPercentageDefault = 13
export default config

View File

@ -1,4 +0,0 @@
import type { Config } from '../types/configTypes.js';
export declare const config: Config;
export declare function lotNameSortNameFunction(lotName: string): string;
export default config;

View File

@ -1,65 +0,0 @@
import NodeCache from 'node-cache';
import { config as cemeteryConfig } from './config.cemetery.ontario.js';
export const config = { ...cemeteryConfig };
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`;
const numericPadding = '00000';
const lotNameSortNameCache = new NodeCache({
stdTTL: 5 * 60,
useClones: false
});
export function lotNameSortNameFunction(lotName) {
let sortName = lotNameSortNameCache.get(lotName) ?? '';
if (sortName === '') {
try {
const lotNameSplit = lotName.toUpperCase().split('-');
const cleanLotNamePieces = [];
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);
}
sortName = cleanLotNamePieces.join('-');
}
catch {
sortName = lotName;
}
lotNameSortNameCache.set(lotName, sortName);
}
return sortName;
}
config.settings.lot.lotNameSortNameFunction = lotNameSortNameFunction;
config.settings.lotOccupancy.occupantCityDefault = 'Sault Ste. Marie';
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;
config.settings.workOrders.workOrderMilestoneDateRecentAfterDays = 30;
config.settings.dynamicsGP = {
integrationIsEnabled: true,
lookupOrder: ['diamond/cashReceipt', 'diamond/extendedInvoice']
};
export default config;

View File

@ -1,91 +0,0 @@
import NodeCache from 'node-cache'
import type { Config } from '../types/configTypes.js'
import { config as cemeteryConfig } from './config.cemetery.ontario.js'
export const config: Config = { ...cemeteryConfig}
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`
const numericPadding = '00000'
const lotNameSortNameCache = new NodeCache({
stdTTL: 5 * 60,
useClones: false
})
export function lotNameSortNameFunction(lotName: string): string {
let sortName: string = lotNameSortNameCache.get(lotName) ?? ''
if (sortName === '') {
try {
const lotNameSplit = lotName.toUpperCase().split('-')
const cleanLotNamePieces: string[] = []
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
)
}
sortName = cleanLotNamePieces.join('-')
} catch {
sortName = lotName
}
lotNameSortNameCache.set(lotName, sortName)
}
return sortName
}
config.settings.lot.lotNameSortNameFunction = lotNameSortNameFunction
config.settings.lotOccupancy.occupantCityDefault = 'Sault Ste. Marie'
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
config.settings.workOrders.workOrderMilestoneDateRecentAfterDays = 30
config.settings.dynamicsGP = {
integrationIsEnabled: true,
lookupOrder: ['diamond/cashReceipt', 'diamond/extendedInvoice']
}
export default config

View File

@ -1,26 +0,0 @@
import type { Config } from '../types/configTypes.js'
import { config as baseConfig } from './config.base.js'
export const config: Config = { ...baseConfig }
config.application = {
applicationName: 'Cemetery Management System',
backgroundURL: '/images/cemetery-background.jpg',
logoURL: '/images/cemetery-logo.svg'
}
config.aliases.lot = 'Burial Site'
config.aliases.lots = 'Burial Sites'
config.aliases.map = 'Cemetery'
config.aliases.maps = 'Cemeteries'
config.aliases.occupancy = 'Contract'
config.aliases.occupancies = 'Contracts'
config.aliases.occupant = 'Customer'
config.aliases.occupants = 'Customers'
config.aliases.workOrderOpenDate = 'Order Date'
config.aliases.workOrderCloseDate = 'Completion Date'
config.settings.lotOccupancy.occupancyEndDateIsRequired = false
export default config

View File

@ -21,15 +21,6 @@ export declare const configDefaultValues: {
'users.canLogin': string[];
'users.canUpdate': string[];
'users.isAdmin': string[];
'aliases.lot': string;
'aliases.lots': string;
'aliases.map': string;
'aliases.maps': string;
'aliases.occupancy': string;
'aliases.occupancies': string;
'aliases.occupancyStartDate': string;
'aliases.occupant': string;
'aliases.occupants': string;
'aliases.externalReceiptNumber': string;
'aliases.workOrderOpenDate': string;
'aliases.workOrderCloseDate': string;

View File

@ -1,7 +1,7 @@
import { hoursToMillis } from '@cityssm/to-millis';
export const configDefaultValues = {
activeDirectory: undefined,
'application.applicationName': 'Lot Occupancy System',
'application.applicationName': 'Sunrise CMS',
'application.backgroundURL': '/images/cemetery-background.jpg',
'application.logoURL': '/images/cemetery-logo.png',
'application.httpPort': 7000,
@ -12,26 +12,17 @@ export const configDefaultValues = {
'reverseProxy.disableCompression': false,
'reverseProxy.disableEtag': false,
'reverseProxy.urlPrefix': '',
'session.cookieName': 'lot-occupancy-system-user-sid',
'session.secret': 'cityssm/lot-occupancy-system',
'session.cookieName': 'sunrise-user-sid',
'session.secret': 'cityssm/sunrise',
'session.maxAgeMillis': hoursToMillis(1),
'session.doKeepAlive': false,
'users.testing': [],
'users.canLogin': ['administrator'],
'users.canUpdate': [],
'users.isAdmin': ['administrator'],
'aliases.lot': 'Lot',
'aliases.lots': 'Lots',
'aliases.map': 'Map',
'aliases.maps': 'Maps',
'aliases.occupancy': 'Occupancy',
'aliases.occupancies': 'Occupancies',
'aliases.occupancyStartDate': 'Start Date',
'aliases.occupant': 'Occupant',
'aliases.occupants': 'Occupants',
'aliases.externalReceiptNumber': 'External Receipt Number',
'aliases.workOrderOpenDate': 'Open Date',
'aliases.workOrderCloseDate': 'Close Date',
'aliases.workOrderOpenDate': 'Order Date',
'aliases.workOrderCloseDate': 'Completion Date',
'settings.map.mapCityDefault': '',
'settings.map.mapProvinceDefault': '',
'settings.lot.lotNamePattern': undefined,

View File

@ -10,7 +10,7 @@ import type {
export const configDefaultValues = {
activeDirectory: undefined as unknown as ConfigActiveDirectory,
'application.applicationName': 'Lot Occupancy System',
'application.applicationName': 'Sunrise CMS',
'application.backgroundURL': '/images/cemetery-background.jpg',
'application.logoURL': '/images/cemetery-logo.png',
'application.httpPort': 7000,
@ -24,8 +24,8 @@ export const configDefaultValues = {
'reverseProxy.disableEtag': false,
'reverseProxy.urlPrefix': '',
'session.cookieName': 'lot-occupancy-system-user-sid',
'session.secret': 'cityssm/lot-occupancy-system',
'session.cookieName': 'sunrise-user-sid',
'session.secret': 'cityssm/sunrise',
'session.maxAgeMillis': hoursToMillis(1),
'session.doKeepAlive': false,
@ -34,19 +34,9 @@ export const configDefaultValues = {
'users.canUpdate': [] as string[],
'users.isAdmin': ['administrator'],
'aliases.lot': 'Lot',
'aliases.lots': 'Lots',
'aliases.map': 'Map',
'aliases.maps': 'Maps',
'aliases.occupancy': 'Occupancy',
'aliases.occupancies': 'Occupancies',
'aliases.occupancyStartDate': 'Start Date',
'aliases.occupant': 'Occupant',
'aliases.occupants': 'Occupants',
'aliases.externalReceiptNumber': 'External Receipt Number',
'aliases.workOrderOpenDate': 'Open Date',
'aliases.workOrderCloseDate': 'Close Date',
'aliases.workOrderOpenDate': 'Order Date',
'aliases.workOrderCloseDate': 'Completion Date',
'settings.map.mapCityDefault': '',
'settings.map.mapProvinceDefault': '',

View File

@ -1,4 +1,4 @@
import { config as cemeteryConfig } from './config.cemetery.ssm.js';
import { config as cemeteryConfig } from './config.baseSsm.js';
export const config = { ...cemeteryConfig };
config.application.useTestDatabases = true;
config.session.doKeepAlive = true;

View File

@ -1,6 +1,6 @@
import type { Config } from '../types/configTypes.js'
import { config as cemeteryConfig } from './config.cemetery.ssm.js'
import { config as cemeteryConfig } from './config.baseSsm.js'
export const config: Config = { ...cemeteryConfig }

View File

@ -1,5 +0,0 @@
export declare const useTestDatabases: boolean;
export declare const lotOccupancyDBLive = "data/lotOccupancy.db";
export declare const lotOccupancyDBTesting = "data/lotOccupancy-testing.db";
export declare const lotOccupancyDB: string;
export declare const backupFolder = "data/backups";

View File

@ -1,15 +0,0 @@
import Debug from 'debug';
import { getConfigProperty } from '../helpers/functions.config.js';
const debug = Debug('lot-occupancy-system:databasePaths');
// Determine if test databases should be used
export const useTestDatabases = getConfigProperty('application.useTestDatabases') ||
process.env.TEST_DATABASES === 'true';
if (useTestDatabases) {
debug('Using "-testing" databases.');
}
export const lotOccupancyDBLive = 'data/lotOccupancy.db';
export const lotOccupancyDBTesting = 'data/lotOccupancy-testing.db';
export const lotOccupancyDB = useTestDatabases
? lotOccupancyDBTesting
: lotOccupancyDBLive;
export const backupFolder = 'data/backups';

View File

@ -1,24 +0,0 @@
import Debug from 'debug'
import { getConfigProperty } from '../helpers/functions.config.js'
const debug = Debug('lot-occupancy-system:databasePaths')
// Determine if test databases should be used
export const useTestDatabases =
getConfigProperty('application.useTestDatabases') ||
process.env.TEST_DATABASES === 'true'
if (useTestDatabases) {
debug('Using "-testing" databases.')
}
export const lotOccupancyDBLive = 'data/lotOccupancy.db'
export const lotOccupancyDBTesting = 'data/lotOccupancy-testing.db'
export const lotOccupancyDB = useTestDatabases
? lotOccupancyDBTesting
: lotOccupancyDBLive
export const backupFolder = 'data/backups'

View File

@ -0,0 +1,5 @@
export interface AddBurialSiteCommentForm {
burialSiteId: string;
comment: string;
}
export default function addBurialSiteComment(commentForm: AddBurialSiteCommentForm, user: User): Promise<number>;

View File

@ -1,16 +1,16 @@
import { dateToInteger, dateToTimeInteger } from '@cityssm/utils-datetime';
import { acquireConnection } from './pool.js';
export default async function addLotComment(lotCommentForm, user) {
export default async function addBurialSiteComment(commentForm, user) {
const database = await acquireConnection();
const rightNow = new Date();
const result = database
.prepare(`insert into LotComments (
lotId,
lotCommentDate, lotCommentTime, lotComment,
.prepare(`insert into BurialSiteComments (
burialSiteId,
commentDate, commentTime, comment,
recordCreate_userName, recordCreate_timeMillis,
recordUpdate_userName, recordUpdate_timeMillis)
values (?, ?, ?, ?, ?, ?, ?, ?)`)
.run(lotCommentForm.lotId, dateToInteger(rightNow), dateToTimeInteger(rightNow), lotCommentForm.lotComment, user.userName, rightNow.getTime(), user.userName, rightNow.getTime());
.run(commentForm.burialSiteId, dateToInteger(rightNow), dateToTimeInteger(rightNow), commentForm.comment, user.userName, rightNow.getTime(), user.userName, rightNow.getTime());
database.release();
return result.lastInsertRowid;
}

View File

@ -2,13 +2,13 @@ import { dateToInteger, dateToTimeInteger } from '@cityssm/utils-datetime'
import { acquireConnection } from './pool.js'
export interface AddLotCommentForm {
lotId: string
lotComment: string
export interface AddBurialSiteCommentForm {
burialSiteId: string
comment: string
}
export default async function addLotComment(
lotCommentForm: AddLotCommentForm,
export default async function addBurialSiteComment(
commentForm: AddBurialSiteCommentForm,
user: User
): Promise<number> {
const database = await acquireConnection()
@ -17,18 +17,18 @@ export default async function addLotComment(
const result = database
.prepare(
`insert into LotComments (
lotId,
lotCommentDate, lotCommentTime, lotComment,
`insert into BurialSiteComments (
burialSiteId,
commentDate, commentTime, comment,
recordCreate_userName, recordCreate_timeMillis,
recordUpdate_userName, recordUpdate_timeMillis)
values (?, ?, ?, ?, ?, ?, ?, ?)`
)
.run(
lotCommentForm.lotId,
commentForm.burialSiteId,
dateToInteger(rightNow),
dateToTimeInteger(rightNow),
lotCommentForm.lotComment,
commentForm.comment,
user.userName,
rightNow.getTime(),
user.userName,

View File

@ -0,0 +1,8 @@
import { type DateString, type TimeString } from '@cityssm/utils-datetime';
export interface AddBurialSiteContractCommentForm {
burialSiteContractId: string | number;
commentDateString?: DateString;
commentTimeString?: TimeString;
comment: string;
}
export default function addLotOccupancyComment(commentForm: AddBurialSiteContractCommentForm, user: User): Promise<number>;

View File

@ -0,0 +1,27 @@
import { dateStringToInteger, dateToInteger, dateToTimeInteger, timeStringToInteger } from '@cityssm/utils-datetime';
import { acquireConnection } from './pool.js';
export default async function addLotOccupancyComment(commentForm, user) {
const rightNow = new Date();
let commentDate = 0;
let commentTime = 0;
if (commentForm.commentDateString === undefined) {
commentDate = dateToInteger(rightNow);
commentTime = dateToTimeInteger(rightNow);
}
else {
commentDate = dateStringToInteger(commentForm.commentDateString);
commentTime = timeStringToInteger(commentForm.commentTimeString);
}
const database = await acquireConnection();
const result = database
.prepare(`insert into BurialSiteContactComments (
burialSiteContractId,
commentDate, commentTime,
comment,
recordCreate_userName, recordCreate_timeMillis,
recordUpdate_userName, recordUpdate_timeMillis)
values (?, ?, ?, ?, ?, ?, ?, ?)`)
.run(commentForm.burialSiteContractId, commentDate, commentTime ?? 0, commentForm.comment, user.userName, rightNow.getTime(), user.userName, rightNow.getTime());
database.release();
return result.lastInsertRowid;
}

View File

@ -0,0 +1,66 @@
import {
type DateString,
type TimeString,
dateStringToInteger,
dateToInteger,
dateToTimeInteger,
timeStringToInteger
} from '@cityssm/utils-datetime'
import { acquireConnection } from './pool.js'
export interface AddBurialSiteContractCommentForm {
burialSiteContractId: string | number
commentDateString?: DateString
commentTimeString?: TimeString
comment: string
}
export default async function addLotOccupancyComment(
commentForm: AddBurialSiteContractCommentForm,
user: User
): Promise<number> {
const rightNow = new Date()
let commentDate = 0
let commentTime: number | undefined = 0
if (commentForm.commentDateString === undefined) {
commentDate = dateToInteger(rightNow)
commentTime = dateToTimeInteger(rightNow)
} else {
commentDate = dateStringToInteger(
commentForm.commentDateString as DateString
)
commentTime = timeStringToInteger(
commentForm.commentTimeString as TimeString
)
}
const database = await acquireConnection()
const result = database
.prepare(
`insert into BurialSiteContactComments (
burialSiteContractId,
commentDate, commentTime,
comment,
recordCreate_userName, recordCreate_timeMillis,
recordUpdate_userName, recordUpdate_timeMillis)
values (?, ?, ?, ?, ?, ?, ?, ?)`
)
.run(
commentForm.burialSiteContractId,
commentDate,
commentTime ?? 0,
commentForm.comment,
user.userName,
rightNow.getTime(),
user.userName,
rightNow.getTime()
)
database.release()
return result.lastInsertRowid as number
}

View File

@ -0,0 +1,12 @@
export interface AddBurialSiteTypeFieldForm {
burialSiteTypeId: string | number;
burialSiteTypeField: string;
fieldType?: string;
fieldValues?: string;
isRequired?: string;
pattern?: string;
minimumLength?: string | number;
maximumLength?: string | number;
orderNumber?: number;
}
export default function addBurialSiteTypeField(addForm: AddBurialSiteTypeFieldForm, user: User): Promise<number>;

View File

@ -0,0 +1,20 @@
import { clearCacheByTableName } from '../helpers/functions.cache.js';
import { acquireConnection } from './pool.js';
export default async function addBurialSiteTypeField(addForm, user) {
const database = await acquireConnection();
const rightNowMillis = Date.now();
const result = database
.prepare(`insert into BurialSiteTypeFields (
burialSiteTypeId, burialSiteTypeField,
fieldType, fieldValues,
isRequired, pattern,
minimumLength, maximumLength,
orderNumber,
recordCreate_userName, recordCreate_timeMillis,
recordUpdate_userName, recordUpdate_timeMillis)
values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`)
.run(addForm.burialSiteTypeId, addForm.burialSiteTypeField, addForm.fieldType ?? 'text', addForm.fieldValues ?? '', addForm.isRequired === '' ? 0 : 1, addForm.pattern ?? '', addForm.minimumLength ?? 0, addForm.maximumLength ?? 100, addForm.orderNumber ?? -1, user.userName, rightNowMillis, user.userName, rightNowMillis);
database.release();
clearCacheByTableName('BurialSiteTypeFields');
return result.lastInsertRowid;
}

View File

@ -2,11 +2,11 @@ import { clearCacheByTableName } from '../helpers/functions.cache.js'
import { acquireConnection } from './pool.js'
export interface AddLotTypeFieldForm {
lotTypeId: string | number
lotTypeField: string
export interface AddBurialSiteTypeFieldForm {
burialSiteTypeId: string | number
burialSiteTypeField: string
fieldType?: string
lotTypeFieldValues?: string
fieldValues?: string
isRequired?: string
pattern?: string
minimumLength?: string | number
@ -14,8 +14,8 @@ export interface AddLotTypeFieldForm {
orderNumber?: number
}
export default async function addLotTypeField(
lotTypeFieldForm: AddLotTypeFieldForm,
export default async function addBurialSiteTypeField(
addForm: AddBurialSiteTypeFieldForm,
user: User
): Promise<number> {
const database = await acquireConnection()
@ -24,8 +24,9 @@ export default async function addLotTypeField(
const result = database
.prepare(
`insert into LotTypeFields (
lotTypeId, lotTypeField, fieldType, lotTypeFieldValues,
`insert into BurialSiteTypeFields (
burialSiteTypeId, burialSiteTypeField,
fieldType, fieldValues,
isRequired, pattern,
minimumLength, maximumLength,
orderNumber,
@ -34,15 +35,15 @@ export default async function addLotTypeField(
values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
)
.run(
lotTypeFieldForm.lotTypeId,
lotTypeFieldForm.lotTypeField,
lotTypeFieldForm.fieldType ?? 'text',
lotTypeFieldForm.lotTypeFieldValues ?? '',
lotTypeFieldForm.isRequired === '' ? 0 : 1,
lotTypeFieldForm.pattern ?? '',
lotTypeFieldForm.minimumLength ?? 0,
lotTypeFieldForm.maximumLength ?? 100,
lotTypeFieldForm.orderNumber ?? -1,
addForm.burialSiteTypeId,
addForm.burialSiteTypeField,
addForm.fieldType ?? 'text',
addForm.fieldValues ?? '',
addForm.isRequired === '' ? 0 : 1,
addForm.pattern ?? '',
addForm.minimumLength ?? 0,
addForm.maximumLength ?? 100,
addForm.orderNumber ?? -1,
user.userName,
rightNowMillis,
user.userName,
@ -51,7 +52,7 @@ export default async function addLotTypeField(
database.release()
clearCacheByTableName('LotTypeFields')
clearCacheByTableName('BurialSiteTypeFields')
return result.lastInsertRowid as number
}

14
database/addCemetery.d.ts vendored 100644
View File

@ -0,0 +1,14 @@
export interface AddCemeteryForm {
cemeteryName: string;
cemeteryDescription: string;
cemeterySvg: string;
cemeteryLatitude: string;
cemeteryLongitude: string;
cemeteryAddress1: string;
cemeteryAddress2: string;
cemeteryCity: string;
cemeteryProvince: string;
cemeteryPostalCode: string;
cemeteryPhoneNumber: string;
}
export default function addCemetery(addForm: AddCemeteryForm, user: User): Promise<number>;

View File

@ -0,0 +1,18 @@
import { acquireConnection } from './pool.js';
export default async function addCemetery(addForm, user) {
const database = await acquireConnection();
const rightNowMillis = Date.now();
const result = database
.prepare(`insert into Cemeteries (
cemeteryName, cemeteryDescription,
cemeterySvg, cemeteryLatitude, cemeteryLongitude,
cemeteryAddress1, cemeteryAddress2,
cemeteryCity, cemeteryProvince, cemeteryPostalCode,
cemeteryPhoneNumber,
recordCreate_userName, recordCreate_timeMillis,
recordUpdate_userName, recordUpdate_timeMillis)
values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`)
.run(addForm.cemeteryName, addForm.cemeteryDescription, addForm.cemeterySvg, addForm.cemeteryLatitude === '' ? undefined : addForm.cemeteryLatitude, addForm.cemeteryLongitude === '' ? undefined : addForm.cemeteryLongitude, addForm.cemeteryAddress1, addForm.cemeteryAddress2, addForm.cemeteryCity, addForm.cemeteryProvince, addForm.cemeteryPostalCode, addForm.cemeteryPhoneNumber, user.userName, rightNowMillis, user.userName, rightNowMillis);
database.release();
return result.lastInsertRowid;
}

View File

@ -0,0 +1,60 @@
import { acquireConnection } from './pool.js'
export interface AddCemeteryForm {
cemeteryName: string
cemeteryDescription: string
cemeterySvg: string
cemeteryLatitude: string
cemeteryLongitude: string
cemeteryAddress1: string
cemeteryAddress2: string
cemeteryCity: string
cemeteryProvince: string
cemeteryPostalCode: string
cemeteryPhoneNumber: string
}
export default async function addCemetery(
addForm: AddCemeteryForm,
user: User
): Promise<number> {
const database = await acquireConnection()
const rightNowMillis = Date.now()
const result = database
.prepare(
`insert into Cemeteries (
cemeteryName, cemeteryDescription,
cemeterySvg, cemeteryLatitude, cemeteryLongitude,
cemeteryAddress1, cemeteryAddress2,
cemeteryCity, cemeteryProvince, cemeteryPostalCode,
cemeteryPhoneNumber,
recordCreate_userName, recordCreate_timeMillis,
recordUpdate_userName, recordUpdate_timeMillis)
values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
)
.run(
addForm.cemeteryName,
addForm.cemeteryDescription,
addForm.cemeterySvg,
addForm.cemeteryLatitude === '' ? undefined : addForm.cemeteryLatitude,
addForm.cemeteryLongitude === '' ? undefined : addForm.cemeteryLongitude,
addForm.cemeteryAddress1,
addForm.cemeteryAddress2,
addForm.cemeteryCity,
addForm.cemeteryProvince,
addForm.cemeteryPostalCode,
addForm.cemeteryPhoneNumber,
user.userName,
rightNowMillis,
user.userName,
rightNowMillis
)
database.release()
return result.lastInsertRowid as number
}

View File

@ -0,0 +1,12 @@
export interface AddContractTypeFieldForm {
contractTypeId?: string | number;
contractTypeField: string;
fieldValues?: string;
fieldType?: string;
isRequired?: string;
pattern?: string;
minimumLength?: string | number;
maximumLength?: string | number;
orderNumber?: number;
}
export default function addContractTypeField(addForm: AddContractTypeFieldForm, user: User): Promise<number>;

View File

@ -0,0 +1,19 @@
import { clearCacheByTableName } from '../helpers/functions.cache.js';
import { acquireConnection } from './pool.js';
export default async function addContractTypeField(addForm, user) {
const database = await acquireConnection();
const rightNowMillis = Date.now();
const result = database
.prepare(`insert into ContractTypeFields (
contractTypeId, contractTypeField, fieldType,
fieldValues, isRequired, pattern,
minimumLength, maximumLength,
orderNumber,
recordCreate_userName, recordCreate_timeMillis,
recordUpdate_userName, recordUpdate_timeMillis)
values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`)
.run(addForm.contractTypeId ?? undefined, addForm.contractTypeField, addForm.fieldType ?? 'text', addForm.fieldValues ?? '', addForm.isRequired === '' ? 0 : 1, addForm.pattern ?? '', addForm.minimumLength ?? 0, addForm.maximumLength ?? 100, addForm.orderNumber ?? -1, user.userName, rightNowMillis, user.userName, rightNowMillis);
database.release();
clearCacheByTableName('OccupancyTypeFields');
return result.lastInsertRowid;
}

View File

@ -2,10 +2,10 @@ import { clearCacheByTableName } from '../helpers/functions.cache.js'
import { acquireConnection } from './pool.js'
export interface AddOccupancyTypeFieldForm {
occupancyTypeId?: string | number
occupancyTypeField: string
occupancyTypeFieldValues?: string
export interface AddContractTypeFieldForm {
contractTypeId?: string | number
contractTypeField: string
fieldValues?: string
fieldType?: string
isRequired?: string
pattern?: string
@ -14,8 +14,8 @@ export interface AddOccupancyTypeFieldForm {
orderNumber?: number
}
export default async function addOccupancyTypeField(
occupancyTypeFieldForm: AddOccupancyTypeFieldForm,
export default async function addContractTypeField(
addForm: AddContractTypeFieldForm,
user: User
): Promise<number> {
const database = await acquireConnection()
@ -24,9 +24,9 @@ export default async function addOccupancyTypeField(
const result = database
.prepare(
`insert into OccupancyTypeFields (
occupancyTypeId, occupancyTypeField, fieldType,
occupancyTypeFieldValues, isRequired, pattern,
`insert into ContractTypeFields (
contractTypeId, contractTypeField, fieldType,
fieldValues, isRequired, pattern,
minimumLength, maximumLength,
orderNumber,
recordCreate_userName, recordCreate_timeMillis,
@ -34,15 +34,15 @@ export default async function addOccupancyTypeField(
values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
)
.run(
occupancyTypeFieldForm.occupancyTypeId ?? undefined,
occupancyTypeFieldForm.occupancyTypeField,
occupancyTypeFieldForm.fieldType ?? 'text',
occupancyTypeFieldForm.occupancyTypeFieldValues ?? '',
occupancyTypeFieldForm.isRequired === '' ? 0 : 1,
occupancyTypeFieldForm.pattern ?? '',
occupancyTypeFieldForm.minimumLength ?? 0,
occupancyTypeFieldForm.maximumLength ?? 100,
occupancyTypeFieldForm.orderNumber ?? -1,
addForm.contractTypeId ?? undefined,
addForm.contractTypeField,
addForm.fieldType ?? 'text',
addForm.fieldValues ?? '',
addForm.isRequired === '' ? 0 : 1,
addForm.pattern ?? '',
addForm.minimumLength ?? 0,
addForm.maximumLength ?? 100,
addForm.orderNumber ?? -1,
user.userName,
rightNowMillis,
user.userName,

View File

@ -0,0 +1,6 @@
export interface AddContractTypePrintForm {
contractTypeId: string | number;
printEJS: string;
orderNumber?: number;
}
export default function addContractTypePrint(addForm: AddContractTypePrintForm, user: User): Promise<boolean>;

View File

@ -1,27 +1,27 @@
import { clearCacheByTableName } from '../helpers/functions.cache.js';
import { acquireConnection } from './pool.js';
export default async function addOccupancyTypePrint(occupancyTypePrintForm, user) {
export default async function addContractTypePrint(addForm, user) {
const database = await acquireConnection();
const rightNowMillis = Date.now();
let result = database
.prepare(`update OccupancyTypePrints
.prepare(`update ContractTypePrints
set recordUpdate_userName = ?,
recordUpdate_timeMillis = ?,
recordDelete_userName = null,
recordDelete_timeMillis = null
where occupancyTypeId = ?
where contractTypeId = ?
and printEJS = ?`)
.run(user.userName, rightNowMillis, occupancyTypePrintForm.occupancyTypeId, occupancyTypePrintForm.printEJS);
.run(user.userName, rightNowMillis, addForm.contractTypeId, addForm.printEJS);
if (result.changes === 0) {
result = database
.prepare(`insert into OccupancyTypePrints (
occupancyTypeId, printEJS, orderNumber,
.prepare(`insert into ContractTypePrints (
contractTypeId, printEJS, orderNumber,
recordCreate_userName, recordCreate_timeMillis,
recordUpdate_userName, recordUpdate_timeMillis)
values (?, ?, ?, ?, ?, ?, ?)`)
.run(occupancyTypePrintForm.occupancyTypeId, occupancyTypePrintForm.printEJS, occupancyTypePrintForm.orderNumber ?? -1, user.userName, rightNowMillis, user.userName, rightNowMillis);
.run(addForm.contractTypeId, addForm.printEJS, addForm.orderNumber ?? -1, user.userName, rightNowMillis, user.userName, rightNowMillis);
}
database.release();
clearCacheByTableName('OccupancyTypePrints');
clearCacheByTableName('ContractTypePrints');
return result.changes > 0;
}

View File

@ -2,14 +2,14 @@ import { clearCacheByTableName } from '../helpers/functions.cache.js'
import { acquireConnection } from './pool.js'
export interface AddOccupancyTypePrintForm {
occupancyTypeId: string | number
export interface AddContractTypePrintForm {
contractTypeId: string | number
printEJS: string
orderNumber?: number
}
export default async function addOccupancyTypePrint(
occupancyTypePrintForm: AddOccupancyTypePrintForm,
export default async function addContractTypePrint(
addForm: AddContractTypePrintForm,
user: User
): Promise<boolean> {
const database = await acquireConnection()
@ -18,34 +18,34 @@ export default async function addOccupancyTypePrint(
let result = database
.prepare(
`update OccupancyTypePrints
`update ContractTypePrints
set recordUpdate_userName = ?,
recordUpdate_timeMillis = ?,
recordDelete_userName = null,
recordDelete_timeMillis = null
where occupancyTypeId = ?
where contractTypeId = ?
and printEJS = ?`
)
.run(
user.userName,
rightNowMillis,
occupancyTypePrintForm.occupancyTypeId,
occupancyTypePrintForm.printEJS
addForm.contractTypeId,
addForm.printEJS
)
if (result.changes === 0) {
result = database
.prepare(
`insert into OccupancyTypePrints (
occupancyTypeId, printEJS, orderNumber,
`insert into ContractTypePrints (
contractTypeId, printEJS, orderNumber,
recordCreate_userName, recordCreate_timeMillis,
recordUpdate_userName, recordUpdate_timeMillis)
values (?, ?, ?, ?, ?, ?, ?)`
)
.run(
occupancyTypePrintForm.occupancyTypeId,
occupancyTypePrintForm.printEJS,
occupancyTypePrintForm.orderNumber ?? -1,
addForm.contractTypeId,
addForm.printEJS,
addForm.orderNumber ?? -1,
user.userName,
rightNowMillis,
user.userName,
@ -55,7 +55,7 @@ export default async function addOccupancyTypePrint(
database.release()
clearCacheByTableName('OccupancyTypePrints')
clearCacheByTableName('ContractTypePrints')
return result.changes > 0
}

10
database/addFee.d.ts vendored
View File

@ -3,15 +3,15 @@ export interface AddFeeForm {
feeName: string;
feeDescription: string;
feeAccount: string;
occupancyTypeId: string;
lotTypeId: string;
contractTypeId: string;
burialSiteTypeId: string;
feeAmount?: string;
feeFunction: string;
feeFunction?: string;
taxAmount?: string;
taxPercentage?: string;
includeQuantity: '' | '1';
includeQuantity?: '' | '1';
quantityUnit?: string;
isRequired: '' | '1';
isRequired?: '' | '1';
orderNumber?: number;
}
export default function addFee(feeForm: AddFeeForm, user: User): Promise<number>;

View File

@ -6,7 +6,7 @@ export default async function addFee(feeForm, user) {
.prepare(`insert into Fees (
feeCategoryId,
feeName, feeDescription, feeAccount,
occupancyTypeId, lotTypeId,
contractTypeId, burialSiteTypeId,
feeAmount, feeFunction,
taxAmount, taxPercentage,
includeQuantity, quantityUnit,
@ -14,7 +14,7 @@ export default async function addFee(feeForm, user) {
recordCreate_userName, recordCreate_timeMillis,
recordUpdate_userName, recordUpdate_timeMillis)
values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`)
.run(feeForm.feeCategoryId, feeForm.feeName, feeForm.feeDescription, feeForm.feeAccount, feeForm.occupancyTypeId === '' ? undefined : feeForm.occupancyTypeId, feeForm.lotTypeId === '' ? undefined : feeForm.lotTypeId, 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, user.userName, rightNowMillis, user.userName, rightNowMillis);
.run(feeForm.feeCategoryId, feeForm.feeName, feeForm.feeDescription, feeForm.feeAccount, feeForm.contractTypeId === '' ? undefined : feeForm.contractTypeId, feeForm.burialSiteTypeId === '' ? undefined : feeForm.burialSiteTypeId, 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, user.userName, rightNowMillis, user.userName, rightNowMillis);
database.release();
return result.lastInsertRowid;
}

View File

@ -5,15 +5,15 @@ export interface AddFeeForm {
feeName: string
feeDescription: string
feeAccount: string
occupancyTypeId: string
lotTypeId: string
contractTypeId: string
burialSiteTypeId: string
feeAmount?: string
feeFunction: string
feeFunction?: string
taxAmount?: string
taxPercentage?: string
includeQuantity: '' | '1'
includeQuantity?: '' | '1'
quantityUnit?: string
isRequired: '' | '1'
isRequired?: '' | '1'
orderNumber?: number
}
@ -30,7 +30,7 @@ export default async function addFee(
`insert into Fees (
feeCategoryId,
feeName, feeDescription, feeAccount,
occupancyTypeId, lotTypeId,
contractTypeId, burialSiteTypeId,
feeAmount, feeFunction,
taxAmount, taxPercentage,
includeQuantity, quantityUnit,
@ -44,8 +44,8 @@ export default async function addFee(
feeForm.feeName,
feeForm.feeDescription,
feeForm.feeAccount,
feeForm.occupancyTypeId === '' ? undefined : feeForm.occupancyTypeId,
feeForm.lotTypeId === '' ? undefined : feeForm.lotTypeId,
feeForm.contractTypeId === '' ? undefined : feeForm.contractTypeId,
feeForm.burialSiteTypeId === '' ? undefined : feeForm.burialSiteTypeId,
feeForm.feeAmount ?? undefined,
feeForm.feeFunction ?? undefined,
feeForm.taxAmount ?? undefined,

View File

@ -1,5 +0,0 @@
export interface AddLotCommentForm {
lotId: string;
lotComment: string;
}
export default function addLotComment(lotCommentForm: AddLotCommentForm, user: User): Promise<number>;

View File

@ -1,7 +0,0 @@
export interface AddLotOccupancyCommentForm {
lotOccupancyId: string | number;
lotOccupancyCommentDateString?: string;
lotOccupancyCommentTimeString?: string;
lotOccupancyComment: string;
}
export default function addLotOccupancyComment(commentForm: AddLotOccupancyCommentForm, user: User): Promise<number>;

View File

@ -1,27 +0,0 @@
import { dateStringToInteger, dateToInteger, dateToTimeInteger, timeStringToInteger } from '@cityssm/utils-datetime';
import { acquireConnection } from './pool.js';
export default async function addLotOccupancyComment(commentForm, user) {
const rightNow = new Date();
let lotOccupancyCommentDate;
let lotOccupancyCommentTime;
if (commentForm.lotOccupancyCommentDateString) {
lotOccupancyCommentDate = dateStringToInteger(commentForm.lotOccupancyCommentDateString);
lotOccupancyCommentTime = timeStringToInteger(commentForm.lotOccupancyCommentTimeString ?? '');
}
else {
lotOccupancyCommentDate = dateToInteger(rightNow);
lotOccupancyCommentTime = dateToTimeInteger(rightNow);
}
const database = await acquireConnection();
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 ?? 0, commentForm.lotOccupancyComment, user.userName, rightNow.getTime(), user.userName, rightNow.getTime());
database.release();
return result.lastInsertRowid;
}

View File

@ -1,66 +0,0 @@
import {
type DateString,
type TimeString,
dateStringToInteger,
dateToInteger,
dateToTimeInteger,
timeStringToInteger
} from '@cityssm/utils-datetime'
import { acquireConnection } from './pool.js'
export interface AddLotOccupancyCommentForm {
lotOccupancyId: string | number
lotOccupancyCommentDateString?: string
lotOccupancyCommentTimeString?: string
lotOccupancyComment: string
}
export default async function addLotOccupancyComment(
commentForm: AddLotOccupancyCommentForm,
user: User
): Promise<number> {
const rightNow = new Date()
let lotOccupancyCommentDate: number
let lotOccupancyCommentTime: number | undefined
if (commentForm.lotOccupancyCommentDateString) {
lotOccupancyCommentDate = dateStringToInteger(
commentForm.lotOccupancyCommentDateString as DateString
)
lotOccupancyCommentTime = timeStringToInteger(
(commentForm.lotOccupancyCommentTimeString as TimeString) ?? ''
)
} else {
lotOccupancyCommentDate = dateToInteger(rightNow)
lotOccupancyCommentTime = dateToTimeInteger(rightNow)
}
const database = await acquireConnection()
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 ?? 0,
commentForm.lotOccupancyComment,
user.userName,
rightNow.getTime(),
user.userName,
rightNow.getTime()
)
database.release()
return result.lastInsertRowid as number
}

View File

@ -1,16 +0,0 @@
import type { PoolConnection } from 'better-sqlite-pool';
export interface AddLotOccupancyOccupantForm {
lotOccupancyId: string | number;
lotOccupantTypeId: string | number;
occupantName: string;
occupantFamilyName: string;
occupantAddress1: string;
occupantAddress2: string;
occupantCity: string;
occupantProvince: string;
occupantPostalCode: string;
occupantPhoneNumber: string;
occupantEmailAddress: string;
occupantComment?: string;
}
export default function addLotOccupancyOccupant(lotOccupancyOccupantForm: AddLotOccupancyOccupantForm, user: User, connectedDatabase?: PoolConnection): Promise<number>;

View File

@ -1,33 +0,0 @@
import { acquireConnection } from './pool.js';
export default async function addLotOccupancyOccupant(lotOccupancyOccupantForm, user, connectedDatabase) {
const database = connectedDatabase ?? (await acquireConnection());
let lotOccupantIndex = 0;
const maxIndexResult = database
.prepare(`select lotOccupantIndex
from LotOccupancyOccupants
where lotOccupancyId = ?
order by lotOccupantIndex desc
limit 1`)
.get(lotOccupancyOccupantForm.lotOccupancyId);
if (maxIndexResult !== undefined) {
lotOccupantIndex = maxIndexResult.lotOccupantIndex + 1;
}
const rightNowMillis = Date.now();
database
.prepare(`insert into LotOccupancyOccupants (
lotOccupancyId, lotOccupantIndex,
occupantName, occupantFamilyName,
occupantAddress1, occupantAddress2,
occupantCity, occupantProvince, occupantPostalCode,
occupantPhoneNumber, occupantEmailAddress,
occupantComment,
lotOccupantTypeId,
recordCreate_userName, recordCreate_timeMillis,
recordUpdate_userName, recordUpdate_timeMillis)
values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`)
.run(lotOccupancyOccupantForm.lotOccupancyId, lotOccupantIndex, lotOccupancyOccupantForm.occupantName, lotOccupancyOccupantForm.occupantFamilyName, lotOccupancyOccupantForm.occupantAddress1, lotOccupancyOccupantForm.occupantAddress2, lotOccupancyOccupantForm.occupantCity, lotOccupancyOccupantForm.occupantProvince, lotOccupancyOccupantForm.occupantPostalCode, lotOccupancyOccupantForm.occupantPhoneNumber, lotOccupancyOccupantForm.occupantEmailAddress, lotOccupancyOccupantForm.occupantComment ?? '', lotOccupancyOccupantForm.lotOccupantTypeId, user.userName, rightNowMillis, user.userName, rightNowMillis);
if (connectedDatabase === undefined) {
database.release();
}
return lotOccupantIndex;
}

View File

@ -1,86 +0,0 @@
import type { PoolConnection } from 'better-sqlite-pool'
import { acquireConnection } from './pool.js'
export interface AddLotOccupancyOccupantForm {
lotOccupancyId: string | number
lotOccupantTypeId: string | number
occupantName: string
occupantFamilyName: string
occupantAddress1: string
occupantAddress2: string
occupantCity: string
occupantProvince: string
occupantPostalCode: string
occupantPhoneNumber: string
occupantEmailAddress: string
occupantComment?: string
}
export default async function addLotOccupancyOccupant(
lotOccupancyOccupantForm: AddLotOccupancyOccupantForm,
user: User,
connectedDatabase?: PoolConnection
): Promise<number> {
const database = connectedDatabase ?? (await acquireConnection())
let lotOccupantIndex = 0
const maxIndexResult = database
.prepare(
`select lotOccupantIndex
from LotOccupancyOccupants
where lotOccupancyId = ?
order by lotOccupantIndex desc
limit 1`
)
.get(lotOccupancyOccupantForm.lotOccupancyId) as
| { lotOccupantIndex: number }
| undefined
if (maxIndexResult !== undefined) {
lotOccupantIndex = maxIndexResult.lotOccupantIndex + 1
}
const rightNowMillis = Date.now()
database
.prepare(
`insert into LotOccupancyOccupants (
lotOccupancyId, lotOccupantIndex,
occupantName, occupantFamilyName,
occupantAddress1, occupantAddress2,
occupantCity, occupantProvince, occupantPostalCode,
occupantPhoneNumber, occupantEmailAddress,
occupantComment,
lotOccupantTypeId,
recordCreate_userName, recordCreate_timeMillis,
recordUpdate_userName, recordUpdate_timeMillis)
values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
)
.run(
lotOccupancyOccupantForm.lotOccupancyId,
lotOccupantIndex,
lotOccupancyOccupantForm.occupantName,
lotOccupancyOccupantForm.occupantFamilyName,
lotOccupancyOccupantForm.occupantAddress1,
lotOccupancyOccupantForm.occupantAddress2,
lotOccupancyOccupantForm.occupantCity,
lotOccupancyOccupantForm.occupantProvince,
lotOccupancyOccupantForm.occupantPostalCode,
lotOccupancyOccupantForm.occupantPhoneNumber,
lotOccupancyOccupantForm.occupantEmailAddress,
lotOccupancyOccupantForm.occupantComment ?? '',
lotOccupancyOccupantForm.lotOccupantTypeId,
user.userName,
rightNowMillis,
user.userName,
rightNowMillis
)
if (connectedDatabase === undefined) {
database.release()
}
return lotOccupantIndex
}

View File

@ -1,7 +0,0 @@
export interface AddLotOccupantTypeForm {
lotOccupantType: string;
fontAwesomeIconClass?: string;
occupantCommentTitle?: string;
orderNumber?: number;
}
export default function addLotOccupantType(lotOccupantTypeForm: AddLotOccupantTypeForm, user: User): Promise<number>;

View File

@ -1,16 +0,0 @@
import { clearCacheByTableName } from '../helpers/functions.cache.js';
import { acquireConnection } from './pool.js';
export default async function addLotOccupantType(lotOccupantTypeForm, user) {
const database = await acquireConnection();
const rightNowMillis = Date.now();
const result = database
.prepare(`insert into LotOccupantTypes (
lotOccupantType, fontAwesomeIconClass, occupantCommentTitle, orderNumber,
recordCreate_userName, recordCreate_timeMillis,
recordUpdate_userName, recordUpdate_timeMillis)
values (?, ?, ?, ?, ?, ?, ?, ?)`)
.run(lotOccupantTypeForm.lotOccupantType, lotOccupantTypeForm.fontAwesomeIconClass ?? '', lotOccupantTypeForm.occupantCommentTitle ?? '', lotOccupantTypeForm.orderNumber ?? -1, user.userName, rightNowMillis, user.userName, rightNowMillis);
database.release();
clearCacheByTableName('LotOccupantTypes');
return result.lastInsertRowid;
}

View File

@ -1,44 +0,0 @@
import { clearCacheByTableName } from '../helpers/functions.cache.js'
import { acquireConnection } from './pool.js'
export interface AddLotOccupantTypeForm {
lotOccupantType: string
fontAwesomeIconClass?: string
occupantCommentTitle?: string
orderNumber?: number
}
export default async function addLotOccupantType(
lotOccupantTypeForm: AddLotOccupantTypeForm,
user: User
): Promise<number> {
const database = await acquireConnection()
const rightNowMillis = Date.now()
const result = database
.prepare(
`insert into LotOccupantTypes (
lotOccupantType, fontAwesomeIconClass, occupantCommentTitle, orderNumber,
recordCreate_userName, recordCreate_timeMillis,
recordUpdate_userName, recordUpdate_timeMillis)
values (?, ?, ?, ?, ?, ?, ?, ?)`
)
.run(
lotOccupantTypeForm.lotOccupantType,
lotOccupantTypeForm.fontAwesomeIconClass ?? '',
lotOccupantTypeForm.occupantCommentTitle ?? '',
lotOccupantTypeForm.orderNumber ?? -1,
user.userName,
rightNowMillis,
user.userName,
rightNowMillis
)
database.release()
clearCacheByTableName('LotOccupantTypes')
return result.lastInsertRowid as number
}

View File

@ -1,12 +0,0 @@
export interface AddLotTypeFieldForm {
lotTypeId: string | number;
lotTypeField: string;
fieldType?: string;
lotTypeFieldValues?: string;
isRequired?: string;
pattern?: string;
minimumLength?: string | number;
maximumLength?: string | number;
orderNumber?: number;
}
export default function addLotTypeField(lotTypeFieldForm: AddLotTypeFieldForm, user: User): Promise<number>;

View File

@ -1,19 +0,0 @@
import { clearCacheByTableName } from '../helpers/functions.cache.js';
import { acquireConnection } from './pool.js';
export default async function addLotTypeField(lotTypeFieldForm, user) {
const database = await acquireConnection();
const rightNowMillis = Date.now();
const result = database
.prepare(`insert into LotTypeFields (
lotTypeId, lotTypeField, fieldType, lotTypeFieldValues,
isRequired, pattern,
minimumLength, maximumLength,
orderNumber,
recordCreate_userName, recordCreate_timeMillis,
recordUpdate_userName, recordUpdate_timeMillis)
values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`)
.run(lotTypeFieldForm.lotTypeId, lotTypeFieldForm.lotTypeField, lotTypeFieldForm.fieldType ?? 'text', lotTypeFieldForm.lotTypeFieldValues ?? '', lotTypeFieldForm.isRequired === '' ? 0 : 1, lotTypeFieldForm.pattern ?? '', lotTypeFieldForm.minimumLength ?? 0, lotTypeFieldForm.maximumLength ?? 100, lotTypeFieldForm.orderNumber ?? -1, user.userName, rightNowMillis, user.userName, rightNowMillis);
database.release();
clearCacheByTableName('LotTypeFields');
return result.lastInsertRowid;
}

14
database/addMap.d.ts vendored
View File

@ -1,14 +0,0 @@
export interface AddMapForm {
mapName: string;
mapDescription: string;
mapSVG: string;
mapLatitude: string;
mapLongitude: string;
mapAddress1: string;
mapAddress2: string;
mapCity: string;
mapProvince: string;
mapPostalCode: string;
mapPhoneNumber: string;
}
export default function addMap(mapForm: AddMapForm, user: User): Promise<number>;

View File

@ -1,18 +0,0 @@
import { acquireConnection } from './pool.js';
export default async function addMap(mapForm, user) {
const database = await acquireConnection();
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, user.userName, rightNowMillis, user.userName, rightNowMillis);
database.release();
return result.lastInsertRowid;
}

View File

@ -1,58 +0,0 @@
import { acquireConnection } from './pool.js'
export interface AddMapForm {
mapName: string
mapDescription: string
mapSVG: string
mapLatitude: string
mapLongitude: string
mapAddress1: string
mapAddress2: string
mapCity: string
mapProvince: string
mapPostalCode: string
mapPhoneNumber: string
}
export default async function addMap(
mapForm: AddMapForm,
user: User
): Promise<number> {
const database = await acquireConnection()
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,
user.userName,
rightNowMillis,
user.userName,
rightNowMillis
)
database.release()
return result.lastInsertRowid as number
}

View File

@ -1,12 +0,0 @@
export interface AddOccupancyTypeFieldForm {
occupancyTypeId?: string | number;
occupancyTypeField: string;
occupancyTypeFieldValues?: string;
fieldType?: string;
isRequired?: string;
pattern?: string;
minimumLength?: string | number;
maximumLength?: string | number;
orderNumber?: number;
}
export default function addOccupancyTypeField(occupancyTypeFieldForm: AddOccupancyTypeFieldForm, user: User): Promise<number>;

View File

@ -1,19 +0,0 @@
import { clearCacheByTableName } from '../helpers/functions.cache.js';
import { acquireConnection } from './pool.js';
export default async function addOccupancyTypeField(occupancyTypeFieldForm, user) {
const database = await acquireConnection();
const rightNowMillis = Date.now();
const result = database
.prepare(`insert into OccupancyTypeFields (
occupancyTypeId, occupancyTypeField, fieldType,
occupancyTypeFieldValues, isRequired, pattern,
minimumLength, maximumLength,
orderNumber,
recordCreate_userName, recordCreate_timeMillis,
recordUpdate_userName, recordUpdate_timeMillis)
values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`)
.run(occupancyTypeFieldForm.occupancyTypeId ?? undefined, occupancyTypeFieldForm.occupancyTypeField, occupancyTypeFieldForm.fieldType ?? 'text', occupancyTypeFieldForm.occupancyTypeFieldValues ?? '', occupancyTypeFieldForm.isRequired === '' ? 0 : 1, occupancyTypeFieldForm.pattern ?? '', occupancyTypeFieldForm.minimumLength ?? 0, occupancyTypeFieldForm.maximumLength ?? 100, occupancyTypeFieldForm.orderNumber ?? -1, user.userName, rightNowMillis, user.userName, rightNowMillis);
database.release();
clearCacheByTableName('OccupancyTypeFields');
return result.lastInsertRowid;
}

View File

@ -1,6 +0,0 @@
export interface AddOccupancyTypePrintForm {
occupancyTypeId: string | number;
printEJS: string;
orderNumber?: number;
}
export default function addOccupancyTypePrint(occupancyTypePrintForm: AddOccupancyTypePrintForm, user: User): Promise<boolean>;

View File

@ -0,0 +1,7 @@
import type { PoolConnection } from 'better-sqlite-pool';
export interface BurialSiteContractFieldForm {
burialSiteContractId: string | number;
contractTypeFieldId: string | number;
fieldValue: string;
}
export default function addOrUpdateBurialSiteContractField(fieldForm: BurialSiteContractFieldForm, user: User, connectedDatabase?: PoolConnection): Promise<boolean>;

View File

@ -0,0 +1,28 @@
import { acquireConnection } from './pool.js';
export default async function addOrUpdateBurialSiteContractField(fieldForm, user, connectedDatabase) {
const database = connectedDatabase ?? (await acquireConnection());
const rightNowMillis = Date.now();
let result = database
.prepare(`update BurialSiteContractFields
set fieldValue = ?,
recordUpdate_userName = ?,
recordUpdate_timeMillis = ?,
recordDelete_userName = null,
recordDelete_timeMillis = null
where burialSiteContractId = ?
and contractTypeFieldId = ?`)
.run(fieldForm.fieldValue, user.userName, rightNowMillis, fieldForm.burialSiteContractId, fieldForm.contractTypeFieldId);
if (result.changes === 0) {
result = database
.prepare(`insert into BurialSiteContractFields (
burialSiteContractId, contractTypeFieldId, fieldValue,
recordCreate_userName, recordCreate_timeMillis,
recordUpdate_userName, recordUpdate_timeMillis)
values (?, ?, ?, ?, ?, ?, ?)`)
.run(fieldForm.burialSiteContractId, fieldForm.contractTypeFieldId, fieldForm.fieldValue, user.userName, rightNowMillis, user.userName, rightNowMillis);
}
if (connectedDatabase === undefined) {
database.release();
}
return result.changes > 0;
}

View File

@ -2,14 +2,14 @@ import type { PoolConnection } from 'better-sqlite-pool'
import { acquireConnection } from './pool.js'
export interface LotOccupancyFieldForm {
lotOccupancyId: string | number
occupancyTypeFieldId: string | number
lotOccupancyFieldValue: string
export interface BurialSiteContractFieldForm {
burialSiteContractId: string | number
contractTypeFieldId: string | number
fieldValue: string
}
export default async function addOrUpdateLotOccupancyField(
lotOccupancyFieldForm: LotOccupancyFieldForm,
export default async function addOrUpdateBurialSiteContractField(
fieldForm: BurialSiteContractFieldForm,
user: User,
connectedDatabase?: PoolConnection
): Promise<boolean> {
@ -19,36 +19,36 @@ export default async function addOrUpdateLotOccupancyField(
let result = database
.prepare(
`update LotOccupancyFields
set lotOccupancyFieldValue = ?,
`update BurialSiteContractFields
set fieldValue = ?,
recordUpdate_userName = ?,
recordUpdate_timeMillis = ?,
recordDelete_userName = null,
recordDelete_timeMillis = null
where lotOccupancyId = ?
and occupancyTypeFieldId = ?`
where burialSiteContractId = ?
and contractTypeFieldId = ?`
)
.run(
lotOccupancyFieldForm.lotOccupancyFieldValue,
fieldForm.fieldValue,
user.userName,
rightNowMillis,
lotOccupancyFieldForm.lotOccupancyId,
lotOccupancyFieldForm.occupancyTypeFieldId
fieldForm.burialSiteContractId,
fieldForm.contractTypeFieldId
)
if (result.changes === 0) {
result = database
.prepare(
`insert into LotOccupancyFields (
lotOccupancyId, occupancyTypeFieldId, lotOccupancyFieldValue,
`insert into BurialSiteContractFields (
burialSiteContractId, contractTypeFieldId, fieldValue,
recordCreate_userName, recordCreate_timeMillis,
recordUpdate_userName, recordUpdate_timeMillis)
values (?, ?, ?, ?, ?, ?, ?)`
)
.run(
lotOccupancyFieldForm.lotOccupancyId,
lotOccupancyFieldForm.occupancyTypeFieldId,
lotOccupancyFieldForm.lotOccupancyFieldValue,
fieldForm.burialSiteContractId,
fieldForm.contractTypeFieldId,
fieldForm.fieldValue,
user.userName,
rightNowMillis,
user.userName,

View File

@ -0,0 +1,7 @@
import type { PoolConnection } from 'better-sqlite-pool';
export interface BurialSiteFieldForm {
burialSiteId: string | number;
burialSiteTypeFieldId: string | number;
fieldValue: string;
}
export default function addOrUpdateBurialSiteField(fieldForm: BurialSiteFieldForm, user: User, connectedDatabase?: PoolConnection): Promise<boolean>;

View File

@ -1,25 +1,25 @@
import { acquireConnection } from './pool.js';
export default async function addOrUpdateLotField(lotFieldForm, user, connectedDatabase) {
export default async function addOrUpdateBurialSiteField(fieldForm, user, connectedDatabase) {
const database = connectedDatabase ?? (await acquireConnection());
const rightNowMillis = Date.now();
let result = database
.prepare(`update LotFields
set lotFieldValue = ?,
.prepare(`update BurialSiteFields
set fieldValue = ?,
recordUpdate_userName = ?,
recordUpdate_timeMillis = ?,
recordDelete_userName = null,
recordDelete_timeMillis = null
where lotId = ?
and lotTypeFieldId = ?`)
.run(lotFieldForm.lotFieldValue, user.userName, rightNowMillis, lotFieldForm.lotId, lotFieldForm.lotTypeFieldId);
where burialSiteId = ?
and burialSiteTypeFieldId = ?`)
.run(fieldForm.fieldValue, user.userName, rightNowMillis, fieldForm.burialSiteId, fieldForm.burialSiteTypeFieldId);
if (result.changes === 0) {
result = database
.prepare(`insert into LotFields (
lotId, lotTypeFieldId, lotFieldValue,
.prepare(`insert into BurialSiteFields (
burialSiteId, burialSiteTypeFieldId, fieldValue,
recordCreate_userName, recordCreate_timeMillis,
recordUpdate_userName, recordUpdate_timeMillis)
values (?, ?, ?, ?, ?, ?, ?)`)
.run(lotFieldForm.lotId, lotFieldForm.lotTypeFieldId, lotFieldForm.lotFieldValue, user.userName, rightNowMillis, user.userName, rightNowMillis);
.run(fieldForm.burialSiteId, fieldForm.burialSiteTypeFieldId, fieldForm.fieldValue, user.userName, rightNowMillis, user.userName, rightNowMillis);
}
if (connectedDatabase === undefined) {
database.release();

View File

@ -2,14 +2,14 @@ import type { PoolConnection } from 'better-sqlite-pool'
import { acquireConnection } from './pool.js'
export interface LotFieldForm {
lotId: string | number
lotTypeFieldId: string | number
lotFieldValue: string
export interface BurialSiteFieldForm {
burialSiteId: string | number
burialSiteTypeFieldId: string | number
fieldValue: string
}
export default async function addOrUpdateLotField(
lotFieldForm: LotFieldForm,
export default async function addOrUpdateBurialSiteField(
fieldForm: BurialSiteFieldForm,
user: User,
connectedDatabase?: PoolConnection
): Promise<boolean> {
@ -19,36 +19,36 @@ export default async function addOrUpdateLotField(
let result = database
.prepare(
`update LotFields
set lotFieldValue = ?,
`update BurialSiteFields
set fieldValue = ?,
recordUpdate_userName = ?,
recordUpdate_timeMillis = ?,
recordDelete_userName = null,
recordDelete_timeMillis = null
where lotId = ?
and lotTypeFieldId = ?`
where burialSiteId = ?
and burialSiteTypeFieldId = ?`
)
.run(
lotFieldForm.lotFieldValue,
fieldForm.fieldValue,
user.userName,
rightNowMillis,
lotFieldForm.lotId,
lotFieldForm.lotTypeFieldId
fieldForm.burialSiteId,
fieldForm.burialSiteTypeFieldId
)
if (result.changes === 0) {
result = database
.prepare(
`insert into LotFields (
lotId, lotTypeFieldId, lotFieldValue,
`insert into BurialSiteFields (
burialSiteId, burialSiteTypeFieldId, fieldValue,
recordCreate_userName, recordCreate_timeMillis,
recordUpdate_userName, recordUpdate_timeMillis)
values (?, ?, ?, ?, ?, ?, ?)`
)
.run(
lotFieldForm.lotId,
lotFieldForm.lotTypeFieldId,
lotFieldForm.lotFieldValue,
fieldForm.burialSiteId,
fieldForm.burialSiteTypeFieldId,
fieldForm.fieldValue,
user.userName,
rightNowMillis,
user.userName,

View File

@ -1,7 +0,0 @@
import type { PoolConnection } from 'better-sqlite-pool';
export interface LotFieldForm {
lotId: string | number;
lotTypeFieldId: string | number;
lotFieldValue: string;
}
export default function addOrUpdateLotField(lotFieldForm: LotFieldForm, user: User, connectedDatabase?: PoolConnection): Promise<boolean>;

View File

@ -1,7 +0,0 @@
import type { PoolConnection } from 'better-sqlite-pool';
export interface LotOccupancyFieldForm {
lotOccupancyId: string | number;
occupancyTypeFieldId: string | number;
lotOccupancyFieldValue: string;
}
export default function addOrUpdateLotOccupancyField(lotOccupancyFieldForm: LotOccupancyFieldForm, user: User, connectedDatabase?: PoolConnection): Promise<boolean>;

View File

@ -1,28 +0,0 @@
import { acquireConnection } from './pool.js';
export default async function addOrUpdateLotOccupancyField(lotOccupancyFieldForm, user, connectedDatabase) {
const database = connectedDatabase ?? (await acquireConnection());
const rightNowMillis = Date.now();
let result = database
.prepare(`update LotOccupancyFields
set lotOccupancyFieldValue = ?,
recordUpdate_userName = ?,
recordUpdate_timeMillis = ?,
recordDelete_userName = null,
recordDelete_timeMillis = null
where lotOccupancyId = ?
and occupancyTypeFieldId = ?`)
.run(lotOccupancyFieldForm.lotOccupancyFieldValue, user.userName, rightNowMillis, lotOccupancyFieldForm.lotOccupancyId, lotOccupancyFieldForm.occupancyTypeFieldId);
if (result.changes === 0) {
result = database
.prepare(`insert into LotOccupancyFields (
lotOccupancyId, occupancyTypeFieldId, lotOccupancyFieldValue,
recordCreate_userName, recordCreate_timeMillis,
recordUpdate_userName, recordUpdate_timeMillis)
values (?, ?, ?, ?, ?, ?, ?)`)
.run(lotOccupancyFieldForm.lotOccupancyId, lotOccupancyFieldForm.occupancyTypeFieldId, lotOccupancyFieldForm.lotOccupancyFieldValue, user.userName, rightNowMillis, user.userName, rightNowMillis);
}
if (connectedDatabase === undefined) {
database.release();
}
return result.changes > 0;
}

View File

@ -1,3 +1,3 @@
type RecordTable = 'LotStatuses' | 'LotTypes' | 'OccupancyTypes' | 'WorkOrderMilestoneTypes' | 'WorkOrderTypes';
export declare function addRecord(recordTable: RecordTable, recordName: string, orderNumber: number | string, user: User): Promise<number>;
type RecordTable = 'BurialSiteStatuses' | 'BurialSiteTypes' | 'ContractTypes' | 'WorkOrderMilestoneTypes' | 'WorkOrderTypes';
export default function addRecord(recordTable: RecordTable, recordName: string, orderNumber: number | string, user: User): Promise<number>;
export {};

View File

@ -1,12 +1,12 @@
import { clearCacheByTableName } from '../helpers/functions.cache.js';
import { acquireConnection } from './pool.js';
const recordNameColumns = new Map();
recordNameColumns.set('LotStatuses', 'lotStatus');
recordNameColumns.set('LotTypes', 'lotType');
recordNameColumns.set('OccupancyTypes', 'occupancyType');
recordNameColumns.set('BurialSiteStatuses', 'burialSiteStatus');
recordNameColumns.set('BurialSiteTypes', 'burialSiteType');
recordNameColumns.set('ContractTypes', 'contractType');
recordNameColumns.set('WorkOrderMilestoneTypes', 'workOrderMilestoneType');
recordNameColumns.set('WorkOrderTypes', 'workOrderType');
export async function addRecord(recordTable, recordName, orderNumber, user) {
export default async function addRecord(recordTable, recordName, orderNumber, user) {
const database = await acquireConnection();
const rightNowMillis = Date.now();
const result = database

View File

@ -3,20 +3,20 @@ import { clearCacheByTableName } from '../helpers/functions.cache.js'
import { acquireConnection } from './pool.js'
type RecordTable =
| 'LotStatuses'
| 'LotTypes'
| 'OccupancyTypes'
| 'BurialSiteStatuses'
| 'BurialSiteTypes'
| 'ContractTypes'
| 'WorkOrderMilestoneTypes'
| 'WorkOrderTypes'
const recordNameColumns = new Map<RecordTable, string>()
recordNameColumns.set('LotStatuses', 'lotStatus')
recordNameColumns.set('LotTypes', 'lotType')
recordNameColumns.set('OccupancyTypes', 'occupancyType')
recordNameColumns.set('BurialSiteStatuses', 'burialSiteStatus')
recordNameColumns.set('BurialSiteTypes', 'burialSiteType')
recordNameColumns.set('ContractTypes', 'contractType')
recordNameColumns.set('WorkOrderMilestoneTypes', 'workOrderMilestoneType')
recordNameColumns.set('WorkOrderTypes', 'workOrderType')
export async function addRecord(
export default async function addRecord(
recordTable: RecordTable,
recordName: string,
orderNumber: number | string,

View File

@ -4,6 +4,6 @@ export interface AddWorkOrderForm {
workOrderDescription: string;
workOrderOpenDateString?: string;
workOrderCloseDateString?: string;
lotOccupancyId?: string;
burialSiteContractId?: string;
}
export default function addWorkOrder(workOrderForm: AddWorkOrderForm, user: User): Promise<number>;

View File

@ -1,5 +1,5 @@
import { dateStringToInteger, dateToInteger } from '@cityssm/utils-datetime';
import addWorkOrderLotOccupancy from './addWorkOrderLotOccupancy.js';
import addWorkOrderBurialSiteContract from './addWorkOrderBurialSiteContract.js';
import getNextWorkOrderNumber from './getNextWorkOrderNumber.js';
import { acquireConnection } from './pool.js';
export default async function addWorkOrder(workOrderForm, user) {
@ -22,10 +22,10 @@ export default async function addWorkOrder(workOrderForm, user) {
? undefined
: dateStringToInteger(workOrderForm.workOrderCloseDateString), user.userName, rightNow.getTime(), user.userName, rightNow.getTime());
const workOrderId = result.lastInsertRowid;
if ((workOrderForm.lotOccupancyId ?? '') !== '') {
await addWorkOrderLotOccupancy({
if ((workOrderForm.burialSiteContractId ?? '') !== '') {
await addWorkOrderBurialSiteContract({
workOrderId,
lotOccupancyId: workOrderForm.lotOccupancyId
burialSiteContractId: workOrderForm.burialSiteContractId
}, user, database);
}
database.release();

View File

@ -4,7 +4,7 @@ import {
dateToInteger
} from '@cityssm/utils-datetime'
import addWorkOrderLotOccupancy from './addWorkOrderLotOccupancy.js'
import addWorkOrderBurialSiteContract from './addWorkOrderBurialSiteContract.js'
import getNextWorkOrderNumber from './getNextWorkOrderNumber.js'
import { acquireConnection } from './pool.js'
@ -14,7 +14,7 @@ export interface AddWorkOrderForm {
workOrderDescription: string
workOrderOpenDateString?: string
workOrderCloseDateString?: string
lotOccupancyId?: string
burialSiteContractId?: string
}
export default async function addWorkOrder(
@ -62,11 +62,11 @@ export default async function addWorkOrder(
const workOrderId = result.lastInsertRowid as number
if ((workOrderForm.lotOccupancyId ?? '') !== '') {
await addWorkOrderLotOccupancy(
if ((workOrderForm.burialSiteContractId ?? '') !== '') {
await addWorkOrderBurialSiteContract(
{
workOrderId,
lotOccupancyId: workOrderForm.lotOccupancyId!
burialSiteContractId: workOrderForm.burialSiteContractId as string
},
user,
database

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