filter prints by occupancy type

deepsource-autofix-76c6eb20
Dan Gowans 2022-12-14 11:04:39 -05:00
parent aa8c760fdf
commit 3af3064880
24 changed files with 270 additions and 52 deletions

View File

@ -1,4 +1,4 @@
import { getLotOccupantTypes, getLotStatuses, getLotTypes, getOccupancyTypes, getWorkOrderTypes } from "../../helpers/functions.cache.js"; import { 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 { getLotOccupancy } from "../../helpers/lotOccupancyDB/getLotOccupancy.js";
import { getMaps } from "../../helpers/lotOccupancyDB/getMaps.js"; import { getMaps } from "../../helpers/lotOccupancyDB/getMaps.js";
@ -8,6 +8,7 @@ export const handler = (request, response) => {
return response.redirect(configFunctions.getProperty("reverseProxy.urlPrefix") + return response.redirect(configFunctions.getProperty("reverseProxy.urlPrefix") +
"/lotOccupancies/?error=lotOccupancyIdNotFound"); "/lotOccupancies/?error=lotOccupancyIdNotFound");
} }
const occupancyTypePrints = getOccupancyTypePrintsById(lotOccupancy.occupancyTypeId);
const occupancyTypes = getOccupancyTypes(); const occupancyTypes = getOccupancyTypes();
const lotOccupantTypes = getLotOccupantTypes(); const lotOccupantTypes = getLotOccupantTypes();
const lotTypes = getLotTypes(); const lotTypes = getLotTypes();
@ -20,6 +21,7 @@ export const handler = (request, response) => {
configFunctions.getProperty("aliases.occupancy") + configFunctions.getProperty("aliases.occupancy") +
" Update", " Update",
lotOccupancy, lotOccupancy,
occupancyTypePrints,
occupancyTypes, occupancyTypes,
lotOccupantTypes, lotOccupantTypes,
lotTypes, lotTypes,

View File

@ -4,6 +4,7 @@ import {
getLotOccupantTypes, getLotOccupantTypes,
getLotStatuses, getLotStatuses,
getLotTypes, getLotTypes,
getOccupancyTypePrintsById,
getOccupancyTypes, getOccupancyTypes,
getWorkOrderTypes getWorkOrderTypes
} from "../../helpers/functions.cache.js"; } from "../../helpers/functions.cache.js";
@ -23,6 +24,8 @@ export const handler: RequestHandler = (request, response) => {
); );
} }
const occupancyTypePrints = getOccupancyTypePrintsById(lotOccupancy.occupancyTypeId);
const occupancyTypes = getOccupancyTypes(); const occupancyTypes = getOccupancyTypes();
const lotOccupantTypes = getLotOccupantTypes(); const lotOccupantTypes = getLotOccupantTypes();
const lotTypes = getLotTypes(); const lotTypes = getLotTypes();
@ -37,6 +40,7 @@ export const handler: RequestHandler = (request, response) => {
configFunctions.getProperty("aliases.occupancy") + configFunctions.getProperty("aliases.occupancy") +
" Update", " Update",
lotOccupancy, lotOccupancy,
occupancyTypePrints,
occupancyTypes, occupancyTypes,
lotOccupantTypes, lotOccupantTypes,

View File

@ -1,3 +1,4 @@
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 = (request, response) => { export const handler = (request, response) => {
@ -6,12 +7,14 @@ export const handler = (request, response) => {
return response.redirect(configFunctions.getProperty("reverseProxy.urlPrefix") + return response.redirect(configFunctions.getProperty("reverseProxy.urlPrefix") +
"/lotOccupancies/?error=lotOccupancyIdNotFound"); "/lotOccupancies/?error=lotOccupancyIdNotFound");
} }
const occupancyTypePrints = getOccupancyTypePrintsById(lotOccupancy.occupancyTypeId);
return response.render("lotOccupancy-view", { return response.render("lotOccupancy-view", {
headTitle: configFunctions.getProperty("aliases.lot") + headTitle: configFunctions.getProperty("aliases.lot") +
" " + " " +
configFunctions.getProperty("aliases.occupancy") + configFunctions.getProperty("aliases.occupancy") +
" View", " View",
lotOccupancy lotOccupancy,
occupancyTypePrints
}); });
}; };
export default handler; export default handler;

View File

@ -1,4 +1,5 @@
import type { RequestHandler } from "express"; 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";
@ -14,13 +15,16 @@ export const handler: RequestHandler = (request, response) => {
); );
} }
const occupancyTypePrints = getOccupancyTypePrintsById(lotOccupancy.occupancyTypeId);
return response.render("lotOccupancy-view", { return response.render("lotOccupancy-view", {
headTitle: headTitle:
configFunctions.getProperty("aliases.lot") + configFunctions.getProperty("aliases.lot") +
" " + " " +
configFunctions.getProperty("aliases.occupancy") + configFunctions.getProperty("aliases.occupancy") +
" View", " View",
lotOccupancy lotOccupancy,
occupancyTypePrints
}); });
}; };

View File

@ -15,6 +15,7 @@ export declare function getOccupancyTypes(): recordTypes.OccupancyType[];
export declare function getAllOccupancyTypeFields(): recordTypes.OccupancyTypeField[]; export declare function getAllOccupancyTypeFields(): recordTypes.OccupancyTypeField[];
export declare function getOccupancyTypeById(occupancyTypeId: number): recordTypes.OccupancyType; export declare function getOccupancyTypeById(occupancyTypeId: number): recordTypes.OccupancyType;
export declare function getOccupancyTypeByOccupancyType(occupancyTypeString: string): recordTypes.OccupancyType; export declare function getOccupancyTypeByOccupancyType(occupancyTypeString: string): recordTypes.OccupancyType;
export declare function getOccupancyTypePrintsById(occupancyTypeId: number): string[];
export declare function clearOccupancyTypesCache(): void; export declare function clearOccupancyTypesCache(): void;
export declare function getWorkOrderTypes(): recordTypes.WorkOrderType[]; export declare function getWorkOrderTypes(): recordTypes.WorkOrderType[];
export declare function clearWorkOrderTypesCache(): void; export declare function clearWorkOrderTypesCache(): void;

