development
parent
4a35da4b13
commit
ea41b0e5e7
|
|
@ -9,6 +9,11 @@ export const config = {
|
|||
lots: "Burial Sites",
|
||||
map: "Cemetery",
|
||||
maps: "Cemeteries"
|
||||
},
|
||||
settings: {
|
||||
lotOccupancy: {
|
||||
occupancyEndDateIsRequired: false
|
||||
}
|
||||
}
|
||||
};
|
||||
export default config;
|
||||
|
|
|
|||
|
|
@ -11,6 +11,11 @@ export const config: Config = {
|
|||
lots: "Burial Sites",
|
||||
map: "Cemetery",
|
||||
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 { getLotOccupancy } from "../../helpers/lotOccupancyDB/getLotOccupancy.js";
|
||||
export const handler = (request, response) => {
|
||||
|
|
@ -5,9 +6,12 @@ export const handler = (request, response) => {
|
|||
if (!lotOccupancy) {
|
||||
return response.redirect(configFunctions.getProperty("reverseProxy.urlPrefix") + "/lotOccupancies/?error=lotOccupancyIdNotFound");
|
||||
}
|
||||
const occupancyTypes = getOccupancyTypes();
|
||||
return response.render("lotOccupancy-edit", {
|
||||
headTitle: configFunctions.getProperty("aliases.lot") + " " + configFunctions.getProperty("aliases.occupancy") + " View",
|
||||
lotOccupancy
|
||||
headTitle: configFunctions.getProperty("aliases.lot") + " " + configFunctions.getProperty("aliases.occupancy") + " Update",
|
||||
lotOccupancy,
|
||||
occupancyTypes,
|
||||
isCreate: false
|
||||
});
|
||||
};
|
||||
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 { getLotOccupancy } from "../../helpers/lotOccupancyDB/getLotOccupancy.js";
|
||||
import {
|
||||
getLotOccupancy
|
||||
} from "../../helpers/lotOccupancyDB/getLotOccupancy.js";
|
||||
|
||||
|
||||
export const handler: RequestHandler = (request, response) => {
|
||||
|
||||
const lotOccupancy = getLotOccupancy(request.params.lotOccupancyId);
|
||||
const lotOccupancy = getLotOccupancy(request.params.lotOccupancyId);
|
||||
|
||||
if (!lotOccupancy) {
|
||||
return response.redirect(configFunctions.getProperty("reverseProxy.urlPrefix") + "/lotOccupancies/?error=lotOccupancyIdNotFound");
|
||||
}
|
||||
if (!lotOccupancy) {
|
||||
return response.redirect(configFunctions.getProperty("reverseProxy.urlPrefix") + "/lotOccupancies/?error=lotOccupancyIdNotFound");
|
||||
}
|
||||
|
||||
return response.render("lotOccupancy-edit", {
|
||||
headTitle: configFunctions.getProperty("aliases.lot") + " " + configFunctions.getProperty("aliases.occupancy") + " View",
|
||||
lotOccupancy
|
||||
});
|
||||
const occupancyTypes = getOccupancyTypes();
|
||||
|
||||
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 { getLotOccupancy } from "../../helpers/lotOccupancyDB/getLotOccupancy.js";
|
||||
import {
|
||||
getLotOccupancy
|
||||
} from "../../helpers/lotOccupancyDB/getLotOccupancy.js";
|
||||
|
||||
|
||||
export const handler: RequestHandler = (request, response) => {
|
||||
|
||||
const lotOccupancy = getLotOccupancy(request.params.lotOccupancyId);
|
||||
const lotOccupancy = getLotOccupancy(request.params.lotOccupancyId);
|
||||
|
||||
if (!lotOccupancy) {
|
||||
return response.redirect(configFunctions.getProperty("reverseProxy.urlPrefix") + "/lotOccupancies/?error=lotOccupancyIdNotFound");
|
||||
}
|
||||
if (!lotOccupancy) {
|
||||
return response.redirect(configFunctions.getProperty("reverseProxy.urlPrefix") + "/lotOccupancies/?error=lotOccupancyIdNotFound");
|
||||
}
|
||||
|
||||
return response.render("lotOccupancy-view", {
|
||||
headTitle: configFunctions.getProperty("aliases.lot") + " " + configFunctions.getProperty("aliases.occupancy") + " View",
|
||||
lotOccupancy
|
||||
});
|
||||
return response.render("lotOccupancy-view", {
|
||||
headTitle: configFunctions.getProperty("aliases.lot") + " " + configFunctions.getProperty("aliases.occupancy") + " View",
|
||||
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.occupant"): string;
|
||||
export declare function getProperty(propertyName: "aliases.occupants"): string;
|
||||
export declare function getProperty(propertyName: "settings.lotOccupancy.occupancyEndDateIsRequired"): boolean;
|
||||
export declare const keepAliveMillis: number;
|
||||
|
|
|
|||
|
|
@ -23,19 +23,19 @@ configFallbackValues.set("aliases.occupancy", "Occupancy");
|
|||
configFallbackValues.set("aliases.occupancies", "Occupancies");
|
||||
configFallbackValues.set("aliases.occupant", "Occupant");
|
||||
configFallbackValues.set("aliases.occupants", "Occupants");
|
||||
configFallbackValues.set("settings.lotOccupancy.occupancyEndDateIsRequired", true);
|
||||
export function getProperty(propertyName) {
|
||||
const propertyNameSplit = propertyName.split(".");
|
||||
let currentObject = config;
|
||||
for (const propertyNamePiece of propertyNameSplit) {
|
||||
if (currentObject[propertyNamePiece]) {
|
||||
if (Object.prototype.hasOwnProperty.call(currentObject, propertyNamePiece)) {
|
||||
currentObject = currentObject[propertyNamePiece];
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
return configFallbackValues.get(propertyName);
|
||||
}
|
||||
return configFallbackValues.get(propertyName);
|
||||
}
|
||||
return currentObject;
|
||||
}
|
||||
export const keepAliveMillis = getProperty("session.doKeepAlive")
|
||||
? Math.max(getProperty("session.maxAgeMillis") / 2, getProperty("session.maxAgeMillis") - (10 * 60 * 1000))
|
||||
: 0;
|
||||
export const keepAliveMillis = getProperty("session.doKeepAlive") ?
|
||||
Math.max(getProperty("session.maxAgeMillis") / 2, getProperty("session.maxAgeMillis") - (10 * 60 * 1000)) :
|
||||
0;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
// 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";
|
||||
|
||||
|
|
@ -8,7 +10,8 @@ import type * as configTypes from "../types/configTypes";
|
|||
* 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.backgroundURL", "/images/cemetery-background.jpg");
|
||||
|
|
@ -38,6 +41,8 @@ configFallbackValues.set("aliases.occupancies", "Occupancies");
|
|||
configFallbackValues.set("aliases.occupant", "Occupant");
|
||||
configFallbackValues.set("aliases.occupants", "Occupants");
|
||||
|
||||
configFallbackValues.set("settings.lotOccupancy.occupancyEndDateIsRequired", true);
|
||||
|
||||
|
||||
/*
|
||||
* 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.occupants"): string;
|
||||
|
||||
export function getProperty(propertyName: "settings.lotOccupancy.occupancyEndDateIsRequired"): boolean;
|
||||
|
||||
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]) {
|
||||
currentObject = currentObject[propertyNamePiece];
|
||||
} else {
|
||||
return configFallbackValues.get(propertyName);
|
||||
if (Object.prototype.hasOwnProperty.call(currentObject, propertyNamePiece)) {
|
||||
currentObject = currentObject[propertyNamePiece];
|
||||
continue;
|
||||
}
|
||||
|
||||
return configFallbackValues.get(propertyName);
|
||||
}
|
||||
}
|
||||
|
||||
return currentObject;
|
||||
|
||||
return currentObject;
|
||||
}
|
||||
|
||||
export const keepAliveMillis =
|
||||
getProperty("session.doKeepAlive")
|
||||
? Math.max(
|
||||
getProperty("session.maxAgeMillis") / 2,
|
||||
getProperty("session.maxAgeMillis") - (10 * 60 * 1000)
|
||||
)
|
||||
: 0;
|
||||
getProperty("session.doKeepAlive") ?
|
||||
Math.max(
|
||||
getProperty("session.maxAgeMillis") / 2,
|
||||
getProperty("session.maxAgeMillis") - (10 * 60 * 1000)
|
||||
) :
|
||||
0;
|
||||
|
|
@ -2,6 +2,10 @@ import { dateIntegerToString } from "@cityssm/expressjs-server-js/dateTimeFns.js
|
|||
import sqlite from "better-sqlite3";
|
||||
import { lotOccupancyDB as databasePath } from "../../data/databasePaths.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) => {
|
||||
const database = sqlite(databasePath, {
|
||||
readonly: true
|
||||
|
|
@ -22,7 +26,11 @@ export const getLotOccupancy = (lotOccupancyId) => {
|
|||
" and o.lotOccupancyId = ?")
|
||||
.get(lotOccupancyId);
|
||||
if (lotOccupancy) {
|
||||
lotOccupancy.lotOccupancyFields = getLotOccupancyFields(lotOccupancyId, database);
|
||||
lotOccupancy.lotOccupancyOccupants = getLotOccupancyOccupants(lotOccupancyId, database);
|
||||
lotOccupancy.lotOccupancyComments = getLotOccupancyComments(lotOccupancyId, database);
|
||||
lotOccupancy.lotOccupancyFees = getLotOccupancyFees(lotOccupancyId, database);
|
||||
lotOccupancy.lotOccupancyTransactions = getLotOccupancyTransactions(lotOccupancyId, database);
|
||||
}
|
||||
database.close();
|
||||
return lotOccupancy;
|
||||
|
|
|
|||
|
|
@ -12,6 +12,22 @@ import {
|
|||
getLotOccupancyOccupants
|
||||
} from "./getLotOccupancyOccupants.js";
|
||||
|
||||
import {
|
||||
getLotOccupancyComments
|
||||
} from "./getLotOccupancyComments.js";
|
||||
|
||||
import {
|
||||
getLotOccupancyFields
|
||||
} from "./getLotOccupancyFields.js";
|
||||
|
||||
import {
|
||||
getLotOccupancyFees
|
||||
} from "./getLotOccupancyFees.js";
|
||||
|
||||
import {
|
||||
getLotOccupancyTransactions
|
||||
} from "./getLotOccupancyTransactions.js";
|
||||
|
||||
import type * as recordTypes from "../../types/recordTypes";
|
||||
|
||||
|
||||
|
|
@ -40,7 +56,11 @@ export const getLotOccupancy = (lotOccupancyId: number | string): recordTypes.Lo
|
|||
.get(lotOccupancyId);
|
||||
|
||||
if (lotOccupancy) {
|
||||
lotOccupancy.lotOccupancyFields = getLotOccupancyFields(lotOccupancyId, database);
|
||||
lotOccupancy.lotOccupancyOccupants = getLotOccupancyOccupants(lotOccupancyId, database);
|
||||
lotOccupancy.lotOccupancyComments = getLotOccupancyComments(lotOccupancyId, database);
|
||||
lotOccupancy.lotOccupancyFees = getLotOccupancyFees(lotOccupancyId, database);
|
||||
lotOccupancy.lotOccupancyTransactions = getLotOccupancyTransactions(lotOccupancyId, database);
|
||||
}
|
||||
|
||||
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 {
|
||||
lotOccupancyDB as databasePath
|
||||
} 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;
|
||||
lotTypeId?: number | string;
|
||||
lotStatusId?: number | string;
|
||||
occupancyStatus?: "" | "occupied" | "unoccupied";
|
||||
}
|
||||
interface GetLotsOptions {
|
||||
limit: number;
|
||||
|
|
|
|||
|
|
@ -26,14 +26,30 @@ export const getLots = (filters, options) => {
|
|||
sqlWhereClause += " and l.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" +
|
||||
" 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)
|
||||
.get(sqlParameters)
|
||||
.recordCount;
|
||||
let lots = [];
|
||||
if (count > 0) {
|
||||
const currentDate = dateToInteger(new Date());
|
||||
lots = database
|
||||
.prepare("select l.lotId, l.lotName," +
|
||||
" t.lotType," +
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ interface GetLotsFilters {
|
|||
mapId ? : number | string;
|
||||
lotTypeId ? : number | string;
|
||||
lotStatusId ? : number | string;
|
||||
occupancyStatus ? : "" | "occupied" | "unoccupied";
|
||||
}
|
||||
|
||||
interface GetLotsOptions {
|
||||
|
|
@ -57,8 +58,26 @@ export const getLots = (filters ? : GetLotsFilters, options ? : GetLotsOptions):
|
|||
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" +
|
||||
" 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)
|
||||
.get(sqlParameters)
|
||||
.recordCount;
|
||||
|
|
@ -67,8 +86,6 @@ export const getLots = (filters ? : GetLotsFilters, options ? : GetLotsOptions):
|
|||
|
||||
if (count > 0) {
|
||||
|
||||
const currentDate = dateToInteger(new Date());
|
||||
|
||||
lots = database
|
||||
.prepare("select l.lotId, l.lotName," +
|
||||
" 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 {
|
||||
cityssmGlobal
|
||||
} from "@cityssm/bulma-webapp-js/src/types";
|
||||
|
||||
import type {
|
||||
BulmaJS
|
||||
} 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_view from "../handlers/lotOccupancies-get/view.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";
|
||||
export const router = Router();
|
||||
router.get("/", handler_search);
|
||||
router.post("/doSearchLotOccupancies", handler_doSearchLotOccupancies);
|
||||
router.get("/:lotOccupancyId", handler_view);
|
||||
router.get("/:lotOccupancyId/edit", permissionHandlers.updateGetHandler, handler_edit);
|
||||
router.post("/doUpdateLotOccupancy", permissionHandlers.updatePostHandler, handler_doUpdateLotOccupancy);
|
||||
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_view from "../handlers/lotOccupancies-get/view.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";
|
||||
|
||||
|
|
@ -22,7 +24,7 @@ router.post("/doSearchLotOccupancies",
|
|||
handler_doSearchLotOccupancies);
|
||||
|
||||
|
||||
router.get("/:lotOccupancyId",
|
||||
router.get("/:lotOccupancyId",
|
||||
handler_view);
|
||||
|
||||
|
||||
|
|
@ -30,5 +32,9 @@ router.get("/:lotOccupancyId/edit",
|
|||
permissionHandlers.updateGetHandler,
|
||||
handler_edit);
|
||||
|
||||
router.post("/doUpdateLotOccupancy",
|
||||
permissionHandlers.updatePostHandler,
|
||||
handler_doUpdateLotOccupancy);
|
||||
|
||||
|
||||
export default router;
|
||||
|
|
@ -23,6 +23,12 @@ export interface Config {
|
|||
occupant?: string;
|
||||
occupants?: string;
|
||||
};
|
||||
settings?: {
|
||||
lotOccupancy?: {
|
||||
lotIdIsRequired?: boolean;
|
||||
occupancyEndDateIsRequired?: boolean;
|
||||
};
|
||||
};
|
||||
}
|
||||
interface ConfigApplication {
|
||||
applicationName?: string;
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ export interface Config {
|
|||
canLogin?: string[];
|
||||
canUpdate?: string[];
|
||||
isAdmin?: string[];
|
||||
},
|
||||
};
|
||||
aliases?: {
|
||||
lot?: string;
|
||||
lots?: string;
|
||||
|
|
@ -22,7 +22,13 @@ export interface Config {
|
|||
occupancies?: string;
|
||||
occupant?: string;
|
||||
occupants?: string;
|
||||
}
|
||||
};
|
||||
settings?: {
|
||||
lotOccupancy?: {
|
||||
lotIdIsRequired?: boolean;
|
||||
occupancyEndDateIsRequired?: boolean;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
interface ConfigApplication {
|
||||
|
|
|
|||
|
|
@ -107,6 +107,30 @@ export interface Occupant extends Record {
|
|||
occupantPostalCode?: 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 {
|
||||
lotOccupancyId?: number;
|
||||
lotOccupantIndex?: number;
|
||||
|
|
@ -122,6 +146,11 @@ export interface LotOccupancyComment extends Record {
|
|||
lotOccupancyCommentTimeString?: string;
|
||||
lotOccupancyComment?: string;
|
||||
}
|
||||
export interface LotOccupancyField extends OccupancyTypeField, Record {
|
||||
lotOccupancyId?: number;
|
||||
occupancyTypeFieldId?: number;
|
||||
lotOccupancyFieldValue?: string;
|
||||
}
|
||||
export interface LotOccupancy extends Record {
|
||||
lotOccupancyId?: number;
|
||||
occupancyTypeId?: number;
|
||||
|
|
@ -134,8 +163,11 @@ export interface LotOccupancy extends Record {
|
|||
occupancyStartDateString?: string;
|
||||
occupancyEndDate?: number;
|
||||
occupancyEndDateString?: string;
|
||||
lotOccupancyFields?: LotOccupancyField[];
|
||||
lotOccupancyComments?: LotOccupancyComment[];
|
||||
lotOccupancyOccupants?: LotOccupancyOccupant[];
|
||||
lotOccupancyFees?: LotOccupancyFee[];
|
||||
lotOccupancyTransactions?: LotOccupancyTransaction[];
|
||||
}
|
||||
export interface User {
|
||||
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 {
|
||||
lotOccupancyId ? : 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 {
|
||||
lotOccupancyId ? : number;
|
||||
|
||||
|
|
@ -192,8 +232,11 @@ export interface LotOccupancy extends Record {
|
|||
occupancyEndDate ? : number;
|
||||
occupancyEndDateString ? : string;
|
||||
|
||||
lotOccupancyFields? : LotOccupancyField[];
|
||||
lotOccupancyComments ? : LotOccupancyComment[];
|
||||
lotOccupancyOccupants ? : LotOccupancyOccupant[];
|
||||
lotOccupancyFees?: LotOccupancyFee[];
|
||||
lotOccupancyTransactions?: LotOccupancyTransaction[];
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -16,28 +16,142 @@
|
|||
</li>
|
||||
<li>
|
||||
<a href="<%= urlPrefix %>/lotOccupancies/<%= lotOccupancy.lotOccupancyId %>">
|
||||
<%= configFunctions.getProperty("aliases.occupancy") %> View
|
||||
<%= configFunctions.getProperty("aliases.occupancy") %>: <%= lotOccupancy.lotName %>
|
||||
</a>
|
||||
</li>
|
||||
<li class="is-active">
|
||||
<a href="#" aria-current="page">
|
||||
<%= configFunctions.getProperty("aliases.occupancy") %> Edit
|
||||
Update <%= configFunctions.getProperty("aliases.occupancy") %>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
<h1 class="title is-1">
|
||||
<%= configFunctions.getProperty("aliases.occupancy") %> Edit
|
||||
<%= configFunctions.getProperty("aliases.occupancy") %> Update
|
||||
</h1>
|
||||
|
||||
<div class="fixed-container is-fixed-bottom-right mx-4 my-4 has-text-right is-hidden-print">
|
||||
<button class="button is-circle is-primary has-tooltip-left" data-tooltip="Update <%= configFunctions.getProperty("aliases.occupancy") %>" type="submit">
|
||||
<i class="fas fa-save" aria-hidden="true"></i>
|
||||
<span class="sr-only">Update <%= configFunctions.getProperty("aliases.occupancy") %></span>
|
||||
</button>
|
||||
</div>
|
||||
<form id="form--lotOccupancy">
|
||||
<div class="fixed-container is-fixed-bottom-right mx-4 my-4 has-text-right is-hidden-print">
|
||||
<button class="button is-circle is-primary has-tooltip-left" data-tooltip="Update <%= configFunctions.getProperty("aliases.occupancy") %>" type="submit">
|
||||
<i class="fas fa-save" aria-hidden="true"></i>
|
||||
<span class="sr-only">Update <%= configFunctions.getProperty("aliases.occupancy") %></span>
|
||||
</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'); -%>
|
||||
|
||||
<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'); -%>
|
||||
|
|
|
|||
|
|
@ -1,39 +1,144 @@
|
|||
<%- include('_header'); -%>
|
||||
|
||||
<nav class="breadcrumb">
|
||||
<ul>
|
||||
<li><a href="<%= urlPrefix %>/dashboard">Home</a></li>
|
||||
<li>
|
||||
<a href="<%= urlPrefix %>/lotOccupancies">
|
||||
<span class="icon is-small">
|
||||
<span class="fa-layers fa-fw" aria-hidden="true">
|
||||
<i class="fas fa-vector-square"></i>
|
||||
<i class="fas fa-user" data-fa-transform="shrink-10"></i>
|
||||
<ul>
|
||||
<li><a href="<%= urlPrefix %>/dashboard">Home</a></li>
|
||||
<li>
|
||||
<a href="<%= urlPrefix %>/lotOccupancies">
|
||||
<span class="icon is-small">
|
||||
<span class="fa-layers fa-fw" aria-hidden="true">
|
||||
<i class="fas fa-vector-square"></i>
|
||||
<i class="fas fa-user" data-fa-transform="shrink-10"></i>
|
||||
</span>
|
||||
</span>
|
||||
</span>
|
||||
<span><%= configFunctions.getProperty("aliases.lots") %> <%= configFunctions.getProperty("aliases.occupancies") %></span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="is-active"><a href="#" aria-current="page">
|
||||
<%= configFunctions.getProperty("aliases.occupancy") %> View
|
||||
</a></li>
|
||||
</ul>
|
||||
<span><%= configFunctions.getProperty("aliases.lots") %>
|
||||
<%= configFunctions.getProperty("aliases.occupancies") %></span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="is-active">
|
||||
<a href="#" aria-current="page">
|
||||
<%= configFunctions.getProperty("aliases.occupancy") %>: <%= lotOccupancy.lotName %>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
<h1 class="title is-1">
|
||||
<%= configFunctions.getProperty("aliases.occupancy") %> View
|
||||
<%= configFunctions.getProperty("aliases.occupancy") %>: <%= lotOccupancy.lotName %>
|
||||
</h1>
|
||||
|
||||
<% if (user.userProperties.canUpdate) { %>
|
||||
<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">
|
||||
<i class="fas fa-pencil-alt" aria-hidden="true"></i>
|
||||
<span class="sr-only">Update <%= configFunctions.getProperty("aliases.occupancy") %></span>
|
||||
<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">
|
||||
<i class="fas fa-pencil-alt" aria-hidden="true"></i>
|
||||
<span class="sr-only">Update <%= configFunctions.getProperty("aliases.occupancy") %></span>
|
||||
</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('_footerB'); -%>
|
||||
<%- include('_footerB'); -%>
|
||||
Loading…
Reference in New Issue