development
parent
4a35da4b13
commit
ea41b0e5e7
|
|
@ -9,6 +9,11 @@ export const config = {
|
||||||
lots: "Burial Sites",
|
lots: "Burial Sites",
|
||||||
map: "Cemetery",
|
map: "Cemetery",
|
||||||
maps: "Cemeteries"
|
maps: "Cemeteries"
|
||||||
|
},
|
||||||
|
settings: {
|
||||||
|
lotOccupancy: {
|
||||||
|
occupancyEndDateIsRequired: false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
export default config;
|
export default config;
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,11 @@ export const config: Config = {
|
||||||
lots: "Burial Sites",
|
lots: "Burial Sites",
|
||||||
map: "Cemetery",
|
map: "Cemetery",
|
||||||
maps: "Cemeteries"
|
maps: "Cemeteries"
|
||||||
|
},
|
||||||
|
settings: {
|
||||||
|
lotOccupancy: {
|
||||||
|
occupancyEndDateIsRequired: false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { getOccupancyTypes } 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) => {
|
||||||
|
|
@ -5,9 +6,12 @@ export const handler = (request, response) => {
|
||||||
if (!lotOccupancy) {
|
if (!lotOccupancy) {
|
||||||
return response.redirect(configFunctions.getProperty("reverseProxy.urlPrefix") + "/lotOccupancies/?error=lotOccupancyIdNotFound");
|
return response.redirect(configFunctions.getProperty("reverseProxy.urlPrefix") + "/lotOccupancies/?error=lotOccupancyIdNotFound");
|
||||||
}
|
}
|
||||||
|
const occupancyTypes = getOccupancyTypes();
|
||||||
return response.render("lotOccupancy-edit", {
|
return response.render("lotOccupancy-edit", {
|
||||||
headTitle: configFunctions.getProperty("aliases.lot") + " " + configFunctions.getProperty("aliases.occupancy") + " View",
|
headTitle: configFunctions.getProperty("aliases.lot") + " " + configFunctions.getProperty("aliases.occupancy") + " Update",
|
||||||
lotOccupancy
|
lotOccupancy,
|
||||||
|
occupancyTypes,
|
||||||
|
isCreate: false
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
export default handler;
|
export default handler;
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,36 @@
|
||||||
import type { RequestHandler } from "express";
|
import type {
|
||||||
|
RequestHandler
|
||||||
|
} from "express";
|
||||||
|
|
||||||
|
import {
|
||||||
|
getOccupancyTypes
|
||||||
|
} from "../../helpers/functions.cache.js";
|
||||||
|
|
||||||
import * as configFunctions from "../../helpers/functions.config.js";
|
import * as configFunctions from "../../helpers/functions.config.js";
|
||||||
|
|
||||||
import { getLotOccupancy } from "../../helpers/lotOccupancyDB/getLotOccupancy.js";
|
import {
|
||||||
|
getLotOccupancy
|
||||||
|
} from "../../helpers/lotOccupancyDB/getLotOccupancy.js";
|
||||||
|
|
||||||
|
|
||||||
export const handler: RequestHandler = (request, response) => {
|
export const handler: RequestHandler = (request, response) => {
|
||||||
|
|
||||||
const lotOccupancy = getLotOccupancy(request.params.lotOccupancyId);
|
const lotOccupancy = getLotOccupancy(request.params.lotOccupancyId);
|
||||||
|
|
||||||
if (!lotOccupancy) {
|
if (!lotOccupancy) {
|
||||||
return response.redirect(configFunctions.getProperty("reverseProxy.urlPrefix") + "/lotOccupancies/?error=lotOccupancyIdNotFound");
|
return response.redirect(configFunctions.getProperty("reverseProxy.urlPrefix") + "/lotOccupancies/?error=lotOccupancyIdNotFound");
|
||||||
}
|
}
|
||||||
|
|
||||||
return response.render("lotOccupancy-edit", {
|
const occupancyTypes = getOccupancyTypes();
|
||||||
headTitle: configFunctions.getProperty("aliases.lot") + " " + configFunctions.getProperty("aliases.occupancy") + " View",
|
|
||||||
lotOccupancy
|
return response.render("lotOccupancy-edit", {
|
||||||
});
|
headTitle: configFunctions.getProperty("aliases.lot") + " " + configFunctions.getProperty("aliases.occupancy") + " Update",
|
||||||
|
lotOccupancy,
|
||||||
|
|
||||||
|
occupancyTypes,
|
||||||
|
isCreate: false
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
export default handler;
|
export default handler;
|
||||||
|
|
@ -1,23 +1,27 @@
|
||||||
import type { RequestHandler } from "express";
|
import type {
|
||||||
|
RequestHandler
|
||||||
|
} from "express";
|
||||||
|
|
||||||
import * as configFunctions from "../../helpers/functions.config.js";
|
import * as configFunctions from "../../helpers/functions.config.js";
|
||||||
|
|
||||||
import { getLotOccupancy } from "../../helpers/lotOccupancyDB/getLotOccupancy.js";
|
import {
|
||||||
|
getLotOccupancy
|
||||||
|
} from "../../helpers/lotOccupancyDB/getLotOccupancy.js";
|
||||||
|
|
||||||
|
|
||||||
export const handler: RequestHandler = (request, response) => {
|
export const handler: RequestHandler = (request, response) => {
|
||||||
|
|
||||||
const lotOccupancy = getLotOccupancy(request.params.lotOccupancyId);
|
const lotOccupancy = getLotOccupancy(request.params.lotOccupancyId);
|
||||||
|
|
||||||
if (!lotOccupancy) {
|
if (!lotOccupancy) {
|
||||||
return response.redirect(configFunctions.getProperty("reverseProxy.urlPrefix") + "/lotOccupancies/?error=lotOccupancyIdNotFound");
|
return response.redirect(configFunctions.getProperty("reverseProxy.urlPrefix") + "/lotOccupancies/?error=lotOccupancyIdNotFound");
|
||||||
}
|
}
|
||||||
|
|
||||||
return response.render("lotOccupancy-view", {
|
return response.render("lotOccupancy-view", {
|
||||||
headTitle: configFunctions.getProperty("aliases.lot") + " " + configFunctions.getProperty("aliases.occupancy") + " View",
|
headTitle: configFunctions.getProperty("aliases.lot") + " " + configFunctions.getProperty("aliases.occupancy") + " View",
|
||||||
lotOccupancy
|
lotOccupancy
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
export default handler;
|
export default handler;
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
import type { RequestHandler } from "express";
|
||||||
|
export declare const handler: RequestHandler;
|
||||||
|
export default handler;
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
import { updateLotOccupancy } from "../../helpers/lotOccupancyDB/updateLotOccupancy.js";
|
||||||
|
export const handler = async (request, response) => {
|
||||||
|
const success = updateLotOccupancy(request.body, request.session);
|
||||||
|
response.json({
|
||||||
|
success,
|
||||||
|
lotOccupancyId: request.body.lotOccupancyId
|
||||||
|
});
|
||||||
|
};
|
||||||
|
export default handler;
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
import type { RequestHandler } from "express";
|
||||||
|
|
||||||
|
import { updateLotOccupancy } from "../../helpers/lotOccupancyDB/updateLotOccupancy.js";
|
||||||
|
|
||||||
|
|
||||||
|
export const handler: RequestHandler = async (request, response) => {
|
||||||
|
|
||||||
|
const success = updateLotOccupancy(request.body, request.session);
|
||||||
|
|
||||||
|
response.json({
|
||||||
|
success,
|
||||||
|
lotOccupancyId: request.body.lotOccupancyId
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
export default handler;
|
||||||
|
|
@ -23,4 +23,5 @@ export declare function getProperty(propertyName: "aliases.occupancy"): string;
|
||||||
export declare function getProperty(propertyName: "aliases.occupancies"): string;
|
export declare function getProperty(propertyName: "aliases.occupancies"): string;
|
||||||
export declare function getProperty(propertyName: "aliases.occupant"): string;
|
export declare function getProperty(propertyName: "aliases.occupant"): string;
|
||||||
export declare function getProperty(propertyName: "aliases.occupants"): string;
|
export declare function getProperty(propertyName: "aliases.occupants"): string;
|
||||||
|
export declare function getProperty(propertyName: "settings.lotOccupancy.occupancyEndDateIsRequired"): boolean;
|
||||||
export declare const keepAliveMillis: number;
|
export declare const keepAliveMillis: number;
|
||||||
|
|
|
||||||
|
|
@ -23,19 +23,19 @@ configFallbackValues.set("aliases.occupancy", "Occupancy");
|
||||||
configFallbackValues.set("aliases.occupancies", "Occupancies");
|
configFallbackValues.set("aliases.occupancies", "Occupancies");
|
||||||
configFallbackValues.set("aliases.occupant", "Occupant");
|
configFallbackValues.set("aliases.occupant", "Occupant");
|
||||||
configFallbackValues.set("aliases.occupants", "Occupants");
|
configFallbackValues.set("aliases.occupants", "Occupants");
|
||||||
|
configFallbackValues.set("settings.lotOccupancy.occupancyEndDateIsRequired", true);
|
||||||
export function getProperty(propertyName) {
|
export function getProperty(propertyName) {
|
||||||
const propertyNameSplit = propertyName.split(".");
|
const propertyNameSplit = propertyName.split(".");
|
||||||
let currentObject = config;
|
let currentObject = config;
|
||||||
for (const propertyNamePiece of propertyNameSplit) {
|
for (const propertyNamePiece of propertyNameSplit) {
|
||||||
if (currentObject[propertyNamePiece]) {
|
if (Object.prototype.hasOwnProperty.call(currentObject, propertyNamePiece)) {
|
||||||
currentObject = currentObject[propertyNamePiece];
|
currentObject = currentObject[propertyNamePiece];
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
else {
|
return configFallbackValues.get(propertyName);
|
||||||
return configFallbackValues.get(propertyName);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return currentObject;
|
return currentObject;
|
||||||
}
|
}
|
||||||
export const keepAliveMillis = getProperty("session.doKeepAlive")
|
export const keepAliveMillis = getProperty("session.doKeepAlive") ?
|
||||||
? Math.max(getProperty("session.maxAgeMillis") / 2, getProperty("session.maxAgeMillis") - (10 * 60 * 1000))
|
Math.max(getProperty("session.maxAgeMillis") / 2, getProperty("session.maxAgeMillis") - (10 * 60 * 1000)) :
|
||||||
: 0;
|
0;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
// eslint-disable-next-line node/no-unpublished-import
|
// eslint-disable-next-line node/no-unpublished-import
|
||||||
import { config } from "../data/config.js";
|
import {
|
||||||
|
config
|
||||||
|
} from "../data/config.js";
|
||||||
|
|
||||||
import type * as configTypes from "../types/configTypes";
|
import type * as configTypes from "../types/configTypes";
|
||||||
|
|
||||||
|
|
@ -8,7 +10,8 @@ import type * as configTypes from "../types/configTypes";
|
||||||
* SET UP FALLBACK VALUES
|
* SET UP FALLBACK VALUES
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const configFallbackValues = new Map<string, unknown>();
|
const configFallbackValues = new Map < string,
|
||||||
|
unknown > ();
|
||||||
|
|
||||||
configFallbackValues.set("application.applicationName", "Lot Occupancy System");
|
configFallbackValues.set("application.applicationName", "Lot Occupancy System");
|
||||||
configFallbackValues.set("application.backgroundURL", "/images/cemetery-background.jpg");
|
configFallbackValues.set("application.backgroundURL", "/images/cemetery-background.jpg");
|
||||||
|
|
@ -38,6 +41,8 @@ configFallbackValues.set("aliases.occupancies", "Occupancies");
|
||||||
configFallbackValues.set("aliases.occupant", "Occupant");
|
configFallbackValues.set("aliases.occupant", "Occupant");
|
||||||
configFallbackValues.set("aliases.occupants", "Occupants");
|
configFallbackValues.set("aliases.occupants", "Occupants");
|
||||||
|
|
||||||
|
configFallbackValues.set("settings.lotOccupancy.occupancyEndDateIsRequired", true);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set up function overloads
|
* Set up function overloads
|
||||||
|
|
@ -73,29 +78,31 @@ export function getProperty(propertyName: "aliases.occupancies"): string;
|
||||||
export function getProperty(propertyName: "aliases.occupant"): string;
|
export function getProperty(propertyName: "aliases.occupant"): string;
|
||||||
export function getProperty(propertyName: "aliases.occupants"): string;
|
export function getProperty(propertyName: "aliases.occupants"): string;
|
||||||
|
|
||||||
|
export function getProperty(propertyName: "settings.lotOccupancy.occupancyEndDateIsRequired"): boolean;
|
||||||
|
|
||||||
export function getProperty(propertyName: string): unknown {
|
export function getProperty(propertyName: string): unknown {
|
||||||
|
|
||||||
const propertyNameSplit = propertyName.split(".");
|
const propertyNameSplit = propertyName.split(".");
|
||||||
|
|
||||||
let currentObject = config;
|
let currentObject = config;
|
||||||
|
|
||||||
for (const propertyNamePiece of propertyNameSplit) {
|
for (const propertyNamePiece of propertyNameSplit) {
|
||||||
|
|
||||||
if (currentObject[propertyNamePiece]) {
|
if (Object.prototype.hasOwnProperty.call(currentObject, propertyNamePiece)) {
|
||||||
currentObject = currentObject[propertyNamePiece];
|
currentObject = currentObject[propertyNamePiece];
|
||||||
} else {
|
continue;
|
||||||
return configFallbackValues.get(propertyName);
|
}
|
||||||
|
|
||||||
|
return configFallbackValues.get(propertyName);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return currentObject;
|
|
||||||
|
|
||||||
|
return currentObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const keepAliveMillis =
|
export const keepAliveMillis =
|
||||||
getProperty("session.doKeepAlive")
|
getProperty("session.doKeepAlive") ?
|
||||||
? Math.max(
|
Math.max(
|
||||||
getProperty("session.maxAgeMillis") / 2,
|
getProperty("session.maxAgeMillis") / 2,
|
||||||
getProperty("session.maxAgeMillis") - (10 * 60 * 1000)
|
getProperty("session.maxAgeMillis") - (10 * 60 * 1000)
|
||||||
)
|
) :
|
||||||
: 0;
|
0;
|
||||||
|
|
@ -2,6 +2,10 @@ import { dateIntegerToString } from "@cityssm/expressjs-server-js/dateTimeFns.js
|
||||||
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 { getLotOccupancyOccupants } from "./getLotOccupancyOccupants.js";
|
import { getLotOccupancyOccupants } from "./getLotOccupancyOccupants.js";
|
||||||
|
import { getLotOccupancyComments } from "./getLotOccupancyComments.js";
|
||||||
|
import { getLotOccupancyFields } from "./getLotOccupancyFields.js";
|
||||||
|
import { getLotOccupancyFees } from "./getLotOccupancyFees.js";
|
||||||
|
import { getLotOccupancyTransactions } from "./getLotOccupancyTransactions.js";
|
||||||
export const getLotOccupancy = (lotOccupancyId) => {
|
export const getLotOccupancy = (lotOccupancyId) => {
|
||||||
const database = sqlite(databasePath, {
|
const database = sqlite(databasePath, {
|
||||||
readonly: true
|
readonly: true
|
||||||
|
|
@ -22,7 +26,11 @@ export const getLotOccupancy = (lotOccupancyId) => {
|
||||||
" and o.lotOccupancyId = ?")
|
" and o.lotOccupancyId = ?")
|
||||||
.get(lotOccupancyId);
|
.get(lotOccupancyId);
|
||||||
if (lotOccupancy) {
|
if (lotOccupancy) {
|
||||||
|
lotOccupancy.lotOccupancyFields = getLotOccupancyFields(lotOccupancyId, database);
|
||||||
lotOccupancy.lotOccupancyOccupants = getLotOccupancyOccupants(lotOccupancyId, database);
|
lotOccupancy.lotOccupancyOccupants = getLotOccupancyOccupants(lotOccupancyId, database);
|
||||||
|
lotOccupancy.lotOccupancyComments = getLotOccupancyComments(lotOccupancyId, database);
|
||||||
|
lotOccupancy.lotOccupancyFees = getLotOccupancyFees(lotOccupancyId, database);
|
||||||
|
lotOccupancy.lotOccupancyTransactions = getLotOccupancyTransactions(lotOccupancyId, database);
|
||||||
}
|
}
|
||||||
database.close();
|
database.close();
|
||||||
return lotOccupancy;
|
return lotOccupancy;
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,22 @@ import {
|
||||||
getLotOccupancyOccupants
|
getLotOccupancyOccupants
|
||||||
} from "./getLotOccupancyOccupants.js";
|
} from "./getLotOccupancyOccupants.js";
|
||||||
|
|
||||||
|
import {
|
||||||
|
getLotOccupancyComments
|
||||||
|
} from "./getLotOccupancyComments.js";
|
||||||
|
|
||||||
|
import {
|
||||||
|
getLotOccupancyFields
|
||||||
|
} from "./getLotOccupancyFields.js";
|
||||||
|
|
||||||
|
import {
|
||||||
|
getLotOccupancyFees
|
||||||
|
} from "./getLotOccupancyFees.js";
|
||||||
|
|
||||||
|
import {
|
||||||
|
getLotOccupancyTransactions
|
||||||
|
} from "./getLotOccupancyTransactions.js";
|
||||||
|
|
||||||
import type * as recordTypes from "../../types/recordTypes";
|
import type * as recordTypes from "../../types/recordTypes";
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -40,7 +56,11 @@ export const getLotOccupancy = (lotOccupancyId: number | string): recordTypes.Lo
|
||||||
.get(lotOccupancyId);
|
.get(lotOccupancyId);
|
||||||
|
|
||||||
if (lotOccupancy) {
|
if (lotOccupancy) {
|
||||||
|
lotOccupancy.lotOccupancyFields = getLotOccupancyFields(lotOccupancyId, database);
|
||||||
lotOccupancy.lotOccupancyOccupants = getLotOccupancyOccupants(lotOccupancyId, database);
|
lotOccupancy.lotOccupancyOccupants = getLotOccupancyOccupants(lotOccupancyId, database);
|
||||||
|
lotOccupancy.lotOccupancyComments = getLotOccupancyComments(lotOccupancyId, database);
|
||||||
|
lotOccupancy.lotOccupancyFees = getLotOccupancyFees(lotOccupancyId, database);
|
||||||
|
lotOccupancy.lotOccupancyTransactions = getLotOccupancyTransactions(lotOccupancyId, database);
|
||||||
}
|
}
|
||||||
|
|
||||||
database.close();
|
database.close();
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
import sqlite from "better-sqlite3";
|
||||||
|
import type * as recordTypes from "../../types/recordTypes";
|
||||||
|
export declare const getLotOccupancyFees: (lotOccupancyId: number | string, connectedDatabase?: sqlite.Database) => recordTypes.LotOccupancyFee[];
|
||||||
|
export default getLotOccupancyFees;
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
import sqlite from "better-sqlite3";
|
||||||
|
import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js";
|
||||||
|
export const getLotOccupancyFees = (lotOccupancyId, connectedDatabase) => {
|
||||||
|
const database = connectedDatabase || sqlite(databasePath, {
|
||||||
|
readonly: true
|
||||||
|
});
|
||||||
|
const lotOccupancyFees = database
|
||||||
|
.prepare("select o.lotOccupancyId, o.feeId, o.feeAmount," +
|
||||||
|
" f.feeName" +
|
||||||
|
" from LotOccupancyFees o" +
|
||||||
|
" left join Fees f on o.feeId = f.feeId" +
|
||||||
|
" where o.recordDelete_timeMillis is null" +
|
||||||
|
" and o.lotOccupancyId = ?" +
|
||||||
|
" order by o.recordCreate_timeMillis")
|
||||||
|
.all(lotOccupancyId);
|
||||||
|
if (!connectedDatabase) {
|
||||||
|
database.close();
|
||||||
|
}
|
||||||
|
return lotOccupancyFees;
|
||||||
|
};
|
||||||
|
export default getLotOccupancyFees;
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
import sqlite from "better-sqlite3";
|
||||||
|
|
||||||
|
import {
|
||||||
|
lotOccupancyDB as databasePath
|
||||||
|
} from "../../data/databasePaths.js";
|
||||||
|
|
||||||
|
import type * as recordTypes from "../../types/recordTypes";
|
||||||
|
|
||||||
|
|
||||||
|
export const getLotOccupancyFees = (lotOccupancyId: number | string,
|
||||||
|
connectedDatabase ? : sqlite.Database): recordTypes.LotOccupancyFee[] => {
|
||||||
|
|
||||||
|
const database = connectedDatabase || sqlite(databasePath, {
|
||||||
|
readonly: true
|
||||||
|
});
|
||||||
|
|
||||||
|
const lotOccupancyFees: recordTypes.LotOccupancyFee[] = database
|
||||||
|
.prepare("select o.lotOccupancyId, o.feeId, o.feeAmount," +
|
||||||
|
" f.feeName" +
|
||||||
|
" from LotOccupancyFees o" +
|
||||||
|
" left join Fees f on o.feeId = f.feeId" +
|
||||||
|
" where o.recordDelete_timeMillis is null" +
|
||||||
|
" and o.lotOccupancyId = ?" +
|
||||||
|
" order by o.recordCreate_timeMillis")
|
||||||
|
.all(lotOccupancyId);
|
||||||
|
|
||||||
|
if (!connectedDatabase) {
|
||||||
|
database.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
return lotOccupancyFees;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
export default getLotOccupancyFees;
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
import sqlite from "better-sqlite3";
|
||||||
|
import type * as recordTypes from "../../types/recordTypes";
|
||||||
|
export declare const getLotOccupancyFields: (lotOccupancyId: number | string, connectedDatabase?: sqlite.Database) => recordTypes.LotOccupancyField[];
|
||||||
|
export default getLotOccupancyFields;
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
import sqlite from "better-sqlite3";
|
||||||
|
import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js";
|
||||||
|
export const getLotOccupancyFields = (lotOccupancyId, connectedDatabase) => {
|
||||||
|
const database = connectedDatabase || sqlite(databasePath, {
|
||||||
|
readonly: true
|
||||||
|
});
|
||||||
|
const lotOccupancyFields = database
|
||||||
|
.prepare("select o.lotOccupancyId," +
|
||||||
|
" o.occupancyTypeFieldId, o.lotOccupancyFieldValue," +
|
||||||
|
" f.occupancyTypeField, f.orderNumber" +
|
||||||
|
" from LotOccupancyFields o" +
|
||||||
|
" left join OccupancyTypeFields f on o.occupancyTypeFieldId = f.occupancyTypeFieldId" +
|
||||||
|
" where o.recordDelete_timeMillis is null" +
|
||||||
|
" and o.lotOccupancyId = ?" +
|
||||||
|
" union" +
|
||||||
|
" select ? as lotOccupancyId," +
|
||||||
|
" f.occupancyTypeFieldId, '' as lotOccupancyFieldValue," +
|
||||||
|
" f.occupancyTypeField, f.orderNumber" +
|
||||||
|
" from OccupancyTypeFields f" +
|
||||||
|
" where f.recordDelete_timeMillis is null" +
|
||||||
|
" and f.occupancyTypeId in (select occupancyTypeId from LotOccupancies where lotOccupancyId = ?)" +
|
||||||
|
" and f.occupancyTypeFieldId not in (select occupancyTypeFieldId from LotOccupancyFields where lotOccupancyId = ?)" +
|
||||||
|
" order by orderNumber, occupancyTypeField")
|
||||||
|
.all(lotOccupancyId, lotOccupancyId, lotOccupancyId, lotOccupancyId);
|
||||||
|
if (!connectedDatabase) {
|
||||||
|
database.close();
|
||||||
|
}
|
||||||
|
return lotOccupancyFields;
|
||||||
|
};
|
||||||
|
export default getLotOccupancyFields;
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
import sqlite from "better-sqlite3";
|
||||||
|
|
||||||
|
import {
|
||||||
|
lotOccupancyDB as databasePath
|
||||||
|
} from "../../data/databasePaths.js";
|
||||||
|
|
||||||
|
import type * as recordTypes from "../../types/recordTypes";
|
||||||
|
|
||||||
|
|
||||||
|
export const getLotOccupancyFields = (lotOccupancyId: number | string,
|
||||||
|
connectedDatabase ? : sqlite.Database): recordTypes.LotOccupancyField[] => {
|
||||||
|
|
||||||
|
const database = connectedDatabase || sqlite(databasePath, {
|
||||||
|
readonly: true
|
||||||
|
});
|
||||||
|
|
||||||
|
const lotOccupancyFields: recordTypes.LotOccupancyField[] = database
|
||||||
|
.prepare("select o.lotOccupancyId," +
|
||||||
|
" o.occupancyTypeFieldId, o.lotOccupancyFieldValue," +
|
||||||
|
" f.occupancyTypeField, f.orderNumber" +
|
||||||
|
" from LotOccupancyFields o" +
|
||||||
|
" left join OccupancyTypeFields f on o.occupancyTypeFieldId = f.occupancyTypeFieldId" +
|
||||||
|
" where o.recordDelete_timeMillis is null" +
|
||||||
|
" and o.lotOccupancyId = ?" +
|
||||||
|
" union" +
|
||||||
|
" select ? as lotOccupancyId," +
|
||||||
|
" f.occupancyTypeFieldId, '' as lotOccupancyFieldValue," +
|
||||||
|
" f.occupancyTypeField, f.orderNumber" +
|
||||||
|
" from OccupancyTypeFields f" +
|
||||||
|
" where f.recordDelete_timeMillis is null" +
|
||||||
|
" and f.occupancyTypeId in (select occupancyTypeId from LotOccupancies where lotOccupancyId = ?)" +
|
||||||
|
" and f.occupancyTypeFieldId not in (select occupancyTypeFieldId from LotOccupancyFields where lotOccupancyId = ?)" +
|
||||||
|
" order by orderNumber, occupancyTypeField")
|
||||||
|
.all(lotOccupancyId, lotOccupancyId, lotOccupancyId, lotOccupancyId);
|
||||||
|
|
||||||
|
if (!connectedDatabase) {
|
||||||
|
database.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
return lotOccupancyFields;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
export default getLotOccupancyFields;
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import sqlite from "better-sqlite3";
|
import sqlite from "better-sqlite3";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
lotOccupancyDB as databasePath
|
lotOccupancyDB as databasePath
|
||||||
} from "../../data/databasePaths.js";
|
} from "../../data/databasePaths.js";
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
import sqlite from "better-sqlite3";
|
||||||
|
import type * as recordTypes from "../../types/recordTypes";
|
||||||
|
export declare const getLotOccupancyTransactions: (lotOccupancyId: number | string, connectedDatabase?: sqlite.Database) => recordTypes.LotOccupancyTransaction[];
|
||||||
|
export default getLotOccupancyTransactions;
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
import { dateIntegerToString, timeIntegerToString } from "@cityssm/expressjs-server-js/dateTimeFns.js";
|
||||||
|
import sqlite from "better-sqlite3";
|
||||||
|
import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js";
|
||||||
|
export const getLotOccupancyTransactions = (lotOccupancyId, connectedDatabase) => {
|
||||||
|
const database = connectedDatabase || sqlite(databasePath, {
|
||||||
|
readonly: true
|
||||||
|
});
|
||||||
|
database.function("userFn_dateIntegerToString", dateIntegerToString);
|
||||||
|
database.function("userFn_timeIntegerToString", timeIntegerToString);
|
||||||
|
const lotOccupancyTransactions = database
|
||||||
|
.prepare("select lotOccupancyId, transactionIndex," +
|
||||||
|
" transactionDate, userFn_dateIntegerToString(transactionDate) as transactionDateString," +
|
||||||
|
" transactionTime, userFn_timeIntegerToString(transactionTime) as transactionTimeString," +
|
||||||
|
" transactionAmount, externalReceiptNumber, transactionNote" +
|
||||||
|
" from LotOccupancyTransactions" +
|
||||||
|
" where recordDelete_timeMillis is null" +
|
||||||
|
" and lotOccupancyId = ?" +
|
||||||
|
" order by transactionDate, transactionTime, transactionIndex")
|
||||||
|
.all(lotOccupancyId);
|
||||||
|
if (!connectedDatabase) {
|
||||||
|
database.close();
|
||||||
|
}
|
||||||
|
return lotOccupancyTransactions;
|
||||||
|
};
|
||||||
|
export default getLotOccupancyTransactions;
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
import { dateIntegerToString, timeIntegerToString } from "@cityssm/expressjs-server-js/dateTimeFns.js";
|
||||||
|
import sqlite from "better-sqlite3";
|
||||||
|
|
||||||
|
import {
|
||||||
|
lotOccupancyDB as databasePath
|
||||||
|
} from "../../data/databasePaths.js";
|
||||||
|
|
||||||
|
import type * as recordTypes from "../../types/recordTypes";
|
||||||
|
|
||||||
|
|
||||||
|
export const getLotOccupancyTransactions = (lotOccupancyId: number | string,
|
||||||
|
connectedDatabase ? : sqlite.Database): recordTypes.LotOccupancyTransaction[] => {
|
||||||
|
|
||||||
|
const database = connectedDatabase || sqlite(databasePath, {
|
||||||
|
readonly: true
|
||||||
|
});
|
||||||
|
|
||||||
|
database.function("userFn_dateIntegerToString", dateIntegerToString);
|
||||||
|
database.function("userFn_timeIntegerToString", timeIntegerToString);
|
||||||
|
|
||||||
|
const lotOccupancyTransactions: recordTypes.LotOccupancyTransaction[] = database
|
||||||
|
.prepare("select lotOccupancyId, transactionIndex," +
|
||||||
|
" transactionDate, userFn_dateIntegerToString(transactionDate) as transactionDateString," +
|
||||||
|
" transactionTime, userFn_timeIntegerToString(transactionTime) as transactionTimeString," +
|
||||||
|
" transactionAmount, externalReceiptNumber, transactionNote" +
|
||||||
|
" from LotOccupancyTransactions" +
|
||||||
|
" where recordDelete_timeMillis is null" +
|
||||||
|
" and lotOccupancyId = ?" +
|
||||||
|
" order by transactionDate, transactionTime, transactionIndex")
|
||||||
|
.all(lotOccupancyId);
|
||||||
|
|
||||||
|
if (!connectedDatabase) {
|
||||||
|
database.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
return lotOccupancyTransactions;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
export default getLotOccupancyTransactions;
|
||||||
|
|
@ -4,6 +4,7 @@ interface GetLotsFilters {
|
||||||
mapId?: number | string;
|
mapId?: number | string;
|
||||||
lotTypeId?: number | string;
|
lotTypeId?: number | string;
|
||||||
lotStatusId?: number | string;
|
lotStatusId?: number | string;
|
||||||
|
occupancyStatus?: "" | "occupied" | "unoccupied";
|
||||||
}
|
}
|
||||||
interface GetLotsOptions {
|
interface GetLotsOptions {
|
||||||
limit: number;
|
limit: number;
|
||||||
|
|
|
||||||
|
|
@ -26,14 +26,30 @@ export const getLots = (filters, options) => {
|
||||||
sqlWhereClause += " and l.lotStatusId = ?";
|
sqlWhereClause += " and l.lotStatusId = ?";
|
||||||
sqlParameters.push(filters.lotStatusId);
|
sqlParameters.push(filters.lotStatusId);
|
||||||
}
|
}
|
||||||
|
if (filters.occupancyStatus) {
|
||||||
|
if (filters.occupancyStatus === "occupied") {
|
||||||
|
sqlWhereClause += " and lotOccupancyCount > 0";
|
||||||
|
}
|
||||||
|
else if (filters.occupancyStatus === "unoccupied") {
|
||||||
|
sqlWhereClause += " and (lotOccupancyCount is null or lotOccupancyCount = 0)";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const currentDate = dateToInteger(new Date());
|
||||||
const count = database.prepare("select count(*) as recordCount" +
|
const count = database.prepare("select count(*) as recordCount" +
|
||||||
" from Lots l" +
|
" from Lots l" +
|
||||||
|
(" left join (" +
|
||||||
|
"select lotId, count(lotOccupancyId) as lotOccupancyCount" +
|
||||||
|
" from LotOccupancies" +
|
||||||
|
" where recordDelete_timeMillis is null" +
|
||||||
|
" and occupancyStartDate <= " + currentDate +
|
||||||
|
" and (occupancyEndDate is null or occupancyEndDate >= " + currentDate + ")" +
|
||||||
|
" group by lotId" +
|
||||||
|
") o on l.lotId = o.lotId") +
|
||||||
sqlWhereClause)
|
sqlWhereClause)
|
||||||
.get(sqlParameters)
|
.get(sqlParameters)
|
||||||
.recordCount;
|
.recordCount;
|
||||||
let lots = [];
|
let lots = [];
|
||||||
if (count > 0) {
|
if (count > 0) {
|
||||||
const currentDate = dateToInteger(new Date());
|
|
||||||
lots = database
|
lots = database
|
||||||
.prepare("select l.lotId, l.lotName," +
|
.prepare("select l.lotId, l.lotName," +
|
||||||
" t.lotType," +
|
" t.lotType," +
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ interface GetLotsFilters {
|
||||||
mapId ? : number | string;
|
mapId ? : number | string;
|
||||||
lotTypeId ? : number | string;
|
lotTypeId ? : number | string;
|
||||||
lotStatusId ? : number | string;
|
lotStatusId ? : number | string;
|
||||||
|
occupancyStatus ? : "" | "occupied" | "unoccupied";
|
||||||
}
|
}
|
||||||
|
|
||||||
interface GetLotsOptions {
|
interface GetLotsOptions {
|
||||||
|
|
@ -57,8 +58,26 @@ export const getLots = (filters ? : GetLotsFilters, options ? : GetLotsOptions):
|
||||||
sqlParameters.push(filters.lotStatusId);
|
sqlParameters.push(filters.lotStatusId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (filters.occupancyStatus) {
|
||||||
|
if (filters.occupancyStatus === "occupied") {
|
||||||
|
sqlWhereClause += " and lotOccupancyCount > 0";
|
||||||
|
} else if (filters.occupancyStatus === "unoccupied") {
|
||||||
|
sqlWhereClause += " and (lotOccupancyCount is null or lotOccupancyCount = 0)";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const currentDate = dateToInteger(new Date());
|
||||||
|
|
||||||
const count: number = database.prepare("select count(*) as recordCount" +
|
const count: number = database.prepare("select count(*) as recordCount" +
|
||||||
" from Lots l" +
|
" from Lots l" +
|
||||||
|
(" left join (" +
|
||||||
|
"select lotId, count(lotOccupancyId) as lotOccupancyCount" +
|
||||||
|
" from LotOccupancies" +
|
||||||
|
" where recordDelete_timeMillis is null" +
|
||||||
|
" and occupancyStartDate <= " + currentDate +
|
||||||
|
" and (occupancyEndDate is null or occupancyEndDate >= " + currentDate + ")" +
|
||||||
|
" group by lotId" +
|
||||||
|
") o on l.lotId = o.lotId") +
|
||||||
sqlWhereClause)
|
sqlWhereClause)
|
||||||
.get(sqlParameters)
|
.get(sqlParameters)
|
||||||
.recordCount;
|
.recordCount;
|
||||||
|
|
@ -67,8 +86,6 @@ export const getLots = (filters ? : GetLotsFilters, options ? : GetLotsOptions):
|
||||||
|
|
||||||
if (count > 0) {
|
if (count > 0) {
|
||||||
|
|
||||||
const currentDate = dateToInteger(new Date());
|
|
||||||
|
|
||||||
lots = database
|
lots = database
|
||||||
.prepare("select l.lotId, l.lotName," +
|
.prepare("select l.lotId, l.lotName," +
|
||||||
" t.lotType," +
|
" t.lotType," +
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
import type * as recordTypes from "../../types/recordTypes";
|
||||||
|
interface UpdateLotOccupancyForm {
|
||||||
|
lotOccupancyId: string | number;
|
||||||
|
occupancyTypeId: string | number;
|
||||||
|
lotId: string | number;
|
||||||
|
occupancyStartDateString: string;
|
||||||
|
occupancyEndDateString: string;
|
||||||
|
}
|
||||||
|
export declare function updateLotOccupancy(lotOccupancyForm: UpdateLotOccupancyForm, requestSession: recordTypes.PartialSession): boolean;
|
||||||
|
export default updateLotOccupancy;
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
import { dateStringToInteger } from "@cityssm/expressjs-server-js/dateTimeFns.js";
|
||||||
|
import sqlite from "better-sqlite3";
|
||||||
|
import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js";
|
||||||
|
export function updateLotOccupancy(lotOccupancyForm, requestSession) {
|
||||||
|
const database = sqlite(databasePath);
|
||||||
|
const rightNowMillis = Date.now();
|
||||||
|
const result = database
|
||||||
|
.prepare("update LotOccupancies" +
|
||||||
|
" set occupancyTypeId = ?," +
|
||||||
|
" lotId = ?," +
|
||||||
|
" occupancyStartDate = ?," +
|
||||||
|
" occupancyEndDate = ?," +
|
||||||
|
" recordUpdate_userName = ?," +
|
||||||
|
" recordUpdate_timeMillis = ?" +
|
||||||
|
" where lotOccupancyId = ?" +
|
||||||
|
" and recordDelete_timeMillis is null")
|
||||||
|
.run(lotOccupancyForm.occupancyTypeId, (lotOccupancyForm.lotId === "" ? undefined : lotOccupancyForm.lotId), dateStringToInteger(lotOccupancyForm.occupancyStartDateString), (lotOccupancyForm.occupancyEndDateString === "" ? undefined : dateStringToInteger(lotOccupancyForm.occupancyEndDateString)), requestSession.user.userName, rightNowMillis, lotOccupancyForm.lotOccupancyId);
|
||||||
|
database.close();
|
||||||
|
return result.changes > 0;
|
||||||
|
}
|
||||||
|
export default updateLotOccupancy;
|
||||||
|
|
@ -0,0 +1,48 @@
|
||||||
|
import { dateStringToInteger } from "@cityssm/expressjs-server-js/dateTimeFns.js";
|
||||||
|
import sqlite from "better-sqlite3";
|
||||||
|
import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js";
|
||||||
|
|
||||||
|
import type * as recordTypes from "../../types/recordTypes";
|
||||||
|
|
||||||
|
|
||||||
|
interface UpdateLotOccupancyForm {
|
||||||
|
lotOccupancyId: string | number;
|
||||||
|
occupancyTypeId: string | number;
|
||||||
|
lotId: string | number;
|
||||||
|
|
||||||
|
occupancyStartDateString: string;
|
||||||
|
occupancyEndDateString: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function updateLotOccupancy(lotOccupancyForm: UpdateLotOccupancyForm, requestSession: recordTypes.PartialSession): boolean {
|
||||||
|
|
||||||
|
const database = sqlite(databasePath);
|
||||||
|
|
||||||
|
const rightNowMillis = Date.now();
|
||||||
|
|
||||||
|
const result = database
|
||||||
|
.prepare("update LotOccupancies" +
|
||||||
|
" set occupancyTypeId = ?," +
|
||||||
|
" lotId = ?," +
|
||||||
|
" occupancyStartDate = ?," +
|
||||||
|
" occupancyEndDate = ?," +
|
||||||
|
" recordUpdate_userName = ?," +
|
||||||
|
" recordUpdate_timeMillis = ?" +
|
||||||
|
" where lotOccupancyId = ?" +
|
||||||
|
" and recordDelete_timeMillis is null")
|
||||||
|
.run(lotOccupancyForm.occupancyTypeId,
|
||||||
|
(lotOccupancyForm.lotId === "" ? undefined : lotOccupancyForm.lotId),
|
||||||
|
dateStringToInteger(lotOccupancyForm.occupancyStartDateString),
|
||||||
|
(lotOccupancyForm.occupancyEndDateString === "" ? undefined : dateStringToInteger(lotOccupancyForm.occupancyEndDateString)),
|
||||||
|
requestSession.user.userName,
|
||||||
|
rightNowMillis,
|
||||||
|
lotOccupancyForm.lotOccupancyId);
|
||||||
|
|
||||||
|
database.close();
|
||||||
|
|
||||||
|
return result.changes > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export default updateLotOccupancy;
|
||||||
|
|
@ -6,6 +6,7 @@ import type * as recordTypes from "../types/recordTypes";
|
||||||
import type {
|
import type {
|
||||||
cityssmGlobal
|
cityssmGlobal
|
||||||
} from "@cityssm/bulma-webapp-js/src/types";
|
} from "@cityssm/bulma-webapp-js/src/types";
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
BulmaJS
|
BulmaJS
|
||||||
} from "@cityssm/bulma-js/types";
|
} from "@cityssm/bulma-js/types";
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
export {};
|
||||||
|
|
@ -0,0 +1,121 @@
|
||||||
|
"use strict";
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
(() => {
|
||||||
|
const los = exports.los;
|
||||||
|
const urlPrefix = document.querySelector("main").dataset.urlPrefix;
|
||||||
|
const lotOccupancyId = document.querySelector("#lotOccupancy--lotOccupancyId").value;
|
||||||
|
const isCreate = (lotOccupancyId === "");
|
||||||
|
let hasUnsavedChanges = false;
|
||||||
|
const setUnsavedChanges = () => {
|
||||||
|
if (!hasUnsavedChanges) {
|
||||||
|
hasUnsavedChanges = true;
|
||||||
|
cityssm.enableNavBlocker();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const clearUnsavedChanges = () => {
|
||||||
|
hasUnsavedChanges = false;
|
||||||
|
cityssm.disableNavBlocker();
|
||||||
|
};
|
||||||
|
const formElement = document.querySelector("#form--lotOccupancy");
|
||||||
|
formElement.addEventListener("submit", (formEvent) => {
|
||||||
|
formEvent.preventDefault();
|
||||||
|
cityssm.postJSON(urlPrefix + "/lotOccupancies/" + (isCreate ? "doCreateLotOccupancy" : "doUpdateLotOccupancy"), formElement, (responseJSON) => {
|
||||||
|
if (responseJSON.success) {
|
||||||
|
clearUnsavedChanges();
|
||||||
|
if (isCreate) {
|
||||||
|
window.location.href = urlPrefix + "/lotOccupancies/" + responseJSON.lotOccupancyId + "/edit";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
bulmaJS.alert({
|
||||||
|
message: exports.aliases.occupancy + " Updated Successfully",
|
||||||
|
contextualColorName: "success"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
bulmaJS.alert({
|
||||||
|
title: "Error Saving " + exports.aliases.occupancy,
|
||||||
|
message: responseJSON.errorMessage,
|
||||||
|
contextualColorName: "danger"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
document.querySelector("#lotOccupancy--lotName").addEventListener("click", () => {
|
||||||
|
let lotSelectCloseModalFunction;
|
||||||
|
let lotSelectFormElement;
|
||||||
|
let lotSelectResultsElement;
|
||||||
|
const selectLot = (clickEvent) => {
|
||||||
|
clickEvent.preventDefault();
|
||||||
|
const selectedLotElement = clickEvent.currentTarget;
|
||||||
|
document.querySelector("#lotOccupancy--lotId").value = selectedLotElement.dataset.lotId;
|
||||||
|
document.querySelector("#lotOccupancy--lotName").value = selectedLotElement.dataset.lotName;
|
||||||
|
setUnsavedChanges();
|
||||||
|
lotSelectCloseModalFunction();
|
||||||
|
};
|
||||||
|
const searchLots = () => {
|
||||||
|
lotSelectResultsElement.innerHTML = "<p class=\"has-text-centered\">" +
|
||||||
|
"<i class=\"fas fa-3x fa-pulse fa-spinner\" aria-hidden=\"true\"></i><br />" +
|
||||||
|
"Searching..." +
|
||||||
|
"</p>";
|
||||||
|
cityssm.postJSON(urlPrefix + "/lots/doSearchLots", lotSelectFormElement, (responseJSON) => {
|
||||||
|
if (responseJSON.count === 0) {
|
||||||
|
lotSelectResultsElement.innerHTML = "<div class=\"message is-info\">" +
|
||||||
|
"<p class=\"message-body\">" +
|
||||||
|
"No results." +
|
||||||
|
"</p>" +
|
||||||
|
"</div>";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const panelElement = document.createElement("div");
|
||||||
|
panelElement.className = "panel";
|
||||||
|
for (const lot of responseJSON.lots) {
|
||||||
|
const panelBlockElement = document.createElement("a");
|
||||||
|
panelBlockElement.className = "panel-block is-block";
|
||||||
|
panelBlockElement.href = "#";
|
||||||
|
panelBlockElement.dataset.lotId = lot.lotId.toString();
|
||||||
|
panelBlockElement.dataset.lotName = lot.lotName;
|
||||||
|
panelBlockElement.innerHTML = "<div class=\"columns\">" +
|
||||||
|
("<div class=\"column\">" +
|
||||||
|
cityssm.escapeHTML(lot.lotName) + "<br />" +
|
||||||
|
"<span class=\"is-size-7\">" + cityssm.escapeHTML(lot.mapName) + "</span>" +
|
||||||
|
"</div>") +
|
||||||
|
("<div class=\"column\">" +
|
||||||
|
cityssm.escapeHTML(lot.lotStatus) + "<br />" +
|
||||||
|
"<span class=\"is-size-7\">" +
|
||||||
|
(lot.lotOccupancyCount > 0 ?
|
||||||
|
"Currently Occupied" : "") +
|
||||||
|
"</span>" +
|
||||||
|
"</div>") +
|
||||||
|
"</div>";
|
||||||
|
panelBlockElement.addEventListener("click", selectLot);
|
||||||
|
panelElement.append(panelBlockElement);
|
||||||
|
}
|
||||||
|
lotSelectResultsElement.innerHTML = "";
|
||||||
|
lotSelectResultsElement.append(panelElement);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
cityssm.openHtmlModal("lotOccupancy-selectLot", {
|
||||||
|
onshow: (modalElement) => {
|
||||||
|
los.populateAliases(modalElement);
|
||||||
|
},
|
||||||
|
onshown: (modalElement, closeModalFunction) => {
|
||||||
|
bulmaJS.toggleHtmlClipped();
|
||||||
|
lotSelectCloseModalFunction = closeModalFunction;
|
||||||
|
const lotNameFilterElement = modalElement.querySelector("#lotSelect--lotName");
|
||||||
|
lotNameFilterElement.focus();
|
||||||
|
lotNameFilterElement.addEventListener("change", searchLots);
|
||||||
|
modalElement.querySelector("#lotSelect--occupancyStatus").addEventListener("change", searchLots);
|
||||||
|
lotSelectFormElement = modalElement.querySelector("#form--lotSelect");
|
||||||
|
lotSelectResultsElement = modalElement.querySelector("#resultsContainer--lotSelect");
|
||||||
|
lotSelectFormElement.addEventListener("submit", (submitEvent) => {
|
||||||
|
submitEvent.preventDefault();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onremoved: () => {
|
||||||
|
bulmaJS.toggleHtmlClipped();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
los.initializeUnlockFieldButtons(formElement);
|
||||||
|
})();
|
||||||
|
|
@ -0,0 +1,188 @@
|
||||||
|
/* eslint-disable unicorn/prefer-module */
|
||||||
|
|
||||||
|
import type * as globalTypes from "../types/globalTypes";
|
||||||
|
import type * as recordTypes from "../types/recordTypes";
|
||||||
|
|
||||||
|
import type {
|
||||||
|
cityssmGlobal
|
||||||
|
} from "@cityssm/bulma-webapp-js/src/types";
|
||||||
|
|
||||||
|
import type {
|
||||||
|
BulmaJS
|
||||||
|
} from "@cityssm/bulma-js/types";
|
||||||
|
|
||||||
|
declare const cityssm: cityssmGlobal;
|
||||||
|
declare const bulmaJS: BulmaJS;
|
||||||
|
|
||||||
|
|
||||||
|
(() => {
|
||||||
|
|
||||||
|
const los = (exports.los as globalTypes.LOS);
|
||||||
|
|
||||||
|
const urlPrefix = document.querySelector("main").dataset.urlPrefix;
|
||||||
|
|
||||||
|
const lotOccupancyId = (document.querySelector("#lotOccupancy--lotOccupancyId") as HTMLInputElement).value;
|
||||||
|
const isCreate = (lotOccupancyId === "");
|
||||||
|
|
||||||
|
// Main form
|
||||||
|
|
||||||
|
let hasUnsavedChanges = false;
|
||||||
|
|
||||||
|
const setUnsavedChanges = () => {
|
||||||
|
if (!hasUnsavedChanges) {
|
||||||
|
hasUnsavedChanges = true;
|
||||||
|
cityssm.enableNavBlocker();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const clearUnsavedChanges = () => {
|
||||||
|
hasUnsavedChanges = false;
|
||||||
|
cityssm.disableNavBlocker();
|
||||||
|
};
|
||||||
|
|
||||||
|
const formElement = document.querySelector("#form--lotOccupancy") as HTMLFormElement;
|
||||||
|
|
||||||
|
formElement.addEventListener("submit", (formEvent) => {
|
||||||
|
formEvent.preventDefault();
|
||||||
|
|
||||||
|
cityssm.postJSON(urlPrefix + "/lotOccupancies/" + (isCreate ? "doCreateLotOccupancy" : "doUpdateLotOccupancy"),
|
||||||
|
formElement,
|
||||||
|
(responseJSON: {
|
||||||
|
success: boolean;
|
||||||
|
lotOccupancyId ? : number;
|
||||||
|
errorMessage ? : string;
|
||||||
|
}) => {
|
||||||
|
|
||||||
|
if (responseJSON.success) {
|
||||||
|
|
||||||
|
clearUnsavedChanges();
|
||||||
|
|
||||||
|
if (isCreate) {
|
||||||
|
window.location.href = urlPrefix + "/lotOccupancies/" + responseJSON.lotOccupancyId + "/edit";
|
||||||
|
} else {
|
||||||
|
bulmaJS.alert({
|
||||||
|
message: exports.aliases.occupancy + " Updated Successfully",
|
||||||
|
contextualColorName: "success"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
bulmaJS.alert({
|
||||||
|
title: "Error Saving " + exports.aliases.occupancy,
|
||||||
|
message: responseJSON.errorMessage,
|
||||||
|
contextualColorName: "danger"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Lot Selector
|
||||||
|
|
||||||
|
document.querySelector("#lotOccupancy--lotName").addEventListener("click", () => {
|
||||||
|
|
||||||
|
let lotSelectCloseModalFunction: () => void;
|
||||||
|
|
||||||
|
let lotSelectFormElement: HTMLFormElement;
|
||||||
|
let lotSelectResultsElement: HTMLElement;
|
||||||
|
|
||||||
|
const selectLot = (clickEvent: Event) => {
|
||||||
|
clickEvent.preventDefault();
|
||||||
|
|
||||||
|
const selectedLotElement = clickEvent.currentTarget as HTMLElement;
|
||||||
|
|
||||||
|
(document.querySelector("#lotOccupancy--lotId") as HTMLInputElement).value = selectedLotElement.dataset.lotId;
|
||||||
|
(document.querySelector("#lotOccupancy--lotName") as HTMLInputElement).value = selectedLotElement.dataset.lotName;
|
||||||
|
|
||||||
|
setUnsavedChanges();
|
||||||
|
|
||||||
|
lotSelectCloseModalFunction();
|
||||||
|
};
|
||||||
|
|
||||||
|
const searchLots = () => {
|
||||||
|
|
||||||
|
lotSelectResultsElement.innerHTML = "<p class=\"has-text-centered\">" +
|
||||||
|
"<i class=\"fas fa-3x fa-pulse fa-spinner\" aria-hidden=\"true\"></i><br />" +
|
||||||
|
"Searching..." +
|
||||||
|
"</p>";
|
||||||
|
|
||||||
|
cityssm.postJSON(urlPrefix + "/lots/doSearchLots", lotSelectFormElement, (responseJSON: {
|
||||||
|
count: number;
|
||||||
|
lots: recordTypes.Lot[];
|
||||||
|
}) => {
|
||||||
|
|
||||||
|
if (responseJSON.count === 0) {
|
||||||
|
lotSelectResultsElement.innerHTML = "<div class=\"message is-info\">" +
|
||||||
|
"<p class=\"message-body\">" +
|
||||||
|
"No results." +
|
||||||
|
"</p>" +
|
||||||
|
"</div>";
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const panelElement = document.createElement("div");
|
||||||
|
panelElement.className = "panel";
|
||||||
|
|
||||||
|
for (const lot of responseJSON.lots) {
|
||||||
|
|
||||||
|
const panelBlockElement = document.createElement("a");
|
||||||
|
panelBlockElement.className = "panel-block is-block";
|
||||||
|
panelBlockElement.href = "#";
|
||||||
|
|
||||||
|
panelBlockElement.dataset.lotId = lot.lotId.toString();
|
||||||
|
panelBlockElement.dataset.lotName = lot.lotName;
|
||||||
|
|
||||||
|
panelBlockElement.innerHTML = "<div class=\"columns\">" +
|
||||||
|
("<div class=\"column\">" +
|
||||||
|
cityssm.escapeHTML(lot.lotName) + "<br />" +
|
||||||
|
"<span class=\"is-size-7\">" + cityssm.escapeHTML(lot.mapName) + "</span>" +
|
||||||
|
"</div>") +
|
||||||
|
("<div class=\"column\">" +
|
||||||
|
cityssm.escapeHTML(lot.lotStatus as string) + "<br />" +
|
||||||
|
"<span class=\"is-size-7\">" +
|
||||||
|
(lot.lotOccupancyCount > 0 ?
|
||||||
|
"Currently Occupied" : "") +
|
||||||
|
"</span>" +
|
||||||
|
"</div>") +
|
||||||
|
"</div>";
|
||||||
|
|
||||||
|
panelBlockElement.addEventListener("click", selectLot);
|
||||||
|
|
||||||
|
panelElement.append(panelBlockElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
lotSelectResultsElement.innerHTML = "";
|
||||||
|
lotSelectResultsElement.append(panelElement);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
cityssm.openHtmlModal("lotOccupancy-selectLot", {
|
||||||
|
onshow: (modalElement) => {
|
||||||
|
los.populateAliases(modalElement);
|
||||||
|
},
|
||||||
|
onshown: (modalElement, closeModalFunction) => {
|
||||||
|
|
||||||
|
bulmaJS.toggleHtmlClipped();
|
||||||
|
|
||||||
|
lotSelectCloseModalFunction = closeModalFunction;
|
||||||
|
|
||||||
|
const lotNameFilterElement = modalElement.querySelector("#lotSelect--lotName") as HTMLInputElement;
|
||||||
|
lotNameFilterElement.focus();
|
||||||
|
lotNameFilterElement.addEventListener("change", searchLots);
|
||||||
|
|
||||||
|
modalElement.querySelector("#lotSelect--occupancyStatus").addEventListener("change", searchLots);
|
||||||
|
|
||||||
|
lotSelectFormElement = modalElement.querySelector("#form--lotSelect");
|
||||||
|
lotSelectResultsElement = modalElement.querySelector("#resultsContainer--lotSelect");
|
||||||
|
|
||||||
|
lotSelectFormElement.addEventListener("submit", (submitEvent) => {
|
||||||
|
submitEvent.preventDefault();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onremoved: () => {
|
||||||
|
bulmaJS.toggleHtmlClipped();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
los.initializeUnlockFieldButtons(formElement);
|
||||||
|
})();
|
||||||
|
|
@ -0,0 +1,45 @@
|
||||||
|
<div class="modal">
|
||||||
|
<div class="modal-background"></div>
|
||||||
|
<div class="modal-card">
|
||||||
|
<header class="modal-card-head">
|
||||||
|
<h3 class="modal-card-title">
|
||||||
|
Select a <span class="alias" data-alias="Lot"></span>
|
||||||
|
</h3>
|
||||||
|
<button class="delete is-close-modal-button" aria-label="close" type="button"></button>
|
||||||
|
</header>
|
||||||
|
<section class="modal-card-body">
|
||||||
|
<div class="box">
|
||||||
|
<form id="form--lotSelect">
|
||||||
|
<input name="limit" type="hidden" value="100" />
|
||||||
|
<input name="offset" type="hidden" value="0" />
|
||||||
|
<div class="field">
|
||||||
|
<div class="control has-icons-left">
|
||||||
|
<input class="input" id="lotSelect--lotName" name="lotName" type="text" />
|
||||||
|
<span class="icon is-small is-left">
|
||||||
|
<i class="fas fa-search" aria-hidden="true"></i>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="field">
|
||||||
|
<div class="control has-icons-left">
|
||||||
|
<div class="select is-fullwidth">
|
||||||
|
<select id="lotSelect--occupancyStatus" name="occupancyStatus">
|
||||||
|
<option value="">(All Statuses)</option>
|
||||||
|
<option value="unoccupied" selected>Currently Unoccupied</option>
|
||||||
|
<option value="occupied">Currently Occupied</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<span class="icon is-small is-left">
|
||||||
|
<i class="fas fa-filter" aria-hidden="true"></i>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div id="resultsContainer--lotSelect"></div>
|
||||||
|
</section>
|
||||||
|
<footer class="modal-card-foot justify-right">
|
||||||
|
<button class="button is-close-modal-button" type="button">Cancel</button>
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),(()=>{const e=exports.los,t=document.querySelector("main").dataset.urlPrefix,c=""===document.querySelector("#lotOccupancy--lotOccupancyId").value;let s=!1;const a=document.querySelector("#form--lotOccupancy");a.addEventListener("submit",e=>{e.preventDefault(),cityssm.postJSON(t+"/lotOccupancies/"+(c?"doCreateLotOccupancy":"doUpdateLotOccupancy"),a,e=>{e.success?(s=!1,cityssm.disableNavBlocker(),c?window.location.href=t+"/lotOccupancies/"+e.lotOccupancyId+"/edit":bulmaJS.alert({message:exports.aliases.occupancy+" Updated Successfully",contextualColorName:"success"})):bulmaJS.alert({title:"Error Saving "+exports.aliases.occupancy,message:e.errorMessage,contextualColorName:"danger"})})}),document.querySelector("#lotOccupancy--lotName").addEventListener("click",()=>{let c,a,o;const l=e=>{e.preventDefault();const t=e.currentTarget;document.querySelector("#lotOccupancy--lotId").value=t.dataset.lotId,document.querySelector("#lotOccupancy--lotName").value=t.dataset.lotName,s||(s=!0,cityssm.enableNavBlocker()),c()},n=()=>{o.innerHTML='<p class="has-text-centered"><i class="fas fa-3x fa-pulse fa-spinner" aria-hidden="true"></i><br />Searching...</p>',cityssm.postJSON(t+"/lots/doSearchLots",a,e=>{if(0===e.count)return void(o.innerHTML='<div class="message is-info"><p class="message-body">No results.</p></div>');const t=document.createElement("div");t.className="panel";for(const c of e.lots){const e=document.createElement("a");e.className="panel-block is-block",e.href="#",e.dataset.lotId=c.lotId.toString(),e.dataset.lotName=c.lotName,e.innerHTML='<div class="columns"><div class="column">'+cityssm.escapeHTML(c.lotName)+'<br /><span class="is-size-7">'+cityssm.escapeHTML(c.mapName)+'</span></div><div class="column">'+cityssm.escapeHTML(c.lotStatus)+'<br /><span class="is-size-7">'+(c.lotOccupancyCount>0?"Currently Occupied":"")+"</span></div></div>",e.addEventListener("click",l),t.append(e)}o.innerHTML="",o.append(t)})};cityssm.openHtmlModal("lotOccupancy-selectLot",{onshow:t=>{e.populateAliases(t)},onshown:(e,t)=>{bulmaJS.toggleHtmlClipped(),c=t;const s=e.querySelector("#lotSelect--lotName");s.focus(),s.addEventListener("change",n),e.querySelector("#lotSelect--occupancyStatus").addEventListener("change",n),a=e.querySelector("#form--lotSelect"),o=e.querySelector("#resultsContainer--lotSelect"),a.addEventListener("submit",e=>{e.preventDefault()})},onremoved:()=>{bulmaJS.toggleHtmlClipped()}})}),e.initializeUnlockFieldButtons(a)})();
|
||||||
|
|
@ -3,10 +3,12 @@ import handler_search from "../handlers/lotOccupancies-get/search.js";
|
||||||
import handler_doSearchLotOccupancies from "../handlers/lotOccupancies-post/doSearchLotOccupancies.js";
|
import handler_doSearchLotOccupancies from "../handlers/lotOccupancies-post/doSearchLotOccupancies.js";
|
||||||
import handler_view from "../handlers/lotOccupancies-get/view.js";
|
import handler_view from "../handlers/lotOccupancies-get/view.js";
|
||||||
import handler_edit from "../handlers/lotOccupancies-get/edit.js";
|
import handler_edit from "../handlers/lotOccupancies-get/edit.js";
|
||||||
|
import handler_doUpdateLotOccupancy from "../handlers/lotOccupancies-post/doUpdateLotOccupancy.js";
|
||||||
import * as permissionHandlers from "../handlers/permissions.js";
|
import * as permissionHandlers from "../handlers/permissions.js";
|
||||||
export const router = Router();
|
export const router = Router();
|
||||||
router.get("/", handler_search);
|
router.get("/", handler_search);
|
||||||
router.post("/doSearchLotOccupancies", handler_doSearchLotOccupancies);
|
router.post("/doSearchLotOccupancies", handler_doSearchLotOccupancies);
|
||||||
router.get("/:lotOccupancyId", handler_view);
|
router.get("/:lotOccupancyId", handler_view);
|
||||||
router.get("/:lotOccupancyId/edit", permissionHandlers.updateGetHandler, handler_edit);
|
router.get("/:lotOccupancyId/edit", permissionHandlers.updateGetHandler, handler_edit);
|
||||||
|
router.post("/doUpdateLotOccupancy", permissionHandlers.updatePostHandler, handler_doUpdateLotOccupancy);
|
||||||
export default router;
|
export default router;
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,9 @@ import handler_search from "../handlers/lotOccupancies-get/search.js";
|
||||||
import handler_doSearchLotOccupancies from "../handlers/lotOccupancies-post/doSearchLotOccupancies.js";
|
import handler_doSearchLotOccupancies from "../handlers/lotOccupancies-post/doSearchLotOccupancies.js";
|
||||||
|
|
||||||
import handler_view from "../handlers/lotOccupancies-get/view.js";
|
import handler_view from "../handlers/lotOccupancies-get/view.js";
|
||||||
|
|
||||||
import handler_edit from "../handlers/lotOccupancies-get/edit.js";
|
import handler_edit from "../handlers/lotOccupancies-get/edit.js";
|
||||||
|
import handler_doUpdateLotOccupancy from "../handlers/lotOccupancies-post/doUpdateLotOccupancy.js";
|
||||||
|
|
||||||
import * as permissionHandlers from "../handlers/permissions.js";
|
import * as permissionHandlers from "../handlers/permissions.js";
|
||||||
|
|
||||||
|
|
@ -22,7 +24,7 @@ router.post("/doSearchLotOccupancies",
|
||||||
handler_doSearchLotOccupancies);
|
handler_doSearchLotOccupancies);
|
||||||
|
|
||||||
|
|
||||||
router.get("/:lotOccupancyId",
|
router.get("/:lotOccupancyId",
|
||||||
handler_view);
|
handler_view);
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -30,5 +32,9 @@ router.get("/:lotOccupancyId/edit",
|
||||||
permissionHandlers.updateGetHandler,
|
permissionHandlers.updateGetHandler,
|
||||||
handler_edit);
|
handler_edit);
|
||||||
|
|
||||||
|
router.post("/doUpdateLotOccupancy",
|
||||||
|
permissionHandlers.updatePostHandler,
|
||||||
|
handler_doUpdateLotOccupancy);
|
||||||
|
|
||||||
|
|
||||||
export default router;
|
export default router;
|
||||||
|
|
@ -23,6 +23,12 @@ export interface Config {
|
||||||
occupant?: string;
|
occupant?: string;
|
||||||
occupants?: string;
|
occupants?: string;
|
||||||
};
|
};
|
||||||
|
settings?: {
|
||||||
|
lotOccupancy?: {
|
||||||
|
lotIdIsRequired?: boolean;
|
||||||
|
occupancyEndDateIsRequired?: boolean;
|
||||||
|
};
|
||||||
|
};
|
||||||
}
|
}
|
||||||
interface ConfigApplication {
|
interface ConfigApplication {
|
||||||
applicationName?: string;
|
applicationName?: string;
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ export interface Config {
|
||||||
canLogin?: string[];
|
canLogin?: string[];
|
||||||
canUpdate?: string[];
|
canUpdate?: string[];
|
||||||
isAdmin?: string[];
|
isAdmin?: string[];
|
||||||
},
|
};
|
||||||
aliases?: {
|
aliases?: {
|
||||||
lot?: string;
|
lot?: string;
|
||||||
lots?: string;
|
lots?: string;
|
||||||
|
|
@ -22,7 +22,13 @@ export interface Config {
|
||||||
occupancies?: string;
|
occupancies?: string;
|
||||||
occupant?: string;
|
occupant?: string;
|
||||||
occupants?: string;
|
occupants?: string;
|
||||||
}
|
};
|
||||||
|
settings?: {
|
||||||
|
lotOccupancy?: {
|
||||||
|
lotIdIsRequired?: boolean;
|
||||||
|
occupancyEndDateIsRequired?: boolean;
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ConfigApplication {
|
interface ConfigApplication {
|
||||||
|
|
|
||||||
|
|
@ -107,6 +107,30 @@ export interface Occupant extends Record {
|
||||||
occupantPostalCode?: string;
|
occupantPostalCode?: string;
|
||||||
occupantPhoneNumber?: string;
|
occupantPhoneNumber?: string;
|
||||||
}
|
}
|
||||||
|
export interface Fee extends Record {
|
||||||
|
feeId?: number;
|
||||||
|
feeName?: string;
|
||||||
|
occupancyTypeId?: number;
|
||||||
|
lotTypeId?: number;
|
||||||
|
feeAmount?: number;
|
||||||
|
feeFunction?: string;
|
||||||
|
isRequired?: boolean;
|
||||||
|
}
|
||||||
|
export interface LotOccupancyFee extends Fee, Record {
|
||||||
|
lotOccupancyId?: number;
|
||||||
|
feeAmount?: number;
|
||||||
|
}
|
||||||
|
export interface LotOccupancyTransaction extends Record {
|
||||||
|
lotOccupancyId?: number;
|
||||||
|
transactionIndex?: number;
|
||||||
|
transactionDate?: number;
|
||||||
|
transactionDateString?: string;
|
||||||
|
transactionTime?: number;
|
||||||
|
transactionTimeString?: string;
|
||||||
|
tranactionAmount?: number;
|
||||||
|
externalReceiptNumber?: string;
|
||||||
|
transactionNote?: string;
|
||||||
|
}
|
||||||
export interface LotOccupancyOccupant extends Occupant, Record {
|
export interface LotOccupancyOccupant extends Occupant, Record {
|
||||||
lotOccupancyId?: number;
|
lotOccupancyId?: number;
|
||||||
lotOccupantIndex?: number;
|
lotOccupantIndex?: number;
|
||||||
|
|
@ -122,6 +146,11 @@ export interface LotOccupancyComment extends Record {
|
||||||
lotOccupancyCommentTimeString?: string;
|
lotOccupancyCommentTimeString?: string;
|
||||||
lotOccupancyComment?: string;
|
lotOccupancyComment?: string;
|
||||||
}
|
}
|
||||||
|
export interface LotOccupancyField extends OccupancyTypeField, Record {
|
||||||
|
lotOccupancyId?: number;
|
||||||
|
occupancyTypeFieldId?: number;
|
||||||
|
lotOccupancyFieldValue?: string;
|
||||||
|
}
|
||||||
export interface LotOccupancy extends Record {
|
export interface LotOccupancy extends Record {
|
||||||
lotOccupancyId?: number;
|
lotOccupancyId?: number;
|
||||||
occupancyTypeId?: number;
|
occupancyTypeId?: number;
|
||||||
|
|
@ -134,8 +163,11 @@ export interface LotOccupancy extends Record {
|
||||||
occupancyStartDateString?: string;
|
occupancyStartDateString?: string;
|
||||||
occupancyEndDate?: number;
|
occupancyEndDate?: number;
|
||||||
occupancyEndDateString?: string;
|
occupancyEndDateString?: string;
|
||||||
|
lotOccupancyFields?: LotOccupancyField[];
|
||||||
lotOccupancyComments?: LotOccupancyComment[];
|
lotOccupancyComments?: LotOccupancyComment[];
|
||||||
lotOccupancyOccupants?: LotOccupancyOccupant[];
|
lotOccupancyOccupants?: LotOccupancyOccupant[];
|
||||||
|
lotOccupancyFees?: LotOccupancyFee[];
|
||||||
|
lotOccupancyTransactions?: LotOccupancyTransaction[];
|
||||||
}
|
}
|
||||||
export interface User {
|
export interface User {
|
||||||
userName: string;
|
userName: string;
|
||||||
|
|
|
||||||
|
|
@ -151,6 +151,39 @@ export interface Occupant extends Record {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export interface Fee extends Record {
|
||||||
|
feeId?: number;
|
||||||
|
feeName?: string;
|
||||||
|
|
||||||
|
occupancyTypeId?: number;
|
||||||
|
lotTypeId?: number;
|
||||||
|
|
||||||
|
feeAmount?: number;
|
||||||
|
feeFunction?: string;
|
||||||
|
|
||||||
|
isRequired?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export interface LotOccupancyFee extends Fee, Record {
|
||||||
|
lotOccupancyId?: number;
|
||||||
|
feeAmount?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export interface LotOccupancyTransaction extends Record {
|
||||||
|
lotOccupancyId?: number;
|
||||||
|
transactionIndex?: number;
|
||||||
|
transactionDate?: number;
|
||||||
|
transactionDateString?: string;
|
||||||
|
transactionTime?: number;
|
||||||
|
transactionTimeString?: string;
|
||||||
|
tranactionAmount?: number;
|
||||||
|
externalReceiptNumber?: string;
|
||||||
|
transactionNote?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
export interface LotOccupancyOccupant extends Occupant, Record {
|
export interface LotOccupancyOccupant extends Occupant, Record {
|
||||||
lotOccupancyId ? : number;
|
lotOccupancyId ? : number;
|
||||||
lotOccupantIndex ? : number;
|
lotOccupantIndex ? : number;
|
||||||
|
|
@ -174,6 +207,13 @@ export interface LotOccupancyComment extends Record {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export interface LotOccupancyField extends OccupancyTypeField, Record {
|
||||||
|
lotOccupancyId?: number;
|
||||||
|
occupancyTypeFieldId?: number;
|
||||||
|
lotOccupancyFieldValue?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
export interface LotOccupancy extends Record {
|
export interface LotOccupancy extends Record {
|
||||||
lotOccupancyId ? : number;
|
lotOccupancyId ? : number;
|
||||||
|
|
||||||
|
|
@ -192,8 +232,11 @@ export interface LotOccupancy extends Record {
|
||||||
occupancyEndDate ? : number;
|
occupancyEndDate ? : number;
|
||||||
occupancyEndDateString ? : string;
|
occupancyEndDateString ? : string;
|
||||||
|
|
||||||
|
lotOccupancyFields? : LotOccupancyField[];
|
||||||
lotOccupancyComments ? : LotOccupancyComment[];
|
lotOccupancyComments ? : LotOccupancyComment[];
|
||||||
lotOccupancyOccupants ? : LotOccupancyOccupant[];
|
lotOccupancyOccupants ? : LotOccupancyOccupant[];
|
||||||
|
lotOccupancyFees?: LotOccupancyFee[];
|
||||||
|
lotOccupancyTransactions?: LotOccupancyTransaction[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,28 +16,142 @@
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href="<%= urlPrefix %>/lotOccupancies/<%= lotOccupancy.lotOccupancyId %>">
|
<a href="<%= urlPrefix %>/lotOccupancies/<%= lotOccupancy.lotOccupancyId %>">
|
||||||
<%= configFunctions.getProperty("aliases.occupancy") %> View
|
<%= configFunctions.getProperty("aliases.occupancy") %>: <%= lotOccupancy.lotName %>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="is-active">
|
<li class="is-active">
|
||||||
<a href="#" aria-current="page">
|
<a href="#" aria-current="page">
|
||||||
<%= configFunctions.getProperty("aliases.occupancy") %> Edit
|
Update <%= configFunctions.getProperty("aliases.occupancy") %>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<h1 class="title is-1">
|
<h1 class="title is-1">
|
||||||
<%= configFunctions.getProperty("aliases.occupancy") %> Edit
|
<%= configFunctions.getProperty("aliases.occupancy") %> Update
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<div class="fixed-container is-fixed-bottom-right mx-4 my-4 has-text-right is-hidden-print">
|
<form id="form--lotOccupancy">
|
||||||
<button class="button is-circle is-primary has-tooltip-left" data-tooltip="Update <%= configFunctions.getProperty("aliases.occupancy") %>" type="submit">
|
<div class="fixed-container is-fixed-bottom-right mx-4 my-4 has-text-right is-hidden-print">
|
||||||
<i class="fas fa-save" aria-hidden="true"></i>
|
<button class="button is-circle is-primary has-tooltip-left" data-tooltip="Update <%= configFunctions.getProperty("aliases.occupancy") %>" type="submit">
|
||||||
<span class="sr-only">Update <%= configFunctions.getProperty("aliases.occupancy") %></span>
|
<i class="fas fa-save" aria-hidden="true"></i>
|
||||||
</button>
|
<span class="sr-only">Update <%= configFunctions.getProperty("aliases.occupancy") %></span>
|
||||||
</div>
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<input id="lotOccupancy--lotOccupancyId" name="lotOccupancyId" type="hidden" value="<%= lotOccupancy.lotOccupancyId %>" />
|
||||||
|
|
||||||
|
<div class="columns">
|
||||||
|
<div class="column">
|
||||||
|
<label class="label" for="lotOccupancy--occupancyTypeId">
|
||||||
|
<%= configFunctions.getProperty("aliases.occupancy") %> Type
|
||||||
|
</label>
|
||||||
|
<div class="field has-addons">
|
||||||
|
<div class="control is-expanded">
|
||||||
|
<div class="select is-fullwidth">
|
||||||
|
<select id="lotOccupancy--occupancyTypeId" name="occupancyTypeId" required>
|
||||||
|
<% if (isCreate) { %>
|
||||||
|
<option value="">(No Type)</option>
|
||||||
|
<% } %>
|
||||||
|
<% let typeIsFound = false; %>
|
||||||
|
<% for (const occupancyType of occupancyTypes) { %>
|
||||||
|
<%
|
||||||
|
if (lotOccupancy.occupancyTypeId === occupancyType.occupancyTypeId) {
|
||||||
|
typeIsFound = true;
|
||||||
|
}
|
||||||
|
%>
|
||||||
|
<option value="<%= occupancyType.occupancyTypeId %>"
|
||||||
|
<%= (lotOccupancy.occupancyTypeId === occupancyType.occupancyTypeId ? " selected" : "") %>
|
||||||
|
<%= (!isCreate && lotOccupancy.occupancyTypeId !== occupancyType.occupancyTypeId ? " disabled" : "") %>>
|
||||||
|
<%= occupancyType.occupancyType %>
|
||||||
|
</option>
|
||||||
|
<% } %>
|
||||||
|
<% if (lotOccupancy.occupancyTypeId && !typeIsFound) { %>
|
||||||
|
<option value="<%= lotOccupancy.occupancyTypeId %>" selected>
|
||||||
|
<%= lotOccupancy.occupancyType %>
|
||||||
|
</option>
|
||||||
|
<% } %>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="control">
|
||||||
|
<button class="button is-unlock-field-button" type="button" title="Unlock Field">
|
||||||
|
<i class="fas fa-unlock" aria-hidden="true"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="column">
|
||||||
|
<input id="lotOccupancy--lotId" name="lotId" type="hidden" value="<%= lotOccupancy.lotId %>" />
|
||||||
|
<label class="label" for="lotOccupancy--lotName">
|
||||||
|
<%= configFunctions.getProperty("aliases.lot") %>
|
||||||
|
</label>
|
||||||
|
<div class="field has-addons">
|
||||||
|
<div class="control is-expanded">
|
||||||
|
<input class="input has-text-left" id="lotOccupancy--lotName" type="button" value="<%= lotOccupancy.lotName %>"
|
||||||
|
<%= (configFunctions.getProperty("settings.lotOccupancy.lotIdIsRequired") ? " required" : "") %>
|
||||||
|
disabled />
|
||||||
|
</div>
|
||||||
|
<div class="control">
|
||||||
|
<button class="button is-unlock-field-button" type="button" title="Unlock Field">
|
||||||
|
<i class="fas fa-unlock" aria-hidden="true"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="columns">
|
||||||
|
<div class="column">
|
||||||
|
<div class="field">
|
||||||
|
<label class="label" for="lotOccupancy--occupancyStartDateString">Start Date</label>
|
||||||
|
<div class="control">
|
||||||
|
<input class="input" id="lotOccupancy--occupancyStartDateString" name="occupancyStartDateString" type="date"
|
||||||
|
value="<%= lotOccupancy.occupancyStartDateString %>" required />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="column">
|
||||||
|
<div class="field">
|
||||||
|
<label class="label" for="lotOccupancy--occupancyEndDateString">End Date</label>
|
||||||
|
<div class="control">
|
||||||
|
<input class="input" id="lotOccupancy--occupancyEndDateString" name="occupancyEndDateString" type="date"
|
||||||
|
value="<%= lotOccupancy.occupancyEndDateString %>"
|
||||||
|
min=""<%= lotOccupancy.occupancyStartDateString %>"
|
||||||
|
<%= (configFunctions.getProperty("settings.lotOccupancy.occupancyEndDateIsRequired") ? " required" : "") %> />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<% if (isCreate) { %>
|
||||||
|
|
||||||
|
<% } else { %>
|
||||||
|
|
||||||
|
<h2 class="title is-4"><%= configFunctions.getProperty("aliases.occupants") %></h2>
|
||||||
|
|
||||||
|
<h2 class="title is-4">Comments</h2>
|
||||||
|
|
||||||
|
<div class="columns">
|
||||||
|
<div class="column">
|
||||||
|
<h2 class="title is-4">Fees</h2>
|
||||||
|
</div>
|
||||||
|
<div class="column">
|
||||||
|
<h2 class="title is-4">Transactions</h2>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<% } %>
|
||||||
|
|
||||||
<%- include('_footerA'); -%>
|
<%- include('_footerA'); -%>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
exports.lotOccupancyOccupants = <%- JSON.stringify(lotOccupancy.lotOccupancyOccupants) %>;
|
||||||
|
exports.lotOccupancyComments = <%- JSON.stringify(lotOccupancy.lotOccupancyComments) %>;
|
||||||
|
exports.lotOccupancyFees = <%- JSON.stringify(lotOccupancy.lotOccupancyFees) %>;
|
||||||
|
exports.lotOccupancyTransactions = <%- JSON.stringify(lotOccupancy.lotOccupancyTransactions) %>;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script src="<%= urlPrefix %>/javascripts/lotOccupancyEdit.min.js"></script>
|
||||||
|
|
||||||
<%- include('_footerB'); -%>
|
<%- include('_footerB'); -%>
|
||||||
|
|
|
||||||
|
|
@ -1,39 +1,144 @@
|
||||||
<%- include('_header'); -%>
|
<%- include('_header'); -%>
|
||||||
|
|
||||||
<nav class="breadcrumb">
|
<nav class="breadcrumb">
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="<%= urlPrefix %>/dashboard">Home</a></li>
|
<li><a href="<%= urlPrefix %>/dashboard">Home</a></li>
|
||||||
<li>
|
<li>
|
||||||
<a href="<%= urlPrefix %>/lotOccupancies">
|
<a href="<%= urlPrefix %>/lotOccupancies">
|
||||||
<span class="icon is-small">
|
<span class="icon is-small">
|
||||||
<span class="fa-layers fa-fw" aria-hidden="true">
|
<span class="fa-layers fa-fw" aria-hidden="true">
|
||||||
<i class="fas fa-vector-square"></i>
|
<i class="fas fa-vector-square"></i>
|
||||||
<i class="fas fa-user" data-fa-transform="shrink-10"></i>
|
<i class="fas fa-user" data-fa-transform="shrink-10"></i>
|
||||||
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</span>
|
<span><%= configFunctions.getProperty("aliases.lots") %>
|
||||||
<span><%= configFunctions.getProperty("aliases.lots") %> <%= configFunctions.getProperty("aliases.occupancies") %></span>
|
<%= configFunctions.getProperty("aliases.occupancies") %></span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="is-active"><a href="#" aria-current="page">
|
<li class="is-active">
|
||||||
<%= configFunctions.getProperty("aliases.occupancy") %> View
|
<a href="#" aria-current="page">
|
||||||
</a></li>
|
<%= configFunctions.getProperty("aliases.occupancy") %>: <%= lotOccupancy.lotName %>
|
||||||
</ul>
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<h1 class="title is-1">
|
<h1 class="title is-1">
|
||||||
<%= configFunctions.getProperty("aliases.occupancy") %> View
|
<%= configFunctions.getProperty("aliases.occupancy") %>: <%= lotOccupancy.lotName %>
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<% if (user.userProperties.canUpdate) { %>
|
<% if (user.userProperties.canUpdate) { %>
|
||||||
<div class="fixed-container is-fixed-bottom-right mx-4 my-4 has-text-right is-hidden-print">
|
<div class="fixed-container is-fixed-bottom-right mx-4 my-4 has-text-right is-hidden-print">
|
||||||
<a class="button is-circle is-primary has-tooltip-left" data-tooltip="Update <%= configFunctions.getProperty("aliases.occupancy") %>" href="<%= urlPrefix %>/lotOccupancies/<%= lotOccupancy.lotOccupancyId %>/edit">
|
<a class="button is-circle is-primary has-tooltip-left"
|
||||||
<i class="fas fa-pencil-alt" aria-hidden="true"></i>
|
data-tooltip="Update <%= configFunctions.getProperty("aliases.occupancy") %>"
|
||||||
<span class="sr-only">Update <%= configFunctions.getProperty("aliases.occupancy") %></span>
|
href="<%= urlPrefix %>/lotOccupancies/<%= lotOccupancy.lotOccupancyId %>/edit">
|
||||||
|
<i class="fas fa-pencil-alt" aria-hidden="true"></i>
|
||||||
|
<span class="sr-only">Update <%= configFunctions.getProperty("aliases.occupancy") %></span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<% } %>
|
<% } %>
|
||||||
|
|
||||||
|
<div class="columns">
|
||||||
|
<div class="column">
|
||||||
|
<p>
|
||||||
|
<strong><%= configFunctions.getProperty("aliases.occupancy") %> Type</strong><br />
|
||||||
|
<%= lotOccupancy.occupancyType %>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="column">
|
||||||
|
<p>
|
||||||
|
<strong><%= configFunctions.getProperty("aliases.lot") %></strong><br />
|
||||||
|
<a href="<%= urlPrefix %>/lots/<%= lotOccupancy.lotId %>"><%= lotOccupancy.lotName %></a>
|
||||||
|
</p>
|
||||||
|
<p class="mt-2">
|
||||||
|
<strong><%= configFunctions.getProperty("aliases.map") %></strong><br />
|
||||||
|
<a href="<%= urlPrefix %>/maps/<%= lotOccupancy.mapId %>"><%= lotOccupancy.mapName %></a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="column">
|
||||||
|
<p>
|
||||||
|
<strong>Start Date</strong><br />
|
||||||
|
<%= lotOccupancy.occupancyStartDateString %>
|
||||||
|
</p>
|
||||||
|
<p class="mt-2">
|
||||||
|
<strong>End Date</strong><br />
|
||||||
|
<%= (lotOccupancy.occupancyEndDateString === "" ? "(No End Date)" : lotOccupancy.occupancyEndDateString) %>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h2 class="title is-4"><%= configFunctions.getProperty("aliases.occupants") %></h2>
|
||||||
|
|
||||||
|
<% if (lotOccupancy.lotOccupancyOccupants.length === 0) { %>
|
||||||
|
<div class="message is-warning">
|
||||||
|
<p class="message-body">There are no <%= configFunctions.getProperty("aliases.occupants").toLowerCase() %>
|
||||||
|
associated with this record.</p>
|
||||||
|
</div>
|
||||||
|
<% } else { %>
|
||||||
|
<table class="table is-fullwidth is-striped is-hoverable">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th><%= configFunctions.getProperty("aliases.occupant") %> Type</th>
|
||||||
|
<th><%= configFunctions.getProperty("aliases.occupant") %></th>
|
||||||
|
<th>Address</th>
|
||||||
|
<th>Phone Number</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<% for (const lotOccupancyOccupant of lotOccupancy.lotOccupancyOccupants) { %>
|
||||||
|
<tr>
|
||||||
|
<td><%= lotOccupancyOccupant.lotOccupantType %></td>
|
||||||
|
<td><%= lotOccupancyOccupant.occupantName %></td>
|
||||||
|
<td>
|
||||||
|
<%= lotOccupancyOccupant.occupantAddress1 %><br />
|
||||||
|
<% if (lotOccupancyOccupant.occupantAddress2 && lotOccupancyOccupant.occupantAddress2 !== "") { %>
|
||||||
|
<%= lotOccupancyOccupant.occupantAddress2 %><br />
|
||||||
|
<% } %>
|
||||||
|
<%= lotOccupancyOccupant.occupantCity %>, <%= lotOccupancyOccupant.occupantProvince %><br />
|
||||||
|
<%= lotOccupancyOccupant.occupantPostalCode %>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<%= lotOccupancyOccupant.occupantPhoneNumber %>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<% } %>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<% } %>
|
||||||
|
|
||||||
|
<% if (lotOccupancy.lotOccupancyComments.length > 0) { %>
|
||||||
|
<h2 class="title is-4">Comments</h2>
|
||||||
|
<% } %>
|
||||||
|
|
||||||
|
<div class="columns">
|
||||||
|
<div class="column">
|
||||||
|
<h2 class="title is-4">Fees</h2>
|
||||||
|
|
||||||
|
<% if (lotOccupancy.lotOccupancyFees.length === 0) { %>
|
||||||
|
<div class="message is-info">
|
||||||
|
<p class="message-body">
|
||||||
|
There are no fees applied to this <%= configFunctions.getProperty("aliases.occupancy").toLowerCase() %> record.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<% } else { %>
|
||||||
|
|
||||||
|
<% } %>
|
||||||
|
</div>
|
||||||
|
<div class="column">
|
||||||
|
<h2 class="title is-4">Transactions</h2>
|
||||||
|
|
||||||
|
<% if (lotOccupancy.lotOccupancyTransactions.length === 0) { %>
|
||||||
|
<div class="message is-info">
|
||||||
|
<p class="message-body">
|
||||||
|
There are no transactions associated with this <%= configFunctions.getProperty("aliases.occupancy").toLowerCase() %> record.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<% } else { %>
|
||||||
|
|
||||||
|
<% } %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<%- include('_footerA'); -%>
|
<%- include('_footerA'); -%>
|
||||||
|
|
||||||
<%- include('_footerB'); -%>
|
<%- include('_footerB'); -%>
|
||||||
Loading…
Reference in New Issue