View File

@ -1,3 +1,4 @@
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";
@ -101,6 +102,16 @@ export function getOccupancyTypeByOccupancyType(occupancyTypeString) {
return currentOccupancyType.occupancyType.toLowerCase() === occupancyTypeLowerCase; return currentOccupancyType.occupancyType.toLowerCase() === occupancyTypeLowerCase;
}); });
} }
export function getOccupancyTypePrintsById(occupancyTypeId) {
const occupancyType = getOccupancyTypeById(occupancyTypeId);
if (!occupancyType || occupancyType.occupancyTypePrints.length === 0) {
return [];
}
if (occupancyType.occupancyTypePrints.includes("*")) {
return configFunctions.getProperty("settings.lotOccupancy.prints");
}
return occupancyType.occupancyTypePrints;
}
export function clearOccupancyTypesCache() { export function clearOccupancyTypesCache() {
occupancyTypes = undefined; occupancyTypes = undefined;
allOccupancyTypeFields = undefined; allOccupancyTypeFields = undefined;

View File

@ -1,3 +1,5 @@
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";
@ -161,6 +163,21 @@ export function getOccupancyTypeByOccupancyType(occupancyTypeString: string) {
}); });
} }
export function getOccupancyTypePrintsById(occupancyTypeId: number): string[] {
const occupancyType = getOccupancyTypeById(occupancyTypeId);
if (!occupancyType || occupancyType.occupancyTypePrints.length === 0) {
return [];
}
if (occupancyType.occupancyTypePrints.includes("*")) {
return configFunctions.getProperty("settings.lotOccupancy.prints");
}
return occupancyType.occupancyTypePrints;
}
export function clearOccupancyTypesCache() { export function clearOccupancyTypesCache() {
occupancyTypes = undefined; occupancyTypes = undefined;
allOccupancyTypeFields = undefined; allOccupancyTypeFields = undefined;

View File

@ -24,7 +24,8 @@ export const initializeDatabase = () => {
")") ")")
.run(); .run();
lotOccupancyDB lotOccupancyDB
.prepare("create index if not exists idx_lottypes_ordernumber" + " on LotTypes (orderNumber, lotType)") .prepare("create index if not exists idx_lottypes_ordernumber" +
" on LotTypes (orderNumber, lotType)")
.run(); .run();
lotOccupancyDB lotOccupancyDB
.prepare("create table if not exists LotTypeFields (" + .prepare("create table if not exists LotTypeFields (" +
@ -55,7 +56,8 @@ export const initializeDatabase = () => {
")") ")")
.run(); .run();
lotOccupancyDB lotOccupancyDB
.prepare("create index if not exists idx_lotstatuses_ordernumber" + " on LotStatuses (orderNumber, lotStatus)") .prepare("create index if not exists idx_lotstatuses_ordernumber" +
" on LotStatuses (orderNumber, lotStatus)")
.run(); .run();
lotOccupancyDB lotOccupancyDB
.prepare("create table if not exists Maps (" + .prepare("create table if not exists Maps (" +
@ -151,6 +153,21 @@ export const initializeDatabase = () => {
.prepare("create index if not exists idx_occupancytypefields_ordernumber" + .prepare("create index if not exists idx_occupancytypefields_ordernumber" +
" on OccupancyTypeFields (occupancyTypeId, orderNumber, occupancyTypeField)") " on OccupancyTypeFields (occupancyTypeId, orderNumber, occupancyTypeField)")
.run(); .run();
lotOccupancyDB
.prepare("create table if not exists OccupancyTypePrints (" +
"occupancyTypeId integer not null," +
" printEJS varchar(100) not null," +
" orderNumber smallint not null default 0," +
recordColumns +
"," +
" primary key (occupancyTypeId, printEJS)," +
" foreign key (occupancyTypeId) references OccupancyTypes (occupancyTypeId)" +
")")
.run();
lotOccupancyDB
.prepare("create index if not exists idx_occupancytypeprints_ordernumber" +
" on OccupancyTypePrints (occupancyTypeId, orderNumber, printEJS)")
.run();
lotOccupancyDB lotOccupancyDB
.prepare("create table if not exists LotOccupantTypes (" + .prepare("create table if not exists LotOccupantTypes (" +
"lotOccupantTypeId integer not null primary key autoincrement," + "lotOccupantTypeId integer not null primary key autoincrement," +
@ -258,7 +275,8 @@ export const initializeDatabase = () => {
")") ")")
.run(); .run();
lotOccupancyDB lotOccupancyDB
.prepare("create index if not exists idx_fees_ordernumber" + " on Fees (orderNumber, feeName)") .prepare("create index if not exists idx_fees_ordernumber" +
" on Fees (orderNumber, feeName)")
.run(); .run();
lotOccupancyDB lotOccupancyDB
.prepare("create table if not exists LotOccupancyFees (" + .prepare("create table if not exists LotOccupancyFees (" +

View File

@ -17,7 +17,9 @@ export const initializeDatabase = (): boolean => {
const lotOccupancyDB = sqlite(databasePath); const lotOccupancyDB = sqlite(databasePath);
const row = lotOccupancyDB const row = lotOccupancyDB
.prepare("select name from sqlite_master where type = 'table' and name = 'WorkOrderMilestones'") .prepare(
"select name from sqlite_master where type = 'table' and name = 'WorkOrderMilestones'"
)
.get(); .get();
if (!row) { if (!row) {
@ -37,7 +39,10 @@ export const initializeDatabase = (): boolean => {
.run(); .run();
lotOccupancyDB lotOccupancyDB
.prepare("create index if not exists idx_lottypes_ordernumber" + " on LotTypes (orderNumber, lotType)") .prepare(
"create index if not exists idx_lottypes_ordernumber" +
" on LotTypes (orderNumber, lotType)"
)
.run(); .run();
lotOccupancyDB lotOccupancyDB
@ -79,7 +84,8 @@ export const initializeDatabase = (): boolean => {
lotOccupancyDB lotOccupancyDB
.prepare( .prepare(
"create index if not exists idx_lotstatuses_ordernumber" + " on LotStatuses (orderNumber, lotStatus)" "create index if not exists idx_lotstatuses_ordernumber" +
" on LotStatuses (orderNumber, lotStatus)"
) )
.run(); .run();
@ -208,6 +214,27 @@ export const initializeDatabase = (): boolean => {
) )
.run(); .run();
lotOccupancyDB
.prepare(
"create table if not exists OccupancyTypePrints (" +
"occupancyTypeId integer not null," +
" printEJS varchar(100) not null," +
" orderNumber smallint not null default 0," +
recordColumns +
"," +
" primary key (occupancyTypeId, printEJS)," +
" foreign key (occupancyTypeId) references OccupancyTypes (occupancyTypeId)" +
")"
)
.run();
lotOccupancyDB
.prepare(
"create index if not exists idx_occupancytypeprints_ordernumber" +
" on OccupancyTypePrints (occupancyTypeId, orderNumber, printEJS)"
)
.run();
lotOccupancyDB lotOccupancyDB
.prepare( .prepare(
"create table if not exists LotOccupantTypes (" + "create table if not exists LotOccupantTypes (" +
@ -344,7 +371,10 @@ export const initializeDatabase = (): boolean => {
.run(); .run();
lotOccupancyDB lotOccupancyDB
.prepare("create index if not exists idx_fees_ordernumber" + " on Fees (orderNumber, feeName)") .prepare(
"create index if not exists idx_fees_ordernumber" +
" on Fees (orderNumber, feeName)"
)
.run(); .run();
lotOccupancyDB lotOccupancyDB

View File

@ -1,6 +1,8 @@
import sqlite from "better-sqlite3"; import sqlite from "better-sqlite3";
import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js"; import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js";
import { dateIntegerToString, dateStringToInteger, dateToInteger } from "@cityssm/expressjs-server-js/dateTimeFns.js"; import { dateIntegerToString, dateStringToInteger, dateToInteger } from "@cityssm/expressjs-server-js/dateTimeFns.js";
import * as configFunctions from "../functions.config.js";
import { getOccupancyTypeById } from "../functions.cache.js";
import { getLotOccupancyOccupants } from "./getLotOccupancyOccupants.js"; import { getLotOccupancyOccupants } from "./getLotOccupancyOccupants.js";
const buildWhereClause = (filters) => { const buildWhereClause = (filters) => {
let sqlWhereClause = " where o.recordDelete_timeMillis is null"; let sqlWhereClause = " where o.recordDelete_timeMillis is null";
@ -123,15 +125,21 @@ export const getLotOccupancies = (filters, options, connectedDatabase) => {
" left join Maps m on l.mapId = m.mapId" + " left join Maps m on l.mapId = m.mapId" +
sqlWhereClause + sqlWhereClause +
" order by o.occupancyStartDate desc, ifnull(o.occupancyEndDate, 99999999) desc, l.lotName, o.lotId" + " order by o.occupancyStartDate desc, ifnull(o.occupancyEndDate, 99999999) desc, l.lotName, o.lotId" +
(options.limit !== -1 (options.limit === -1
? " limit " + options.limit + " offset " + options.offset ? ""
: "")) : " limit " + options.limit + " offset " + options.offset))
.all(sqlParameters); .all(sqlParameters);
if (options.limit === -1) { if (options.limit === -1) {
count = lotOccupancies.length; count = lotOccupancies.length;
} }
if (options.includeOccupants) { for (const lotOccupancy of lotOccupancies) {
for (const lotOccupancy of lotOccupancies) { const occupancyType = getOccupancyTypeById(lotOccupancy.occupancyTypeId);
if (occupancyType) {
lotOccupancy.printEJS = occupancyType.occupancyTypePrints.includes("*")
? configFunctions.getProperty("settings.lotOccupancy.prints")[0]
: occupancyType.occupancyTypePrints[0];
}
if (options.includeOccupants) {
lotOccupancy.lotOccupancyOccupants = getLotOccupancyOccupants(lotOccupancy.lotOccupancyId, database); lotOccupancy.lotOccupancyOccupants = getLotOccupancyOccupants(lotOccupancy.lotOccupancyId, database);
} }
} }

View File

@ -8,6 +8,9 @@ import {
dateToInteger dateToInteger
} from "@cityssm/expressjs-server-js/dateTimeFns.js"; } from "@cityssm/expressjs-server-js/dateTimeFns.js";
import * as configFunctions from "../functions.config.js";
import { getOccupancyTypeById } from "../functions.cache.js";
import { getLotOccupancyOccupants } from "./getLotOccupancyOccupants.js"; import { getLotOccupancyOccupants } from "./getLotOccupancyOccupants.js";
import type * as recordTypes from "../../types/recordTypes"; import type * as recordTypes from "../../types/recordTypes";
@ -190,9 +193,9 @@ export const getLotOccupancies = (
" left join Maps m on l.mapId = m.mapId" + " left join Maps m on l.mapId = m.mapId" +
sqlWhereClause + sqlWhereClause +
" order by o.occupancyStartDate desc, ifnull(o.occupancyEndDate, 99999999) desc, l.lotName, o.lotId" + " order by o.occupancyStartDate desc, ifnull(o.occupancyEndDate, 99999999) desc, l.lotName, o.lotId" +
(options.limit !== -1 (options.limit === -1
? " limit " + options.limit + " offset " + options.offset ? ""
: "") : " limit " + options.limit + " offset " + options.offset)
) )
.all(sqlParameters); .all(sqlParameters);
@ -200,8 +203,16 @@ export const getLotOccupancies = (
count = lotOccupancies.length; count = lotOccupancies.length;
} }
if (options.includeOccupants) { for (const lotOccupancy of lotOccupancies) {
for (const lotOccupancy of lotOccupancies) { const occupancyType = getOccupancyTypeById(lotOccupancy.occupancyTypeId);
if (occupancyType) {
lotOccupancy.printEJS = occupancyType.occupancyTypePrints.includes("*")
? configFunctions.getProperty("settings.lotOccupancy.prints")[0]
: occupancyType.occupancyTypePrints[0];
}
if (options.includeOccupants) {
lotOccupancy.lotOccupancyOccupants = getLotOccupancyOccupants( lotOccupancy.lotOccupancyOccupants = getLotOccupancyOccupants(
lotOccupancy.lotOccupancyId as number, lotOccupancy.lotOccupancyId as number,
database database

View File

@ -0,0 +1,3 @@
import sqlite from "better-sqlite3";
export declare const getOccupancyTypePrints: (occupancyTypeId: number, connectedDatabase?: sqlite.Database) => string[];
export default getOccupancyTypePrints;

View File

@ -0,0 +1,41 @@
import sqlite from "better-sqlite3";
import * as configFunctions from "../functions.config.js";
import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js";
const availablePrints = configFunctions.getProperty("settings.lotOccupancy.prints");
const userFunction_configContainsPrintEJS = (printEJS) => {
if (printEJS === "*" || availablePrints.includes(printEJS)) {
return 1;
}
return 0;
};
export const getOccupancyTypePrints = (occupancyTypeId, connectedDatabase) => {
const database = connectedDatabase || sqlite(databasePath);
database.function("userFn_configContainsPrintEJS", userFunction_configContainsPrintEJS);
const results = database
.prepare("select printEJS, orderNumber" +
" from OccupancyTypePrints" +
" where recordDelete_timeMillis is null" +
" and occupancyTypeId = ?" +
" and userFn_configContainsPrintEJS(printEJS) = 1" +
" order by orderNumber, printEJS")
.all(occupancyTypeId);
let expectedOrderNumber = -1;
const prints = [];
for (const result of results) {
expectedOrderNumber += 1;
if (result.orderNumber !== expectedOrderNumber) {
database
.prepare("update OccupancyTypeFields" +
" set orderNumber = ?" +
" where occupancyTypeId = ?" +
" and printEJS = ?")
.run(expectedOrderNumber, occupancyTypeId, result.printEJS);
}
prints.push(result.printEJS);
}
if (!connectedDatabase) {
database.close();
}
return prints;
};
export default getOccupancyTypePrints;

View File

@ -0,0 +1,63 @@
import sqlite from "better-sqlite3";
import * as configFunctions from "../functions.config.js";
import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js";
const availablePrints = configFunctions.getProperty("settings.lotOccupancy.prints");
const userFunction_configContainsPrintEJS = (printEJS: string): number => {
if (printEJS === "*" || availablePrints.includes(printEJS)) {
return 1;
}
return 0;
};
export const getOccupancyTypePrints = (
occupancyTypeId: number,
connectedDatabase?: sqlite.Database
): string[] => {
const database = connectedDatabase || sqlite(databasePath);
database.function("userFn_configContainsPrintEJS", userFunction_configContainsPrintEJS);
const results: { printEJS: string; orderNumber: number }[] = database
.prepare(
"select printEJS, orderNumber" +
" from OccupancyTypePrints" +
" where recordDelete_timeMillis is null" +
" and occupancyTypeId = ?" +
" and userFn_configContainsPrintEJS(printEJS) = 1" +
" order by orderNumber, printEJS"
)
.all(occupancyTypeId);
let expectedOrderNumber = -1;
const prints = [];
for (const result of results) {
expectedOrderNumber += 1;
if (result.orderNumber !== expectedOrderNumber) {
database
.prepare(
"update OccupancyTypeFields" +
" set orderNumber = ?" +
" where occupancyTypeId = ?" +
" and printEJS = ?"
)
.run(expectedOrderNumber, occupancyTypeId, result.printEJS);
}
prints.push(result.printEJS);
}
if (!connectedDatabase) {
database.close();
}
return prints;
};
export default getOccupancyTypePrints;

View File

@ -1,6 +1,7 @@
import sqlite from "better-sqlite3"; import sqlite from "better-sqlite3";
import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js"; import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js";
import { getOccupancyTypeFields } from "./getOccupancyTypeFields.js"; import { getOccupancyTypeFields } from "./getOccupancyTypeFields.js";
import { getOccupancyTypePrints } from "./getOccupancyTypePrints.js";
export const getOccupancyTypes = () => { export const getOccupancyTypes = () => {
const database = sqlite(databasePath); const database = sqlite(databasePath);
const occupancyTypes = database const occupancyTypes = database
@ -19,6 +20,7 @@ export const getOccupancyTypes = () => {
occupancyType.orderNumber = expectedTypeOrderNumber; occupancyType.orderNumber = expectedTypeOrderNumber;
} }
occupancyType.occupancyTypeFields = getOccupancyTypeFields(occupancyType.occupancyTypeId, database); occupancyType.occupancyTypeFields = getOccupancyTypeFields(occupancyType.occupancyTypeId, database);
occupancyType.occupancyTypePrints = getOccupancyTypePrints(occupancyType.occupancyTypeId, database);
let expectedFieldOrderNumber = -1; let expectedFieldOrderNumber = -1;
for (const occupancyTypeField of occupancyType.occupancyTypeFields) { for (const occupancyTypeField of occupancyType.occupancyTypeFields) {
expectedFieldOrderNumber += 1; expectedFieldOrderNumber += 1;

View File

@ -3,6 +3,7 @@ import sqlite from "better-sqlite3";
import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js"; import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js";
import { getOccupancyTypeFields } from "./getOccupancyTypeFields.js"; import { getOccupancyTypeFields } from "./getOccupancyTypeFields.js";
import { getOccupancyTypePrints } from "./getOccupancyTypePrints.js";
import type * as recordTypes from "../../types/recordTypes"; import type * as recordTypes from "../../types/recordTypes";
@ -37,6 +38,11 @@ export const getOccupancyTypes = (): recordTypes.OccupancyType[] => {
occupancyType.occupancyTypeId, occupancyType.occupancyTypeId,
database database
); );
occupancyType.occupancyTypePrints = getOccupancyTypePrints(
occupancyType.occupancyTypeId,
database
);
let expectedFieldOrderNumber = -1; let expectedFieldOrderNumber = -1;

View File

@ -2,7 +2,6 @@
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
(() => { (() => {
const los = exports.los; const los = exports.los;
const lotOccupancyPrints = exports.lotOccupancyPrints;
const searchFilterFormElement = document.querySelector("#form--searchFilters"); const searchFilterFormElement = document.querySelector("#form--searchFilters");
const searchResultsContainerElement = document.querySelector("#container--searchResults"); const searchResultsContainerElement = document.querySelector("#container--searchResults");
const limit = Number.parseInt(document.querySelector("#searchFilter--limit").value, 10); const limit = Number.parseInt(document.querySelector("#searchFilter--limit").value, 10);
@ -111,19 +110,19 @@ Object.defineProperty(exports, "__esModule", { value: true });
: '<span class="has-text-grey">(No End Date)</span>') + : '<span class="has-text-grey">(No End Date)</span>') +
"</td>") + "</td>") +
("<td>" + occupantsHTML + "</td>") + ("<td>" + occupantsHTML + "</td>") +
(lotOccupancyPrints.length > 0 "<td>" +
? "<td>" + (lotOccupancy.printEJS
'<a class="button is-small" data-tooltip="Print" href="' + ? '<a class="button is-small" data-tooltip="Print" href="' +
los.urlPrefix + los.urlPrefix +
"/print/" + "/print/" +
lotOccupancyPrints[0] + lotOccupancy.printEJS +
"/?lotOccupancyId=" + "/?lotOccupancyId=" +
lotOccupancy.lotOccupancyId + lotOccupancy.lotOccupancyId +
'" target="_blank">' + '" target="_blank">' +
'<i class="fas fa-print" aria-label="Print"></i>' + '<i class="fas fa-print" aria-label="Print"></i>' +
"</a>" + "</a>"
"</td>"
: "") + : "") +
"</td>" +
"</tr>"); "</tr>");
} }
searchResultsContainerElement.innerHTML = searchResultsContainerElement.innerHTML =
@ -135,9 +134,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
("<th>" + cityssm.escapeHTML(exports.aliases.occupancyStartDate) + "</th>") + ("<th>" + cityssm.escapeHTML(exports.aliases.occupancyStartDate) + "</th>") +
"<th>End Date</th>" + "<th>End Date</th>" +
("<th>" + cityssm.escapeHTML(exports.aliases.occupants) + "</th>") + ("<th>" + cityssm.escapeHTML(exports.aliases.occupants) + "</th>") +
(lotOccupancyPrints.length > 0 '<th class="has-width-1"><span class="is-sr-only">Print</span></th>' +
? '<th class="has-width-1"><span class="is-sr-only">Print</span></th>'
: "") +
"</tr></thead>" + "</tr></thead>" +
"<table>" + "<table>" +
'<div class="level">' + '<div class="level">' +

View File

@ -10,8 +10,6 @@ declare const cityssm: cityssmGlobal;
(() => { (() => {
const los = exports.los as globalTypes.LOS; const los = exports.los as globalTypes.LOS;
const lotOccupancyPrints: string[] = exports.lotOccupancyPrints;
const searchFilterFormElement = document.querySelector( const searchFilterFormElement = document.querySelector(
"#form--searchFilters" "#form--searchFilters"
) as HTMLFormElement; ) as HTMLFormElement;
@ -145,19 +143,19 @@ declare const cityssm: cityssmGlobal;
: '<span class="has-text-grey">(No End Date)</span>') + : '<span class="has-text-grey">(No End Date)</span>') +
"</td>") + "</td>") +
("<td>" + occupantsHTML + "</td>") + ("<td>" + occupantsHTML + "</td>") +
(lotOccupancyPrints.length > 0 "<td>" +
? "<td>" + (lotOccupancy.printEJS
'<a class="button is-small" data-tooltip="Print" href="' + ? '<a class="button is-small" data-tooltip="Print" href="' +
los.urlPrefix + los.urlPrefix +
"/print/" + "/print/" +
lotOccupancyPrints[0] + lotOccupancy.printEJS +
"/?lotOccupancyId=" + "/?lotOccupancyId=" +
lotOccupancy.lotOccupancyId + lotOccupancy.lotOccupancyId +
'" target="_blank">' + '" target="_blank">' +
'<i class="fas fa-print" aria-label="Print"></i>' + '<i class="fas fa-print" aria-label="Print"></i>' +
"</a>" + "</a>"
"</td>"
: "") + : "") +
"</td>" +
"</tr>" "</tr>"
); );
} }
@ -171,9 +169,7 @@ declare const cityssm: cityssmGlobal;
("<th>" + cityssm.escapeHTML(exports.aliases.occupancyStartDate) + "</th>") + ("<th>" + cityssm.escapeHTML(exports.aliases.occupancyStartDate) + "</th>") +
"<th>End Date</th>" + "<th>End Date</th>" +
("<th>" + cityssm.escapeHTML(exports.aliases.occupants) + "</th>") + ("<th>" + cityssm.escapeHTML(exports.aliases.occupants) + "</th>") +
(lotOccupancyPrints.length > 0 '<th class="has-width-1"><span class="is-sr-only">Print</span></th>' +
? '<th class="has-width-1"><span class="is-sr-only">Print</span></th>'
: "") +
"</tr></thead>" + "</tr></thead>" +
"<table>" + "<table>" +
'<div class="level">' + '<div class="level">' +

View File

@ -1 +1 @@
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),(()=>{const t=exports.los,a=exports.lotOccupancyPrints,e=document.querySelector("#form--searchFilters"),s=document.querySelector("#container--searchResults"),c=Number.parseInt(document.querySelector("#searchFilter--limit").value,10),i=document.querySelector("#searchFilter--offset"),o=()=>{const o=Number.parseInt(i.value,10);s.innerHTML='<div class="has-text-grey has-text-centered"><i class="fas fa-5x fa-circle-notch fa-spin" aria-hidden="true"></i><br />Loading '+exports.aliases.occupancies+"...</div>",cityssm.postJSON(t.urlPrefix+"/lotOccupancies/doSearchLotOccupancies",e,e=>{if(0===e.lotOccupancies.length)return void(s.innerHTML='<div class="message is-info"><p class="message-body">There are no '+cityssm.escapeHTML(exports.aliases.occupancy.toLowerCase())+" records that meet the search criteria.</p></div>");const i=document.createElement("tbody"),r=cityssm.dateToString(new Date);for(const s of e.lotOccupancies){let e="";e=s.occupancyStartDateString<=r&&(""===s.occupancyEndDateString||s.occupancyEndDateString>=r)?'<span class="has-tooltip-right" data-tooltip="Current '+exports.aliases.occupancy+'"><i class="fas fa-play" aria-label="Current '+exports.aliases.occupancy+'"></i></span>':s.occupancyStartDateString>r?'<span class="has-tooltip-right" data-tooltip="Future '+exports.aliases.occupancy+'"><i class="fas fa-fast-forward" aria-label="Future '+exports.aliases.occupancy+'"></i></span>':'<span class="has-tooltip-right" data-tooltip="Past '+exports.aliases.occupancy+'"><i class="fas fa-stop" aria-label="Past '+exports.aliases.occupancy+'"></i></span>';let c="";for(const t of s.lotOccupancyOccupants)c+='<span class="has-tooltip-left" data-tooltip="'+cityssm.escapeHTML(t.lotOccupantType||"")+'"><i class="fas fa-fw fa-'+cityssm.escapeHTML(t.fontAwesomeIconClass||"user")+'" aria-hidden="true"></i> '+cityssm.escapeHTML(t.occupantName||"")+"</span><br />";i.insertAdjacentHTML("beforeend",'<tr><td class="has-width-1">'+e+'</td><td><a class="has-text-weight-bold" href="'+t.urlPrefix+"/lotOccupancies/"+s.lotOccupancyId+'">'+cityssm.escapeHTML(s.occupancyType)+"</a></td><td>"+(s.lotName?'<a class="has-tooltip-right" data-tooltip="'+cityssm.escapeHTML(s.lotType||"")+'" href="'+t.urlPrefix+"/lots/"+s.lotId+'">'+cityssm.escapeHTML(s.lotName)+"</a>":'<span class="has-text-grey">(No '+cityssm.escapeHTML(exports.aliases.lot)+")</span>")+'<br /><span class="is-size-7">'+cityssm.escapeHTML(s.mapName||"")+"</span></td><td>"+s.occupancyStartDateString+"</td><td>"+(s.occupancyEndDate?s.occupancyEndDateString:'<span class="has-text-grey">(No End Date)</span>')+"</td><td>"+c+"</td>"+(a.length>0?'<td><a class="button is-small" data-tooltip="Print" href="'+t.urlPrefix+"/print/"+a[0]+"/?lotOccupancyId="+s.lotOccupancyId+'" target="_blank"><i class="fas fa-print" aria-label="Print"></i></a></td>':"")+"</tr>")}s.innerHTML='<table class="table is-fullwidth is-striped is-hoverable has-sticky-header"><thead><tr><th class="has-width-1"></th><th>'+cityssm.escapeHTML(exports.aliases.occupancy)+" Type</th><th>"+cityssm.escapeHTML(exports.aliases.lot)+"</th><th>"+cityssm.escapeHTML(exports.aliases.occupancyStartDate)+"</th><th>End Date</th><th>"+cityssm.escapeHTML(exports.aliases.occupants)+"</th>"+(a.length>0?'<th class="has-width-1"><span class="is-sr-only">Print</span></th>':"")+'</tr></thead><table><div class="level"><div class="level-left"><div class="level-item has-text-weight-bold">Displaying '+(o+1).toString()+" to "+Math.min(e.count,c+o)+" of "+e.count+'</div></div><div class="level-right">'+(o>0?'<div class="level-item"><button class="button is-rounded is-link is-outlined" data-page="previous" type="button" title="Previous"><i class="fas fa-arrow-left" aria-hidden="true"></i></button></div>':"")+(c+o<e.count?'<div class="level-item"><button class="button is-rounded is-link" data-page="next" type="button" title="Next"><span>Next</span><span class="icon"><i class="fas fa-arrow-right" aria-hidden="true"></i></span></button></div>':"")+"</div></div>",s.querySelector("table").append(i),o>0&&s.querySelector("button[data-page='previous']").addEventListener("click",l),c+o<e.count&&s.querySelector("button[data-page='next']").addEventListener("click",n)})},r=()=>{i.value="0",o()},l=()=>{i.value=Math.max(Number.parseInt(i.value,10)-c,0).toString(),o()},n=()=>{i.value=(Number.parseInt(i.value,10)+c).toString(),o()},p=e.querySelectorAll("input, select");for(const t of p)t.addEventListener("change",r);e.addEventListener("submit",t=>{t.preventDefault(),r()}),o()})(); "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),(()=>{const t=exports.los,a=document.querySelector("#form--searchFilters"),e=document.querySelector("#container--searchResults"),s=Number.parseInt(document.querySelector("#searchFilter--limit").value,10),c=document.querySelector("#searchFilter--offset"),i=()=>{const i=Number.parseInt(c.value,10);e.innerHTML='<div class="has-text-grey has-text-centered"><i class="fas fa-5x fa-circle-notch fa-spin" aria-hidden="true"></i><br />Loading '+exports.aliases.occupancies+"...</div>",cityssm.postJSON(t.urlPrefix+"/lotOccupancies/doSearchLotOccupancies",a,a=>{if(0===a.lotOccupancies.length)return void(e.innerHTML='<div class="message is-info"><p class="message-body">There are no '+cityssm.escapeHTML(exports.aliases.occupancy.toLowerCase())+" records that meet the search criteria.</p></div>");const c=document.createElement("tbody"),r=cityssm.dateToString(new Date);for(const e of a.lotOccupancies){let a="";a=e.occupancyStartDateString<=r&&(""===e.occupancyEndDateString||e.occupancyEndDateString>=r)?'<span class="has-tooltip-right" data-tooltip="Current '+exports.aliases.occupancy+'"><i class="fas fa-play" aria-label="Current '+exports.aliases.occupancy+'"></i></span>':e.occupancyStartDateString>r?'<span class="has-tooltip-right" data-tooltip="Future '+exports.aliases.occupancy+'"><i class="fas fa-fast-forward" aria-label="Future '+exports.aliases.occupancy+'"></i></span>':'<span class="has-tooltip-right" data-tooltip="Past '+exports.aliases.occupancy+'"><i class="fas fa-stop" aria-label="Past '+exports.aliases.occupancy+'"></i></span>';let s="";for(const t of e.lotOccupancyOccupants)s+='<span class="has-tooltip-left" data-tooltip="'+cityssm.escapeHTML(t.lotOccupantType||"")+'"><i class="fas fa-fw fa-'+cityssm.escapeHTML(t.fontAwesomeIconClass||"user")+'" aria-hidden="true"></i> '+cityssm.escapeHTML(t.occupantName||"")+"</span><br />";c.insertAdjacentHTML("beforeend",'<tr><td class="has-width-1">'+a+'</td><td><a class="has-text-weight-bold" href="'+t.urlPrefix+"/lotOccupancies/"+e.lotOccupancyId+'">'+cityssm.escapeHTML(e.occupancyType)+"</a></td><td>"+(e.lotName?'<a class="has-tooltip-right" data-tooltip="'+cityssm.escapeHTML(e.lotType||"")+'" href="'+t.urlPrefix+"/lots/"+e.lotId+'">'+cityssm.escapeHTML(e.lotName)+"</a>":'<span class="has-text-grey">(No '+cityssm.escapeHTML(exports.aliases.lot)+")</span>")+'<br /><span class="is-size-7">'+cityssm.escapeHTML(e.mapName||"")+"</span></td><td>"+e.occupancyStartDateString+"</td><td>"+(e.occupancyEndDate?e.occupancyEndDateString:'<span class="has-text-grey">(No End Date)</span>')+"</td><td>"+s+"</td><td>"+(e.printEJS?'<a class="button is-small" data-tooltip="Print" href="'+t.urlPrefix+"/print/"+e.printEJS+"/?lotOccupancyId="+e.lotOccupancyId+'" target="_blank"><i class="fas fa-print" aria-label="Print"></i></a>':"")+"</td></tr>")}e.innerHTML='<table class="table is-fullwidth is-striped is-hoverable has-sticky-header"><thead><tr><th class="has-width-1"></th><th>'+cityssm.escapeHTML(exports.aliases.occupancy)+" Type</th><th>"+cityssm.escapeHTML(exports.aliases.lot)+"</th><th>"+cityssm.escapeHTML(exports.aliases.occupancyStartDate)+"</th><th>End Date</th><th>"+cityssm.escapeHTML(exports.aliases.occupants)+'</th><th class="has-width-1"><span class="is-sr-only">Print</span></th></tr></thead><table><div class="level"><div class="level-left"><div class="level-item has-text-weight-bold">Displaying '+(i+1).toString()+" to "+Math.min(a.count,s+i)+" of "+a.count+'</div></div><div class="level-right">'+(i>0?'<div class="level-item"><button class="button is-rounded is-link is-outlined" data-page="previous" type="button" title="Previous"><i class="fas fa-arrow-left" aria-hidden="true"></i></button></div>':"")+(s+i<a.count?'<div class="level-item"><button class="button is-rounded is-link" data-page="next" type="button" title="Next"><span>Next</span><span class="icon"><i class="fas fa-arrow-right" aria-hidden="true"></i></span></button></div>':"")+"</div></div>",e.querySelector("table").append(c),i>0&&e.querySelector("button[data-page='previous']").addEventListener("click",o),s+i<a.count&&e.querySelector("button[data-page='next']").addEventListener("click",n)})},r=()=>{c.value="0",i()},o=()=>{c.value=Math.max(Number.parseInt(c.value,10)-s,0).toString(),i()},n=()=>{c.value=(Number.parseInt(c.value,10)+s).toString(),i()},l=a.querySelectorAll("input, select");for(const t of l)t.addEventListener("change",r);a.addEventListener("submit",t=>{t.preventDefault(),r()}),i()})();

View File

@ -80,6 +80,7 @@ export interface OccupancyType extends Record {
occupancyType: string; occupancyType: string;
orderNumber?: number; orderNumber?: number;
occupancyTypeFields?: OccupancyTypeField[]; occupancyTypeFields?: OccupancyTypeField[];
occupancyTypePrints?: string[];
} }
export interface OccupancyTypeField { export interface OccupancyTypeField {
occupancyTypeFieldId?: number; occupancyTypeFieldId?: number;
@ -178,6 +179,7 @@ export interface LotOccupancy extends Record {
lotOccupancyId?: number; lotOccupancyId?: number;
occupancyTypeId?: number; occupancyTypeId?: number;
occupancyType?: string; occupancyType?: string;
printEJS?: string;
lotId?: number; lotId?: number;
lotTypeId?: number; lotTypeId?: number;
lotType?: string; lotType?: string;

View File

@ -108,6 +108,7 @@ export interface OccupancyType extends Record {
occupancyType: string; occupancyType: string;
orderNumber?: number; orderNumber?: number;
occupancyTypeFields?: OccupancyTypeField[]; occupancyTypeFields?: OccupancyTypeField[];
occupancyTypePrints?: string[];
} }
export interface OccupancyTypeField { export interface OccupancyTypeField {
@ -236,6 +237,7 @@ export interface LotOccupancy extends Record {
occupancyTypeId?: number; occupancyTypeId?: number;
occupancyType?: string; occupancyType?: string;
printEJS?: string;
lotId?: number; lotId?: number;
lotTypeId?: number; lotTypeId?: number;

View File

@ -46,10 +46,10 @@
</h1> </h1>
</div> </div>
</div> </div>
<% if (configFunctions.getProperty("settings.lotOccupancy.prints").length > 0) { %> <% if (occupancyTypePrints.length > 0) { %>
<div class="level-right is-hidden-print"> <div class="level-right is-hidden-print">
<div class="level-item is-justify-content-right"> <div class="level-item is-justify-content-right">
<% if (configFunctions.getProperty("settings.lotOccupancy.prints").length === 1) { %> <% if (occupancyTypePrints.length === 1) { %>
<a class="button is-link" href="<%= urlPrefix %>/print/<%= configFunctions.getProperty("settings.lotOccupancy.prints")[0] %>/?lotOccupancyId=<%= lotOccupancy.lotOccupancyId %>" target="_blank"> <a class="button is-link" href="<%= urlPrefix %>/print/<%= configFunctions.getProperty("settings.lotOccupancy.prints")[0] %>/?lotOccupancyId=<%= lotOccupancy.lotOccupancyId %>" target="_blank">
<span class="icon is-small"><i class="fas fa-print" aria-hidden="true"></i></span> <span class="icon is-small"><i class="fas fa-print" aria-hidden="true"></i></span>
<span>Print</span> <span>Print</span>
@ -65,7 +65,7 @@
</div> </div>
<div class="dropdown-menu"> <div class="dropdown-menu">
<div class="dropdown-content"> <div class="dropdown-content">
<% for (const printName of configFunctions.getProperty("settings.lotOccupancy.prints")) { %> <% for (const printName of occupancyTypePrints) { %>
<% const printConfig = printFunctions.getPrintConfig(printName); %> <% const printConfig = printFunctions.getPrintConfig(printName); %>
<% if (printConfig) { %> <% if (printConfig) { %>
<a class="dropdown-item" href="<%= urlPrefix %>/print/<%= printName %>/?lotOccupancyId=<%= lotOccupancy.lotOccupancyId %>" target="_blank"> <a class="dropdown-item" href="<%= urlPrefix %>/print/<%= printName %>/?lotOccupancyId=<%= lotOccupancy.lotOccupancyId %>" target="_blank">

View File

@ -151,9 +151,6 @@
<%- include('_footerA'); -%> <%- include('_footerA'); -%>
<script>
exports.lotOccupancyPrints = <%- JSON.stringify(configFunctions.getProperty("settings.lotOccupancy.prints")) %>;
</script>
<script src="<%= urlPrefix %>/javascripts/lotOccupancySearch.min.js"></script> <script src="<%= urlPrefix %>/javascripts/lotOccupancySearch.min.js"></script>
<%- include('_footerB'); -%> <%- include('_footerB'); -%>

View File

@ -31,11 +31,11 @@
</h1> </h1>
</div> </div>
</div> </div>
<% if (configFunctions.getProperty("settings.lotOccupancy.prints").length > 0) { %> <% if (occupancyTypePrints.length > 0) { %>
<div class="level-right is-hidden-print"> <div class="level-right is-hidden-print">
<div class="level-item is-justify-content-right"> <div class="level-item is-justify-content-right">
<% if (configFunctions.getProperty("settings.lotOccupancy.prints").length === 1) { %> <% if (occupancyTypePrints.length === 1) { %>
<a class="button is-link" href="<%= urlPrefix %>/print/<%= configFunctions.getProperty("settings.lotOccupancy.prints")[0] %>/?lotOccupancyId=<%= lotOccupancy.lotOccupancyId %>" target="_blank"> <a class="button is-link" href="<%= urlPrefix %>/print/<%= occupancyTypePrints[0] %>/?lotOccupancyId=<%= lotOccupancy.lotOccupancyId %>" target="_blank">
<span class="icon is-small"><i class="fas fa-print" aria-hidden="true"></i></span> <span class="icon is-small"><i class="fas fa-print" aria-hidden="true"></i></span>
<span>Print</span> <span>Print</span>
</a> </a>
@ -50,7 +50,7 @@
</div> </div>
<div class="dropdown-menu"> <div class="dropdown-menu">
<div class="dropdown-content"> <div class="dropdown-content">
<% for (const printName of configFunctions.getProperty("settings.lotOccupancy.prints")) { %> <% for (const printName of occupancyTypePrints) { %>
<% const printConfig = printFunctions.getPrintConfig(printName); %> <% const printConfig = printFunctions.getPrintConfig(printName); %>
<% if (printConfig) { %> <% if (printConfig) { %>
<a class="dropdown-item" href="<%= urlPrefix %>/print/<%= printName %>/?lotOccupancyId=<%= lotOccupancy.lotOccupancyId %>" target="_blank"> <a class="dropdown-item" href="<%= urlPrefix %>/print/<%= printName %>/?lotOccupancyId=<%= lotOccupancy.lotOccupancyId %>" target="_blank">