major refactoring, but the application starts!

deepsource-autofix-76c6eb20
Dan Gowans 2025-02-25 15:25:38 -05:00
parent 06f6874298
commit 0bdc76247f
98 changed files with 7548 additions and 1115 deletions

View File

@ -3,7 +3,7 @@ export const configDefaultValues = {
activeDirectory: undefined, activeDirectory: undefined,
'application.applicationName': 'Sunrise CMS', 'application.applicationName': 'Sunrise CMS',
'application.backgroundURL': '/images/cemetery-background.jpg', 'application.backgroundURL': '/images/cemetery-background.jpg',
'application.logoURL': '/images/cemetery-logo.png', 'application.logoURL': '/images/sunrise-cms.png',
'application.httpPort': 7000, 'application.httpPort': 7000,
'application.userDomain': '', 'application.userDomain': '',
'application.useTestDatabases': false, 'application.useTestDatabases': false,

View File

@ -13,7 +13,7 @@ export const configDefaultValues = {
'application.applicationName': 'Sunrise CMS', 'application.applicationName': 'Sunrise CMS',
'application.backgroundURL': '/images/cemetery-background.jpg', 'application.backgroundURL': '/images/cemetery-background.jpg',
'application.logoURL': '/images/cemetery-logo.png', 'application.logoURL': '/images/sunrise-cms.png',
'application.httpPort': 7000, 'application.httpPort': 7000,
'application.userDomain': '', 'application.userDomain': '',
'application.useTestDatabases': false, 'application.useTestDatabases': false,

View File

@ -13,4 +13,4 @@ export interface AddBurialSiteForm {
burialSiteTypeFieldIds?: string; burialSiteTypeFieldIds?: string;
[fieldValue_burialSiteTypeFieldId: string]: unknown; [fieldValue_burialSiteTypeFieldId: string]: unknown;
} }
export default function addLot(burialSiteForm: AddBurialSiteForm, user: User): Promise<number>; export default function addBurialSite(burialSiteForm: AddBurialSiteForm, user: User): Promise<number>;

View File

@ -1,7 +1,7 @@
import { buildBurialSiteName } from '../helpers/burialSites.helpers.js'; import { buildBurialSiteName } from '../helpers/burialSites.helpers.js';
import addOrUpdateBurialSiteField from './addOrUpdateBurialSiteField.js'; import addOrUpdateBurialSiteField from './addOrUpdateBurialSiteField.js';
import { acquireConnection } from './pool.js'; import { acquireConnection } from './pool.js';
export default async function addLot(burialSiteForm, user) { export default async function addBurialSite(burialSiteForm, user) {
const database = await acquireConnection(); const database = await acquireConnection();
const rightNowMillis = Date.now(); const rightNowMillis = Date.now();
const burialSiteName = buildBurialSiteName(burialSiteForm); const burialSiteName = buildBurialSiteName(burialSiteForm);

View File

@ -23,7 +23,7 @@ export interface AddBurialSiteForm {
[fieldValue_burialSiteTypeFieldId: string]: unknown [fieldValue_burialSiteTypeFieldId: string]: unknown
} }
export default async function addLot( export default async function addBurialSite(
burialSiteForm: AddBurialSiteForm, burialSiteForm: AddBurialSiteForm,
user: User user: User
): Promise<number> { ): Promise<number> {

View File

@ -1,14 +1,10 @@
import { dateStringToInteger } from '@cityssm/utils-datetime'; import { dateStringToInteger } from '@cityssm/utils-datetime';
import addBurialSiteContractOccupant from './addBurialSiteContractOccupant.js';
import addOrUpdateBurialSiteContractField from './addOrUpdateBurialSiteContractField.js'; import addOrUpdateBurialSiteContractField from './addOrUpdateBurialSiteContractField.js';
import { acquireConnection } from './pool.js'; import { acquireConnection } from './pool.js';
export default async function addBurialSiteContract(addForm, user, connectedDatabase) { export default async function addBurialSiteContract(addForm, user, connectedDatabase) {
const database = connectedDatabase ?? (await acquireConnection()); const database = connectedDatabase ?? (await acquireConnection());
const rightNowMillis = Date.now(); const rightNowMillis = Date.now();
const contractStartDate = dateStringToInteger(addForm.contractStartDateString); const contractStartDate = dateStringToInteger(addForm.contractStartDateString);
if (contractStartDate <= 0) {
console.error(addForm);
}
const result = database const result = database
.prepare(`insert into BurialSiteContracts ( .prepare(`insert into BurialSiteContracts (
contractTypeId, lotId, contractTypeId, lotId,
@ -22,31 +18,15 @@ export default async function addBurialSiteContract(addForm, user, connectedData
const burialSiteContractId = result.lastInsertRowid; const burialSiteContractId = result.lastInsertRowid;
const contractTypeFieldIds = (addForm.contractTypeFieldIds ?? '').split(','); const contractTypeFieldIds = (addForm.contractTypeFieldIds ?? '').split(',');
for (const contractTypeFieldId of contractTypeFieldIds) { for (const contractTypeFieldId of contractTypeFieldIds) {
const burialSiteContractFieldValue = addForm[`burialSiteContractFieldValue_${contractTypeFieldId}`]; const fieldValue = addForm[`fieldValue_${contractTypeFieldId}`];
if ((burialSiteContractFieldValue ?? '') !== '') { if ((fieldValue ?? '') !== '') {
await addOrUpdateBurialSiteContractField({ await addOrUpdateBurialSiteContractField({
burialSiteContractId, burialSiteContractId,
contractTypeFieldId, contractTypeFieldId,
burialSiteContractFieldValue: burialSiteContractFieldValue ?? '' fieldValue: fieldValue ?? ''
}, user, database); }, user, database);
} }
} }
if ((addForm.lotOccupantTypeId ?? '') !== '') {
await addBurialSiteContractOccupant({
burialSiteContractId,
lotOccupantTypeId: addForm.lotOccupantTypeId ?? '',
occupantName: addForm.occupantName ?? '',
occupantFamilyName: addForm.occupantFamilyName ?? '',
occupantAddress1: addForm.occupantAddress1 ?? '',
occupantAddress2: addForm.occupantAddress2 ?? '',
occupantCity: addForm.occupantCity ?? '',
occupantProvince: addForm.occupantProvince ?? '',
occupantPostalCode: addForm.occupantPostalCode ?? '',
occupantPhoneNumber: addForm.occupantPhoneNumber ?? '',
occupantEmailAddress: addForm.occupantEmailAddress ?? '',
occupantComment: addForm.occupantComment ?? ''
}, user, database);
}
if (connectedDatabase === undefined) { if (connectedDatabase === undefined) {
database.release(); database.release();
} }

View File

@ -1,7 +1,6 @@
import { type DateString, dateStringToInteger } from '@cityssm/utils-datetime' import { type DateString, dateStringToInteger } from '@cityssm/utils-datetime'
import type { PoolConnection } from 'better-sqlite-pool' import type { PoolConnection } from 'better-sqlite-pool'
import addBurialSiteContractOccupant from './addBurialSiteContractOccupant.js'
import addOrUpdateBurialSiteContractField from './addOrUpdateBurialSiteContractField.js' import addOrUpdateBurialSiteContractField from './addOrUpdateBurialSiteContractField.js'
import { acquireConnection } from './pool.js' import { acquireConnection } from './pool.js'
@ -41,10 +40,6 @@ export default async function addBurialSiteContract(
addForm.contractStartDateString as DateString addForm.contractStartDateString as DateString
) )
if (contractStartDate <= 0) {
console.error(addForm)
}
const result = database const result = database
.prepare( .prepare(
`insert into BurialSiteContracts ( `insert into BurialSiteContracts (
@ -60,9 +55,7 @@ export default async function addBurialSiteContract(
contractStartDate, contractStartDate,
addForm.contractEndDateString === '' addForm.contractEndDateString === ''
? undefined ? undefined
: dateStringToInteger( : dateStringToInteger(addForm.contractEndDateString as DateString),
addForm.contractEndDateString as DateString
),
user.userName, user.userName,
rightNowMillis, rightNowMillis,
user.userName, user.userName,
@ -71,21 +64,19 @@ export default async function addBurialSiteContract(
const burialSiteContractId = result.lastInsertRowid as number const burialSiteContractId = result.lastInsertRowid as number
const contractTypeFieldIds = ( const contractTypeFieldIds = (addForm.contractTypeFieldIds ?? '').split(',')
addForm.contractTypeFieldIds ?? ''
).split(',')
for (const contractTypeFieldId of contractTypeFieldIds) { for (const contractTypeFieldId of contractTypeFieldIds) {
const burialSiteContractFieldValue = addForm[ const fieldValue = addForm[`fieldValue_${contractTypeFieldId}`] as
`burialSiteContractFieldValue_${contractTypeFieldId}` | string
] as string | undefined | undefined
if ((burialSiteContractFieldValue ?? '') !== '') { if ((fieldValue ?? '') !== '') {
await addOrUpdateBurialSiteContractField( await addOrUpdateBurialSiteContractField(
{ {
burialSiteContractId, burialSiteContractId,
contractTypeFieldId, contractTypeFieldId,
burialSiteContractFieldValue: burialSiteContractFieldValue ?? '' fieldValue: fieldValue ?? ''
}, },
user, user,
database database
@ -93,27 +84,6 @@ export default async function addBurialSiteContract(
} }
} }
if ((addForm.lotOccupantTypeId ?? '') !== '') {
await addBurialSiteContractOccupant(
{
burialSiteContractId,
lotOccupantTypeId: addForm.lotOccupantTypeId ?? '',
occupantName: addForm.occupantName ?? '',
occupantFamilyName: addForm.occupantFamilyName ?? '',
occupantAddress1: addForm.occupantAddress1 ?? '',
occupantAddress2: addForm.occupantAddress2 ?? '',
occupantCity: addForm.occupantCity ?? '',
occupantProvince: addForm.occupantProvince ?? '',
occupantPostalCode: addForm.occupantPostalCode ?? '',
occupantPhoneNumber: addForm.occupantPhoneNumber ?? '',
occupantEmailAddress: addForm.occupantEmailAddress ?? '',
occupantComment: addForm.occupantComment ?? ''
},
user,
database
)
}
if (connectedDatabase === undefined) { if (connectedDatabase === undefined) {
database.release() database.release()
} }

View File

@ -1,5 +1,6 @@
export interface AddCemeteryForm { export interface AddCemeteryForm {
cemeteryName: string; cemeteryName: string;
cemeteryKey: string;
cemeteryDescription: string; cemeteryDescription: string;
cemeterySvg: string; cemeterySvg: string;
cemeteryLatitude: string; cemeteryLatitude: string;

View File

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

View File

@ -2,6 +2,7 @@ import { acquireConnection } from './pool.js'
export interface AddCemeteryForm { export interface AddCemeteryForm {
cemeteryName: string cemeteryName: string
cemeteryKey: string
cemeteryDescription: string cemeteryDescription: string
cemeterySvg: string cemeterySvg: string
@ -27,17 +28,18 @@ export default async function addCemetery(
const result = database const result = database
.prepare( .prepare(
`insert into Cemeteries ( `insert into Cemeteries (
cemeteryName, cemeteryDescription, cemeteryName, cemeteryKey, cemeteryDescription,
cemeterySvg, cemeteryLatitude, cemeteryLongitude, cemeterySvg, cemeteryLatitude, cemeteryLongitude,
cemeteryAddress1, cemeteryAddress2, cemeteryAddress1, cemeteryAddress2,
cemeteryCity, cemeteryProvince, cemeteryPostalCode, cemeteryCity, cemeteryProvince, cemeteryPostalCode,
cemeteryPhoneNumber, cemeteryPhoneNumber,
recordCreate_userName, recordCreate_timeMillis, recordCreate_userName, recordCreate_timeMillis,
recordUpdate_userName, recordUpdate_timeMillis) recordUpdate_userName, recordUpdate_timeMillis)
values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)` values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
) )
.run( .run(
addForm.cemeteryName, addForm.cemeteryName,
addForm.cemeteryKey,
addForm.cemeteryDescription, addForm.cemeteryDescription,
addForm.cemeterySvg, addForm.cemeterySvg,
addForm.cemeteryLatitude === '' ? undefined : addForm.cemeteryLatitude, addForm.cemeteryLatitude === '' ? undefined : addForm.cemeteryLatitude,

View File

@ -2,4 +2,4 @@ export interface AddWorkOrderLotForm {
workOrderId: number | string; workOrderId: number | string;
burialSiteId: number | string; burialSiteId: number | string;
} }
export default function addWorkOrderLot(workOrderLotForm: AddWorkOrderLotForm, user: User): Promise<boolean>; export default function addWorkOrderBurialSite(workOrderLotForm: AddWorkOrderLotForm, user: User): Promise<boolean>;

View File

@ -1,5 +1,5 @@
import { acquireConnection } from './pool.js'; import { acquireConnection } from './pool.js';
export default async function addWorkOrderLot(workOrderLotForm, user) { export default async function addWorkOrderBurialSite(workOrderLotForm, user) {
const database = await acquireConnection(); const database = await acquireConnection();
const rightNowMillis = Date.now(); const rightNowMillis = Date.now();
const row = database const row = database

View File

@ -5,7 +5,7 @@ export interface AddWorkOrderLotForm {
burialSiteId: number | string burialSiteId: number | string
} }
export default async function addWorkOrderLot( export default async function addWorkOrderBurialSite(
workOrderLotForm: AddWorkOrderLotForm, workOrderLotForm: AddWorkOrderLotForm,
user: User user: User
): Promise<boolean> { ): Promise<boolean> {

View File

@ -1,2 +1,2 @@
import type { Cemetery } from '../types/recordTypes.js'; import type { Cemetery } from '../types/recordTypes.js';
export default function getMap(cemeteryId: number | string): Promise<Cemetery | undefined>; export default function getCemetery(cemeteryId: number | string): Promise<Cemetery | undefined>;

View File

@ -1,8 +1,8 @@
import { acquireConnection } from './pool.js'; import { acquireConnection } from './pool.js';
export default async function getMap(cemeteryId) { export default async function getCemetery(cemeteryId) {
const database = await acquireConnection(); const database = await acquireConnection();
const map = database const map = database
.prepare(`select m.cemeteryId, m.cemeteryName, m.cemeteryDescription, .prepare(`select m.cemeteryId, m.cemeteryName, m.cemeteryKey, m.cemeteryDescription,
m.cemeteryLatitude, m.cemeteryLongitude, m.cemeterySvg, m.cemeteryLatitude, m.cemeteryLongitude, m.cemeterySvg,
m.cemeteryAddress1, m.cemeteryAddress2, m.cemeteryCity, m.cemeteryProvince, m.cemeteryPostalCode, m.cemeteryAddress1, m.cemeteryAddress2, m.cemeteryCity, m.cemeteryProvince, m.cemeteryPostalCode,
m.cemeteryPhoneNumber, m.cemeteryPhoneNumber,

View File

@ -2,14 +2,14 @@ import type { Cemetery } from '../types/recordTypes.js'
import { acquireConnection } from './pool.js' import { acquireConnection } from './pool.js'
export default async function getMap( export default async function getCemetery(
cemeteryId: number | string cemeteryId: number | string
): Promise<Cemetery | undefined> { ): Promise<Cemetery | undefined> {
const database = await acquireConnection() const database = await acquireConnection()
const map = database const map = database
.prepare( .prepare(
`select m.cemeteryId, m.cemeteryName, m.cemeteryDescription, `select m.cemeteryId, m.cemeteryName, m.cemeteryKey, m.cemeteryDescription,
m.cemeteryLatitude, m.cemeteryLongitude, m.cemeterySvg, m.cemeteryLatitude, m.cemeteryLongitude, m.cemeterySvg,
m.cemeteryAddress1, m.cemeteryAddress2, m.cemeteryCity, m.cemeteryProvince, m.cemeteryPostalCode, m.cemeteryAddress1, m.cemeteryAddress2, m.cemeteryCity, m.cemeteryProvince, m.cemeteryPostalCode,
m.cemeteryPhoneNumber, m.cemeteryPhoneNumber,

View File

@ -23,7 +23,7 @@ const createStatements = [
orderNumber smallint not null default 0, orderNumber smallint not null default 0,
${recordColumns})`, ${recordColumns})`,
`create index if not exists idx_BurialSiteTypes_orderNumber `create index if not exists idx_BurialSiteTypes_orderNumber
on LotTypes (orderNumber, burialSiteType)`, on BurialSiteTypes (orderNumber, burialSiteType)`,
`create table if not exists BurialSiteTypeFields ( `create table if not exists BurialSiteTypeFields (
burialSiteTypeFieldId integer not null primary key autoincrement, burialSiteTypeFieldId integer not null primary key autoincrement,
burialSiteTypeId integer not null, burialSiteTypeId integer not null,
@ -110,7 +110,7 @@ const createStatements = [
commentTime integer not null check (commentTime >= 0), commentTime integer not null check (commentTime >= 0),
comment text not null, comment text not null,
${recordColumns}, ${recordColumns},
foreign key (lotId) references BurialSites (burialSiteId))`, foreign key (burialSiteId) references BurialSites (burialSiteId))`,
`create index if not exists idx_BurialSiteComments_datetime `create index if not exists idx_BurialSiteComments_datetime
on BurialSiteComments (burialSiteId, commentDate, commentTime)`, on BurialSiteComments (burialSiteId, commentDate, commentTime)`,
/* /*
@ -221,9 +221,9 @@ const createStatements = [
`create table if not exists BurialSiteContractInterments ( `create table if not exists BurialSiteContractInterments (
burialSiteContractId integer not null, burialSiteContractId integer not null,
intermentNumber integer not null, intermentNumber integer not null,
isCremated bit not null default 0,
deceasedName varchar(50) not null, deceasedName varchar(50) not null,
isCremated bit not null default 0,
birthDate integer, birthDate integer,
birthPlace varchar(100), birthPlace varchar(100),
@ -239,7 +239,7 @@ const createStatements = [
${recordColumns}, ${recordColumns},
primary key (burialSiteContractId, intermentNumber), primary key (burialSiteContractId, intermentNumber),
foreign key (burialSiteId) references BurialSites (burialSiteId), foreign key (burialSiteContractId) references BurialSiteContracts (burialSiteContractId),
foreign key (intermentContainerTypeId) references IntermentContainerTypes (intermentContainerTypeId), foreign key (intermentContainerTypeId) references IntermentContainerTypes (intermentContainerTypeId),
foreign key (intermentCommittalTypeId) references IntermentCommittalTypes (intermentCommittalTypeId)) without rowid`, foreign key (intermentCommittalTypeId) references IntermentCommittalTypes (intermentCommittalTypeId)) without rowid`,
/* /*

View File

@ -31,7 +31,7 @@ const createStatements = [
${recordColumns})`, ${recordColumns})`,
`create index if not exists idx_BurialSiteTypes_orderNumber `create index if not exists idx_BurialSiteTypes_orderNumber
on LotTypes (orderNumber, burialSiteType)`, on BurialSiteTypes (orderNumber, burialSiteType)`,
`create table if not exists BurialSiteTypeFields ( `create table if not exists BurialSiteTypeFields (
burialSiteTypeFieldId integer not null primary key autoincrement, burialSiteTypeFieldId integer not null primary key autoincrement,
@ -129,7 +129,7 @@ const createStatements = [
commentTime integer not null check (commentTime >= 0), commentTime integer not null check (commentTime >= 0),
comment text not null, comment text not null,
${recordColumns}, ${recordColumns},
foreign key (lotId) references BurialSites (burialSiteId))`, foreign key (burialSiteId) references BurialSites (burialSiteId))`,
`create index if not exists idx_BurialSiteComments_datetime `create index if not exists idx_BurialSiteComments_datetime
on BurialSiteComments (burialSiteId, commentDate, commentTime)`, on BurialSiteComments (burialSiteId, commentDate, commentTime)`,
@ -260,9 +260,9 @@ const createStatements = [
`create table if not exists BurialSiteContractInterments ( `create table if not exists BurialSiteContractInterments (
burialSiteContractId integer not null, burialSiteContractId integer not null,
intermentNumber integer not null, intermentNumber integer not null,
isCremated bit not null default 0,
deceasedName varchar(50) not null, deceasedName varchar(50) not null,
isCremated bit not null default 0,
birthDate integer, birthDate integer,
birthPlace varchar(100), birthPlace varchar(100),
@ -278,7 +278,7 @@ const createStatements = [
${recordColumns}, ${recordColumns},
primary key (burialSiteContractId, intermentNumber), primary key (burialSiteContractId, intermentNumber),
foreign key (burialSiteId) references BurialSites (burialSiteId), foreign key (burialSiteContractId) references BurialSiteContracts (burialSiteContractId),
foreign key (intermentContainerTypeId) references IntermentContainerTypes (intermentContainerTypeId), foreign key (intermentContainerTypeId) references IntermentContainerTypes (intermentContainerTypeId),
foreign key (intermentCommittalTypeId) references IntermentCommittalTypes (intermentCommittalTypeId)) without rowid`, foreign key (intermentCommittalTypeId) references IntermentCommittalTypes (intermentCommittalTypeId)) without rowid`,

View File

@ -1,6 +1,7 @@
export interface UpdateCemeteryForm { export interface UpdateCemeteryForm {
cemeteryId: string; cemeteryId: string;
cemeteryName: string; cemeteryName: string;
cemeteryKey: string;
cemeteryDescription: string; cemeteryDescription: string;
cemeterySvg: string; cemeterySvg: string;
cemeteryLatitude: string; cemeteryLatitude: string;

View File

@ -2,23 +2,28 @@ import { acquireConnection } from './pool.js';
export default async function updateCemetery(updateForm, user) { export default async function updateCemetery(updateForm, user) {
const database = await acquireConnection(); const database = await acquireConnection();
const result = database const result = database
.prepare(`update Maps .prepare(`update Cemeteries
set cemeteryName = ?, set cemeteryName = ?,
mapDescription = ?, cemeteryKey = ?,
mapSVG = ?, cemeteryDescription = ?,
mapLatitude = ?, cemeterySvg = ?,
mapLongitude = ?, cemeteryLatitude = ?,
mapAddress1 = ?, cemeteryLongitude = ?,
mapAddress2 = ?, cemeteryAddress1 = ?,
mapCity = ?, cemeteryAddress2 = ?,
mapProvince = ?, cemeteryCity = ?,
mapPostalCode = ?, cemeteryProvince = ?,
mapPhoneNumber = ?, cemeteryPostalCode = ?,
cemeteryPhoneNumber = ?,
recordUpdate_userName = ?, recordUpdate_userName = ?,
recordUpdate_timeMillis = ? recordUpdate_timeMillis = ?
where cemeteryId = ? where cemeteryId = ?
and recordDelete_timeMillis is null`) and recordDelete_timeMillis is null`)
.run(updateForm.cemeteryName, updateForm.cemeteryDescription, updateForm.cemeterySvg, updateForm.cemeteryLatitude === '' ? undefined : updateForm.cemeteryLatitude, updateForm.cemeteryLongitude === '' ? undefined : updateForm.cemeteryLongitude, updateForm.cemeteryAddress1, updateForm.cemeteryAddress2, updateForm.cemeteryCity, updateForm.cemeteryProvince, updateForm.cemeteryPostalCode, updateForm.cemeteryPhoneNumber, user.userName, Date.now(), updateForm.cemeteryId); .run(updateForm.cemeteryName, updateForm.cemeteryKey, updateForm.cemeteryDescription, updateForm.cemeterySvg, updateForm.cemeteryLatitude === ''
? undefined
: updateForm.cemeteryLatitude, updateForm.cemeteryLongitude === ''
? undefined
: updateForm.cemeteryLongitude, updateForm.cemeteryAddress1, updateForm.cemeteryAddress2, updateForm.cemeteryCity, updateForm.cemeteryProvince, updateForm.cemeteryPostalCode, updateForm.cemeteryPhoneNumber, user.userName, Date.now(), updateForm.cemeteryId);
database.release(); database.release();
return result.changes > 0; return result.changes > 0;
} }

View File

@ -3,6 +3,7 @@ import { acquireConnection } from './pool.js'
export interface UpdateCemeteryForm { export interface UpdateCemeteryForm {
cemeteryId: string cemeteryId: string
cemeteryName: string cemeteryName: string
cemeteryKey: string
cemeteryDescription: string cemeteryDescription: string
cemeterySvg: string cemeterySvg: string
cemeteryLatitude: string cemeteryLatitude: string
@ -23,18 +24,19 @@ export default async function updateCemetery(
const result = database const result = database
.prepare( .prepare(
`update Maps `update Cemeteries
set cemeteryName = ?, set cemeteryName = ?,
mapDescription = ?, cemeteryKey = ?,
mapSVG = ?, cemeteryDescription = ?,
mapLatitude = ?, cemeterySvg = ?,
mapLongitude = ?, cemeteryLatitude = ?,
mapAddress1 = ?, cemeteryLongitude = ?,
mapAddress2 = ?, cemeteryAddress1 = ?,
mapCity = ?, cemeteryAddress2 = ?,
mapProvince = ?, cemeteryCity = ?,
mapPostalCode = ?, cemeteryProvince = ?,
mapPhoneNumber = ?, cemeteryPostalCode = ?,
cemeteryPhoneNumber = ?,
recordUpdate_userName = ?, recordUpdate_userName = ?,
recordUpdate_timeMillis = ? recordUpdate_timeMillis = ?
where cemeteryId = ? where cemeteryId = ?
@ -42,10 +44,15 @@ export default async function updateCemetery(
) )
.run( .run(
updateForm.cemeteryName, updateForm.cemeteryName,
updateForm.cemeteryKey,
updateForm.cemeteryDescription, updateForm.cemeteryDescription,
updateForm.cemeterySvg, updateForm.cemeterySvg,
updateForm.cemeteryLatitude === '' ? undefined : updateForm.cemeteryLatitude, updateForm.cemeteryLatitude === ''
updateForm.cemeteryLongitude === '' ? undefined : updateForm.cemeteryLongitude, ? undefined
: updateForm.cemeteryLatitude,
updateForm.cemeteryLongitude === ''
? undefined
: updateForm.cemeteryLongitude,
updateForm.cemeteryAddress1, updateForm.cemeteryAddress1,
updateForm.cemeteryAddress2, updateForm.cemeteryAddress2,
updateForm.cemeteryCity, updateForm.cemeteryCity,

View File

@ -5,7 +5,7 @@ import { minutesToSeconds } from '@cityssm/to-millis';
import Debug from 'debug'; import Debug from 'debug';
import NodeCache from 'node-cache'; import NodeCache from 'node-cache';
import getNextBurialSiteIdFromDatabase from '../database/getNextBurialSiteId.js'; import getNextBurialSiteIdFromDatabase from '../database/getNextBurialSiteId.js';
import getPreviousLotIdFromDatabase from '../database/getPreviousLotId.js'; import getPreviousBurialSiteIdFromDatabase from '../database/getPreviousBurialSiteId.js';
import { DEBUG_NAMESPACE } from '../debug.config.js'; import { DEBUG_NAMESPACE } from '../debug.config.js';
import { getConfigProperty } from './config.helpers.js'; import { getConfigProperty } from './config.helpers.js';
const debug = Debug(`${DEBUG_NAMESPACE}:burialSites.helpers:${process.pid}`); const debug = Debug(`${DEBUG_NAMESPACE}:burialSites.helpers:${process.pid}`);
@ -46,7 +46,7 @@ export async function getNextBurialSiteId(burialSiteId) {
export async function getPreviousBurialSiteId(burialSiteId) { export async function getPreviousBurialSiteId(burialSiteId) {
let previousBurialSiteId = previousBurialSiteIdCache.get(burialSiteId); let previousBurialSiteId = previousBurialSiteIdCache.get(burialSiteId);
if (previousBurialSiteId === undefined) { if (previousBurialSiteId === undefined) {
previousBurialSiteId = await getPreviousLotIdFromDatabase(burialSiteId); previousBurialSiteId = await getPreviousBurialSiteIdFromDatabase(burialSiteId);
if (previousBurialSiteId !== undefined) { if (previousBurialSiteId !== undefined) {
cacheBurialSiteIds(previousBurialSiteId, burialSiteId); cacheBurialSiteIds(previousBurialSiteId, burialSiteId);
} }

View File

@ -8,7 +8,7 @@ import Debug from 'debug'
import NodeCache from 'node-cache' import NodeCache from 'node-cache'
import getNextBurialSiteIdFromDatabase from '../database/getNextBurialSiteId.js' import getNextBurialSiteIdFromDatabase from '../database/getNextBurialSiteId.js'
import getPreviousLotIdFromDatabase from '../database/getPreviousLotId.js' import getPreviousBurialSiteIdFromDatabase from '../database/getPreviousBurialSiteId.js'
import { DEBUG_NAMESPACE } from '../debug.config.js' import { DEBUG_NAMESPACE } from '../debug.config.js'
import type { import type {
CacheBurialSiteIdsWorkerMessage, CacheBurialSiteIdsWorkerMessage,
@ -79,7 +79,7 @@ export async function getPreviousBurialSiteId(
previousBurialSiteIdCache.get(burialSiteId) previousBurialSiteIdCache.get(burialSiteId)
if (previousBurialSiteId === undefined) { if (previousBurialSiteId === undefined) {
previousBurialSiteId = await getPreviousLotIdFromDatabase(burialSiteId) previousBurialSiteId = await getPreviousBurialSiteIdFromDatabase(burialSiteId)
if (previousBurialSiteId !== undefined) { if (previousBurialSiteId !== undefined) {
cacheBurialSiteIds(previousBurialSiteId, burialSiteId) cacheBurialSiteIds(previousBurialSiteId, burialSiteId)

View File

@ -29,15 +29,15 @@ export async function authenticate(userName, password) {
const safeRedirects = new Set([ const safeRedirects = new Set([
'/admin/cleanup', '/admin/cleanup',
'/admin/fees', '/admin/fees',
'/admin/lottypes', '/admin/burialsitetypes',
'/admin/occupancytypes', '/admin/contracttypes',
'/admin/tables', '/admin/tables',
'/lotoccupancies', '/contracts',
'/contracts/new', '/contracts/new',
'/lots', '/burialSites',
'/lots/new', '/burialSites/new',
'/maps', '/cemeteries',
'/maps/new', '/cemeteries/new',
'/workorders', '/workorders',
'/workorders/new', '/workorders/new',
'/workorders/milestonecalendar', '/workorders/milestonecalendar',
@ -45,7 +45,7 @@ const safeRedirects = new Set([
'/reports' '/reports'
]); ]);
/* eslint-enable @cspell/spellchecker */ /* eslint-enable @cspell/spellchecker */
const recordUrl = /^\/(?:maps|lots|lotoccupancies|workorders)\/\d+(?:\/edit)?$/; const recordUrl = /^\/(?:cemeteries|burialSites|contracts|workorders)\/\d+(?:\/edit)?$/;
const printUrl = /^\/print\/(?:pdf|screen)\/[\d/=?A-Za-z-]+$/; const printUrl = /^\/print\/(?:pdf|screen)\/[\d/=?A-Za-z-]+$/;
export function getSafeRedirectURL(possibleRedirectURL = '') { export function getSafeRedirectURL(possibleRedirectURL = '') {
const urlPrefix = getConfigProperty('reverseProxy.urlPrefix'); const urlPrefix = getConfigProperty('reverseProxy.urlPrefix');

View File

@ -45,15 +45,15 @@ export async function authenticate(
const safeRedirects = new Set([ const safeRedirects = new Set([
'/admin/cleanup', '/admin/cleanup',
'/admin/fees', '/admin/fees',
'/admin/lottypes', '/admin/burialsitetypes',
'/admin/occupancytypes', '/admin/contracttypes',
'/admin/tables', '/admin/tables',
'/lotoccupancies', '/contracts',
'/contracts/new', '/contracts/new',
'/lots', '/burialSites',
'/lots/new', '/burialSites/new',
'/maps', '/cemeteries',
'/maps/new', '/cemeteries/new',
'/workorders', '/workorders',
'/workorders/new', '/workorders/new',
'/workorders/milestonecalendar', '/workorders/milestonecalendar',
@ -63,7 +63,7 @@ const safeRedirects = new Set([
/* eslint-enable @cspell/spellchecker */ /* eslint-enable @cspell/spellchecker */
const recordUrl = /^\/(?:maps|lots|lotoccupancies|workorders)\/\d+(?:\/edit)?$/ const recordUrl = /^\/(?:cemeteries|burialSites|contracts|workorders)\/\d+(?:\/edit)?$/
const printUrl = /^\/print\/(?:pdf|screen)\/[\d/=?A-Za-z-]+$/ const printUrl = /^\/print\/(?:pdf|screen)\/[\d/=?A-Za-z-]+$/

View File

@ -17,6 +17,6 @@ export declare function getWorkOrderMilestoneTypeById(workOrderMilestoneTypeId:
export declare function getWorkOrderMilestoneTypeByWorkOrderMilestoneType(workOrderMilestoneTypeString: string): Promise<WorkOrderMilestoneType | undefined>; export declare function getWorkOrderMilestoneTypeByWorkOrderMilestoneType(workOrderMilestoneTypeString: string): Promise<WorkOrderMilestoneType | undefined>;
export declare function preloadCaches(): Promise<void>; export declare function preloadCaches(): Promise<void>;
export declare function clearCaches(): void; export declare function clearCaches(): void;
type CacheTableNames = 'BurialSiteStatuses' | 'BurialSiteTypes' | 'BurialSiteTypeFields' | 'ContractTypes' | 'ContractTypeFields' | 'ContractTypePrints' | 'WorkOrderMilestoneTypes' | 'WorkOrderTypes'; type CacheTableNames = 'BurialSiteStatuses' | 'BurialSiteTypes' | 'BurialSiteTypeFields' | 'ContractTypes' | 'ContractTypeFields' | 'ContractTypePrints' | 'WorkOrderMilestoneTypes' | 'WorkOrderTypes' | 'FeeCategories';
export declare function clearCacheByTableName(tableName: CacheTableNames, relayMessage?: boolean): void; export declare function clearCacheByTableName(tableName: CacheTableNames, relayMessage?: boolean): void;
export {}; export {};

View File

@ -177,7 +177,6 @@ export function clearCacheByTableName(tableName, relayMessage = true) {
clearWorkOrderTypesCache(); clearWorkOrderTypesCache();
break; break;
} }
// eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check
default: { default: {
return; return;
} }

View File

@ -280,6 +280,7 @@ type CacheTableNames =
| 'ContractTypePrints' | 'ContractTypePrints'
| 'WorkOrderMilestoneTypes' | 'WorkOrderMilestoneTypes'
| 'WorkOrderTypes' | 'WorkOrderTypes'
| 'FeeCategories'
export function clearCacheByTableName( export function clearCacheByTableName(
tableName: CacheTableNames, tableName: CacheTableNames,
@ -314,7 +315,6 @@ export function clearCacheByTableName(
break break
} }
// eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check
default: { default: {
return return
} }

View File

@ -1,3 +1,5 @@
// eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair
/* eslint-disable security/detect-object-injection */
import * as dateTimeFunctions from '@cityssm/utils-datetime'; import * as dateTimeFunctions from '@cityssm/utils-datetime';
import getBurialSite from '../database/getBurialSite.js'; import getBurialSite from '../database/getBurialSite.js';
import getBurialSiteContract from '../database/getBurialSiteContract.js'; import getBurialSiteContract from '../database/getBurialSiteContract.js';

View File

@ -1,3 +1,6 @@
// eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair
/* eslint-disable security/detect-object-injection */
import * as dateTimeFunctions from '@cityssm/utils-datetime' import * as dateTimeFunctions from '@cityssm/utils-datetime'
import getBurialSite from '../database/getBurialSite.js' import getBurialSite from '../database/getBurialSite.js'

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

View File

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

View File

@ -0,0 +1,367 @@
"use strict";
// eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair
/* eslint-disable unicorn/prefer-module */
Object.defineProperty(exports, "__esModule", { value: true });
(() => {
const los = exports.los;
const lotId = document.querySelector('#lot--lotId')
.value;
const isCreate = lotId === '';
// Main form
let refreshAfterSave = isCreate;
function setUnsavedChanges() {
los.setUnsavedChanges();
document
.querySelector("button[type='submit'][form='form--lot']")
?.classList.remove('is-light');
}
function clearUnsavedChanges() {
los.clearUnsavedChanges();
document
.querySelector("button[type='submit'][form='form--lot']")
?.classList.add('is-light');
}
const formElement = document.querySelector('#form--lot');
function updateBurialSite(formEvent) {
formEvent.preventDefault();
cityssm.postJSON(`${los.urlPrefix}/lots/${isCreate ? 'doCreateBurialSite' : 'doUpdateBurialSite'}`, formElement, (rawResponseJSON) => {
const responseJSON = rawResponseJSON;
if (responseJSON.success) {
clearUnsavedChanges();
if (isCreate || refreshAfterSave) {
window.location.href = los.getBurialSiteURL(responseJSON.lotId, true, true);
}
else {
bulmaJS.alert({
message: `${los.escapedAliases.Lot} Updated Successfully`,
contextualColorName: 'success'
});
}
}
else {
bulmaJS.alert({
title: `Error Updating ${los.escapedAliases.Lot}`,
message: responseJSON.errorMessage ?? '',
contextualColorName: 'danger'
});
}
});
}
formElement.addEventListener('submit', updateBurialSite);
const formInputElements = formElement.querySelectorAll('input, select');
for (const formInputElement of formInputElements) {
formInputElement.addEventListener('change', setUnsavedChanges);
}
los.initializeUnlockFieldButtons(formElement);
document
.querySelector('#button--deleteLot')
?.addEventListener('click', (clickEvent) => {
clickEvent.preventDefault();
function doDelete() {
cityssm.postJSON(`${los.urlPrefix}/lots/doDeleteBurialSite`, {
lotId
}, (rawResponseJSON) => {
const responseJSON = rawResponseJSON;
if (responseJSON.success) {
clearUnsavedChanges();
window.location.href = los.getBurialSiteURL();
}
else {
bulmaJS.alert({
title: `Error Deleting ${los.escapedAliases.Lot}`,
message: responseJSON.errorMessage ?? '',
contextualColorName: 'danger'
});
}
});
}
bulmaJS.confirm({
title: `Delete ${los.escapedAliases.Lot}`,
message: `Are you sure you want to delete this ${los.escapedAliases.lot}?`,
contextualColorName: 'warning',
okButton: {
text: `Yes, Delete ${los.escapedAliases.Lot}`,
callbackFunction: doDelete
}
});
});
// Lot Type
const burialSiteTypeIdElement = document.querySelector('#lot--burialSiteTypeId');
if (isCreate) {
const lotFieldsContainerElement = document.querySelector('#container--lotFields');
burialSiteTypeIdElement.addEventListener('change', () => {
if (burialSiteTypeIdElement.value === '') {
// eslint-disable-next-line no-unsanitized/property
lotFieldsContainerElement.innerHTML = `<div class="message is-info">
<p class="message-body">Select the ${los.escapedAliases.lot} type to load the available fields.</p>
</div>`;
return;
}
cityssm.postJSON(`${los.urlPrefix}/lots/doGetBurialSiteTypeFields`, {
burialSiteTypeId: burialSiteTypeIdElement.value
}, (rawResponseJSON) => {
const responseJSON = rawResponseJSON;
if (responseJSON.BurialSiteTypeFields.length === 0) {
// eslint-disable-next-line no-unsanitized/property
lotFieldsContainerElement.innerHTML = `<div class="message is-info">
<p class="message-body">
There are no additional fields for this ${los.escapedAliases.lot} type.
</p>
</div>`;
return;
}
lotFieldsContainerElement.innerHTML = '';
let lotTypeFieldIds = '';
for (const lotTypeField of responseJSON.BurialSiteTypeFields) {
lotTypeFieldIds += `,${lotTypeField.lotTypeFieldId.toString()}`;
const fieldName = `lotFieldValue_${lotTypeField.lotTypeFieldId.toString()}`;
const fieldId = `lot--${fieldName}`;
const fieldElement = document.createElement('div');
fieldElement.className = 'field';
// eslint-disable-next-line no-unsanitized/property
fieldElement.innerHTML = `<label class="label" for="${fieldId}"></label>
<div class="control"></div>`;
fieldElement.querySelector('label').textContent = lotTypeField.lotTypeField;
if (lotTypeField.lotTypeFieldValues === '') {
const inputElement = document.createElement('input');
inputElement.className = 'input';
inputElement.id = fieldId;
inputElement.name = fieldName;
inputElement.type = 'text';
inputElement.required = lotTypeField.isRequired;
inputElement.minLength = lotTypeField.minimumLength;
inputElement.maxLength = lotTypeField.maximumLength;
if ((lotTypeField.pattern ?? '') !== '') {
inputElement.pattern = lotTypeField.pattern ?? '';
}
fieldElement.querySelector('.control')?.append(inputElement);
}
else {
// eslint-disable-next-line no-unsanitized/property
;
fieldElement.querySelector('.control').innerHTML = `<div class="select is-fullwidth">
<select id="${fieldId}" name="${fieldName}"><option value="">(Not Set)</option></select>
</div>`;
const selectElement = fieldElement.querySelector('select');
selectElement.required = lotTypeField.isRequired;
const optionValues = lotTypeField.lotTypeFieldValues.split('\n');
for (const optionValue of optionValues) {
const optionElement = document.createElement('option');
optionElement.value = optionValue;
optionElement.textContent = optionValue;
selectElement.append(optionElement);
}
}
lotFieldsContainerElement.append(fieldElement);
}
lotFieldsContainerElement.insertAdjacentHTML('beforeend', `<input name="lotTypeFieldIds" type="hidden"
value="${cityssm.escapeHTML(lotTypeFieldIds.slice(1))}" />`);
});
});
}
else {
const originalburialSiteTypeId = burialSiteTypeIdElement.value;
burialSiteTypeIdElement.addEventListener('change', () => {
if (burialSiteTypeIdElement.value !== originalburialSiteTypeId) {
bulmaJS.confirm({
title: 'Confirm Change',
message: `Are you sure you want to change the ${los.escapedAliases.lot} type?\n
This change affects the additional fields associated with this record.`,
contextualColorName: 'warning',
okButton: {
text: 'Yes, Keep the Change',
callbackFunction() {
refreshAfterSave = true;
}
},
cancelButton: {
text: 'Revert the Change',
callbackFunction() {
burialSiteTypeIdElement.value = originalburialSiteTypeId;
}
}
});
}
});
}
// Comments
let lotComments = exports.lotComments;
delete exports.lotComments;
function openEditLotComment(clickEvent) {
const lotCommentId = Number.parseInt(clickEvent.currentTarget.closest('tr')?.dataset
.lotCommentId ?? '', 10);
const lotComment = lotComments.find((currentLotComment) => {
return currentLotComment.lotCommentId === lotCommentId;
});
let editFormElement;
let editCloseModalFunction;
function editComment(submitEvent) {
submitEvent.preventDefault();
cityssm.postJSON(`${los.urlPrefix}/lots/doUpdateBurialSiteComment`, editFormElement, (rawResponseJSON) => {
const responseJSON = rawResponseJSON;
if (responseJSON.success) {
lotComments = responseJSON.lotComments;
editCloseModalFunction();
renderLotComments();
}
else {
bulmaJS.alert({
title: 'Error Updating Comment',
message: responseJSON.errorMessage ?? '',
contextualColorName: 'danger'
});
}
});
}
cityssm.openHtmlModal('lot-editComment', {
onshow(modalElement) {
los.populateAliases(modalElement);
modalElement.querySelector('#lotCommentEdit--lotId').value = lotId;
modalElement.querySelector('#lotCommentEdit--lotCommentId').value = lotCommentId.toString();
modalElement.querySelector('#lotCommentEdit--lotComment').value = lotComment.lotComment ?? '';
const lotCommentDateStringElement = modalElement.querySelector('#lotCommentEdit--lotCommentDateString');
lotCommentDateStringElement.value =
lotComment.lotCommentDateString ?? '';
const currentDateString = cityssm.dateToString(new Date());
lotCommentDateStringElement.max =
lotComment.lotCommentDateString <= currentDateString
? currentDateString
: lotComment.lotCommentDateString ?? '';
modalElement.querySelector('#lotCommentEdit--lotCommentTimeString').value = lotComment.lotCommentTimeString ?? '';
},
onshown(modalElement, closeModalFunction) {
bulmaJS.toggleHtmlClipped();
los.initializeDatePickers(modalElement);
modalElement.querySelector('#lotCommentEdit--lotComment').focus();
editFormElement = modalElement.querySelector('form');
editFormElement.addEventListener('submit', editComment);
editCloseModalFunction = closeModalFunction;
},
onremoved() {
bulmaJS.toggleHtmlClipped();
}
});
}
function deleteLotComment(clickEvent) {
const lotCommentId = Number.parseInt(clickEvent.currentTarget.closest('tr')?.dataset
.lotCommentId ?? '', 10);
function doDelete() {
cityssm.postJSON(`${los.urlPrefix}/lots/doDeleteBurialSiteComment`, {
lotId,
lotCommentId
}, (rawResponseJSON) => {
const responseJSON = rawResponseJSON;
if (responseJSON.success) {
lotComments = responseJSON.lotComments;
renderLotComments();
}
else {
bulmaJS.alert({
title: 'Error Removing Comment',
message: responseJSON.errorMessage ?? '',
contextualColorName: 'danger'
});
}
});
}
bulmaJS.confirm({
title: 'Remove Comment?',
message: 'Are you sure you want to remove this comment?',
okButton: {
text: 'Yes, Remove Comment',
callbackFunction: doDelete
},
contextualColorName: 'warning'
});
}
function renderLotComments() {
const containerElement = document.querySelector('#container--lotComments');
if (lotComments.length === 0) {
containerElement.innerHTML = `<div class="message is-info">
<p class="message-body">There are no comments to display.</p>
</div>`;
return;
}
const tableElement = document.createElement('table');
tableElement.className = 'table is-fullwidth is-striped is-hoverable';
tableElement.innerHTML = `<thead><tr>
<th>Commentor</th>
<th>Comment Date</th>
<th>Comment</th>
<th class="is-hidden-print"><span class="is-sr-only">Options</span></th>
</tr></thead>
<tbody></tbody>`;
for (const lotComment of lotComments) {
const tableRowElement = document.createElement('tr');
tableRowElement.dataset.lotCommentId = lotComment.lotCommentId?.toString();
// eslint-disable-next-line no-unsanitized/property
tableRowElement.innerHTML = `<td>
${cityssm.escapeHTML(lotComment.recordCreate_userName ?? '')}
</td><td>
${lotComment.lotCommentDateString}
${lotComment.lotCommentTime === 0
? ''
: ` ${lotComment.lotCommentTimePeriodString}`}
</td><td>
${cityssm.escapeHTML(lotComment.lotComment ?? '')}
</td><td class="is-hidden-print">
<div class="buttons are-small is-justify-content-end">
<button class="button is-primary button--edit" type="button">
<span class="icon is-small"><i class="fas fa-pencil-alt" aria-hidden="true"></i></span>
<span>Edit</span>
</button>
<button class="button is-light is-danger button--delete" data-tooltip="Delete Comment" type="button" aria-label="Delete">
<i class="fas fa-trash" aria-hidden="true"></i>
</button>
</div>
</td>`;
tableRowElement
.querySelector('.button--edit')
?.addEventListener('click', openEditLotComment);
tableRowElement
.querySelector('.button--delete')
?.addEventListener('click', deleteLotComment);
tableElement.querySelector('tbody')?.append(tableRowElement);
}
containerElement.innerHTML = '';
containerElement.append(tableElement);
}
function openAddCommentModal() {
let addCommentCloseModalFunction;
function doAddComment(formEvent) {
formEvent.preventDefault();
cityssm.postJSON(`${los.urlPrefix}/lots/doAddBurialSiteComment`, formEvent.currentTarget, (rawResponseJSON) => {
const responseJSON = rawResponseJSON;
if (responseJSON.success) {
lotComments = responseJSON.lotComments;
renderLotComments();
addCommentCloseModalFunction();
}
});
}
cityssm.openHtmlModal('lot-addComment', {
onshow(modalElement) {
los.populateAliases(modalElement);
modalElement.querySelector('#lotCommentAdd--lotId').value = lotId;
modalElement
.querySelector('form')
?.addEventListener('submit', doAddComment);
},
onshown(modalElement, closeModalFunction) {
bulmaJS.toggleHtmlClipped();
addCommentCloseModalFunction = closeModalFunction;
modalElement.querySelector('#lotCommentAdd--lotComment').focus();
},
onremoved() {
bulmaJS.toggleHtmlClipped();
document.querySelector('#lotComments--add').focus();
}
});
}
if (!isCreate) {
document
.querySelector('#lotComments--add')
?.addEventListener('click', openAddCommentModal);
renderLotComments();
}
})();

View File

@ -55,7 +55,7 @@ declare const exports: Record<string, unknown>
clearUnsavedChanges() clearUnsavedChanges()
if (isCreate || refreshAfterSave) { if (isCreate || refreshAfterSave) {
window.location.href = los.getLotURL(responseJSON.lotId, true, true) window.location.href = los.getBurialSiteURL(responseJSON.lotId, true, true)
} else { } else {
bulmaJS.alert({ bulmaJS.alert({
message: `${los.escapedAliases.Lot} Updated Successfully`, message: `${los.escapedAliases.Lot} Updated Successfully`,
@ -102,7 +102,7 @@ declare const exports: Record<string, unknown>
if (responseJSON.success) { if (responseJSON.success) {
clearUnsavedChanges() clearUnsavedChanges()
window.location.href = los.getLotURL() window.location.href = los.getBurialSiteURL()
} else { } else {
bulmaJS.alert({ bulmaJS.alert({
title: `Error Deleting ${los.escapedAliases.Lot}`, title: `Error Deleting ${los.escapedAliases.Lot}`,

View File

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

View File

@ -20,13 +20,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
// eslint-disable-next-line no-unsanitized/method // eslint-disable-next-line no-unsanitized/method
resultsTbodyElement.insertAdjacentHTML('beforeend', `<tr> resultsTbodyElement.insertAdjacentHTML('beforeend', `<tr>
<td> <td>
<a class="has-text-weight-bold" href="${los.getLotURL(lot.lotId)}"> <a class="has-text-weight-bold" href="${los.getBurialSiteURL(lot.lotId)}">
${cityssm.escapeHTML(lot.lotName ?? '')} ${cityssm.escapeHTML(lot.lotName ?? '')}
</a> </a>
</td><td> </td><td>
<a href="${los.getMapURL(lot.mapId)}"> <a href="${los.getCemeteryURL(lot.cemeteryId)}">
${lot.mapName ${lot.cemeteryName
? cityssm.escapeHTML(lot.mapName) ? cityssm.escapeHTML(lot.cemeteryName)
: '<span class="has-text-grey">(No Name)</span>'} : '<span class="has-text-grey">(No Name)</span>'}
</a> </a>
</td><td> </td><td>
@ -35,7 +35,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
${lot.burialSiteStatusId ${lot.burialSiteStatusId
? cityssm.escapeHTML(lot.lotStatus ?? '') ? cityssm.escapeHTML(lot.lotStatus ?? '')
: '<span class="has-text-grey">(No Status)</span>'}<br /> : '<span class="has-text-grey">(No Status)</span>'}<br />
${(lot.lotOccupancyCount ?? 0) > 0 ${(lot.burialSiteContractCount ?? 0) > 0
? '<span class="is-size-7">Currently Occupied</span>' ? '<span class="is-size-7">Currently Occupied</span>'
: ''} : ''}
</td> </td>
@ -62,22 +62,22 @@ Object.defineProperty(exports, "__esModule", { value: true });
.querySelector("button[data-page='next']") .querySelector("button[data-page='next']")
?.addEventListener('click', nextAndGetLots); ?.addEventListener('click', nextAndGetLots);
} }
function getLots() { function getBurialSites() {
// eslint-disable-next-line no-unsanitized/property // eslint-disable-next-line no-unsanitized/property
searchResultsContainerElement.innerHTML = los.getLoadingParagraphHTML(`Loading ${los.escapedAliases.Lots}...`); searchResultsContainerElement.innerHTML = los.getLoadingParagraphHTML(`Loading ${los.escapedAliases.Lots}...`);
cityssm.postJSON(`${los.urlPrefix}/lots/doSearchLots`, searchFilterFormElement, renderLots); cityssm.postJSON(`${los.urlPrefix}/lots/doSearchBurialSites`, searchFilterFormElement, renderLots);
} }
function resetOffsetAndGetLots() { function resetOffsetAndGetLots() {
offsetElement.value = '0'; offsetElement.value = '0';
getLots(); getBurialSites();
} }
function previousAndGetLots() { function previousAndGetLots() {
offsetElement.value = Math.max(Number.parseInt(offsetElement.value, 10) - limit, 0).toString(); offsetElement.value = Math.max(Number.parseInt(offsetElement.value, 10) - limit, 0).toString();
getLots(); getBurialSites();
} }
function nextAndGetLots() { function nextAndGetLots() {
offsetElement.value = (Number.parseInt(offsetElement.value, 10) + limit).toString(); offsetElement.value = (Number.parseInt(offsetElement.value, 10) + limit).toString();
getLots(); getBurialSites();
} }
const filterElements = searchFilterFormElement.querySelectorAll('input, select'); const filterElements = searchFilterFormElement.querySelectorAll('input, select');
for (const filterElement of filterElements) { for (const filterElement of filterElements) {
@ -86,5 +86,5 @@ Object.defineProperty(exports, "__esModule", { value: true });
searchFilterFormElement.addEventListener('submit', (formEvent) => { searchFilterFormElement.addEventListener('submit', (formEvent) => {
formEvent.preventDefault(); formEvent.preventDefault();
}); });
getLots(); getBurialSites();
})(); })();

View File

@ -49,11 +49,11 @@ declare const exports: Record<string, unknown>
'beforeend', 'beforeend',
`<tr> `<tr>
<td> <td>
<a class="has-text-weight-bold" href="${los.getLotURL(lot.lotId)}"> <a class="has-text-weight-bold" href="${los.getBurialSiteURL(lot.lotId)}">
${cityssm.escapeHTML(lot.lotName ?? '')} ${cityssm.escapeHTML(lot.lotName ?? '')}
</a> </a>
</td><td> </td><td>
<a href="${los.getMapURL(lot.cemeteryId)}"> <a href="${los.getCemeteryURL(lot.cemeteryId)}">
${ ${
lot.cemeteryName lot.cemeteryName
? cityssm.escapeHTML(lot.cemeteryName) ? cityssm.escapeHTML(lot.cemeteryName)

View File

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

View File

@ -0,0 +1,9 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
(() => {
const mapContainerElement = document.querySelector('#lot--map');
if (mapContainerElement !== null) {
;
exports.los.highlightMap(mapContainerElement, mapContainerElement.dataset.mapKey ?? '', 'success');
}
})();

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -0,0 +1,152 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
(() => {
const los = exports.los;
const searchFilterFormElement = document.querySelector('#form--searchFilters');
const searchResultsContainerElement = document.querySelector('#container--searchResults');
const limit = Number.parseInt(document.querySelector('#searchFilter--limit').value, 10);
const offsetElement = document.querySelector('#searchFilter--offset');
function renderLotOccupancies(rawResponseJSON) {
const responseJSON = rawResponseJSON;
if (responseJSON.lotOccupancies.length === 0) {
// eslint-disable-next-line no-unsanitized/property
searchResultsContainerElement.innerHTML = `<div class="message is-info">
<p class="message-body">
There are no ${los.escapedAliases.occupancy} records that meet the search criteria.
</p>
</div>`;
return;
}
const resultsTbodyElement = document.createElement('tbody');
const nowDateString = cityssm.dateToString(new Date());
for (const burialSiteContract of responseJSON.lotOccupancies) {
let occupancyTimeHTML = '';
if (burialSiteContract.contractStartDateString <= nowDateString &&
(burialSiteContract.contractEndDateString === '' ||
burialSiteContract.contractEndDateString >= nowDateString)) {
occupancyTimeHTML = `<span class="has-tooltip-right" data-tooltip="Current ${los.escapedAliases.Occupancy}">
<i class="fas fa-play" aria-label="Current ${los.escapedAliases.Occupancy}"></i>
</span>`;
}
else if (burialSiteContract.contractStartDateString > nowDateString) {
occupancyTimeHTML = `<span class="has-tooltip-right" data-tooltip="Future ${los.escapedAliases.Occupancy}">
<i class="fas fa-fast-forward" aria-label="Future ${los.escapedAliases.Occupancy}"></i>
</span>`;
}
else {
occupancyTimeHTML = `<span class="has-tooltip-right" data-tooltip="Past ${los.escapedAliases.Occupancy}">
<i class="fas fa-stop" aria-label="Past ${los.escapedAliases.Occupancy}"></i>
</span>`;
}
let occupantsHTML = '';
for (const occupant of burialSiteContract.burialSiteContractOccupants ?? []) {
occupantsHTML += `<li class="has-tooltip-left" data-tooltip="${cityssm.escapeHTML(occupant.lotOccupantType ?? '')}">
<span class="fa-li">
<i class="fas fa-fw fa-${cityssm.escapeHTML((occupant.fontAwesomeIconClass ?? '') === ''
? 'user'
: occupant.fontAwesomeIconClass ?? '')}" aria-hidden="true"></i>
</span>
${cityssm.escapeHTML(occupant.occupantName ?? '')}
${cityssm.escapeHTML(occupant.occupantFamilyName ?? '')}
</li>`;
}
const feeTotal = (burialSiteContract.burialSiteContractFees?.reduce((soFar, currentFee) => soFar +
((currentFee.feeAmount ?? 0) + (currentFee.taxAmount ?? 0)) *
(currentFee.quantity ?? 0), 0) ?? 0).toFixed(2);
const transactionTotal = (burialSiteContract.burialSiteContractTransactions?.reduce((soFar, currentTransaction) => soFar + currentTransaction.transactionAmount, 0) ?? 0).toFixed(2);
let feeIconHTML = '';
if (feeTotal !== '0.00' || transactionTotal !== '0.00') {
feeIconHTML = `<span class="icon"
data-tooltip="Total Fees: $${feeTotal}"
aria-label="Total Fees: $${feeTotal}">
<i class="fas fa-dollar-sign ${feeTotal === transactionTotal
? 'has-text-success'
: 'has-text-danger'}" aria-hidden="true"></i>
</span>`;
}
// eslint-disable-next-line no-unsanitized/method
resultsTbodyElement.insertAdjacentHTML('beforeend', `<tr>
<td class="has-width-1">
${occupancyTimeHTML}
</td><td>
<a class="has-text-weight-bold"
href="${los.getBurialSiteContractURL(burialSiteContract.burialSiteContractId)}">
${cityssm.escapeHTML(burialSiteContract.occupancyType ?? '')}
</a><br />
<span class="is-size-7">#${burialSiteContract.burialSiteContractId}</span>
</td><td>
${(burialSiteContract.lotId ?? -1) === -1
? `<span class="has-text-grey">(No ${los.escapedAliases.Lot})</span>`
: `<a class="has-tooltip-right" data-tooltip="${cityssm.escapeHTML(burialSiteContract.lotType ?? '')}" href="${los.getBurialSiteURL(burialSiteContract.lotId)}">${cityssm.escapeHTML(burialSiteContract.lotName ?? '')}</a>`}<br />
<span class="is-size-7">${cityssm.escapeHTML(burialSiteContract.cemeteryName ?? '')}</span>
</td><td>
${burialSiteContract.contractStartDateString}
</td><td>
${burialSiteContract.contractEndDate
? burialSiteContract.contractEndDateString
: '<span class="has-text-grey">(No End Date)</span>'}
</td><td>
${occupantsHTML === ''
? ''
: `<ul class="fa-ul ml-5">${occupantsHTML}</ul>`}
</td><td>
${feeIconHTML}
</td><td>
${burialSiteContract.printEJS
? `<a class="button is-small" data-tooltip="Print"
href="${los.urlPrefix}/print/${burialSiteContract.printEJS}/?burialSiteContractId=${burialSiteContract.burialSiteContractId.toString()}" target="_blank">
<i class="fas fa-print" aria-label="Print"></i>
</a>`
: ''}</td></tr>`);
}
// eslint-disable-next-line no-unsanitized/property
searchResultsContainerElement.innerHTML = `<table class="table is-fullwidth is-striped is-hoverable has-sticky-header">
<thead><tr>
<th class="has-width-1"></th>
<th>${los.escapedAliases.Occupancy} Type</th>
<th>${los.escapedAliases.Lot}</th>
<th>${los.escapedAliases.contractStartDate}</th>
<th>End Date</th>
<th>${los.escapedAliases.Occupants}</th>
<th class="has-width-1"><span class="is-sr-only">Fees and Transactions</span></th>
<th class="has-width-1"><span class="is-sr-only">Print</span></th>
</tr></thead>
<table>`;
searchResultsContainerElement
.querySelector('table')
?.append(resultsTbodyElement);
// eslint-disable-next-line no-unsanitized/method
searchResultsContainerElement.insertAdjacentHTML('beforeend', los.getSearchResultsPagerHTML(limit, responseJSON.offset, responseJSON.count));
searchResultsContainerElement
.querySelector("button[data-page='previous']")
?.addEventListener('click', previousAndGetLotOccupancies);
searchResultsContainerElement
.querySelector("button[data-page='next']")
?.addEventListener('click', nextAndGetLotOccupancies);
}
function getBurialSiteContracts() {
// eslint-disable-next-line no-unsanitized/property
searchResultsContainerElement.innerHTML = los.getLoadingParagraphHTML(`Loading ${los.escapedAliases.Occupancies}...`);
cityssm.postJSON(`${los.urlPrefix}/contracts/doSearchLotOccupancies`, searchFilterFormElement, renderLotOccupancies);
}
function resetOffsetAndGetLotOccupancies() {
offsetElement.value = '0';
getBurialSiteContracts();
}
function previousAndGetLotOccupancies() {
offsetElement.value = Math.max(Number.parseInt(offsetElement.value, 10) - limit, 0).toString();
getBurialSiteContracts();
}
function nextAndGetLotOccupancies() {
offsetElement.value = (Number.parseInt(offsetElement.value, 10) + limit).toString();
getBurialSiteContracts();
}
const filterElements = searchFilterFormElement.querySelectorAll('input, select');
for (const filterElement of filterElements) {
filterElement.addEventListener('change', resetOffsetAndGetLotOccupancies);
}
searchFilterFormElement.addEventListener('submit', (formEvent) => {
formEvent.preventDefault();
});
getBurialSiteContracts();
})();

View File

@ -133,7 +133,7 @@ declare const exports: Record<string, unknown>
${ ${
(burialSiteContract.lotId ?? -1) === -1 (burialSiteContract.lotId ?? -1) === -1
? `<span class="has-text-grey">(No ${los.escapedAliases.Lot})</span>` ? `<span class="has-text-grey">(No ${los.escapedAliases.Lot})</span>`
: `<a class="has-tooltip-right" data-tooltip="${cityssm.escapeHTML(burialSiteContract.lotType ?? '')}" href="${los.getLotURL(burialSiteContract.lotId)}">${cityssm.escapeHTML(burialSiteContract.lotName ?? '')}</a>` : `<a class="has-tooltip-right" data-tooltip="${cityssm.escapeHTML(burialSiteContract.lotType ?? '')}" href="${los.getBurialSiteURL(burialSiteContract.lotId)}">${cityssm.escapeHTML(burialSiteContract.lotName ?? '')}</a>`
}<br /> }<br />
<span class="is-size-7">${cityssm.escapeHTML(burialSiteContract.cemeteryName ?? '')}</span> <span class="is-size-7">${cityssm.escapeHTML(burialSiteContract.cemeteryName ?? '')}</span>
</td><td> </td><td>

View File

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

View File

@ -0,0 +1,409 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
(() => {
const los = exports.los;
const containerElement = document.querySelector('#container--lotTypes');
let lotTypes = exports.lotTypes;
delete exports.lotTypes;
const expandedLotTypes = new Set();
function toggleBurialSiteTypeFields(clickEvent) {
const toggleButtonElement = clickEvent.currentTarget;
const lotTypeElement = toggleButtonElement.closest('.container--lotType');
const burialSiteTypeId = Number.parseInt(lotTypeElement.dataset.burialSiteTypeId ?? '', 10);
if (expandedLotTypes.has(burialSiteTypeId)) {
expandedLotTypes.delete(burialSiteTypeId);
}
else {
expandedLotTypes.add(burialSiteTypeId);
}
// eslint-disable-next-line no-unsanitized/property
toggleButtonElement.innerHTML = expandedLotTypes.has(burialSiteTypeId)
? '<i class="fas fa-fw fa-minus" aria-hidden="true"></i>'
: '<i class="fas fa-fw fa-plus" aria-hidden="true"></i>';
const panelBlockElements = lotTypeElement.querySelectorAll('.panel-block');
for (const panelBlockElement of panelBlockElements) {
panelBlockElement.classList.toggle('is-hidden');
}
}
function lotTypeResponseHandler(rawResponseJSON) {
const responseJSON = rawResponseJSON;
if (responseJSON.success) {
lotTypes = responseJSON.lotTypes;
renderLotTypes();
}
else {
bulmaJS.alert({
title: `Error Updating ${los.escapedAliases.Lot} Type`,
message: responseJSON.errorMessage ?? '',
contextualColorName: 'danger'
});
}
}
function deleteLotType(clickEvent) {
const burialSiteTypeId = Number.parseInt(clickEvent.currentTarget.closest('.container--lotType').dataset.burialSiteTypeId ?? '', 10);
function doDelete() {
cityssm.postJSON(`${los.urlPrefix}/admin/doDeleteBurialSiteType`, {
burialSiteTypeId
}, lotTypeResponseHandler);
}
bulmaJS.confirm({
title: `Delete ${los.escapedAliases.Lot} Type`,
message: `Are you sure you want to delete this ${los.escapedAliases.lot} type?`,
contextualColorName: 'warning',
okButton: {
text: `Yes, Delete ${los.escapedAliases.Lot} Type`,
callbackFunction: doDelete
}
});
}
function openEditLotType(clickEvent) {
const burialSiteTypeId = Number.parseInt(clickEvent.currentTarget.closest('.container--lotType').dataset.burialSiteTypeId ?? '', 10);
const lotType = lotTypes.find((currentLotType) => burialSiteTypeId === currentLotType.burialSiteTypeId);
let editCloseModalFunction;
function doEdit(submitEvent) {
submitEvent.preventDefault();
cityssm.postJSON(`${los.urlPrefix}/admin/doUpdateBurialSiteType`, submitEvent.currentTarget, (rawResponseJSON) => {
const responseJSON = rawResponseJSON;
lotTypeResponseHandler(responseJSON);
if (responseJSON.success) {
editCloseModalFunction();
}
});
}
cityssm.openHtmlModal('adminLotTypes-editLotType', {
onshow(modalElement) {
los.populateAliases(modalElement);
modalElement.querySelector('#lotTypeEdit--burialSiteTypeId').value = burialSiteTypeId.toString();
modalElement.querySelector('#lotTypeEdit--lotType').value = lotType.lotType;
},
onshown(modalElement, closeModalFunction) {
editCloseModalFunction = closeModalFunction;
modalElement.querySelector('#lotTypeEdit--lotType').focus();
modalElement.querySelector('form')?.addEventListener('submit', doEdit);
bulmaJS.toggleHtmlClipped();
},
onremoved() {
bulmaJS.toggleHtmlClipped();
}
});
}
function openAddLotTypeField(clickEvent) {
const burialSiteTypeId = Number.parseInt(clickEvent.currentTarget.closest('.container--lotType').dataset.burialSiteTypeId ?? '', 10);
let addCloseModalFunction;
function doAdd(submitEvent) {
submitEvent.preventDefault();
cityssm.postJSON(`${los.urlPrefix}/admin/doAddBurialSiteTypeField`, submitEvent.currentTarget, (rawResponseJSON) => {
const responseJSON = rawResponseJSON;
expandedLotTypes.add(burialSiteTypeId);
lotTypeResponseHandler(responseJSON);
if (responseJSON.success) {
addCloseModalFunction();
openEditLotTypeField(burialSiteTypeId, responseJSON.lotTypeFieldId);
}
});
}
cityssm.openHtmlModal('adminLotTypes-addBurialSiteTypeField', {
onshow(modalElement) {
los.populateAliases(modalElement);
if (burialSiteTypeId) {
;
modalElement.querySelector('#lotTypeFieldAdd--burialSiteTypeId').value = burialSiteTypeId.toString();
}
},
onshown(modalElement, closeModalFunction) {
addCloseModalFunction = closeModalFunction;
modalElement.querySelector('#lotTypeFieldAdd--lotTypeField').focus();
modalElement.querySelector('form')?.addEventListener('submit', doAdd);
bulmaJS.toggleHtmlClipped();
},
onremoved() {
bulmaJS.toggleHtmlClipped();
}
});
}
function moveLotType(clickEvent) {
const buttonElement = clickEvent.currentTarget;
const burialSiteTypeId = buttonElement.closest('.container--lotType').dataset.burialSiteTypeId;
cityssm.postJSON(`${los.urlPrefix}/admin/${buttonElement.dataset.direction === 'up'
? 'doMoveBurialSiteTypeUp'
: 'doMoveBurialSiteTypeDown'}`, {
burialSiteTypeId,
moveToEnd: clickEvent.shiftKey ? '1' : '0'
}, lotTypeResponseHandler);
}
function openEditLotTypeField(burialSiteTypeId, lotTypeFieldId) {
const lotType = lotTypes.find((currentLotType) => currentLotType.burialSiteTypeId === burialSiteTypeId);
const lotTypeField = (lotType.BurialSiteTypeFields ?? []).find((currentLotTypeField) => currentLotTypeField.lotTypeFieldId === lotTypeFieldId);
let fieldTypeElement;
let minimumLengthElement;
let maximumLengthElement;
let patternElement;
let lotTypeFieldValuesElement;
let editCloseModalFunction;
function updateMaximumLengthMin() {
maximumLengthElement.min = minimumLengthElement.value;
}
function toggleInputFields() {
switch (fieldTypeElement.value) {
case 'date': {
minimumLengthElement.disabled = true;
maximumLengthElement.disabled = true;
patternElement.disabled = true;
lotTypeFieldValuesElement.disabled = true;
break;
}
case 'select': {
minimumLengthElement.disabled = true;
maximumLengthElement.disabled = true;
patternElement.disabled = true;
lotTypeFieldValuesElement.disabled = false;
break;
}
default: {
minimumLengthElement.disabled = false;
maximumLengthElement.disabled = false;
patternElement.disabled = false;
lotTypeFieldValuesElement.disabled = true;
break;
}
}
}
function doUpdate(submitEvent) {
submitEvent.preventDefault();
cityssm.postJSON(`${los.urlPrefix}/admin/doUpdateBurialSiteTypeField`, submitEvent.currentTarget, (rawResponseJSON) => {
const responseJSON = rawResponseJSON;
lotTypeResponseHandler(responseJSON);
if (responseJSON.success) {
editCloseModalFunction();
}
});
}
function doDelete() {
cityssm.postJSON(`${los.urlPrefix}/admin/doDeleteBurialSiteTypeField`, {
lotTypeFieldId
}, (rawResponseJSON) => {
const responseJSON = rawResponseJSON;
lotTypeResponseHandler(responseJSON);
if (responseJSON.success) {
editCloseModalFunction();
}
});
}
function confirmDoDelete() {
bulmaJS.confirm({
title: 'Delete Field',
message: 'Are you sure you want to delete this field? Note that historical records that make use of this field will not be affected.',
contextualColorName: 'warning',
okButton: {
text: 'Yes, Delete Field',
callbackFunction: doDelete
}
});
}
cityssm.openHtmlModal('adminLotTypes-editLotTypeField', {
onshow(modalElement) {
los.populateAliases(modalElement);
modalElement.querySelector('#lotTypeFieldEdit--lotTypeFieldId').value = lotTypeField.lotTypeFieldId.toString();
modalElement.querySelector('#lotTypeFieldEdit--lotTypeField').value = lotTypeField.lotTypeField ?? '';
modalElement.querySelector('#lotTypeFieldEdit--isRequired').value = lotTypeField.isRequired ? '1' : '0';
fieldTypeElement = modalElement.querySelector('#lotTypeFieldEdit--fieldType');
fieldTypeElement.value = lotTypeField.fieldType;
minimumLengthElement = modalElement.querySelector('#lotTypeFieldEdit--minimumLength');
minimumLengthElement.value =
lotTypeField.minimumLength?.toString() ?? '';
maximumLengthElement = modalElement.querySelector('#lotTypeFieldEdit--maximumLength');
maximumLengthElement.value =
lotTypeField.maximumLength?.toString() ?? '';
patternElement = modalElement.querySelector('#lotTypeFieldEdit--pattern');
patternElement.value = lotTypeField.pattern ?? '';
lotTypeFieldValuesElement = modalElement.querySelector('#lotTypeFieldEdit--lotTypeFieldValues');
lotTypeFieldValuesElement.value = lotTypeField.lotTypeFieldValues ?? '';
toggleInputFields();
},
onshown(modalElement, closeModalFunction) {
editCloseModalFunction = closeModalFunction;
bulmaJS.init(modalElement);
bulmaJS.toggleHtmlClipped();
cityssm.enableNavBlocker();
modalElement.querySelector('form')?.addEventListener('submit', doUpdate);
minimumLengthElement.addEventListener('keyup', updateMaximumLengthMin);
updateMaximumLengthMin();
fieldTypeElement.addEventListener('change', toggleInputFields);
modalElement
.querySelector('#button--deleteLotTypeField')
?.addEventListener('click', confirmDoDelete);
},
onremoved() {
bulmaJS.toggleHtmlClipped();
cityssm.disableNavBlocker();
}
});
}
function openEditLotTypeFieldByClick(clickEvent) {
clickEvent.preventDefault();
const lotTypeFieldId = Number.parseInt(clickEvent.currentTarget.closest('.container--lotTypeField').dataset.lotTypeFieldId ?? '', 10);
const burialSiteTypeId = Number.parseInt(clickEvent.currentTarget.closest('.container--lotType').dataset.burialSiteTypeId ?? '', 10);
openEditLotTypeField(burialSiteTypeId, lotTypeFieldId);
}
function moveLotTypeField(clickEvent) {
const buttonElement = clickEvent.currentTarget;
const lotTypeFieldId = buttonElement.closest('.container--lotTypeField').dataset.lotTypeFieldId;
cityssm.postJSON(`${los.urlPrefix}/admin/${buttonElement.dataset.direction === 'up'
? 'doMoveBurialSiteTypeFieldUp'
: 'doMoveBurialSiteTypeFieldDown'}`, {
lotTypeFieldId,
moveToEnd: clickEvent.shiftKey ? '1' : '0'
}, lotTypeResponseHandler);
}
function renderBurialSiteTypeFields(panelElement, burialSiteTypeId, BurialSiteTypeFields) {
if (BurialSiteTypeFields.length === 0) {
// eslint-disable-next-line no-unsanitized/method
panelElement.insertAdjacentHTML('beforeend', `<div class="panel-block is-block
${expandedLotTypes.has(burialSiteTypeId) ? '' : ' is-hidden'}">
<div class="message is-info"><p class="message-body">There are no additional fields.</p></div>
</div>`);
}
else {
for (const lotTypeField of BurialSiteTypeFields) {
const panelBlockElement = document.createElement('div');
panelBlockElement.className =
'panel-block is-block container--lotTypeField';
if (!expandedLotTypes.has(burialSiteTypeId)) {
panelBlockElement.classList.add('is-hidden');
}
panelBlockElement.dataset.lotTypeFieldId =
lotTypeField.lotTypeFieldId.toString();
// eslint-disable-next-line no-unsanitized/property
panelBlockElement.innerHTML = `<div class="level is-mobile">
<div class="level-left">
<div class="level-item">
<a class="has-text-weight-bold button--editLotTypeField" href="#">
${cityssm.escapeHTML(lotTypeField.lotTypeField ?? '')}
</a>
</div>
</div>
<div class="level-right">
<div class="level-item">
${los.getMoveUpDownButtonFieldHTML('button--moveLotTypeFieldUp', 'button--moveLotTypeFieldDown')}
</div>
</div>
</div>`;
panelBlockElement
.querySelector('.button--editLotTypeField')
?.addEventListener('click', openEditLotTypeFieldByClick);
panelBlockElement.querySelector('.button--moveLotTypeFieldUp').addEventListener('click', moveLotTypeField);
panelBlockElement.querySelector('.button--moveLotTypeFieldDown').addEventListener('click', moveLotTypeField);
panelElement.append(panelBlockElement);
}
}
}
function renderLotTypes() {
containerElement.innerHTML = '';
if (lotTypes.length === 0) {
// eslint-disable-next-line no-unsanitized/method
containerElement.insertAdjacentHTML('afterbegin', `<div class="message is-warning>
<p class="message-body">There are no active ${los.escapedAliases.lot} types.</p>
</div>`);
return;
}
for (const lotType of lotTypes) {
const lotTypeContainer = document.createElement('div');
lotTypeContainer.className = 'panel container--lotType';
lotTypeContainer.dataset.burialSiteTypeId = lotType.burialSiteTypeId.toString();
// eslint-disable-next-line no-unsanitized/property
lotTypeContainer.innerHTML = `<div class="panel-heading">
<div class="level is-mobile">
<div class="level-left">
<div class="level-item">
<button class="button is-small button--toggleBurialSiteTypeFields" data-tooltip="Toggle Fields" type="button" aria-label="Toggle Fields">
${expandedLotTypes.has(lotType.burialSiteTypeId)
? '<i class="fas fa-fw fa-minus" aria-hidden="true"></i>'
: '<i class="fas fa-fw fa-plus" aria-hidden="true"></i>'}
</button>
</div>
<div class="level-item">
<h2 class="title is-4">${cityssm.escapeHTML(lotType.lotType)}</h2>
</div>
</div>
<div class="level-right">
<div class="level-item">
<button class="button is-danger is-small button--deleteLotType" type="button">
<span class="icon is-small"><i class="fas fa-trash" aria-hidden="true"></i></span>
<span>Delete</span>
</button>
</div>
<div class="level-item">
<button class="button is-primary is-small button--editLotType" type="button">
<span class="icon is-small"><i class="fas fa-pencil-alt" aria-hidden="true"></i></span>
<span>Edit ${los.escapedAliases.Lot} Type</span>
</button>
</div>
<div class="level-item">
<button class="button is-success is-small button--addBurialSiteTypeField" type="button">
<span class="icon is-small"><i class="fas fa-plus" aria-hidden="true"></i></span>
<span>Add Field</span>
</button>
</div>
<div class="level-item">
${los.getMoveUpDownButtonFieldHTML('button--moveLotTypeUp', 'button--moveLotTypeDown')}
</div>
</div>
</div>
</div>`;
renderBurialSiteTypeFields(lotTypeContainer, lotType.burialSiteTypeId, lotType.BurialSiteTypeFields ?? []);
lotTypeContainer
.querySelector('.button--toggleBurialSiteTypeFields')
?.addEventListener('click', toggleBurialSiteTypeFields);
lotTypeContainer
.querySelector('.button--deleteLotType')
?.addEventListener('click', deleteLotType);
lotTypeContainer
.querySelector('.button--editLotType')
?.addEventListener('click', openEditLotType);
lotTypeContainer
.querySelector('.button--addBurialSiteTypeField')
?.addEventListener('click', openAddLotTypeField);
lotTypeContainer.querySelector('.button--moveLotTypeUp').addEventListener('click', moveLotType);
lotTypeContainer.querySelector('.button--moveLotTypeDown').addEventListener('click', moveLotType);
containerElement.append(lotTypeContainer);
}
}
document
.querySelector('#button--addBurialSiteType')
?.addEventListener('click', () => {
let addCloseModalFunction;
function doAdd(submitEvent) {
submitEvent.preventDefault();
cityssm.postJSON(`${los.urlPrefix}/admin/doAddLotType`, submitEvent.currentTarget, (rawResponseJSON) => {
const responseJSON = rawResponseJSON;
if (responseJSON.success) {
addCloseModalFunction();
lotTypes = responseJSON.lotTypes;
renderLotTypes();
}
else {
bulmaJS.alert({
title: `Error Adding ${los.escapedAliases.Lot} Type`,
message: responseJSON.errorMessage ?? '',
contextualColorName: 'danger'
});
}
});
}
cityssm.openHtmlModal('adminLotTypes-addBurialSiteType', {
onshow(modalElement) {
los.populateAliases(modalElement);
},
onshown(modalElement, closeModalFunction) {
addCloseModalFunction = closeModalFunction;
modalElement.querySelector('#lotTypeAdd--lotType').focus();
modalElement.querySelector('form')?.addEventListener('submit', doAdd);
bulmaJS.toggleHtmlClipped();
},
onremoved() {
bulmaJS.toggleHtmlClipped();
}
});
});
renderLotTypes();
})();

View File

@ -208,7 +208,7 @@ type ResponseJSON =
) )
} }
cityssm.openHtmlModal('adminLotTypes-addLotTypeField', { cityssm.openHtmlModal('adminLotTypes-addBurialSiteTypeField', {
onshow(modalElement) { onshow(modalElement) {
los.populateAliases(modalElement) los.populateAliases(modalElement)
@ -598,7 +598,7 @@ type ResponseJSON =
</button> </button>
</div> </div>
<div class="level-item"> <div class="level-item">
<button class="button is-success is-small button--addLotTypeField" type="button"> <button class="button is-success is-small button--addBurialSiteTypeField" type="button">
<span class="icon is-small"><i class="fas fa-plus" aria-hidden="true"></i></span> <span class="icon is-small"><i class="fas fa-plus" aria-hidden="true"></i></span>
<span>Add Field</span> <span>Add Field</span>
</button> </button>
@ -632,7 +632,7 @@ type ResponseJSON =
?.addEventListener('click', openEditLotType) ?.addEventListener('click', openEditLotType)
lotTypeContainer lotTypeContainer
.querySelector('.button--addLotTypeField') .querySelector('.button--addBurialSiteTypeField')
?.addEventListener('click', openAddLotTypeField) ?.addEventListener('click', openAddLotTypeField)
;( ;(
lotTypeContainer.querySelector( lotTypeContainer.querySelector(
@ -650,7 +650,7 @@ type ResponseJSON =
} }
document document
.querySelector('#button--addLotType') .querySelector('#button--addBurialSiteType')
?.addEventListener('click', () => { ?.addEventListener('click', () => {
let addCloseModalFunction: () => void let addCloseModalFunction: () => void
@ -678,7 +678,7 @@ type ResponseJSON =
) )
} }
cityssm.openHtmlModal('adminLotTypes-addLotType', { cityssm.openHtmlModal('adminLotTypes-addBurialSiteType', {
onshow(modalElement) { onshow(modalElement) {
los.populateAliases(modalElement) los.populateAliases(modalElement)
}, },

View File

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

View File

@ -0,0 +1,81 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
(() => {
const los = exports.los;
const cemeteryId = document.querySelector('#cemetery--cemeteryId').value;
const isCreate = cemeteryId === '';
const cemeteryForm = document.querySelector('#form--cemetery');
function setUnsavedChanges() {
los.setUnsavedChanges();
document
.querySelector("button[type='submit'][form='form--cemetery']")
?.classList.remove('is-light');
}
function clearUnsavedChanges() {
los.clearUnsavedChanges();
document
.querySelector("button[type='submit'][form='form--cemetery']")
?.classList.add('is-light');
}
function updateCemetery(formEvent) {
formEvent.preventDefault();
cityssm.postJSON(`${los.urlPrefix}/cemeteries/${isCreate ? 'doCreateCemetery' : 'doUpdateCemetery'}`, cemeteryForm, (rawResponseJSON) => {
const responseJSON = rawResponseJSON;
if (responseJSON.success) {
clearUnsavedChanges();
if (isCreate) {
globalThis.location.href = los.getCemeteryURL(responseJSON.cemeteryId, true);
}
else {
bulmaJS.alert({
message: `Cemetery Updated Successfully`,
contextualColorName: 'success'
});
}
}
else {
bulmaJS.alert({
title: `Error Updating Cemetery`,
message: responseJSON.errorMessage ?? '',
contextualColorName: 'danger'
});
}
});
}
cemeteryForm.addEventListener('submit', updateCemetery);
const inputElements = cemeteryForm.querySelectorAll('input, select');
for (const inputElement of inputElements) {
inputElement.addEventListener('change', setUnsavedChanges);
}
document
.querySelector('#button--deleteCemetery')
?.addEventListener('click', (clickEvent) => {
clickEvent.preventDefault();
function doDelete() {
cityssm.postJSON(`${los.urlPrefix}/cemeteries/doDeleteCemetery`, {
cemeteryId
}, (rawResponseJSON) => {
const responseJSON = rawResponseJSON;
if (responseJSON.success) {
globalThis.location.href = los.getCemeteryURL();
}
else {
bulmaJS.alert({
title: `Error Deleting Cemetery`,
message: responseJSON.errorMessage ?? '',
contextualColorName: 'danger'
});
}
});
}
bulmaJS.confirm({
title: `Delete Cemetery`,
message: `Are you sure you want to delete this cemetery and all related burial sites?`,
contextualColorName: 'warning',
okButton: {
text: `Yes, Delete Cemetery`,
callbackFunction: doDelete
}
});
});
})();

View File

@ -1,7 +1,7 @@
import type { BulmaJS } from '@cityssm/bulma-js/types.js' import type { BulmaJS } from '@cityssm/bulma-js/types.js'
import type { cityssmGlobal } from '@cityssm/bulma-webapp-js/src/types.js' import type { cityssmGlobal } from '@cityssm/bulma-webapp-js/src/types.js'
import type { LOS } from '../../types/globalTypes.js' import type { LOS } from './types.js'
declare const cityssm: cityssmGlobal declare const cityssm: cityssmGlobal
declare const bulmaJS: BulmaJS declare const bulmaJS: BulmaJS
@ -10,32 +10,35 @@ declare const exports: Record<string, unknown>
;(() => { ;(() => {
const los = exports.los as LOS const los = exports.los as LOS
const cemeteryId = (document.querySelector('#map--cemeteryId') as HTMLInputElement) const cemeteryId = (
.value document.querySelector('#cemetery--cemeteryId') as HTMLInputElement
).value
const isCreate = cemeteryId === '' const isCreate = cemeteryId === ''
const mapForm = document.querySelector('#form--map') as HTMLFormElement const cemeteryForm = document.querySelector(
'#form--cemetery'
) as HTMLFormElement
function setUnsavedChanges(): void { function setUnsavedChanges(): void {
los.setUnsavedChanges() los.setUnsavedChanges()
document document
.querySelector("button[type='submit'][form='form--map']") .querySelector("button[type='submit'][form='form--cemetery']")
?.classList.remove('is-light') ?.classList.remove('is-light')
} }
function clearUnsavedChanges(): void { function clearUnsavedChanges(): void {
los.clearUnsavedChanges() los.clearUnsavedChanges()
document document
.querySelector("button[type='submit'][form='form--map']") .querySelector("button[type='submit'][form='form--cemetery']")
?.classList.add('is-light') ?.classList.add('is-light')
} }
function updateMap(formEvent: SubmitEvent): void { function updateCemetery(formEvent: SubmitEvent): void {
formEvent.preventDefault() formEvent.preventDefault()
cityssm.postJSON( cityssm.postJSON(
`${los.urlPrefix}/maps/${isCreate ? 'doCreateMap' : 'doUpdateMap'}`, `${los.urlPrefix}/cemeteries/${isCreate ? 'doCreateCemetery' : 'doUpdateCemetery'}`,
mapForm, cemeteryForm,
(rawResponseJSON) => { (rawResponseJSON) => {
const responseJSON = rawResponseJSON as { const responseJSON = rawResponseJSON as {
success: boolean success: boolean
@ -47,16 +50,19 @@ declare const exports: Record<string, unknown>
clearUnsavedChanges() clearUnsavedChanges()
if (isCreate) { if (isCreate) {
globalThis.location.href = los.getMapURL(responseJSON.cemeteryId, true) globalThis.location.href = los.getCemeteryURL(
responseJSON.cemeteryId,
true
)
} else { } else {
bulmaJS.alert({ bulmaJS.alert({
message: `${los.escapedAliases.Map} Updated Successfully`, message: `Cemetery Updated Successfully`,
contextualColorName: 'success' contextualColorName: 'success'
}) })
} }
} else { } else {
bulmaJS.alert({ bulmaJS.alert({
title: `Error Updating ${los.escapedAliases.Map}`, title: `Error Updating Cemetery`,
message: responseJSON.errorMessage ?? '', message: responseJSON.errorMessage ?? '',
contextualColorName: 'danger' contextualColorName: 'danger'
}) })
@ -65,23 +71,23 @@ declare const exports: Record<string, unknown>
) )
} }
mapForm.addEventListener('submit', updateMap) cemeteryForm.addEventListener('submit', updateCemetery)
const inputElements: NodeListOf<HTMLInputElement | HTMLSelectElement> = const inputElements: NodeListOf<HTMLInputElement | HTMLSelectElement> =
mapForm.querySelectorAll('input, select') cemeteryForm.querySelectorAll('input, select')
for (const inputElement of inputElements) { for (const inputElement of inputElements) {
inputElement.addEventListener('change', setUnsavedChanges) inputElement.addEventListener('change', setUnsavedChanges)
} }
document document
.querySelector('#button--deleteMap') .querySelector('#button--deleteCemetery')
?.addEventListener('click', (clickEvent) => { ?.addEventListener('click', (clickEvent) => {
clickEvent.preventDefault() clickEvent.preventDefault()
function doDelete(): void { function doDelete(): void {
cityssm.postJSON( cityssm.postJSON(
`${los.urlPrefix}/maps/doDeleteMap`, `${los.urlPrefix}/cemeteries/doDeleteCemetery`,
{ {
cemeteryId cemeteryId
}, },
@ -92,10 +98,10 @@ declare const exports: Record<string, unknown>
} }
if (responseJSON.success) { if (responseJSON.success) {
globalThis.location.href = los.getMapURL() globalThis.location.href = los.getCemeteryURL()
} else { } else {
bulmaJS.alert({ bulmaJS.alert({
title: `Error Deleting ${los.escapedAliases.Map}`, title: `Error Deleting Cemetery`,
message: responseJSON.errorMessage ?? '', message: responseJSON.errorMessage ?? '',
contextualColorName: 'danger' contextualColorName: 'danger'
}) })
@ -105,11 +111,11 @@ declare const exports: Record<string, unknown>
} }
bulmaJS.confirm({ bulmaJS.confirm({
title: `Delete ${los.escapedAliases.Map}`, title: `Delete Cemetery`,
message: `Are you sure you want to delete this ${los.escapedAliases.map} and all related ${los.escapedAliases.lots}?`, message: `Are you sure you want to delete this cemetery and all related burial sites?`,
contextualColorName: 'warning', contextualColorName: 'warning',
okButton: { okButton: {
text: `Yes, Delete ${los.escapedAliases.Map}`, text: `Yes, Delete Cemetery`,
callbackFunction: doDelete callbackFunction: doDelete
} }
}) })

View File

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

View File

@ -0,0 +1,102 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
(() => {
const los = exports.los;
const cemeteries = exports.cemeteries;
const searchFilterElement = document.querySelector('#searchFilter--cemetery');
const searchResultsContainerElement = document.querySelector('#container--searchResults');
// eslint-disable-next-line complexity
function renderResults() {
// eslint-disable-next-line no-unsanitized/property
searchResultsContainerElement.innerHTML = los.getLoadingParagraphHTML(`Loading Cemeteries...`);
let searchResultCount = 0;
const searchResultsTbodyElement = document.createElement('tbody');
const filterStringSplit = searchFilterElement.value
.trim()
.toLowerCase()
.split(' ');
for (const cemetery of cemeteries) {
const cemeterySearchString = `${cemetery.cemeteryName ?? ''} ${cemetery.cemeteryDescription ?? ''} ${cemetery.cemeteryAddress1 ?? ''} ${cemetery.cemeteryAddress2 ?? ''}`.toLowerCase();
let showCemetery = true;
for (const filterStringPiece of filterStringSplit) {
if (!cemeterySearchString.includes(filterStringPiece)) {
showCemetery = false;
break;
}
}
if (!showCemetery) {
continue;
}
searchResultCount += 1;
// eslint-disable-next-line no-unsanitized/method
searchResultsTbodyElement.insertAdjacentHTML('beforeend', `<tr>
<td>
<a class="has-text-weight-bold" href="${los.getCemeteryURL(cemetery.cemeteryId)}">
${cityssm.escapeHTML((cemetery.cemeteryName ?? '') === '' ? '(No Name)' : cemetery.cemeteryName ?? '')}
</a><br />
<span class="is-size-7">
${cityssm.escapeHTML(cemetery.cemeteryDescription ?? '')}
</span>
</td><td>
${(cemetery.cemeteryAddress1 ?? '') === ''
? ''
: `${cityssm.escapeHTML(cemetery.cemeteryAddress1 ?? '')}<br />`}
${(cemetery.cemeteryAddress2 ?? '') === ''
? ''
: `${cityssm.escapeHTML(cemetery.cemeteryAddress2 ?? '')}<br />`}
${cemetery.cemeteryCity || cemetery.cemeteryProvince
? `${cityssm.escapeHTML(cemetery.cemeteryCity ?? '')}, ${cityssm.escapeHTML(cemetery.cemeteryProvince ?? '')}<br />`
: ''}
${(cemetery.cemeteryPostalCode ?? '') === ''
? ''
: cityssm.escapeHTML(cemetery.cemeteryPostalCode ?? '')}
</td><td>
${cityssm.escapeHTML(cemetery.cemeteryPhoneNumber ?? '')}
</td><td class="has-text-centered">
${cemetery.cemeteryLatitude && cemetery.cemeteryLongitude
? `<span data-tooltip="Has Geographic Coordinates">
<i class="fas fa-map-marker-alt" role="img" aria-label="Has Geographic Coordinates"></i>
</span>`
: ''}
</td><td class="has-text-centered">
${(cemetery.cemeterySvg ?? '') === ''
? ''
: '<span data-tooltip="Has Image"><i class="fas fa-image" role="img" aria-label="Has Image"></i></span>'}
</td><td class="has-text-right">
<a href="${los.urlPrefix}/burialSites?cemeteryId=${cemetery.cemeteryId}">${cemetery.burialSiteCount}</a>
</td>
</tr>`);
}
searchResultsContainerElement.innerHTML = '';
if (searchResultCount === 0) {
// eslint-disable-next-line no-unsanitized/property
searchResultsContainerElement.innerHTML = `<div class="message is-info">
<p class="message-body">There are no cemeteries that meet the search criteria.</p>
</div>`;
}
else {
const searchResultsTableElement = document.createElement('table');
searchResultsTableElement.className =
'table is-fullwidth is-striped is-hoverable has-sticky-header';
// eslint-disable-next-line no-unsanitized/property
searchResultsTableElement.innerHTML = `<thead><tr>
<th>Cemetery</th>
<th>Address</th>
<th>Phone Number</th>
<th class="has-text-centered">Coordinates</th>
<th class="has-text-centered">Image</th>
<th class="has-text-right">Burial Site Count</th>
</tr></thead>`;
searchResultsTableElement.append(searchResultsTbodyElement);
searchResultsContainerElement.append(searchResultsTableElement);
}
}
searchFilterElement.addEventListener('keyup', renderResults);
document
.querySelector('#form--searchFilters')
?.addEventListener('submit', (formEvent) => {
formEvent.preventDefault();
renderResults();
});
renderResults();
})();

View File

@ -1,7 +1,8 @@
import type { cityssmGlobal } from '@cityssm/bulma-webapp-js/src/types.js' import type { cityssmGlobal } from '@cityssm/bulma-webapp-js/src/types.js'
import type { LOS } from '../../types/globalTypes.js' import type { Cemetery } from '../../types/recordTypes.js'
import type { MapRecord } from '../../types/recordTypes.js'
import type { LOS } from './types.js'
declare const cityssm: cityssmGlobal declare const cityssm: cityssmGlobal
@ -9,20 +10,21 @@ declare const exports: Record<string, unknown>
;(() => { ;(() => {
const los = exports.los as LOS const los = exports.los as LOS
const maps = exports.maps as MapRecord[] const cemeteries = exports.cemeteries as Cemetery[]
const searchFilterElement = document.querySelector( const searchFilterElement = document.querySelector(
'#searchFilter--map' '#searchFilter--cemetery'
) as HTMLInputElement ) as HTMLInputElement
const searchResultsContainerElement = document.querySelector( const searchResultsContainerElement = document.querySelector(
'#container--searchResults' '#container--searchResults'
) as HTMLElement ) as HTMLElement
// eslint-disable-next-line complexity
function renderResults(): void { function renderResults(): void {
// eslint-disable-next-line no-unsanitized/property // eslint-disable-next-line no-unsanitized/property
searchResultsContainerElement.innerHTML = los.getLoadingParagraphHTML( searchResultsContainerElement.innerHTML = los.getLoadingParagraphHTML(
`Loading ${los.escapedAliases.Maps}...` `Loading Cemeteries...`
) )
let searchResultCount = 0 let searchResultCount = 0
@ -33,21 +35,21 @@ declare const exports: Record<string, unknown>
.toLowerCase() .toLowerCase()
.split(' ') .split(' ')
for (const map of maps) { for (const cemetery of cemeteries) {
const mapSearchString = `${map.cemeteryName ?? ''} ${ const cemeterySearchString = `${cemetery.cemeteryName ?? ''} ${
map.mapDescription ?? '' cemetery.cemeteryDescription ?? ''
} ${map.mapAddress1 ?? ''} ${map.mapAddress2 ?? ''}`.toLowerCase() } ${cemetery.cemeteryAddress1 ?? ''} ${cemetery.cemeteryAddress2 ?? ''}`.toLowerCase()
let showMap = true let showCemetery = true
for (const filterStringPiece of filterStringSplit) { for (const filterStringPiece of filterStringSplit) {
if (!mapSearchString.includes(filterStringPiece)) { if (!cemeterySearchString.includes(filterStringPiece)) {
showMap = false showCemetery = false
break break
} }
} }
if (!showMap) { if (!showCemetery) {
continue continue
} }
@ -58,40 +60,40 @@ declare const exports: Record<string, unknown>
'beforeend', 'beforeend',
`<tr> `<tr>
<td> <td>
<a class="has-text-weight-bold" href="${los.getMapURL(map.cemeteryId)}"> <a class="has-text-weight-bold" href="${los.getCemeteryURL(cemetery.cemeteryId)}">
${cityssm.escapeHTML( ${cityssm.escapeHTML(
(map.cemeteryName ?? '') === '' ? '(No Name)' : map.cemeteryName ?? '' (cemetery.cemeteryName ?? '') === '' ? '(No Name)' : cemetery.cemeteryName ?? ''
)} )}
</a><br /> </a><br />
<span class="is-size-7"> <span class="is-size-7">
${cityssm.escapeHTML(map.mapDescription ?? '')} ${cityssm.escapeHTML(cemetery.cemeteryDescription ?? '')}
</span> </span>
</td><td> </td><td>
${ ${
(map.mapAddress1 ?? '') === '' (cemetery.cemeteryAddress1 ?? '') === ''
? '' ? ''
: `${cityssm.escapeHTML(map.mapAddress1 ?? '')}<br />` : `${cityssm.escapeHTML(cemetery.cemeteryAddress1 ?? '')}<br />`
} }
${ ${
(map.mapAddress2 ?? '') === '' (cemetery.cemeteryAddress2 ?? '') === ''
? '' ? ''
: `${cityssm.escapeHTML(map.mapAddress2 ?? '')}<br />` : `${cityssm.escapeHTML(cemetery.cemeteryAddress2 ?? '')}<br />`
} }
${ ${
map.mapCity || map.mapProvince cemetery.cemeteryCity || cemetery.cemeteryProvince
? `${cityssm.escapeHTML(map.mapCity ?? '')}, ${cityssm.escapeHTML(map.mapProvince ?? '')}<br />` ? `${cityssm.escapeHTML(cemetery.cemeteryCity ?? '')}, ${cityssm.escapeHTML(cemetery.cemeteryProvince ?? '')}<br />`
: '' : ''
} }
${ ${
(map.mapPostalCode ?? '') === '' (cemetery.cemeteryPostalCode ?? '') === ''
? '' ? ''
: cityssm.escapeHTML(map.mapPostalCode ?? '') : cityssm.escapeHTML(cemetery.cemeteryPostalCode ?? '')
} }
</td><td> </td><td>
${cityssm.escapeHTML(map.mapPhoneNumber ?? '')} ${cityssm.escapeHTML(cemetery.cemeteryPhoneNumber ?? '')}
</td><td class="has-text-centered"> </td><td class="has-text-centered">
${ ${
map.mapLatitude && map.mapLongitude cemetery.cemeteryLatitude && cemetery.cemeteryLongitude
? `<span data-tooltip="Has Geographic Coordinates"> ? `<span data-tooltip="Has Geographic Coordinates">
<i class="fas fa-map-marker-alt" role="img" aria-label="Has Geographic Coordinates"></i> <i class="fas fa-map-marker-alt" role="img" aria-label="Has Geographic Coordinates"></i>
</span>` </span>`
@ -99,12 +101,12 @@ declare const exports: Record<string, unknown>
} }
</td><td class="has-text-centered"> </td><td class="has-text-centered">
${ ${
(map.mapSVG ?? '') === '' (cemetery.cemeterySvg ?? '') === ''
? '' ? ''
: '<span data-tooltip="Has Image"><i class="fas fa-image" role="img" aria-label="Has Image"></i></span>' : '<span data-tooltip="Has Image"><i class="fas fa-image" role="img" aria-label="Has Image"></i></span>'
} }
</td><td class="has-text-right"> </td><td class="has-text-right">
<a href="${los.urlPrefix}/lots?cemeteryId=${map.cemeteryId}">${map.lotCount}</a> <a href="${los.urlPrefix}/burialSites?cemeteryId=${cemetery.cemeteryId}">${cemetery.burialSiteCount}</a>
</td> </td>
</tr>` </tr>`
) )
@ -115,7 +117,7 @@ declare const exports: Record<string, unknown>
if (searchResultCount === 0) { if (searchResultCount === 0) {
// eslint-disable-next-line no-unsanitized/property // eslint-disable-next-line no-unsanitized/property
searchResultsContainerElement.innerHTML = `<div class="message is-info"> searchResultsContainerElement.innerHTML = `<div class="message is-info">
<p class="message-body">There are no ${los.escapedAliases.maps} that meet the search criteria.</p> <p class="message-body">There are no cemeteries that meet the search criteria.</p>
</div>` </div>`
} else { } else {
const searchResultsTableElement = document.createElement('table') const searchResultsTableElement = document.createElement('table')
@ -125,12 +127,12 @@ declare const exports: Record<string, unknown>
// eslint-disable-next-line no-unsanitized/property // eslint-disable-next-line no-unsanitized/property
searchResultsTableElement.innerHTML = `<thead><tr> searchResultsTableElement.innerHTML = `<thead><tr>
<th>${los.escapedAliases.Map}</th> <th>Cemetery</th>
<th>Address</th> <th>Address</th>
<th>Phone Number</th> <th>Phone Number</th>
<th class="has-text-centered">Coordinates</th> <th class="has-text-centered">Coordinates</th>
<th class="has-text-centered">Image</th> <th class="has-text-centered">Image</th>
<th class="has-text-right">${los.escapedAliases.Lot} Count</th> <th class="has-text-right">Burial Site Count</th>
</tr></thead>` </tr></thead>`
searchResultsTableElement.append(searchResultsTbodyElement) searchResultsTableElement.append(searchResultsTbodyElement)

View File

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

View File

@ -0,0 +1,20 @@
"use strict";
// eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair
/* eslint-disable @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call */
Object.defineProperty(exports, "__esModule", { value: true });
(() => {
const mapContainerElement = document.querySelector('#map--leaflet');
if (mapContainerElement !== null) {
const mapLatitude = Number.parseFloat(mapContainerElement.dataset.mapLatitude ?? '');
const mapLongitude = Number.parseFloat(mapContainerElement.dataset.mapLongitude ?? '');
const mapCoordinates = [mapLatitude, mapLongitude];
// eslint-disable-next-line unicorn/no-array-callback-reference
const map = L.map(mapContainerElement);
map.setView(mapCoordinates, 15);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
attribution: '© OpenStreetMap'
}).addTo(map);
L.marker(mapCoordinates).addTo(map);
}
})();

View File

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

View File

@ -0,0 +1,602 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
(() => {
const los = exports.los;
const occupancyTypesContainerElement = document.querySelector('#container--occupancyTypes');
const ContractTypePrintsContainerElement = document.querySelector('#container--ContractTypePrints');
let occupancyTypes = exports.occupancyTypes;
delete exports.occupancyTypes;
let allContractTypeFields = exports.allContractTypeFields;
delete exports.allContractTypeFields;
const expandedOccupancyTypes = new Set();
function toggleContractTypeFields(clickEvent) {
const toggleButtonElement = clickEvent.currentTarget;
const occupancyTypeElement = toggleButtonElement.closest('.container--occupancyType');
const contractTypeId = Number.parseInt(occupancyTypeElement.dataset.contractTypeId ?? '', 10);
if (expandedOccupancyTypes.has(contractTypeId)) {
expandedOccupancyTypes.delete(contractTypeId);
}
else {
expandedOccupancyTypes.add(contractTypeId);
}
// eslint-disable-next-line no-unsanitized/property
toggleButtonElement.innerHTML = expandedOccupancyTypes.has(contractTypeId)
? '<i class="fas fa-fw fa-minus" aria-hidden="true"></i>'
: '<i class="fas fa-fw fa-plus" aria-hidden="true"></i>';
const panelBlockElements = occupancyTypeElement.querySelectorAll('.panel-block');
for (const panelBlockElement of panelBlockElements) {
panelBlockElement.classList.toggle('is-hidden');
}
}
function occupancyTypeResponseHandler(rawResponseJSON) {
const responseJSON = rawResponseJSON;
if (responseJSON.success) {
occupancyTypes = responseJSON.occupancyTypes;
allContractTypeFields = responseJSON.allContractTypeFields;
renderOccupancyTypes();
}
else {
bulmaJS.alert({
title: `Error Updating ${los.escapedAliases.Occupancy} Type`,
message: responseJSON.errorMessage ?? '',
contextualColorName: 'danger'
});
}
}
function deleteOccupancyType(clickEvent) {
const contractTypeId = Number.parseInt(clickEvent.currentTarget.closest('.container--occupancyType').dataset.contractTypeId ?? '', 10);
function doDelete() {
cityssm.postJSON(`${los.urlPrefix}/admin/doDeleteContractType`, {
contractTypeId
}, occupancyTypeResponseHandler);
}
bulmaJS.confirm({
title: `Delete ${los.escapedAliases.Occupancy} Type`,
message: `Are you sure you want to delete this ${los.escapedAliases.occupancy} type?`,
contextualColorName: 'warning',
okButton: {
text: `Yes, Delete ${los.escapedAliases.Occupancy} Type`,
callbackFunction: doDelete
}
});
}
function openEditOccupancyType(clickEvent) {
const contractTypeId = Number.parseInt(clickEvent.currentTarget.closest('.container--occupancyType').dataset.contractTypeId ?? '', 10);
const occupancyType = occupancyTypes.find((currentOccupancyType) => contractTypeId === currentOccupancyType.contractTypeId);
let editCloseModalFunction;
function doEdit(submitEvent) {
submitEvent.preventDefault();
cityssm.postJSON(`${los.urlPrefix}/admin/doUpdateContractType`, submitEvent.currentTarget, (rawResponseJSON) => {
const responseJSON = rawResponseJSON;
occupancyTypeResponseHandler(responseJSON);
if (responseJSON.success) {
editCloseModalFunction();
}
});
}
cityssm.openHtmlModal('adminOccupancyTypes-editOccupancyType', {
onshow(modalElement) {
los.populateAliases(modalElement);
modalElement.querySelector('#occupancyTypeEdit--contractTypeId').value = contractTypeId.toString();
modalElement.querySelector('#occupancyTypeEdit--occupancyType').value = occupancyType.occupancyType;
},
onshown(modalElement, closeModalFunction) {
editCloseModalFunction = closeModalFunction;
modalElement.querySelector('#occupancyTypeEdit--occupancyType').focus();
modalElement.querySelector('form')?.addEventListener('submit', doEdit);
bulmaJS.toggleHtmlClipped();
},
onremoved() {
bulmaJS.toggleHtmlClipped();
}
});
}
function openAddOccupancyTypeField(clickEvent) {
const contractTypeId = Number.parseInt(clickEvent.currentTarget.closest('.container--occupancyType').dataset.contractTypeId ?? '', 10);
let addCloseModalFunction;
function doAdd(submitEvent) {
submitEvent.preventDefault();
cityssm.postJSON(`${los.urlPrefix}/admin/doAddContractTypeField`, submitEvent.currentTarget, (rawResponseJSON) => {
const responseJSON = rawResponseJSON;
expandedOccupancyTypes.add(contractTypeId);
occupancyTypeResponseHandler(responseJSON);
if (responseJSON.success) {
addCloseModalFunction();
openEditOccupancyTypeField(contractTypeId, responseJSON.contractTypeFieldId ?? 0);
}
});
}
cityssm.openHtmlModal('adminOccupancyTypes-addOccupancyTypeField', {
onshow(modalElement) {
los.populateAliases(modalElement);
if (contractTypeId) {
;
modalElement.querySelector('#occupancyTypeFieldAdd--contractTypeId').value = contractTypeId.toString();
}
},
onshown(modalElement, closeModalFunction) {
addCloseModalFunction = closeModalFunction;
modalElement.querySelector('#occupancyTypeFieldAdd--occupancyTypeField').focus();
modalElement.querySelector('form')?.addEventListener('submit', doAdd);
bulmaJS.toggleHtmlClipped();
},
onremoved() {
bulmaJS.toggleHtmlClipped();
}
});
}
function moveOccupancyType(clickEvent) {
const buttonElement = clickEvent.currentTarget;
const contractTypeId = clickEvent.currentTarget.closest('.container--occupancyType').dataset.contractTypeId;
cityssm.postJSON(`${los.urlPrefix}/admin/${buttonElement.dataset.direction === 'up'
? 'doMoveContractTypeUp'
: 'doMoveContractTypeDown'}`, {
contractTypeId,
moveToEnd: clickEvent.shiftKey ? '1' : '0'
}, occupancyTypeResponseHandler);
}
function openEditOccupancyTypeField(contractTypeId, contractTypeFieldId) {
let occupancyType;
if (contractTypeId) {
occupancyType = occupancyTypes.find((currentOccupancyType) => currentOccupancyType.contractTypeId === contractTypeId);
}
const occupancyTypeField = (occupancyType
? occupancyType.ContractTypeFields ?? []
: allContractTypeFields).find((currentOccupancyTypeField) => currentOccupancyTypeField.contractTypeFieldId === contractTypeFieldId);
let fieldTypeElement;
let minimumLengthElement;
let maximumLengthElement;
let patternElement;
let occupancyTypeFieldValuesElement;
let editCloseModalFunction;
function updateMaximumLengthMin() {
maximumLengthElement.min = minimumLengthElement.value;
}
function toggleInputFields() {
switch (fieldTypeElement.value) {
case 'date': {
minimumLengthElement.disabled = true;
maximumLengthElement.disabled = true;
patternElement.disabled = true;
occupancyTypeFieldValuesElement.disabled = true;
break;
}
case 'select': {
minimumLengthElement.disabled = true;
maximumLengthElement.disabled = true;
patternElement.disabled = true;
occupancyTypeFieldValuesElement.disabled = false;
break;
}
default: {
minimumLengthElement.disabled = false;
maximumLengthElement.disabled = false;
patternElement.disabled = false;
occupancyTypeFieldValuesElement.disabled = true;
break;
}
}
}
function doUpdate(submitEvent) {
submitEvent.preventDefault();
cityssm.postJSON(`${los.urlPrefix}/admin/doUpdateContractTypeField`, submitEvent.currentTarget, (rawResponseJSON) => {
const responseJSON = rawResponseJSON;
occupancyTypeResponseHandler(responseJSON);
if (responseJSON.success) {
editCloseModalFunction();
}
});
}
function doDelete() {
cityssm.postJSON(`${los.urlPrefix}/admin/doDeleteContractTypeField`, {
contractTypeFieldId
}, (rawResponseJSON) => {
const responseJSON = rawResponseJSON;
occupancyTypeResponseHandler(responseJSON);
if (responseJSON.success) {
editCloseModalFunction();
}
});
}
function confirmDoDelete() {
bulmaJS.confirm({
title: 'Delete Field',
message: 'Are you sure you want to delete this field? Note that historical records that make use of this field will not be affected.',
contextualColorName: 'warning',
okButton: {
text: 'Yes, Delete Field',
callbackFunction: doDelete
}
});
}
cityssm.openHtmlModal('adminOccupancyTypes-editOccupancyTypeField', {
onshow: (modalElement) => {
los.populateAliases(modalElement);
modalElement.querySelector('#occupancyTypeFieldEdit--contractTypeFieldId').value = occupancyTypeField.contractTypeFieldId.toString();
modalElement.querySelector('#occupancyTypeFieldEdit--occupancyTypeField').value = occupancyTypeField.occupancyTypeField ?? '';
modalElement.querySelector('#occupancyTypeFieldEdit--isRequired').value = occupancyTypeField.isRequired ?? false ? '1' : '0';
fieldTypeElement = modalElement.querySelector('#occupancyTypeFieldEdit--fieldType');
fieldTypeElement.value = occupancyTypeField.fieldType;
minimumLengthElement = modalElement.querySelector('#occupancyTypeFieldEdit--minimumLength');
minimumLengthElement.value =
occupancyTypeField.minimumLength?.toString() ?? '';
maximumLengthElement = modalElement.querySelector('#occupancyTypeFieldEdit--maximumLength');
maximumLengthElement.value =
occupancyTypeField.maximumLength?.toString() ?? '';
patternElement = modalElement.querySelector('#occupancyTypeFieldEdit--pattern');
patternElement.value = occupancyTypeField.pattern ?? '';
occupancyTypeFieldValuesElement = modalElement.querySelector('#occupancyTypeFieldEdit--occupancyTypeFieldValues');
occupancyTypeFieldValuesElement.value =
occupancyTypeField.occupancyTypeFieldValues ?? '';
toggleInputFields();
},
onshown: (modalElement, closeModalFunction) => {
editCloseModalFunction = closeModalFunction;
bulmaJS.init(modalElement);
bulmaJS.toggleHtmlClipped();
cityssm.enableNavBlocker();
modalElement.querySelector('form')?.addEventListener('submit', doUpdate);
minimumLengthElement.addEventListener('keyup', updateMaximumLengthMin);
updateMaximumLengthMin();
fieldTypeElement.addEventListener('change', toggleInputFields);
modalElement
.querySelector('#button--deleteOccupancyTypeField')
?.addEventListener('click', confirmDoDelete);
},
onremoved: () => {
bulmaJS.toggleHtmlClipped();
cityssm.disableNavBlocker();
}
});
}
function openEditOccupancyTypeFieldByClick(clickEvent) {
clickEvent.preventDefault();
const contractTypeFieldId = Number.parseInt(clickEvent.currentTarget.closest('.container--occupancyTypeField').dataset.contractTypeFieldId ?? '', 10);
const contractTypeId = Number.parseInt(clickEvent.currentTarget.closest('.container--occupancyType').dataset.contractTypeId ?? '', 10);
openEditOccupancyTypeField(contractTypeId, contractTypeFieldId);
}
function moveOccupancyTypeField(clickEvent) {
const buttonElement = clickEvent.currentTarget;
const contractTypeFieldId = clickEvent.currentTarget.closest('.container--occupancyTypeField').dataset.contractTypeFieldId;
cityssm.postJSON(`${los.urlPrefix}/admin/${buttonElement.dataset.direction === 'up'
? 'doMoveContractTypeFieldUp'
: // eslint-disable-next-line no-secrets/no-secrets
'doMoveContractTypeFieldDown'}`, {
contractTypeFieldId,
moveToEnd: clickEvent.shiftKey ? '1' : '0'
}, occupancyTypeResponseHandler);
}
function renderContractTypeFields(panelElement, contractTypeId, ContractTypeFields) {
if (ContractTypeFields.length === 0) {
// eslint-disable-next-line no-unsanitized/method
panelElement.insertAdjacentHTML('beforeend', `<div class="panel-block is-block ${!contractTypeId || expandedOccupancyTypes.has(contractTypeId)
? ''
: ' is-hidden'}">
<div class="message is-info"><p class="message-body">There are no additional fields.</p></div>
</div>`);
}
else {
for (const occupancyTypeField of ContractTypeFields) {
const panelBlockElement = document.createElement('div');
panelBlockElement.className =
'panel-block is-block container--occupancyTypeField';
if (contractTypeId && !expandedOccupancyTypes.has(contractTypeId)) {
panelBlockElement.classList.add('is-hidden');
}
panelBlockElement.dataset.contractTypeFieldId =
occupancyTypeField.contractTypeFieldId.toString();
// eslint-disable-next-line no-unsanitized/property
panelBlockElement.innerHTML = `<div class="level is-mobile">
<div class="level-left">
<div class="level-item">
<a class="has-text-weight-bold button--editOccupancyTypeField" href="#">
${cityssm.escapeHTML(occupancyTypeField.occupancyTypeField ?? '')}
</a>
</div>
</div>
<div class="level-right">
<div class="level-item">
${los.getMoveUpDownButtonFieldHTML('button--moveOccupancyTypeFieldUp', 'button--moveOccupancyTypeFieldDown')}
</div>
</div>
</div>`;
panelBlockElement
.querySelector('.button--editOccupancyTypeField')
?.addEventListener('click', openEditOccupancyTypeFieldByClick);
panelBlockElement.querySelector('.button--moveOccupancyTypeFieldUp').addEventListener('click', moveOccupancyTypeField);
panelBlockElement.querySelector('.button--moveOccupancyTypeFieldDown').addEventListener('click', moveOccupancyTypeField);
panelElement.append(panelBlockElement);
}
}
}
function openAddOccupancyTypePrint(clickEvent) {
const contractTypeId = clickEvent.currentTarget.closest('.container--occupancyTypePrintList').dataset.contractTypeId ?? '';
let closeAddModalFunction;
function doAdd(formEvent) {
formEvent.preventDefault();
cityssm.postJSON(`${los.urlPrefix}/admin/doAddContractTypePrint`, formEvent.currentTarget, (rawResponseJSON) => {
const responseJSON = rawResponseJSON;
if (responseJSON.success) {
closeAddModalFunction();
}
occupancyTypeResponseHandler(responseJSON);
});
}
cityssm.openHtmlModal('adminOccupancyTypes-addOccupancyTypePrint', {
onshow(modalElement) {
los.populateAliases(modalElement);
modalElement.querySelector('#occupancyTypePrintAdd--contractTypeId').value = contractTypeId;
const printSelectElement = modalElement.querySelector('#occupancyTypePrintAdd--printEJS');
for (const [printEJS, printTitle] of Object.entries(exports.occupancyTypePrintTitles)) {
const optionElement = document.createElement('option');
optionElement.value = printEJS;
optionElement.textContent = printTitle;
printSelectElement.append(optionElement);
}
},
onshown(modalElement, closeModalFunction) {
closeAddModalFunction = closeModalFunction;
modalElement.querySelector('form')?.addEventListener('submit', doAdd);
}
});
}
function moveOccupancyTypePrint(clickEvent) {
const buttonElement = clickEvent.currentTarget;
const printEJS = buttonElement.closest('.container--occupancyTypePrint').dataset.printEJS;
const contractTypeId = buttonElement.closest('.container--occupancyTypePrintList').dataset.contractTypeId;
cityssm.postJSON(`${los.urlPrefix}/admin/${buttonElement.dataset.direction === 'up'
? // eslint-disable-next-line no-secrets/no-secrets
'doMoveContractTypePrintUp'
: // eslint-disable-next-line no-secrets/no-secrets
'doMoveContractTypePrintDown'}`, {
contractTypeId,
printEJS,
moveToEnd: clickEvent.shiftKey ? '1' : '0'
}, occupancyTypeResponseHandler);
}
function deleteOccupancyTypePrint(clickEvent) {
clickEvent.preventDefault();
const printEJS = clickEvent.currentTarget.closest('.container--occupancyTypePrint').dataset.printEJS;
const contractTypeId = clickEvent.currentTarget.closest('.container--occupancyTypePrintList').dataset.contractTypeId;
function doDelete() {
cityssm.postJSON(`${los.urlPrefix}/admin/doDeleteContractTypePrint`, {
contractTypeId,
printEJS
}, occupancyTypeResponseHandler);
}
bulmaJS.confirm({
title: 'Delete Print',
message: 'Are you sure you want to remove this print option?',
contextualColorName: 'warning',
okButton: {
text: 'Yes, Remove Print',
callbackFunction: doDelete
}
});
}
function renderContractTypePrints(panelElement, contractTypeId, ContractTypePrints) {
if (ContractTypePrints.length === 0) {
panelElement.insertAdjacentHTML('beforeend', `<div class="panel-block is-block">
<div class="message is-info">
<p class="message-body">There are no prints associated with this record.</p>
</div>
</div>`);
}
else {
for (const printEJS of ContractTypePrints) {
const panelBlockElement = document.createElement('div');
panelBlockElement.className =
'panel-block is-block container--occupancyTypePrint';
panelBlockElement.dataset.printEJS = printEJS;
const printTitle = printEJS === '*'
? '(All Available Prints)'
: exports.occupancyTypePrintTitles[printEJS];
let printIconClass = 'fa-star';
if (printEJS.startsWith('pdf/')) {
printIconClass = 'fa-file-pdf';
}
else if (printEJS.startsWith('screen/')) {
printIconClass = 'fa-file';
}
// eslint-disable-next-line no-unsanitized/property
panelBlockElement.innerHTML = `<div class="level is-mobile">
<div class="level-left">
<div class="level-item">
<i class="fas fa-fw ${printIconClass}" aria-hidden="true"></i>
</div>
<div class="level-item">
${cityssm.escapeHTML(printTitle || printEJS)}
</div>
</div>
<div class="level-right">
<div class="level-item">
${los.getMoveUpDownButtonFieldHTML('button--moveOccupancyTypePrintUp', 'button--moveOccupancyTypePrintDown')}
</div>
<div class="level-item">
<button class="button is-small is-danger button--deleteOccupancyTypePrint" data-tooltip="Delete" type="button" aria-label="Delete Print">
<i class="fas fa-trash" aria-hidden="true"></i>
</button>
</div>
</div>
</div>`;
panelBlockElement.querySelector('.button--moveOccupancyTypePrintUp').addEventListener('click', moveOccupancyTypePrint);
panelBlockElement.querySelector('.button--moveOccupancyTypePrintDown').addEventListener('click', moveOccupancyTypePrint);
panelBlockElement
.querySelector('.button--deleteOccupancyTypePrint')
?.addEventListener('click', deleteOccupancyTypePrint);
panelElement.append(panelBlockElement);
}
}
}
function renderOccupancyTypes() {
// eslint-disable-next-line no-unsanitized/property
occupancyTypesContainerElement.innerHTML = `<div class="panel container--occupancyType" id="container--allContractTypeFields" data-occupancy-type-id="">
<div class="panel-heading">
<div class="level is-mobile">
<div class="level-left">
<div class="level-item">
<h2 class="title is-4">(All ${los.escapedAliases.Occupancy} Types)</h2>
</div>
</div>
<div class="level-right">
<div class="level-item">
<button class="button is-success is-small button--addOccupancyTypeField" type="button">
<span class="icon is-small"><i class="fas fa-plus" aria-hidden="true"></i></span>
<span>Add Field</span>
</button>
</div>
</div>
</div>
</div>
</div>`;
ContractTypePrintsContainerElement.innerHTML = '';
renderContractTypeFields(occupancyTypesContainerElement.querySelector('#container--allContractTypeFields'), undefined, allContractTypeFields);
occupancyTypesContainerElement
.querySelector('.button--addOccupancyTypeField')
?.addEventListener('click', openAddOccupancyTypeField);
if (occupancyTypes.length === 0) {
// eslint-disable-next-line no-unsanitized/method
occupancyTypesContainerElement.insertAdjacentHTML('afterbegin', `<div class="message is-warning>
<p class="message-body">There are no active ${los.escapedAliases.occupancy} types.</p>
</div>`);
// eslint-disable-next-line no-unsanitized/method
ContractTypePrintsContainerElement.insertAdjacentHTML('afterbegin', `<div class="message is-warning>
<p class="message-body">There are no active ${los.escapedAliases.occupancy} types.</p>
</div>`);
return;
}
for (const occupancyType of occupancyTypes) {
/*
* Types and Fields
*/
const occupancyTypeContainer = document.createElement('div');
occupancyTypeContainer.className = 'panel container--occupancyType';
occupancyTypeContainer.dataset.contractTypeId =
occupancyType.contractTypeId.toString();
// eslint-disable-next-line no-unsanitized/property
occupancyTypeContainer.innerHTML = `<div class="panel-heading">
<div class="level is-mobile">
<div class="level-left">
<div class="level-item">
<button class="button is-small button--toggleContractTypeFields" data-tooltip="Toggle Fields" type="button" aria-label="Toggle Fields">
${expandedOccupancyTypes.has(occupancyType.contractTypeId)
? '<i class="fas fa-fw fa-minus" aria-hidden="true"></i>'
: '<i class="fas fa-fw fa-plus" aria-hidden="true"></i>'}
</button>
</div>
<div class="level-item">
<h2 class="title is-4">${cityssm.escapeHTML(occupancyType.occupancyType)}</h2>
</div>
</div>
<div class="level-right">
<div class="level-item">
<button class="button is-danger is-small button--deleteOccupancyType" type="button">
<span class="icon is-small"><i class="fas fa-trash" aria-hidden="true"></i></span>
<span>Delete</span>
</button>
</div>
<div class="level-item">
<button class="button is-primary is-small button--editOccupancyType" type="button">
<span class="icon is-small"><i class="fas fa-pencil-alt" aria-hidden="true"></i></span>
<span>Edit ${los.escapedAliases.Occupancy} Type</span>
</button>
</div>
<div class="level-item">
<button class="button is-success is-small button--addOccupancyTypeField" type="button">
<span class="icon is-small"><i class="fas fa-plus" aria-hidden="true"></i></span>
<span>Add Field</span>
</button>
</div>
<div class="level-item">
${los.getMoveUpDownButtonFieldHTML('button--moveOccupancyTypeUp', 'button--moveOccupancyTypeDown')}
</div>
</div>
</div>
</div>`;
renderContractTypeFields(occupancyTypeContainer, occupancyType.contractTypeId, occupancyType.ContractTypeFields ?? []);
occupancyTypeContainer
.querySelector('.button--toggleContractTypeFields')
?.addEventListener('click', toggleContractTypeFields);
occupancyTypeContainer
.querySelector('.button--deleteOccupancyType')
?.addEventListener('click', deleteOccupancyType);
occupancyTypeContainer
.querySelector('.button--editOccupancyType')
?.addEventListener('click', openEditOccupancyType);
occupancyTypeContainer
.querySelector('.button--addOccupancyTypeField')
?.addEventListener('click', openAddOccupancyTypeField);
occupancyTypeContainer.querySelector('.button--moveOccupancyTypeUp').addEventListener('click', moveOccupancyType);
occupancyTypeContainer.querySelector('.button--moveOccupancyTypeDown').addEventListener('click', moveOccupancyType);
occupancyTypesContainerElement.append(occupancyTypeContainer);
/*
* Prints
*/
const occupancyTypePrintContainer = document.createElement('div');
occupancyTypePrintContainer.className =
'panel container--occupancyTypePrintList';
occupancyTypePrintContainer.dataset.contractTypeId =
occupancyType.contractTypeId.toString();
occupancyTypePrintContainer.innerHTML = `<div class="panel-heading">
<div class="level is-mobile">
<div class="level-left">
<div class="level-item">
<h2 class="title is-4">${cityssm.escapeHTML(occupancyType.occupancyType)}</h2>
</div>
</div>
<div class="level-right">
<div class="level-item">
<button class="button is-success is-small button--addOccupancyTypePrint" type="button">
<span class="icon is-small"><i class="fas fa-plus" aria-hidden="true"></i></span>
<span>Add Print</span>
</button>
</div>
</div>
</div>
</div>`;
renderContractTypePrints(occupancyTypePrintContainer, occupancyType.contractTypeId, occupancyType.ContractTypePrints ?? []);
occupancyTypePrintContainer
.querySelector('.button--addOccupancyTypePrint')
?.addEventListener('click', openAddOccupancyTypePrint);
ContractTypePrintsContainerElement.append(occupancyTypePrintContainer);
}
}
document
.querySelector('#button--addOccupancyType')
?.addEventListener('click', () => {
let addCloseModalFunction;
function doAdd(submitEvent) {
submitEvent.preventDefault();
cityssm.postJSON(`${los.urlPrefix}/admin/doAddContractType`, submitEvent.currentTarget, (rawResponseJSON) => {
const responseJSON = rawResponseJSON;
if (responseJSON.success) {
addCloseModalFunction();
occupancyTypes = responseJSON.occupancyTypes;
renderOccupancyTypes();
}
else {
bulmaJS.alert({
title: `Error Adding ${los.escapedAliases.Occupancy} Type`,
message: responseJSON.errorMessage ?? '',
contextualColorName: 'danger'
});
}
});
}
cityssm.openHtmlModal('adminOccupancyTypes-addOccupancyType', {
onshow(modalElement) {
los.populateAliases(modalElement);
},
onshown(modalElement, closeModalFunction) {
addCloseModalFunction = closeModalFunction;
modalElement.querySelector('#occupancyTypeAdd--occupancyType').focus();
modalElement.querySelector('form')?.addEventListener('submit', doAdd);
bulmaJS.toggleHtmlClipped();
},
onremoved() {
bulmaJS.toggleHtmlClipped();
}
});
});
renderOccupancyTypes();
})();

View File

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

View File

@ -0,0 +1,70 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
(() => {
const los = exports.los;
function doBackup() {
cityssm.postJSON(`${los.urlPrefix}/admin/doBackupDatabase`, {}, (rawResponseJSON) => {
const responseJSON = rawResponseJSON;
if (responseJSON.success) {
bulmaJS.alert({
title: 'Database Backed Up Successfully',
message: `Backed up to <strong>${responseJSON.fileName}</strong><br />
To request a copy of the backup, contact your application administrator.`,
messageIsHtml: true,
contextualColorName: 'success'
});
}
else {
bulmaJS.alert({
title: 'Error Backing Up Database',
message: responseJSON.errorMessage ?? '',
contextualColorName: 'danger'
});
}
});
}
function doCleanup() {
cityssm.postJSON(`${los.urlPrefix}/admin/doCleanupDatabase`, {}, (rawResponseJSON) => {
const responseJSON = rawResponseJSON;
if (responseJSON.success) {
bulmaJS.alert({
title: 'Database Cleaned Up Successfully',
message: `${responseJSON.inactivatedRecordCount} records inactivated,
${responseJSON.purgedRecordCount} permanently deleted.`,
contextualColorName: 'success'
});
}
else {
bulmaJS.alert({
title: 'Error Cleaning Database',
message: responseJSON.errorMessage ?? '',
contextualColorName: 'danger'
});
}
});
}
document
.querySelector('#button--cleanupDatabase')
?.addEventListener('click', () => {
bulmaJS.confirm({
title: 'Cleanup Database',
message: 'Are you sure you want to cleanup up the database?',
okButton: {
text: 'Yes, Cleanup Database',
callbackFunction: doCleanup
}
});
});
document
.querySelector('#button--backupDatabase')
?.addEventListener('click', () => {
bulmaJS.confirm({
title: 'Backup Database',
message: 'Are you sure you want to backup up the database?',
okButton: {
text: 'Yes, Backup Database',
callbackFunction: doBackup
}
});
});
})();

View File

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

View File

@ -0,0 +1,659 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
(() => {
const los = exports.los;
const feeCategoriesContainerElement = document.querySelector('#container--feeCategories');
let feeCategories = exports.feeCategories;
delete exports.feeCategories;
function getFeeCategory(feeCategoryId) {
return feeCategories.find((currentFeeCategory) => currentFeeCategory.feeCategoryId === feeCategoryId);
}
function getFee(feeCategory, feeId) {
return feeCategory.fees.find((currentFee) => currentFee.feeId === feeId);
}
function renderFeeCategories() {
if (feeCategories.length === 0) {
feeCategoriesContainerElement.innerHTML = `<div class="message is-warning">
<p class="message-body">There are no available fees.</p>
</div>`;
return;
}
feeCategoriesContainerElement.innerHTML = '';
for (const feeCategory of feeCategories) {
const feeCategoryContainerElement = document.createElement('section');
feeCategoryContainerElement.className = 'panel container--feeCategory';
feeCategoryContainerElement.dataset.feeCategoryId =
feeCategory.feeCategoryId.toString();
// eslint-disable-next-line no-unsanitized/property
feeCategoryContainerElement.innerHTML = `<div class="panel-heading">
<div class="columns">
<div class="column">
<h2 class="title is-4 mb-2">${cityssm.escapeHTML(feeCategory.feeCategory ?? '')}</h2>
${feeCategory.isGroupedFee
? '<span class="tag">Grouped Fee</span>'
: ''}
</div>
<div class="column is-narrow">
<div class="field is-grouped is-justify-content-end">
${feeCategory.fees.length === 0
? `<div class="control">
<button class="button is-small is-danger button--deleteFeeCategory" type="button">
<span class="icon is-small"><i class="fas fa-trash" aria-hidden="true"></i></span>
<span>Delete Category</span>
</button>
</div>`
: ''}
<div class="control">
<button class="button is-small is-primary button--editFeeCategory" type="button">
<span class="icon is-small"><i class="fas fa-pencil-alt" aria-hidden="true"></i></span>
<span>
${feeCategory.isGroupedFee
? 'Edit Grouped Fee'
: 'Edit Category'}
</span>
</button>
</div>
<div class="control">
<button class="button is-small is-success button--addFee" data-cy="addFee" type="button">
<span class="icon is-small"><i class="fas fa-plus" aria-hidden="true"></i></span>
<span>Add Fee</span>
</button>
</div>
<div class="control">
${los.getMoveUpDownButtonFieldHTML('button--moveFeeCategoryUp', 'button--moveFeeCategoryDown')}
</div>
</div>
</div>
</div>`;
if (feeCategory.fees.length === 0) {
feeCategoryContainerElement.insertAdjacentHTML('beforeend', `<div class="panel-block is-block">
<div class="message is-info">
<p class="message-body">
There are no fees in the
"${cityssm.escapeHTML(feeCategory.feeCategory ?? '')}"
category.
</p>
</div>
</div>`);
feeCategoryContainerElement
.querySelector('.button--deleteFeeCategory')
?.addEventListener('click', confirmDeleteFeeCategory);
}
for (const fee of feeCategory.fees) {
const panelBlockElement = document.createElement('div');
panelBlockElement.className = 'panel-block is-block container--fee';
panelBlockElement.dataset.feeId = fee.feeId.toString();
const hasTagsBlock = (fee.isRequired ?? false) ||
fee.contractTypeId !== undefined ||
fee.burialSiteTypeId !== undefined;
// eslint-disable-next-line no-unsanitized/property
panelBlockElement.innerHTML = `<div class="columns">
<div class="column is-half">
<p>
<a class="has-text-weight-bold a--editFee" href="#">${cityssm.escapeHTML(fee.feeName ?? '')}</a><br />
<small>
${
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
cityssm
.escapeHTML(fee.feeDescription ?? '')
.replaceAll('\n', '<br />')}
</small>
</p>
${hasTagsBlock
? `<p class="tags">
${fee.isRequired ?? false
? '<span class="tag is-warning">Required</span>'
: ''}
${(fee.contractTypeId ?? -1) === -1
? ''
: ` <span class="tag has-tooltip-bottom" data-tooltip="${los.escapedAliases.Occupancy} Type Filter">
<span class="icon is-small"><i class="fas fa-filter" aria-hidden="true"></i></span>
<span>${cityssm.escapeHTML(fee.occupancyType ?? '')}</span>
</span>`}
${(fee.burialSiteTypeId ?? -1) === -1
? ''
: ` <span class="tag has-tooltip-bottom" data-tooltip="${los.escapedAliases.Lot} Type Filter">
<span class="icon is-small"><i class="fas fa-filter" aria-hidden="true"></i></span>
<span>${cityssm.escapeHTML(fee.lotType ?? '')}</span>
</span>`}
</p>`
: ''}
</div>
<div class="column">
<div class="columns is-mobile">
<div class="column has-text-centered">
${fee.feeFunction
? `${cityssm.escapeHTML(fee.feeFunction)}<br />
<small>Fee Function</small>`
: `<a class="a--editFeeAmount" href="#">
$${(fee.feeAmount ?? 0).toFixed(2)}<br />
<small>Fee</small>
</a>`}
</div>
<div class="column has-text-centered">
${fee.taxPercentage
? `${fee.taxPercentage.toString()}%`
: `$${(fee.taxAmount ?? 0).toFixed(2)}`}<br />
<small>Tax</small>
</div>
<div class="column has-text-centered">
${fee.includeQuantity
? `${cityssm.escapeHTML(fee.quantityUnit ?? '')}<br />
<small>Quantity</small>`
: ''}
</div>
</div>
</div>
<div class="column is-narrow">
${los.getMoveUpDownButtonFieldHTML('button--moveFeeUp', 'button--moveFeeDown')}
</div>
</div>`;
panelBlockElement
.querySelector('.a--editFee')
?.addEventListener('click', openEditFee);
panelBlockElement
.querySelector('.a--editFeeAmount')
?.addEventListener('click', openEditFeeAmount);
panelBlockElement.querySelector('.button--moveFeeUp').addEventListener('click', moveFee);
panelBlockElement.querySelector('.button--moveFeeDown').addEventListener('click', moveFee);
feeCategoryContainerElement.append(panelBlockElement);
}
feeCategoryContainerElement
.querySelector('.button--editFeeCategory')
?.addEventListener('click', openEditFeeCategory);
feeCategoryContainerElement
.querySelector('.button--addFee')
?.addEventListener('click', openAddFee);
feeCategoryContainerElement.querySelector('.button--moveFeeCategoryUp').addEventListener('click', moveFeeCategory);
feeCategoryContainerElement.querySelector('.button--moveFeeCategoryDown').addEventListener('click', moveFeeCategory);
feeCategoriesContainerElement.append(feeCategoryContainerElement);
}
}
/*
* Fee Categories
*/
document
.querySelector('#button--addFeeCategory')
?.addEventListener('click', () => {
let addCloseModalFunction;
function doAddFeeCategory(submitEvent) {
submitEvent.preventDefault();
cityssm.postJSON(`${los.urlPrefix}/admin/doAddFeeCategory`, submitEvent.currentTarget, (rawResponseJSON) => {
const responseJSON = rawResponseJSON;
if (responseJSON.success) {
feeCategories = responseJSON.feeCategories;
addCloseModalFunction();
renderFeeCategories();
}
else {
bulmaJS.alert({
title: 'Error Creating Fee Category',
message: responseJSON.errorMessage ?? '',
contextualColorName: 'danger'
});
}
});
}
cityssm.openHtmlModal('adminFees-addFeeCategory', {
onshown(modalElement, closeModalFunction) {
bulmaJS.toggleHtmlClipped();
modalElement.querySelector('#feeCategoryAdd--feeCategory').focus();
addCloseModalFunction = closeModalFunction;
modalElement
.querySelector('form')
?.addEventListener('submit', doAddFeeCategory);
},
onremoved() {
bulmaJS.toggleHtmlClipped();
document.querySelector('#button--addFeeCategory').focus();
}
});
});
function openEditFeeCategory(clickEvent) {
const feeCategoryId = Number.parseInt(clickEvent.currentTarget.closest('.container--feeCategory').dataset.feeCategoryId ?? '', 10);
const feeCategory = getFeeCategory(feeCategoryId);
let editCloseModalFunction;
function doUpdateFeeCategory(submitEvent) {
submitEvent.preventDefault();
cityssm.postJSON(`${los.urlPrefix}/admin/doUpdateFeeCategory`, submitEvent.currentTarget, (rawResponseJSON) => {
const responseJSON = rawResponseJSON;
if (responseJSON.success) {
feeCategories = responseJSON.feeCategories;
editCloseModalFunction();
renderFeeCategories();
}
else {
bulmaJS.alert({
title: 'Error Updating Fee Category',
message: responseJSON.errorMessage ?? '',
contextualColorName: 'danger'
});
}
});
}
cityssm.openHtmlModal('adminFees-editFeeCategory', {
onshow(modalElement) {
;
modalElement.querySelector('#feeCategoryEdit--feeCategoryId').value = feeCategory.feeCategoryId.toString();
modalElement.querySelector('#feeCategoryEdit--feeCategory').value = feeCategory.feeCategory;
if (feeCategory.isGroupedFee) {
;
modalElement.querySelector('#feeCategoryEdit--isGroupedFee').checked = true;
}
},
onshown(modalElement, closeModalFunction) {
bulmaJS.toggleHtmlClipped();
editCloseModalFunction = closeModalFunction;
modalElement
.querySelector('form')
?.addEventListener('submit', doUpdateFeeCategory);
modalElement.querySelector('#feeCategoryEdit--feeCategory').focus();
},
onremoved: () => {
bulmaJS.toggleHtmlClipped();
}
});
}
function confirmDeleteFeeCategory(clickEvent) {
const feeCategoryId = Number.parseInt(clickEvent.currentTarget.closest('.container--feeCategory').dataset.feeCategoryId ?? '', 10);
function doDelete() {
cityssm.postJSON(`${los.urlPrefix}/admin/doDeleteFeeCategory`, {
feeCategoryId
}, (rawResponseJSON) => {
const responseJSON = rawResponseJSON;
if (responseJSON.success) {
feeCategories = responseJSON.feeCategories;
renderFeeCategories();
}
else {
bulmaJS.alert({
title: 'Error Updating Fee Category',
message: responseJSON.errorMessage ?? '',
contextualColorName: 'danger'
});
}
});
}
bulmaJS.confirm({
title: 'Delete Fee Category?',
message: 'Are you sure you want to delete this fee category?',
contextualColorName: 'warning',
okButton: {
text: 'Yes, Delete the Fee Category',
callbackFunction: doDelete
}
});
}
function moveFeeCategory(clickEvent) {
const buttonElement = clickEvent.currentTarget;
const feeCategoryId = buttonElement.closest('.container--feeCategory').dataset
.feeCategoryId ?? '';
cityssm.postJSON(`${los.urlPrefix}/admin/${buttonElement.dataset.direction === 'up'
? 'doMoveFeeCategoryUp'
: 'doMoveFeeCategoryDown'}`, {
feeCategoryId,
moveToEnd: clickEvent.shiftKey ? '1' : '0'
}, (rawResponseJSON) => {
const responseJSON = rawResponseJSON;
if (responseJSON.success) {
feeCategories = responseJSON.feeCategories;
renderFeeCategories();
}
else {
bulmaJS.alert({
title: 'Error Moving Fee Category',
message: responseJSON.errorMessage ?? '',
contextualColorName: 'danger'
});
}
});
}
/*
* Fees
*/
function openAddFee(clickEvent) {
const feeCategoryId = Number.parseInt(clickEvent.currentTarget.closest('.container--feeCategory').dataset.feeCategoryId ?? '', 10);
let addCloseModalFunction;
function doAddFee(submitEvent) {
submitEvent.preventDefault();
cityssm.postJSON(`${los.urlPrefix}/admin/doAddFee`, submitEvent.currentTarget, (rawResponseJSON) => {
const responseJSON = rawResponseJSON;
if (responseJSON.success) {
feeCategories = responseJSON.feeCategories;
addCloseModalFunction();
renderFeeCategories();
}
else {
bulmaJS.alert({
title: 'Error Adding Fee',
message: responseJSON.errorMessage ?? '',
contextualColorName: 'danger'
});
}
});
}
cityssm.openHtmlModal('adminFees-addFee', {
onshow(modalElement) {
const feeCategoryElement = modalElement.querySelector('#feeAdd--feeCategoryId');
for (const feeCategory of feeCategories) {
const optionElement = document.createElement('option');
optionElement.value = feeCategory.feeCategoryId.toString();
optionElement.textContent = feeCategory.feeCategory;
if (feeCategory.feeCategoryId === feeCategoryId) {
optionElement.selected = true;
}
feeCategoryElement.append(optionElement);
}
const occupancyTypeElement = modalElement.querySelector('#feeAdd--contractTypeId');
for (const occupancyType of exports.occupancyTypes) {
const optionElement = document.createElement('option');
optionElement.value = occupancyType.contractTypeId.toString();
optionElement.textContent = occupancyType.occupancyType;
occupancyTypeElement.append(optionElement);
}
const lotTypeElement = modalElement.querySelector('#feeAdd--burialSiteTypeId');
for (const lotType of exports.lotTypes) {
const optionElement = document.createElement('option');
optionElement.value = lotType.burialSiteTypeId.toString();
optionElement.textContent = lotType.lotType;
lotTypeElement.append(optionElement);
}
;
modalElement.querySelector('#feeAdd--taxPercentage').value = exports.taxPercentageDefault.toString();
los.populateAliases(modalElement);
},
onshown(modalElement, closeModalFunction) {
bulmaJS.toggleHtmlClipped();
addCloseModalFunction = closeModalFunction;
modalElement.querySelector('form')?.addEventListener('submit', doAddFee);
modalElement.querySelector('#feeAdd--feeName').focus();
modalElement.querySelector('#feeAdd--feeFunction').addEventListener('change', () => {
const feeAmountElement = modalElement.querySelector('#feeAdd--feeAmount');
const feeFunctionElement = modalElement.querySelector('#feeAdd--feeFunction');
if (feeFunctionElement.value === '') {
feeFunctionElement
.closest('.select')
?.classList.remove('is-success');
feeAmountElement.classList.add('is-success');
feeAmountElement.disabled = false;
}
else {
feeFunctionElement.closest('.select')?.classList.add('is-success');
feeAmountElement.classList.remove('is-success');
feeAmountElement.disabled = true;
}
});
modalElement
.querySelector('#feeAdd--taxPercentage')
?.addEventListener('keyup', () => {
const taxAmountElement = modalElement.querySelector('#feeAdd--taxAmount');
const taxPercentageElement = modalElement.querySelector('#feeAdd--taxPercentage');
if (taxPercentageElement.value === '') {
taxPercentageElement.classList.remove('is-success');
taxAmountElement.classList.add('is-success');
taxAmountElement.disabled = false;
}
else {
taxPercentageElement.classList.add('is-success');
taxAmountElement.classList.remove('is-success');
taxAmountElement.disabled = true;
}
});
modalElement
.querySelector('#feeAdd--includeQuantity')
?.addEventListener('change', () => {
;
modalElement.querySelector('#feeAdd--quantityUnit').disabled =
modalElement.querySelector('#feeAdd--includeQuantity').value === '';
});
},
onremoved() {
bulmaJS.toggleHtmlClipped();
}
});
}
function openEditFeeAmount(clickEvent) {
clickEvent.preventDefault();
const feeContainerElement = clickEvent.currentTarget.closest('.container--fee');
const feeId = Number.parseInt(feeContainerElement.dataset.feeId ?? '', 10);
const feeCategoryId = Number.parseInt(feeContainerElement.closest('.container--feeCategory')
.dataset.feeCategoryId ?? '');
const feeCategory = getFeeCategory(feeCategoryId);
const fee = getFee(feeCategory, feeId);
let editCloseModalFunction;
function doUpdateFeeAmount(submitEvent) {
submitEvent.preventDefault();
cityssm.postJSON(`${los.urlPrefix}/admin/doUpdateFeeAmount`, submitEvent.currentTarget, (rawResponseJSON) => {
const responseJSON = rawResponseJSON;
if (responseJSON.success) {
feeCategories = responseJSON.feeCategories;
editCloseModalFunction();
renderFeeCategories();
}
else {
bulmaJS.alert({
title: 'Error Updating Fee Amount',
message: responseJSON.errorMessage ?? '',
contextualColorName: 'danger'
});
}
});
}
cityssm.openHtmlModal('adminFees-editFeeAmount', {
onshow(modalElement) {
;
modalElement.querySelector('#feeAmountEdit--feeId').value = fee.feeId.toString();
modalElement.querySelector('#feeAmountEdit--feeCategory').textContent = feeCategory.feeCategory;
modalElement.querySelector('#feeAmountEdit--feeName').textContent = fee.feeName ?? '';
modalElement.querySelector('#feeAmountEdit--feeAmount').value = fee.feeAmount?.toFixed(2) ?? '0';
},
onshown(modalElement, closeModalFunction) {
;
modalElement.querySelector('#feeAmountEdit--feeAmount').select();
editCloseModalFunction = closeModalFunction;
modalElement
.querySelector('form')
?.addEventListener('submit', doUpdateFeeAmount);
}
});
}
function openEditFee(clickEvent) {
clickEvent.preventDefault();
const feeContainerElement = clickEvent.currentTarget.closest('.container--fee');
const feeId = Number.parseInt(feeContainerElement.dataset.feeId ?? '', 10);
const feeCategoryId = Number.parseInt(feeContainerElement.closest('.container--feeCategory')
.dataset.feeCategoryId ?? '');
const feeCategory = getFeeCategory(feeCategoryId);
const fee = getFee(feeCategory, feeId);
let editCloseModalFunction;
let editModalElement;
function doUpdateFee(submitEvent) {
submitEvent.preventDefault();
cityssm.postJSON(`${los.urlPrefix}/admin/doUpdateFee`, submitEvent.currentTarget, (rawResponseJSON) => {
const responseJSON = rawResponseJSON;
if (responseJSON.success) {
feeCategories = responseJSON.feeCategories;
editCloseModalFunction();
renderFeeCategories();
}
else {
bulmaJS.alert({
title: 'Error Updating Fee',
message: responseJSON.errorMessage ?? '',
contextualColorName: 'danger'
});
}
});
}
function confirmDeleteFee(clickEvent) {
clickEvent.preventDefault();
function doDelete() {
cityssm.postJSON(`${los.urlPrefix}/admin/doDeleteFee`, {
feeId
}, (rawResponseJSON) => {
const responseJSON = rawResponseJSON;
if (responseJSON.success) {
feeCategories = responseJSON.feeCategories;
editCloseModalFunction();
renderFeeCategories();
}
else {
bulmaJS.alert({
title: 'Error Deleting Fee',
message: responseJSON.errorMessage ?? '',
contextualColorName: 'danger'
});
}
});
}
bulmaJS.confirm({
title: 'Delete Fee?',
message: 'Are you sure you want to delete this fee?',
contextualColorName: 'warning',
okButton: {
text: 'Yes, Delete the Fee',
callbackFunction: doDelete
}
});
}
function toggleFeeFields() {
const feeAmountElement = editModalElement.querySelector('#feeEdit--feeAmount');
const feeFunctionElement = editModalElement.querySelector('#feeEdit--feeFunction');
if (feeFunctionElement.value === '') {
feeFunctionElement.closest('.select')?.classList.remove('is-success');
feeAmountElement.classList.add('is-success');
feeAmountElement.disabled = false;
}
else {
feeFunctionElement.closest('.select')?.classList.add('is-success');
feeAmountElement.classList.remove('is-success');
feeAmountElement.disabled = true;
}
}
function toggleTaxFields() {
const taxAmountElement = editModalElement.querySelector('#feeEdit--taxAmount');
const taxPercentageElement = editModalElement.querySelector('#feeEdit--taxPercentage');
if (taxPercentageElement.value === '') {
taxPercentageElement.classList.remove('is-success');
taxAmountElement.classList.add('is-success');
taxAmountElement.disabled = false;
}
else {
taxPercentageElement.classList.add('is-success');
taxAmountElement.classList.remove('is-success');
taxAmountElement.disabled = true;
}
}
function toggleQuantityFields() {
const includeQuantityValue = editModalElement.querySelector('#feeEdit--includeQuantity').value;
editModalElement.querySelector('#feeEdit--quantityUnit').disabled = includeQuantityValue === '';
}
cityssm.openHtmlModal('adminFees-editFee', {
onshow(modalElement) {
editModalElement = modalElement;
modalElement.querySelector('#feeEdit--feeId').value = fee.feeId.toString();
const feeCategoryElement = modalElement.querySelector('#feeEdit--feeCategoryId');
for (const feeCategory of feeCategories) {
const optionElement = document.createElement('option');
optionElement.value = feeCategory.feeCategoryId.toString();
optionElement.textContent = feeCategory.feeCategory;
if (feeCategory.feeCategoryId === feeCategoryId) {
optionElement.selected = true;
}
feeCategoryElement.append(optionElement);
}
;
modalElement.querySelector('#feeEdit--feeName').value = fee.feeName ?? '';
modalElement.querySelector('#feeEdit--feeAccount').value = fee.feeAccount ?? '';
modalElement.querySelector('#feeEdit--feeDescription').value = fee.feeDescription ?? '';
const occupancyTypeElement = modalElement.querySelector('#feeEdit--contractTypeId');
for (const occupancyType of exports.occupancyTypes) {
const optionElement = document.createElement('option');
optionElement.value = occupancyType.contractTypeId.toString();
optionElement.textContent = occupancyType.occupancyType;
if (occupancyType.contractTypeId === fee.contractTypeId) {
optionElement.selected = true;
}
occupancyTypeElement.append(optionElement);
}
const lotTypeElement = modalElement.querySelector('#feeEdit--burialSiteTypeId');
for (const lotType of exports.lotTypes) {
const optionElement = document.createElement('option');
optionElement.value = lotType.burialSiteTypeId.toString();
optionElement.textContent = lotType.lotType;
if (lotType.burialSiteTypeId === fee.burialSiteTypeId) {
optionElement.selected = true;
}
lotTypeElement.append(optionElement);
}
;
modalElement.querySelector('#feeEdit--feeAmount').value = fee.feeAmount ? fee.feeAmount.toFixed(2) : '';
modalElement
.querySelector('#feeEdit--feeFunction')
?.addEventListener('change', toggleFeeFields);
toggleFeeFields();
modalElement.querySelector('#feeEdit--taxAmount').value = fee.taxAmount ? fee.taxAmount.toFixed(2) : '';
const taxPercentageElement = modalElement.querySelector('#feeEdit--taxPercentage');
taxPercentageElement.value = fee.taxPercentage
? fee.taxPercentage.toString()
: '';
taxPercentageElement.addEventListener('keyup', toggleTaxFields);
toggleTaxFields();
const includeQuantityElement = modalElement.querySelector('#feeEdit--includeQuantity');
if (fee.includeQuantity ?? false) {
includeQuantityElement.value = '1';
}
includeQuantityElement.addEventListener('change', toggleQuantityFields);
modalElement.querySelector('#feeEdit--quantityUnit').value = fee.quantityUnit ?? '';
toggleQuantityFields();
if (fee.isRequired ?? false) {
;
modalElement.querySelector('#feeEdit--isRequired').value = '1';
}
los.populateAliases(modalElement);
},
onshown(modalElement, closeModalFunction) {
bulmaJS.toggleHtmlClipped();
editCloseModalFunction = closeModalFunction;
modalElement
.querySelector('form')
?.addEventListener('submit', doUpdateFee);
bulmaJS.init(modalElement);
modalElement
.querySelector('.button--deleteFee')
?.addEventListener('click', confirmDeleteFee);
},
onremoved() {
bulmaJS.toggleHtmlClipped();
}
});
}
function moveFee(clickEvent) {
const buttonElement = clickEvent.currentTarget;
const feeContainerElement = buttonElement.closest('.container--fee');
const feeId = feeContainerElement.dataset.feeId ?? '';
cityssm.postJSON(`${los.urlPrefix}/admin/${buttonElement.dataset.direction === 'up'
? 'doMoveFeeUp'
: 'doMoveFeeDown'}`, {
feeId,
moveToEnd: clickEvent.shiftKey ? '1' : '0'
}, (rawResponseJSON) => {
const responseJSON = rawResponseJSON;
if (responseJSON.success) {
feeCategories = responseJSON.feeCategories;
renderFeeCategories();
}
else {
bulmaJS.alert({
title: 'Error Moving Fee',
message: responseJSON.errorMessage ?? '',
contextualColorName: 'danger'
});
}
});
}
/*
* Initialize
*/
renderFeeCategories();
})();

View File

@ -25,7 +25,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
// Search for ID // Search for ID
let svgId = mapKey; let svgId = mapKey;
let svgElementToHighlight; let svgElementToHighlight;
// eslint-disable-next-line no-constant-condition
while (true) { while (true) {
svgElementToHighlight = mapContainerElement.querySelector(`#${svgId}`); svgElementToHighlight = mapContainerElement.querySelector(`#${svgId}`);
if (svgElementToHighlight !== null || !svgId.includes('-')) { if (svgElementToHighlight !== null || !svgId.includes('-')) {
@ -44,7 +43,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
} }
function unlockField(clickEvent) { function unlockField(clickEvent) {
const fieldElement = clickEvent.currentTarget.closest('.field'); const fieldElement = clickEvent.currentTarget.closest('.field');
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
const inputOrSelectElement = fieldElement.querySelector('input, select'); const inputOrSelectElement = fieldElement.querySelector('input, select');
inputOrSelectElement.classList.remove('is-readonly'); inputOrSelectElement.classList.remove('is-readonly');
if (inputOrSelectElement.tagName === 'INPUT') { if (inputOrSelectElement.tagName === 'INPUT') {
@ -141,63 +139,15 @@ Object.defineProperty(exports, "__esModule", { value: true });
function populateAliases(containerElement) { function populateAliases(containerElement) {
const aliasElements = containerElement.querySelectorAll('.alias'); const aliasElements = containerElement.querySelectorAll('.alias');
for (const aliasElement of aliasElements) { for (const aliasElement of aliasElements) {
switch (aliasElement.dataset.alias) { if (aliasElement.dataset.alias === 'ExternalReceiptNumber') {
case 'Map': {
aliasElement.textContent = exports.aliases.map;
break;
}
case 'Lot': {
aliasElement.textContent = exports.aliases.lot;
break;
}
case 'lot': {
aliasElement.textContent = exports.aliases.lot.toLowerCase();
break;
}
case 'Occupancy': {
aliasElement.textContent = exports.aliases.occupancy;
break;
}
case 'occupancy': {
aliasElement.textContent = exports.aliases.occupancy.toLowerCase();
break;
}
case 'Occupant': {
aliasElement.textContent = exports.aliases.occupant;
break;
}
case 'occupant': {
aliasElement.textContent = exports.aliases.occupant.toLowerCase();
break;
}
case 'ExternalReceiptNumber': {
aliasElement.textContent = exports.aliases.externalReceiptNumber; aliasElement.textContent = exports.aliases.externalReceiptNumber;
break; break;
} }
} }
} }
}
const escapedAliases = Object.freeze({ const escapedAliases = Object.freeze({
Map: cityssm.escapeHTML(exports.aliases.map),
map: cityssm.escapeHTML(exports.aliases.map.toLowerCase()),
Maps: cityssm.escapeHTML(exports.aliases.maps),
maps: cityssm.escapeHTML(exports.aliases.maps.toLowerCase()),
Lot: cityssm.escapeHTML(exports.aliases.lot),
lot: cityssm.escapeHTML(exports.aliases.lot.toLowerCase()),
Lots: cityssm.escapeHTML(exports.aliases.lots),
lots: cityssm.escapeHTML(exports.aliases.lots.toLowerCase()),
Occupancy: cityssm.escapeHTML(exports.aliases.occupancy),
occupancy: cityssm.escapeHTML(exports.aliases.occupancy.toLowerCase()),
Occupancies: cityssm.escapeHTML(exports.aliases.occupancies),
occupancies: cityssm.escapeHTML(exports.aliases.occupancies.toLowerCase()),
Occupant: cityssm.escapeHTML(exports.aliases.occupant),
occupant: cityssm.escapeHTML(exports.aliases.occupant.toLowerCase()),
Occupants: cityssm.escapeHTML(exports.aliases.occupants),
occupants: cityssm.escapeHTML(exports.aliases.occupants.toLowerCase()),
ExternalReceiptNumber: cityssm.escapeHTML(exports.aliases.externalReceiptNumber), ExternalReceiptNumber: cityssm.escapeHTML(exports.aliases.externalReceiptNumber),
externalReceiptNumber: cityssm.escapeHTML(exports.aliases.externalReceiptNumber.toLowerCase()), externalReceiptNumber: cityssm.escapeHTML(exports.aliases.externalReceiptNumber.toLowerCase()),
OccupancyStartDate: cityssm.escapeHTML(exports.aliases.occupancyStartDate),
occupancyStartDate: cityssm.escapeHTML(exports.aliases.occupancyStartDate.toLowerCase()),
WorkOrderOpenDate: cityssm.escapeHTML(exports.aliases.workOrderOpenDate), WorkOrderOpenDate: cityssm.escapeHTML(exports.aliases.workOrderOpenDate),
workOrderOpenDate: cityssm.escapeHTML(exports.aliases.workOrderOpenDate.toLowerCase()), workOrderOpenDate: cityssm.escapeHTML(exports.aliases.workOrderOpenDate.toLowerCase()),
WorkOrderCloseDate: cityssm.escapeHTML(exports.aliases.workOrderCloseDate), WorkOrderCloseDate: cityssm.escapeHTML(exports.aliases.workOrderCloseDate),
@ -298,14 +248,14 @@ Object.defineProperty(exports, "__esModule", { value: true });
(recordId && edit ? '/edit' : '') + (recordId && edit ? '/edit' : '') +
(time ? `/?t=${Date.now().toString()}` : '')); (time ? `/?t=${Date.now().toString()}` : ''));
} }
function getMapURL(mapId = '', edit = false, time = false) { function getCemeteryURL(cemeteryId = '', edit = false, time = false) {
return getRecordURL('maps', mapId, edit, time); return getRecordURL('cemeteries', cemeteryId, edit, time);
} }
function getLotURL(lotId = '', edit = false, time = false) { function getBurialSiteURL(burialSiteId = '', edit = false, time = false) {
return getRecordURL('lots', lotId, edit, time); return getRecordURL('burialSites', burialSiteId, edit, time);
} }
function getLotOccupancyURL(lotOccupancyId = '', edit = false, time = false) { function getBurialSiteContractURL(burialSiteContractId = '', edit = false, time = false) {
return getRecordURL('lotOccupancies', lotOccupancyId, edit, time); return getRecordURL('contracts', burialSiteContractId, edit, time);
} }
function getWorkOrderURL(workOrderId = '', edit = false, time = false) { function getWorkOrderURL(workOrderId = '', edit = false, time = false) {
return getRecordURL('workOrders', workOrderId, edit, time); return getRecordURL('workOrders', workOrderId, edit, time);
@ -333,9 +283,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
getMoveUpDownButtonFieldHTML, getMoveUpDownButtonFieldHTML,
getLoadingParagraphHTML, getLoadingParagraphHTML,
getSearchResultsPagerHTML, getSearchResultsPagerHTML,
getMapURL, getCemeteryURL,
getLotURL, getBurialSiteURL,
getLotOccupancyURL, getBurialSiteContractURL,
getWorkOrderURL getWorkOrderURL
}; };
exports.los = los; exports.los = los;

View File

@ -2,7 +2,7 @@ import type { BulmaJS } from '@cityssm/bulma-js/types.js'
import type { cityssmGlobal } from '@cityssm/bulma-webapp-js/src/types.js' import type { cityssmGlobal } from '@cityssm/bulma-webapp-js/src/types.js'
import type { Options as BulmaCalendarOptions } from 'bulma-calendar' import type { Options as BulmaCalendarOptions } from 'bulma-calendar'
import type { LOS } from '../../types/globalTypes.js' import type { LOS } from './types.js'
type RandomColorHue = type RandomColorHue =
| 'red' | 'red'
@ -64,7 +64,6 @@ declare const exports: Record<string, unknown> & {
let svgId = mapKey let svgId = mapKey
let svgElementToHighlight: SVGElement | null let svgElementToHighlight: SVGElement | null
// eslint-disable-next-line no-constant-condition
while (true) { while (true) {
svgElementToHighlight = mapContainerElement.querySelector(`#${svgId}`) svgElementToHighlight = mapContainerElement.querySelector(`#${svgId}`)
@ -92,7 +91,6 @@ declare const exports: Record<string, unknown> & {
'.field' '.field'
) as HTMLElement ) as HTMLElement
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
const inputOrSelectElement = fieldElement.querySelector( const inputOrSelectElement = fieldElement.querySelector(
'input, select' 'input, select'
) as HTMLElement ) as HTMLElement
@ -230,64 +228,14 @@ declare const exports: Record<string, unknown> & {
containerElement.querySelectorAll('.alias') containerElement.querySelectorAll('.alias')
for (const aliasElement of aliasElements) { for (const aliasElement of aliasElements) {
switch (aliasElement.dataset.alias) { if (aliasElement.dataset.alias === 'ExternalReceiptNumber') {
case 'Map': {
aliasElement.textContent = exports.aliases.map
break
}
case 'Lot': {
aliasElement.textContent = exports.aliases.lot
break
}
case 'lot': {
aliasElement.textContent = exports.aliases.lot.toLowerCase()
break
}
case 'Occupancy': {
aliasElement.textContent = exports.aliases.occupancy
break
}
case 'occupancy': {
aliasElement.textContent = exports.aliases.occupancy.toLowerCase()
break
}
case 'Occupant': {
aliasElement.textContent = exports.aliases.occupant
break
}
case 'occupant': {
aliasElement.textContent = exports.aliases.occupant.toLowerCase()
break
}
case 'ExternalReceiptNumber': {
aliasElement.textContent = exports.aliases.externalReceiptNumber aliasElement.textContent = exports.aliases.externalReceiptNumber
break break
} }
} }
} }
}
const escapedAliases = Object.freeze({ const escapedAliases = Object.freeze({
Map: cityssm.escapeHTML(exports.aliases.map),
map: cityssm.escapeHTML(exports.aliases.map.toLowerCase()),
Maps: cityssm.escapeHTML(exports.aliases.maps),
maps: cityssm.escapeHTML(exports.aliases.maps.toLowerCase()),
Lot: cityssm.escapeHTML(exports.aliases.lot),
lot: cityssm.escapeHTML(exports.aliases.lot.toLowerCase()),
Lots: cityssm.escapeHTML(exports.aliases.lots),
lots: cityssm.escapeHTML(exports.aliases.lots.toLowerCase()),
Occupancy: cityssm.escapeHTML(exports.aliases.occupancy),
occupancy: cityssm.escapeHTML(exports.aliases.occupancy.toLowerCase()),
Occupancies: cityssm.escapeHTML(exports.aliases.occupancies),
occupancies: cityssm.escapeHTML(exports.aliases.occupancies.toLowerCase()),
Occupant: cityssm.escapeHTML(exports.aliases.occupant),
occupant: cityssm.escapeHTML(exports.aliases.occupant.toLowerCase()),
Occupants: cityssm.escapeHTML(exports.aliases.occupants),
occupants: cityssm.escapeHTML(exports.aliases.occupants.toLowerCase()),
ExternalReceiptNumber: cityssm.escapeHTML( ExternalReceiptNumber: cityssm.escapeHTML(
exports.aliases.externalReceiptNumber exports.aliases.externalReceiptNumber
), ),
@ -295,11 +243,6 @@ declare const exports: Record<string, unknown> & {
exports.aliases.externalReceiptNumber.toLowerCase() exports.aliases.externalReceiptNumber.toLowerCase()
), ),
contractStartDate: cityssm.escapeHTML(exports.aliases.contractStartDate),
contractStartDate: cityssm.escapeHTML(
exports.aliases.contractStartDate.toLowerCase()
),
WorkOrderOpenDate: cityssm.escapeHTML(exports.aliases.workOrderOpenDate), WorkOrderOpenDate: cityssm.escapeHTML(exports.aliases.workOrderOpenDate),
workOrderOpenDate: cityssm.escapeHTML( workOrderOpenDate: cityssm.escapeHTML(
exports.aliases.workOrderOpenDate.toLowerCase() exports.aliases.workOrderOpenDate.toLowerCase()
@ -429,7 +372,7 @@ declare const exports: Record<string, unknown> & {
const urlPrefix = document.querySelector('main')?.dataset.urlPrefix ?? '' const urlPrefix = document.querySelector('main')?.dataset.urlPrefix ?? ''
function getRecordURL( function getRecordURL(
recordTypePlural: 'maps' | 'lots' | 'lotOccupancies' | 'workOrders', recordTypePlural: 'cemeteries' | 'burialSites' | 'contracts' | 'workOrders',
recordId: number | string, recordId: number | string,
edit: boolean, edit: boolean,
time: boolean time: boolean
@ -444,20 +387,20 @@ declare const exports: Record<string, unknown> & {
) )
} }
function getMapURL( function getCemeteryURL(
cemeteryId: number | string = '', cemeteryId: number | string = '',
edit = false, edit = false,
time = false time = false
): string { ): string {
return getRecordURL('maps', cemeteryId, edit, time) return getRecordURL('cemeteries', cemeteryId, edit, time)
} }
function getLotURL( function getBurialSiteURL(
lotId: number | string = '', burialSiteId: number | string = '',
edit = false, edit = false,
time = false time = false
): string { ): string {
return getRecordURL('lots', lotId, edit, time) return getRecordURL('burialSites', burialSiteId, edit, time)
} }
function getBurialSiteContractURL( function getBurialSiteContractURL(
@ -465,7 +408,7 @@ declare const exports: Record<string, unknown> & {
edit = false, edit = false,
time = false time = false
): string { ): string {
return getRecordURL('lotOccupancies', burialSiteContractId, edit, time) return getRecordURL('contracts', burialSiteContractId, edit, time)
} }
function getWorkOrderURL( function getWorkOrderURL(
@ -508,8 +451,8 @@ declare const exports: Record<string, unknown> & {
getLoadingParagraphHTML, getLoadingParagraphHTML,
getSearchResultsPagerHTML, getSearchResultsPagerHTML,
getMapURL, getCemeteryURL,
getLotURL, getBurialSiteURL,
getBurialSiteContractURL, getBurialSiteContractURL,
getWorkOrderURL getWorkOrderURL
} }

View File

View File

@ -0,0 +1,28 @@
;
(() => {
const menuTabElements = document.querySelectorAll('.menu a');
const tabContainerElements = document.querySelectorAll('.tabs-container > div');
function selectTab(clickEvent) {
clickEvent.preventDefault();
// Remove .is-active from all tabs
for (const menuTabElement of menuTabElements) {
menuTabElement.classList.remove('is-active');
}
// Set .is-active on clicked tab
const selectedTabElement = clickEvent.currentTarget;
selectedTabElement.classList.add('is-active');
// Hide all but selected tab
const selectedTabContainerId = selectedTabElement.href.slice(Math.max(0, selectedTabElement.href.indexOf('#') + 1));
for (const tabContainerElement of tabContainerElements) {
if (tabContainerElement.id === selectedTabContainerId) {
tabContainerElement.classList.remove('is-hidden');
}
else {
tabContainerElement.classList.add('is-hidden');
}
}
}
for (const menuTabElement of menuTabElements) {
menuTabElement.addEventListener('click', selectTab);
}
})();

View File

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

View File

@ -0,0 +1,716 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
(() => {
const los = exports.los;
function refreshFontAwesomeIcon(changeEvent) {
const inputElement = changeEvent.currentTarget;
const fontAwesomeIconClass = inputElement.value;
(inputElement
.closest('.field')
?.querySelectorAll('.button.is-static'))[1].innerHTML =
`<i class="fas fa-fw fa-${fontAwesomeIconClass}" aria-hidden="true"></i>`;
}
/**
* Work Order Types
*/
;
(() => {
let workOrderTypes = exports.workOrderTypes;
delete exports.workOrderTypes;
function updateWorkOrderType(submitEvent) {
submitEvent.preventDefault();
cityssm.postJSON(`${los.urlPrefix}/admin/doUpdateWorkOrderType`, submitEvent.currentTarget, (rawResponseJSON) => {
const responseJSON = rawResponseJSON;
if (responseJSON.success) {
workOrderTypes = responseJSON.workOrderTypes;
bulmaJS.alert({
message: 'Work Order Type Updated Successfully',
contextualColorName: 'success'
});
}
else {
bulmaJS.alert({
title: 'Error Updating Work Order Type',
message: responseJSON.errorMessage ?? '',
contextualColorName: 'danger'
});
}
});
}
function deleteWorkOrderType(clickEvent) {
const tableRowElement = clickEvent.currentTarget.closest('tr');
const workOrderTypeId = tableRowElement.dataset.workOrderTypeId;
function doDelete() {
cityssm.postJSON(`${los.urlPrefix}/admin/doDeleteWorkOrderType`, {
workOrderTypeId
}, (rawResponseJSON) => {
const responseJSON = rawResponseJSON;
if (responseJSON.success) {
workOrderTypes = responseJSON.workOrderTypes;
if (workOrderTypes.length === 0) {
renderWorkOrderTypes();
}
else {
tableRowElement.remove();
}
bulmaJS.alert({
message: 'Work Order Type Deleted Successfully',
contextualColorName: 'success'
});
}
else {
bulmaJS.alert({
title: 'Error Deleting Work Order Type',
message: responseJSON.errorMessage ?? '',
contextualColorName: 'danger'
});
}
});
}
bulmaJS.confirm({
title: 'Delete Work Order Type',
message: `Are you sure you want to delete this work order type?<br />
Note that no work orders will be removed.`,
messageIsHtml: true,
contextualColorName: 'warning',
okButton: {
text: 'Yes, Delete Work Order Type',
callbackFunction: doDelete
}
});
}
function moveWorkOrderType(clickEvent) {
const buttonElement = clickEvent.currentTarget;
const tableRowElement = buttonElement.closest('tr');
const workOrderTypeId = tableRowElement.dataset.workOrderTypeId;
cityssm.postJSON(`${los.urlPrefix}/admin/${buttonElement.dataset.direction === 'up'
? 'doMoveWorkOrderTypeUp'
: 'doMoveWorkOrderTypeDown'}`, {
workOrderTypeId,
moveToEnd: clickEvent.shiftKey ? '1' : '0'
}, (rawResponseJSON) => {
const responseJSON = rawResponseJSON;
if (responseJSON.success) {
workOrderTypes = responseJSON.workOrderTypes;
renderWorkOrderTypes();
}
else {
bulmaJS.alert({
title: 'Error Moving Work Order Type',
message: responseJSON.errorMessage ?? '',
contextualColorName: 'danger'
});
}
});
}
function renderWorkOrderTypes() {
const containerElement = document.querySelector('#container--workOrderTypes');
if (workOrderTypes.length === 0) {
containerElement.innerHTML = `<tr><td colspan="2">
<div class="message is-warning"><p class="message-body">There are no active work order types.</p></div>
</td></tr>`;
return;
}
containerElement.innerHTML = '';
for (const workOrderType of workOrderTypes) {
const tableRowElement = document.createElement('tr');
tableRowElement.dataset.workOrderTypeId =
workOrderType.workOrderTypeId.toString();
// eslint-disable-next-line no-unsanitized/property
tableRowElement.innerHTML = `<td>
<form>
<input name="workOrderTypeId" type="hidden" value="${workOrderType.workOrderTypeId.toString()}" />
<div class="field has-addons">
<div class="control">
<input class="input" name="workOrderType" type="text"
value="${cityssm.escapeHTML(workOrderType.workOrderType ?? '')}" maxlength="100" aria-label="Work Order Type" required />
</div>
<div class="control">
<button class="button is-success" type="submit" aria-label="Save">
<i class="fas fa-save" aria-hidden="true"></i>
</button>
</div>
</div>
</form>
</td><td class="is-nowrap">
<div class="field is-grouped">
<div class="control">
${los.getMoveUpDownButtonFieldHTML('button--moveWorkOrderTypeUp', 'button--moveWorkOrderTypeDown', false)}
</div>
<div class="control">
<button class="button is-danger is-light button--deleteWorkOrderType" data-tooltip="Delete Work Order Type" type="button" aria-label="Delete Work Order Type">
<i class="fas fa-trash" aria-hidden="true"></i>
</button>
</div>
</div>
</td>`;
tableRowElement
.querySelector('form')
?.addEventListener('submit', updateWorkOrderType);
tableRowElement.querySelector('.button--moveWorkOrderTypeUp').addEventListener('click', moveWorkOrderType);
tableRowElement.querySelector('.button--moveWorkOrderTypeDown').addEventListener('click', moveWorkOrderType);
tableRowElement
.querySelector('.button--deleteWorkOrderType')
?.addEventListener('click', deleteWorkOrderType);
containerElement.append(tableRowElement);
}
}
;
document.querySelector('#form--addWorkOrderType').addEventListener('submit', (submitEvent) => {
submitEvent.preventDefault();
const formElement = submitEvent.currentTarget;
cityssm.postJSON(`${los.urlPrefix}/admin/doAddWorkOrderType`, formElement, (rawResponseJSON) => {
const responseJSON = rawResponseJSON;
if (responseJSON.success) {
workOrderTypes = responseJSON.workOrderTypes;
renderWorkOrderTypes();
formElement.reset();
formElement.querySelector('input')?.focus();
}
else {
bulmaJS.alert({
title: 'Error Adding Work Order Type',
message: responseJSON.errorMessage ?? '',
contextualColorName: 'danger'
});
}
});
});
renderWorkOrderTypes();
})();
(() => {
let workOrderMilestoneTypes = exports.workOrderMilestoneTypes;
delete exports.workOrderMilestoneTypes;
function updateWorkOrderMilestoneType(submitEvent) {
submitEvent.preventDefault();
cityssm.postJSON(`${los.urlPrefix}/admin/doUpdateWorkOrderMilestoneType`, submitEvent.currentTarget, (rawResponseJSON) => {
const responseJSON = rawResponseJSON;
if (responseJSON.success) {
workOrderMilestoneTypes = responseJSON.workOrderMilestoneTypes;
bulmaJS.alert({
message: 'Work Order Milestone Type Updated Successfully',
contextualColorName: 'success'
});
}
else {
bulmaJS.alert({
title: 'Error Updating Work Order Milestone Type',
message: responseJSON.errorMessage ?? '',
contextualColorName: 'danger'
});
}
});
}
function deleteWorkOrderMilestoneType(clickEvent) {
const tableRowElement = clickEvent.currentTarget.closest('tr');
const workOrderMilestoneTypeId = tableRowElement.dataset.workOrderMilestoneTypeId;
function doDelete() {
cityssm.postJSON(`${los.urlPrefix}/admin/doDeleteWorkOrderMilestoneType`, {
workOrderMilestoneTypeId
}, (rawResponseJSON) => {
const responseJSON = rawResponseJSON;
if (responseJSON.success) {
workOrderMilestoneTypes = responseJSON.workOrderMilestoneTypes;
if (workOrderMilestoneTypes.length === 0) {
renderWorkOrderMilestoneTypes();
}
else {
tableRowElement.remove();
}
bulmaJS.alert({
message: 'Work Order Milestone Type Deleted Successfully',
contextualColorName: 'success'
});
}
else {
bulmaJS.alert({
title: 'Error Deleting Work Order Milestone Type',
message: responseJSON.errorMessage ?? '',
contextualColorName: 'danger'
});
}
});
}
bulmaJS.confirm({
title: 'Delete Work Order Milestone Type',
message: `Are you sure you want to delete this work order milestone type?<br />
Note that no work orders will be removed.`,
messageIsHtml: true,
contextualColorName: 'warning',
okButton: {
text: 'Yes, Delete Work Order Milestone Type',
callbackFunction: doDelete
}
});
}
function moveWorkOrderMilestoneType(clickEvent) {
const buttonElement = clickEvent.currentTarget;
const tableRowElement = buttonElement.closest('tr');
const workOrderMilestoneTypeId = tableRowElement.dataset.workOrderMilestoneTypeId;
cityssm.postJSON(`${los.urlPrefix}/admin/${buttonElement.dataset.direction === 'up'
? 'doMoveWorkOrderMilestoneTypeUp'
: 'doMoveWorkOrderMilestoneTypeDown'}`, {
workOrderMilestoneTypeId,
moveToEnd: clickEvent.shiftKey ? '1' : '0'
}, (rawResponseJSON) => {
const responseJSON = rawResponseJSON;
if (responseJSON.success) {
workOrderMilestoneTypes = responseJSON.workOrderMilestoneTypes;
renderWorkOrderMilestoneTypes();
}
else {
bulmaJS.alert({
title: 'Error Moving Work Order Milestone Type',
message: responseJSON.errorMessage ?? '',
contextualColorName: 'danger'
});
}
});
}
function renderWorkOrderMilestoneTypes() {
const containerElement = document.querySelector('#container--workOrderMilestoneTypes');
if (workOrderMilestoneTypes.length === 0) {
containerElement.innerHTML = `<tr><td colspan="2">
<div class="message is-warning">
<p class="message-body">There are no active work order milestone types.</p>
</div>
</td></tr>`;
return;
}
containerElement.innerHTML = '';
for (const workOrderMilestoneType of workOrderMilestoneTypes) {
const tableRowElement = document.createElement('tr');
tableRowElement.dataset.workOrderMilestoneTypeId =
workOrderMilestoneType.workOrderMilestoneTypeId.toString();
// eslint-disable-next-line no-unsanitized/property, no-secrets/no-secrets
tableRowElement.innerHTML = `<td>
<form>
<input name="workOrderMilestoneTypeId" type="hidden" value="${workOrderMilestoneType.workOrderMilestoneTypeId.toString()}" />
<div class="field has-addons">
<div class="control">
<input class="input" name="workOrderMilestoneType" type="text"
value="${cityssm.escapeHTML(workOrderMilestoneType.workOrderMilestoneType)}" maxlength="100" aria-label="Work Order Milestone Type" required />
</div>
<div class="control">
<button class="button is-success" type="submit" aria-label="Save">
<i class="fas fa-save" aria-hidden="true"></i>
</button>
</div>
</div>
</form>
</td><td class="is-nowrap">
<div class="field is-grouped">
<div class="control">
${los.getMoveUpDownButtonFieldHTML('button--moveWorkOrderMilestoneTypeUp', 'button--moveWorkOrderMilestoneTypeDown', false)}
</div>
<div class="control">
<button class="button is-danger is-light button--deleteWorkOrderMilestoneType" data-tooltip="Delete Mielstone Type" type="button" aria-label="Delete Milestone Type">
<i class="fas fa-trash" aria-hidden="true"></i>
</button>
</div>
</div>
</td>`;
tableRowElement
.querySelector('form')
?.addEventListener('submit', updateWorkOrderMilestoneType);
tableRowElement.querySelector('.button--moveWorkOrderMilestoneTypeUp').addEventListener('click', moveWorkOrderMilestoneType);
tableRowElement.querySelector('.button--moveWorkOrderMilestoneTypeDown').addEventListener('click', moveWorkOrderMilestoneType);
tableRowElement
.querySelector('.button--deleteWorkOrderMilestoneType')
?.addEventListener('click', deleteWorkOrderMilestoneType);
containerElement.append(tableRowElement);
}
}
;
document.querySelector('#form--addWorkOrderMilestoneType').addEventListener('submit', (submitEvent) => {
submitEvent.preventDefault();
const formElement = submitEvent.currentTarget;
cityssm.postJSON(`${los.urlPrefix}/admin/doAddWorkOrderMilestoneType`, formElement, (rawResponseJSON) => {
const responseJSON = rawResponseJSON;
if (responseJSON.success) {
workOrderMilestoneTypes = responseJSON.workOrderMilestoneTypes;
renderWorkOrderMilestoneTypes();
formElement.reset();
formElement.querySelector('input')?.focus();
}
else {
bulmaJS.alert({
title: 'Error Adding Work Order Milestone Type',
message: responseJSON.errorMessage ?? '',
contextualColorName: 'danger'
});
}
});
});
renderWorkOrderMilestoneTypes();
})();
(() => {
let lotStatuses = exports.lotStatuses;
delete exports.lotStatuses;
function updateBurialSiteStatus(submitEvent) {
submitEvent.preventDefault();
cityssm.postJSON(`${los.urlPrefix}/admin/doUpdateBurialSiteStatus`, submitEvent.currentTarget, (rawResponseJSON) => {
const responseJSON = rawResponseJSON;
if (responseJSON.success) {
lotStatuses = responseJSON.lotStatuses;
bulmaJS.alert({
message: `${los.escapedAliases.Lot} Status Updated Successfully`,
contextualColorName: 'success'
});
}
else {
bulmaJS.alert({
title: `Error Updating ${los.escapedAliases.Lot} Status`,
message: responseJSON.errorMessage ?? '',
contextualColorName: 'danger'
});
}
});
}
function deleteLotStatus(clickEvent) {
const tableRowElement = clickEvent.currentTarget.closest('tr');
const burialSiteStatusId = tableRowElement.dataset.burialSiteStatusId;
function doDelete() {
cityssm.postJSON(`${los.urlPrefix}/admin/doDeleteBurialSiteStatus`, {
burialSiteStatusId
}, (rawResponseJSON) => {
const responseJSON = rawResponseJSON;
if (responseJSON.success) {
lotStatuses = responseJSON.lotStatuses;
if (lotStatuses.length === 0) {
renderLotStatuses();
}
else {
tableRowElement.remove();
}
bulmaJS.alert({
message: `${los.escapedAliases.Lot} Status Deleted Successfully`,
contextualColorName: 'success'
});
}
else {
bulmaJS.alert({
title: `Error Deleting ${los.escapedAliases.Lot} Status`,
message: responseJSON.errorMessage ?? '',
contextualColorName: 'danger'
});
}
});
}
bulmaJS.confirm({
title: `Delete ${los.escapedAliases.Lot} Status`,
message: `Are you sure you want to delete this status?<br />
Note that no ${los.escapedAliases.lot} will be removed.`,
messageIsHtml: true,
contextualColorName: 'warning',
okButton: {
text: 'Yes, Delete Status',
callbackFunction: doDelete
}
});
}
function moveLotStatus(clickEvent) {
const buttonElement = clickEvent.currentTarget;
const tableRowElement = buttonElement.closest('tr');
const burialSiteStatusId = tableRowElement.dataset.burialSiteStatusId;
cityssm.postJSON(`${los.urlPrefix}/admin/${buttonElement.dataset.direction === 'up'
? 'doMoveBurialSiteStatusUp'
: 'doMoveBurialSiteStatusDown'}`, {
burialSiteStatusId,
moveToEnd: clickEvent.shiftKey ? '1' : '0'
}, (rawResponseJSON) => {
const responseJSON = rawResponseJSON;
if (responseJSON.success) {
lotStatuses = responseJSON.lotStatuses;
renderLotStatuses();
}
else {
bulmaJS.alert({
title: `Error Moving ${los.escapedAliases.Lot} Status`,
message: responseJSON.errorMessage ?? '',
contextualColorName: 'danger'
});
}
});
}
function renderLotStatuses() {
const containerElement = document.querySelector('#container--lotStatuses');
if (lotStatuses.length === 0) {
// eslint-disable-next-line no-unsanitized/property
containerElement.innerHTML = `<tr><td colspan="2">
<div class="message is-warning">
<p class="message-body">There are no active ${los.escapedAliases.lot} statuses.</p>
</div>
</td></tr>`;
return;
}
containerElement.innerHTML = '';
for (const lotStatus of lotStatuses) {
const tableRowElement = document.createElement('tr');
tableRowElement.dataset.burialSiteStatusId = lotStatus.burialSiteStatusId.toString();
// eslint-disable-next-line no-unsanitized/property
tableRowElement.innerHTML = `<td>
<form>
<input name="burialSiteStatusId" type="hidden" value="${lotStatus.burialSiteStatusId.toString()}" />
<div class="field has-addons">
<div class="control">
<input class="input" name="lotStatus" type="text"
value="${cityssm.escapeHTML(lotStatus.lotStatus)}"
aria-label="${los.escapedAliases.Lot} Status" maxlength="100" required />
</div>
<div class="control">
<button class="button is-success" type="submit" aria-label="Save">
<i class="fas fa-save" aria-hidden="true"></i>\
</button>
</div>
</div>
</form>
</td><td class="is-nowrap">
<div class="field is-grouped">
<div class="control">
${los.getMoveUpDownButtonFieldHTML('button--moveLotStatusUp', 'button--moveLotStatusDown', false)}
</div>
<div class="control">
<button class="button is-danger is-light button--deleteLotStatus" data-tooltip="Delete Status" type="button" aria-label="Delete Status">
<i class="fas fa-trash" aria-hidden="true"></i>
</button>
</div>
</div>
</td>`;
tableRowElement
.querySelector('form')
?.addEventListener('submit', updateBurialSiteStatus);
tableRowElement.querySelector('.button--moveLotStatusUp').addEventListener('click', moveLotStatus);
tableRowElement.querySelector('.button--moveLotStatusDown').addEventListener('click', moveLotStatus);
tableRowElement
.querySelector('.button--deleteLotStatus')
?.addEventListener('click', deleteLotStatus);
containerElement.append(tableRowElement);
}
}
;
document.querySelector('#form--addBurialSiteStatus').addEventListener('submit', (submitEvent) => {
submitEvent.preventDefault();
const formElement = submitEvent.currentTarget;
cityssm.postJSON(`${los.urlPrefix}/admin/doAddBurialSiteStatus`, formElement, (rawResponseJSON) => {
const responseJSON = rawResponseJSON;
if (responseJSON.success) {
lotStatuses = responseJSON.lotStatuses;
renderLotStatuses();
formElement.reset();
formElement.querySelector('input')?.focus();
}
else {
bulmaJS.alert({
title: `Error Adding ${los.escapedAliases.Lot} Status`,
message: responseJSON.errorMessage ?? '',
contextualColorName: 'danger'
});
}
});
});
renderLotStatuses();
})();
(() => {
let lotOccupantTypes = exports.lotOccupantTypes;
delete exports.lotOccupantTypes;
function updateBurialSiteOccupantType(submitEvent) {
submitEvent.preventDefault();
cityssm.postJSON(`${los.urlPrefix}/admin/doUpdateBurialSiteOccupantType`, submitEvent.currentTarget, (rawResponseJSON) => {
const responseJSON = rawResponseJSON;
if (responseJSON.success) {
lotOccupantTypes = responseJSON.lotOccupantTypes;
bulmaJS.alert({
message: `${los.escapedAliases.Lot} ${los.escapedAliases.Occupant} Type Updated Successfully`,
contextualColorName: 'success'
});
}
else {
bulmaJS.alert({
title: `Error Updating ${los.escapedAliases.Lot} ${los.escapedAliases.Occupant} Type`,
message: responseJSON.errorMessage ?? '',
contextualColorName: 'danger'
});
}
});
}
function deleteLotOccupantType(clickEvent) {
const tableRowElement = clickEvent.currentTarget.closest('tr');
const lotOccupantTypeId = tableRowElement.dataset.lotOccupantTypeId;
function doDelete() {
cityssm.postJSON(`${los.urlPrefix}/admin/doDeleteBurialSiteOccupantType`, {
lotOccupantTypeId
}, (rawResponseJSON) => {
const responseJSON = rawResponseJSON;
if (responseJSON.success) {
lotOccupantTypes = responseJSON.lotOccupantTypes;
if (lotOccupantTypes.length === 0) {
renderLotOccupantTypes();
}
else {
tableRowElement.remove();
}
bulmaJS.alert({
message: `${los.escapedAliases.Lot} ${los.escapedAliases.Occupant} Type Deleted Successfully`,
contextualColorName: 'success'
});
}
else {
bulmaJS.alert({
title: `Error Deleting ${los.escapedAliases.Lot} ${los.escapedAliases.Occupant} Type`,
message: responseJSON.errorMessage ?? '',
contextualColorName: 'danger'
});
}
});
}
bulmaJS.confirm({
title: `Delete ${los.escapedAliases.Lot} ${los.escapedAliases.Occupant} Type`,
message: `Are you sure you want to delete this ${los.escapedAliases.lot} ${los.escapedAliases.occupant} type?<br />
Note that no ${los.escapedAliases.lot} ${los.escapedAliases.occupants} will be removed.`,
messageIsHtml: true,
contextualColorName: 'warning',
okButton: {
text: `Yes, Delete ${los.escapedAliases.Lot} ${los.escapedAliases.Occupant} Type`,
callbackFunction: doDelete
}
});
}
function moveLotOccupantType(clickEvent) {
const buttonElement = clickEvent.currentTarget;
const tableRowElement = buttonElement.closest('tr');
const lotOccupantTypeId = tableRowElement.dataset.lotOccupantTypeId;
cityssm.postJSON(`${los.urlPrefix}/admin/${buttonElement.dataset.direction === 'up'
? 'doMoveLotOccupantTypeUp'
: 'doMoveLotOccupantTypeDown'}`, {
lotOccupantTypeId,
moveToEnd: clickEvent.shiftKey ? '1' : '0'
}, (rawResponseJSON) => {
const responseJSON = rawResponseJSON;
if (responseJSON.success) {
lotOccupantTypes = responseJSON.lotOccupantTypes;
renderLotOccupantTypes();
}
else {
bulmaJS.alert({
title: `Error Moving ${los.escapedAliases.Lot} ${los.escapedAliases.Occupant} Type`,
message: responseJSON.errorMessage ?? '',
contextualColorName: 'danger'
});
}
});
}
function renderLotOccupantTypes() {
const containerElement = document.querySelector('#container--lotOccupantTypes');
if (lotOccupantTypes.length === 0) {
// eslint-disable-next-line no-unsanitized/property
containerElement.innerHTML = `<tr><td colspan="3">
<div class="message is-warning">
<p class="message-body">There are no active ${los.escapedAliases.lot} ${los.escapedAliases.occupant} types.</p>
</div>
</td></tr>`;
return;
}
containerElement.innerHTML = '';
for (const lotOccupantType of lotOccupantTypes) {
const tableRowElement = document.createElement('tr');
tableRowElement.dataset.lotOccupantTypeId =
lotOccupantType.lotOccupantTypeId.toString();
const formId = `form--lotOccupantType-${lotOccupantType.lotOccupantTypeId.toString()}`;
// eslint-disable-next-line no-unsanitized/property
tableRowElement.innerHTML = `<td>
<div class="field">
<div class="control">
<input class="input" name="lotOccupantType" type="text"
value="${cityssm.escapeHTML(lotOccupantType.lotOccupantType)}"
form="${formId}"
aria-label="${los.escapedAliases.Lot} ${los.escapedAliases.Occupant} Type" maxlength="100" required />
</div>
</div>
</td><td>
<div class="field has-addons">
<div class="control">
<span class="button is-static">fa-</span>
</div>
<div class="control">
<input class="input" name="fontAwesomeIconClass" type="text"
value="${cityssm.escapeHTML(lotOccupantType.fontAwesomeIconClass)}"
form="${formId}"
list="datalist--fontAwesomeIconClass" aria-label="Icon Name" maxlength="50" />
</div>
<div class="control">
<span class="button is-static">
<i class="fas fa-fw fa-${cityssm.escapeHTML(lotOccupantType.fontAwesomeIconClass)}"></i>
</span>
</div>
</div>
</td><td>
<div class="field">
<div class="control">
<input class="input" name="occupantCommentTitle" type="text"
value="${cityssm.escapeHTML(lotOccupantType.occupantCommentTitle)}"
form="${formId}"
aria-label="${los.escapedAliases.Occupant} Comment Title" maxlength="50" />
</div>
</div>
</td><td>
<form id="${formId}">
<input name="lotOccupantTypeId" type="hidden"
value="${lotOccupantType.lotOccupantTypeId.toString()}" />
<button class="button is-success" type="submit" aria-label="Save">
<i class="fas fa-save" aria-hidden="true"></i>
</button>
</form>
</td><td class="is-nowrap">
<div class="field is-grouped">
<div class="control">
${los.getMoveUpDownButtonFieldHTML('button--moveLotOccupantTypeUp', 'button--moveLotOccupantTypeDown', false)}
</div>
<div class="control">
<button class="button is-danger is-light button--deleteLotOccupantType"
data-tooltip="Delete ${los.escapedAliases.Lot} ${los.escapedAliases.Occupant} Type"
type="button"
aria-label="Delete ${los.escapedAliases.Lot} ${los.escapedAliases.Occupant} Type">
<i class="fas fa-trash" aria-hidden="true"></i>
</button>
</div>
</div>
</td>`;
const fontAwesomeInputElement = tableRowElement.querySelector("input[name='fontAwesomeIconClass']");
fontAwesomeInputElement.addEventListener('keyup', refreshFontAwesomeIcon);
fontAwesomeInputElement.addEventListener('change', refreshFontAwesomeIcon);
tableRowElement
.querySelector('form')
?.addEventListener('submit', updateBurialSiteOccupantType);
tableRowElement.querySelector('.button--moveLotOccupantTypeUp').addEventListener('click', moveLotOccupantType);
tableRowElement.querySelector('.button--moveLotOccupantTypeDown').addEventListener('click', moveLotOccupantType);
tableRowElement
.querySelector('.button--deleteLotOccupantType')
?.addEventListener('click', deleteLotOccupantType);
containerElement.append(tableRowElement);
}
}
;
document.querySelector('#form--addBurialSiteOccupantType').addEventListener('submit', (submitEvent) => {
submitEvent.preventDefault();
const formElement = submitEvent.currentTarget;
cityssm.postJSON(`${los.urlPrefix}/admin/doAddLotOccupantType`, formElement, (rawResponseJSON) => {
const responseJSON = rawResponseJSON;
if (responseJSON.success) {
lotOccupantTypes = responseJSON.lotOccupantTypes;
renderLotOccupantTypes();
formElement.reset();
formElement.querySelector('input')?.focus();
}
else {
bulmaJS.alert({
title: `Error Adding ${los.escapedAliases.Lot} ${los.escapedAliases.Occupant} Type`,
message: responseJSON.errorMessage ?? '',
contextualColorName: 'danger'
});
}
});
});
renderLotOccupantTypes();
})();
})();

View File

@ -723,7 +723,7 @@ declare const bulmaJS: BulmaJS
} }
} }
;( ;(
document.querySelector('#form--addLotStatus') as HTMLFormElement document.querySelector('#form--addBurialSiteStatus') as HTMLFormElement
).addEventListener('submit', (submitEvent: SubmitEvent) => { ).addEventListener('submit', (submitEvent: SubmitEvent) => {
submitEvent.preventDefault() submitEvent.preventDefault()
@ -1010,7 +1010,7 @@ declare const bulmaJS: BulmaJS
} }
} }
;( ;(
document.querySelector('#form--addLotOccupantType') as HTMLFormElement document.querySelector('#form--addBurialSiteOccupantType') as HTMLFormElement
).addEventListener('submit', (submitEvent: SubmitEvent) => { ).addEventListener('submit', (submitEvent: SubmitEvent) => {
submitEvent.preventDefault() submitEvent.preventDefault()

28
public/javascripts/types.d.ts vendored 100644
View File

@ -0,0 +1,28 @@
export interface LOS {
urlPrefix: string;
apiKey: string;
highlightMap: (mapContainerElement: HTMLElement, mapKey: string, contextualClass: 'success' | 'danger') => void;
initializeDatePickers: (containerElement: HTMLElement) => void;
initializeUnlockFieldButtons: (containerElement: HTMLElement) => void;
populateAliases: (containerElement: HTMLElement) => void;
escapedAliases: {
ExternalReceiptNumber: string;
externalReceiptNumber: string;
WorkOrderOpenDate: string;
workOrderOpenDate: string;
WorkOrderCloseDate: string;
workOrderCloseDate: string;
};
dynamicsGPIntegrationIsEnabled: boolean;
getRandomColor: (seedString: string) => string;
setUnsavedChanges: () => void;
clearUnsavedChanges: () => void;
hasUnsavedChanges: () => boolean;
getMoveUpDownButtonFieldHTML: (upButtonClassNames: string, downButtonClassNames: string, isSmall?: boolean) => string;
getLoadingParagraphHTML: (captionText?: string) => string;
getSearchResultsPagerHTML: (limit: number, offset: number, count: number) => string;
getCemeteryURL: (cemeteryId?: number | string, edit?: boolean, time?: boolean) => string;
getBurialSiteURL: (burialSiteId?: number | string, edit?: boolean, time?: boolean) => string;
getBurialSiteContractURL: (burialSiteContractId?: number | string, edit?: boolean, time?: boolean) => string;
getWorkOrderURL: (workOrderId?: number | string, edit?: boolean, time?: boolean) => string;
}

View File

@ -0,0 +1,2 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });

View File

@ -18,8 +18,6 @@ export interface LOS {
escapedAliases: { escapedAliases: {
ExternalReceiptNumber: string ExternalReceiptNumber: string
externalReceiptNumber: string externalReceiptNumber: string
contractStartDate: string
contractStartDate: string
WorkOrderOpenDate: string WorkOrderOpenDate: string
workOrderOpenDate: string workOrderOpenDate: string
WorkOrderCloseDate: string WorkOrderCloseDate: string
@ -46,8 +44,8 @@ export interface LOS {
count: number count: number
) => string ) => string
getMapURL: (cemeteryId?: number | string, edit?: boolean, time?: boolean) => string getCemeteryURL: (cemeteryId?: number | string, edit?: boolean, time?: boolean) => string
getLotURL: (lotId?: number | string, edit?: boolean, time?: boolean) => string getBurialSiteURL: (burialSiteId?: number | string, edit?: boolean, time?: boolean) => string
getBurialSiteContractURL: ( getBurialSiteContractURL: (
burialSiteContractId?: number | string, burialSiteContractId?: number | string,
edit?: boolean, edit?: boolean,

View File

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

File diff suppressed because it is too large Load Diff

View File

@ -270,7 +270,7 @@ declare const exports: Record<string, unknown>
}) })
} }
function addLot( function addBurialSite(
lotId: number | string, lotId: number | string,
callbackFunction?: (success: boolean) => void callbackFunction?: (success: boolean) => void
): void { ): void {
@ -340,10 +340,10 @@ declare const exports: Record<string, unknown>
) )
} }
function addLotFromLotOccupancy(clickEvent: Event): void { function addBurialSiteFromLotOccupancy(clickEvent: Event): void {
const lotId = const lotId =
(clickEvent.currentTarget as HTMLElement).dataset.lotId ?? '' (clickEvent.currentTarget as HTMLElement).dataset.lotId ?? ''
addLot(lotId) addBurialSite(lotId)
} }
function renderRelatedOccupancies(): void { function renderRelatedOccupancies(): void {
@ -420,7 +420,7 @@ declare const exports: Record<string, unknown>
${ ${
hasLotRecord hasLotRecord
? '' ? ''
: ` <button class="button is-small is-light is-success button--addLot" : ` <button class="button is-small is-light is-success button--addBurialSite"
data-lot-id="${burialSiteContract.lotId.toString()}" data-lot-id="${burialSiteContract.lotId.toString()}"
data-tooltip="Add ${los.escapedAliases.Lot}" data-tooltip="Add ${los.escapedAliases.Lot}"
aria-label="Add ${los.escapedAliases.Lot}" type="button"> aria-label="Add ${los.escapedAliases.Lot}" type="button">
@ -479,8 +479,8 @@ declare const exports: Record<string, unknown>
) )
rowElement rowElement
.querySelector('.button--addLot') .querySelector('.button--addBurialSite')
?.addEventListener('click', addLotFromLotOccupancy) ?.addEventListener('click', addBurialSiteFromLotOccupancy)
rowElement rowElement
.querySelector('.button--deleteLotOccupancy') .querySelector('.button--deleteLotOccupancy')
@ -686,7 +686,7 @@ declare const exports: Record<string, unknown>
// eslint-disable-next-line no-unsanitized/property // eslint-disable-next-line no-unsanitized/property
rowElement.innerHTML = `<td> rowElement.innerHTML = `<td>
<a class="has-text-weight-bold" href="${los.getLotURL(lot.lotId)}"> <a class="has-text-weight-bold" href="${los.getBurialSiteURL(lot.lotId)}">
${cityssm.escapeHTML(lot.lotName ?? '')} ${cityssm.escapeHTML(lot.lotName ?? '')}
</a> </a>
</td><td> </td><td>
@ -923,7 +923,7 @@ declare const exports: Record<string, unknown>
const lotId = rowElement.dataset.lotId ?? '' const lotId = rowElement.dataset.lotId ?? ''
addLot(lotId, (success) => { addBurialSite(lotId, (success) => {
if (success) { if (success) {
rowElement.remove() rowElement.remove()
} }
@ -931,7 +931,7 @@ declare const exports: Record<string, unknown>
} }
document document
.querySelector('#button--addLot') .querySelector('#button--addBurialSite')
?.addEventListener('click', () => { ?.addEventListener('click', () => {
let searchFormElement: HTMLFormElement let searchFormElement: HTMLFormElement
let searchResultsContainerElement: HTMLElement let searchResultsContainerElement: HTMLElement
@ -977,7 +977,7 @@ declare const exports: Record<string, unknown>
rowElement.dataset.lotId = lot.lotId.toString() rowElement.dataset.lotId = lot.lotId.toString()
rowElement.innerHTML = `<td class="has-text-centered"> rowElement.innerHTML = `<td class="has-text-centered">
<button class="button is-small is-success button--addLot" data-tooltip="Add" type="button" aria-label="Add"> <button class="button is-small is-success button--addBurialSite" data-tooltip="Add" type="button" aria-label="Add">
<i class="fas fa-plus" aria-hidden="true"></i> <i class="fas fa-plus" aria-hidden="true"></i>
</button> </button>
</td><td class="has-text-weight-bold"> </td><td class="has-text-weight-bold">
@ -991,7 +991,7 @@ declare const exports: Record<string, unknown>
</td>` </td>`
rowElement rowElement
.querySelector('.button--addLot') .querySelector('.button--addBurialSite')
?.addEventListener('click', doAddLot) ?.addEventListener('click', doAddLot)
searchResultsContainerElement searchResultsContainerElement
@ -1002,7 +1002,7 @@ declare const exports: Record<string, unknown>
) )
} }
cityssm.openHtmlModal('workOrder-addLot', { cityssm.openHtmlModal('workOrder-addBurialSite', {
onshow(modalElement) { onshow(modalElement) {
los.populateAliases(modalElement) los.populateAliases(modalElement)
@ -1051,7 +1051,7 @@ declare const exports: Record<string, unknown>
onremoved() { onremoved() {
bulmaJS.toggleHtmlClipped() bulmaJS.toggleHtmlClipped()
;( ;(
document.querySelector('#button--addLot') as HTMLButtonElement document.querySelector('#button--addBurialSite') as HTMLButtonElement
).focus() ).focus()
} }
}) })

View File

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

View File

@ -0,0 +1,118 @@
"use strict";
// eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair
/* eslint-disable unicorn/prefer-module */
Object.defineProperty(exports, "__esModule", { value: true });
(() => {
const los = exports.los;
const workOrderSearchFiltersFormElement = document.querySelector('#form--searchFilters');
const workOrderMilestoneDateFilterElement = workOrderSearchFiltersFormElement.querySelector('#searchFilter--workOrderMilestoneDateFilter');
const workOrderMilestoneDateStringElement = workOrderSearchFiltersFormElement.querySelector('#searchFilter--workOrderMilestoneDateString');
const milestoneCalendarContainerElement = document.querySelector('#container--milestoneCalendar');
function renderMilestones(workOrderMilestones) {
if (workOrderMilestones.length === 0) {
milestoneCalendarContainerElement.innerHTML = `<div class="message is-info">
<p class="message-body">There are no milestones that meet the search criteria.</p>
</div>`;
return;
}
milestoneCalendarContainerElement.innerHTML = '';
const currentDate = cityssm.dateToString(new Date());
let currentPanelElement;
let currentPanelDateString = 'x';
for (const milestone of workOrderMilestones) {
if (currentPanelDateString !== milestone.workOrderMilestoneDateString) {
if (currentPanelElement) {
milestoneCalendarContainerElement.append(currentPanelElement);
}
currentPanelElement = document.createElement('div');
currentPanelElement.className = 'panel';
currentPanelElement.innerHTML = `<h2 class="panel-heading">
${cityssm.escapeHTML(milestone.workOrderMilestoneDate === 0
? 'No Set Date'
: milestone.workOrderMilestoneDateString ?? '')}
</h2>`;
currentPanelDateString = milestone.workOrderMilestoneDateString ?? '';
}
const panelBlockElement = document.createElement('div');
panelBlockElement.className = 'panel-block is-block';
if (!milestone.workOrderMilestoneCompletionDate &&
milestone.workOrderMilestoneDateString !== '' &&
milestone.workOrderMilestoneDateString < currentDate) {
panelBlockElement.classList.add('has-background-warning-light');
}
let burialSiteContractHTML = '';
for (const lot of milestone.workOrderLots ?? []) {
burialSiteContractHTML += `<li class="has-tooltip-left"
data-tooltip="${cityssm.escapeHTML(lot.cemeteryName ?? '')}">
<span class="fa-li">
<i class="fas fa-vector-square"
aria-label="${los.escapedAliases.Lot}"></i>
</span>
${cityssm.escapeHTML(lot.lotName ?? '')}
</li>`;
}
for (const burialSiteContract of milestone.workOrderBurialSiteContracts ?? []) {
for (const occupant of burialSiteContract.burialSiteContractOccupants ?? []) {
burialSiteContractHTML += `<li class="has-tooltip-left"
data-tooltip="${cityssm.escapeHTML(occupant.lotOccupantType ?? '')}">
<span class="fa-li">
<i class="fas fa-user"
aria-label="${los.escapedAliases.Occupancy}"></i>
</span>
${cityssm.escapeHTML(occupant.occupantName ?? '')}
${cityssm.escapeHTML(occupant.occupantFamilyName ?? '')}
</li>`;
}
}
// eslint-disable-next-line no-unsanitized/property
panelBlockElement.innerHTML = `<div class="columns">
<div class="column is-narrow">
<span class="icon is-small">
${milestone.workOrderMilestoneCompletionDate
? '<i class="fas fa-check" aria-label="Completed"></i>'
: '<i class="far fa-square has-text-grey" aria-label="Incomplete"></i>'}
</span>
</div><div class="column">
${milestone.workOrderMilestoneTime === 0
? ''
: `${milestone.workOrderMilestoneTimePeriodString}<br />`}
${milestone.workOrderMilestoneTypeId
? `<strong>${cityssm.escapeHTML(milestone.workOrderMilestoneType ?? '')}</strong><br />`
: ''}
<span class="is-size-7">
${cityssm.escapeHTML(milestone.workOrderMilestoneDescription ?? '')}
</span>
</div><div class="column">
<i class="fas fa-circle" style="color:${los.getRandomColor(milestone.workOrderNumber ?? '')}" aria-hidden="true"></i>
<a class="has-text-weight-bold" href="${los.getWorkOrderURL(milestone.workOrderId)}">
${cityssm.escapeHTML(milestone.workOrderNumber ?? '')}
</a><br />
<span class="is-size-7">${cityssm.escapeHTML(milestone.workOrderDescription ?? '')}</span>
</div><div class="column is-size-7">
${burialSiteContractHTML === ''
? ''
: `<ul class="fa-ul ml-4">${burialSiteContractHTML}</ul>`}</div></div>`;
currentPanelElement.append(panelBlockElement);
}
milestoneCalendarContainerElement.append(currentPanelElement);
}
function getMilestones(event) {
if (event) {
event.preventDefault();
}
// eslint-disable-next-line no-unsanitized/property
milestoneCalendarContainerElement.innerHTML = los.getLoadingParagraphHTML('Loading Milestones...');
cityssm.postJSON(`${los.urlPrefix}/workOrders/doGetWorkOrderMilestones`, workOrderSearchFiltersFormElement, (responseJSON) => {
renderMilestones(responseJSON.workOrderMilestones);
});
}
workOrderMilestoneDateFilterElement.addEventListener('change', () => {
;
workOrderMilestoneDateStringElement.closest('fieldset').disabled = workOrderMilestoneDateFilterElement.value !== 'date';
getMilestones();
});
los.initializeDatePickers(workOrderSearchFiltersFormElement);
workOrderMilestoneDateStringElement.addEventListener('change', getMilestones);
workOrderSearchFiltersFormElement.addEventListener('submit', getMilestones);
getMilestones();
})();

View File

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

View File

@ -0,0 +1,46 @@
"use strict";
// eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair
/* eslint-disable unicorn/prefer-module */
Object.defineProperty(exports, "__esModule", { value: true });
(() => {
const los = exports.los;
const workOrderTypeIdsElement = document.querySelector('#icsFilters--workOrderTypeIds');
const workOrderMilestoneTypeIdsElement = document.querySelector('#icsFilters--workOrderMilestoneTypeIds');
const calendarLinkElement = document.querySelector('#icsFilters--calendarURL');
function updateCalendarURL() {
let url = `${window.location.href.slice(0, Math.max(0, window.location.href.indexOf(window.location.pathname) + 1)) + los.urlPrefix}api/${los.apiKey}/milestoneICS/?`;
if (!workOrderTypeIdsElement.disabled &&
workOrderTypeIdsElement.selectedOptions.length > 0) {
url += 'workOrderTypeIds=';
for (const optionElement of workOrderTypeIdsElement.selectedOptions) {
url += `${optionElement.value},`;
}
url = `${url.slice(0, -1)}&`;
}
if (!workOrderMilestoneTypeIdsElement.disabled &&
workOrderMilestoneTypeIdsElement.selectedOptions.length > 0) {
url += 'workOrderMilestoneTypeIds=';
for (const optionElement of workOrderMilestoneTypeIdsElement.selectedOptions) {
url += `${optionElement.value},`;
}
url = `${url.slice(0, -1)}&`;
}
calendarLinkElement.value = url.slice(0, -1);
}
;
document.querySelector('#icsFilters--workOrderTypeIds-all').addEventListener('change', (changeEvent) => {
workOrderTypeIdsElement.disabled = changeEvent.currentTarget.checked;
});
document.querySelector('#icsFilters--workOrderMilestoneTypeIds-all').addEventListener('change', (changeEvent) => {
workOrderMilestoneTypeIdsElement.disabled = changeEvent.currentTarget.checked;
});
const inputSelectElements = document.querySelector('#panel--icsFilters').querySelectorAll('input, select');
for (const element of inputSelectElements) {
element.addEventListener('change', updateCalendarURL);
}
updateCalendarURL();
calendarLinkElement.addEventListener('click', () => {
calendarLinkElement.focus();
calendarLinkElement.select();
});
})();

View File

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

View File

@ -0,0 +1,180 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
(() => {
const los = exports.los;
const workOrderPrints = exports.workOrderPrints;
const searchFilterFormElement = document.querySelector('#form--searchFilters');
los.initializeDatePickers(searchFilterFormElement);
const searchResultsContainerElement = document.querySelector('#container--searchResults');
const limit = Number.parseInt(document.querySelector('#searchFilter--limit').value, 10);
const offsetElement = document.querySelector('#searchFilter--offset');
function renderWorkOrders(rawResponseJSON) {
const responseJSON = rawResponseJSON;
if (responseJSON.workOrders.length === 0) {
searchResultsContainerElement.innerHTML = `<div class="message is-info">
<p class="message-body">There are no work orders that meet the search criteria.</p>
</div>`;
return;
}
const resultsTbodyElement = document.createElement('tbody');
for (const workOrder of responseJSON.workOrders) {
let relatedHTML = '';
for (const lot of workOrder.workOrderLots ?? []) {
relatedHTML += `<li class="has-tooltip-left"
data-tooltip="${cityssm.escapeHTML(lot.cemeteryName ?? '')}">
<span class="fa-li">
<i class="fas fa-fw fa-vector-square"
aria-label="${los.escapedAliases.Lot}"></i>
</span>
${cityssm.escapeHTML((lot.lotName ?? '') === ''
? `(No ${los.escapedAliases.Lot} Name)`
: lot.lotName ?? '')}
</li>`;
}
for (const occupancy of workOrder.workOrderBurialSiteContracts ?? []) {
for (const occupant of occupancy.burialSiteContractOccupants ?? []) {
relatedHTML += `<li class="has-tooltip-left"
data-tooltip="${cityssm.escapeHTML(occupant.lotOccupantType ?? '')}">
<span class="fa-li">
<i class="fas fa-fw fa-${cityssm.escapeHTML((occupant.fontAwesomeIconClass ?? '') === ''
? 'user'
: occupant.fontAwesomeIconClass ?? '')}" aria-label="${los.escapedAliases.occupant}"></i>
</span>
${cityssm.escapeHTML((occupant.occupantName ?? '') === '' &&
(occupant.occupantFamilyName ?? '') === ''
? '(No Name)'
: `${occupant.occupantName} ${occupant.occupantFamilyName}`)}
</li>`;
}
}
// eslint-disable-next-line no-unsanitized/method
resultsTbodyElement.insertAdjacentHTML('beforeend', `<tr>
<td>
<a class="has-text-weight-bold" href="${los.getWorkOrderURL(workOrder.workOrderId)}">
${workOrder.workOrderNumber?.trim() === ''
? '(No Number)'
: cityssm.escapeHTML(workOrder.workOrderNumber ?? '')}
</a>
</td><td>
${cityssm.escapeHTML(workOrder.workOrderType ?? '')}<br />
<span class="is-size-7">
${cityssm.escapeHTML(workOrder.workOrderDescription ?? '')}
</span>
</td><td>
${relatedHTML === ''
? ''
: `<ul class="fa-ul ml-5 is-size-7">${relatedHTML}</ul>`}
</td><td>
<ul class="fa-ul ml-5 is-size-7">
<li class="has-tooltip-left"
data-tooltip="${los.escapedAliases.WorkOrderOpenDate}">
<span class="fa-li">
<i class="fas fa-fw fa-play" aria-label="${los.escapedAliases.WorkOrderOpenDate}"></i>
</span>
${workOrder.workOrderOpenDateString}
</li>
<li class="has-tooltip-left" data-tooltip="${los.escapedAliases.WorkOrderCloseDate}">
<span class="fa-li">
<i class="fas fa-fw fa-stop" aria-label="${los.escapedAliases.WorkOrderCloseDate}"></i>
</span>
${workOrder.workOrderCloseDate
? workOrder.workOrderCloseDateString
: `<span class="has-text-grey">(No ${los.escapedAliases.WorkOrderCloseDate})</span>`}
</li>
</ul>
</td><td>
${workOrder.workOrderMilestoneCount === 0
? '-'
: `${(workOrder.workOrderMilestoneCompletionCount ?? '').toString()}
/
${(workOrder.workOrderMilestoneCount ?? '').toString()}`}
</td>
${workOrderPrints.length > 0
? `<td>
<a class="button is-small" data-tooltip="Print"
href="${los.urlPrefix}/print/${workOrderPrints[0]}/?workOrderId=${workOrder.workOrderId.toString()}"
target="_blank">
<i class="fas fa-print" aria-label="Print"></i>
</a>
</td>`
: ''}</tr>`);
}
// eslint-disable-next-line no-unsanitized/property
searchResultsContainerElement.innerHTML = `<table class="table is-fullwidth is-striped is-hoverable has-sticky-header">
<thead><tr>
<th>Work Order Number</th>
<th>Description</th>
<th>Related</th>
<th>Date</th>
<th class="has-tooltip-bottom" data-tooltip="Completed / Total Milestones">Progress</th>
${workOrderPrints.length > 0 ? '<th class="has-width-1"></th>' : ''}
</tr></thead>
<table>`;
// eslint-disable-next-line no-unsanitized/method
searchResultsContainerElement.insertAdjacentHTML('beforeend', los.getSearchResultsPagerHTML(limit, responseJSON.offset, responseJSON.count));
searchResultsContainerElement
.querySelector('table')
?.append(resultsTbodyElement);
searchResultsContainerElement
.querySelector("button[data-page='previous']")
?.addEventListener('click', previousAndGetWorkOrders);
searchResultsContainerElement
.querySelector("button[data-page='next']")
?.addEventListener('click', nextAndGetWorkOrders);
}
function getWorkOrders() {
// eslint-disable-next-line no-unsanitized/property
searchResultsContainerElement.innerHTML = los.getLoadingParagraphHTML('Loading Work Orders...');
cityssm.postJSON(`${los.urlPrefix}/workOrders/doSearchWorkOrders`, searchFilterFormElement, renderWorkOrders);
}
function resetOffsetAndGetWorkOrders() {
offsetElement.value = '0';
getWorkOrders();
}
function previousAndGetWorkOrders() {
offsetElement.value = Math.max(Number.parseInt(offsetElement.value, 10) - limit, 0).toString();
getWorkOrders();
}
function nextAndGetWorkOrders() {
offsetElement.value = (Number.parseInt(offsetElement.value, 10) + limit).toString();
getWorkOrders();
}
const filterElements = searchFilterFormElement.querySelectorAll('input, select');
for (const filterElement of filterElements) {
filterElement.addEventListener('change', resetOffsetAndGetWorkOrders);
}
searchFilterFormElement.addEventListener('submit', (formEvent) => {
formEvent.preventDefault();
});
// eslint-disable-next-line no-secrets/no-secrets
/*
const workOrderOpenDateStringElement = document.querySelector("#searchFilter--workOrderOpenDateString") as HTMLInputElement;
document.querySelector("#button--workOrderOpenDateString-previous").addEventListener("click", () => {
if (workOrderOpenDateStringElement.value === "") {
workOrderOpenDateStringElement.valueAsDate = new Date();
} else {
const openDate = workOrderOpenDateStringElement.valueAsDate;
openDate.setDate(openDate.getDate() - 1);
workOrderOpenDateStringElement.valueAsDate = openDate;
}
resetOffsetAndGetWorkOrders();
});
document.querySelector("#button--workOrderOpenDateString-next").addEventListener("click", () => {
if (workOrderOpenDateStringElement.value === "") {
workOrderOpenDateStringElement.valueAsDate = new Date();
} else {
const openDate = workOrderOpenDateStringElement.valueAsDate;
openDate.setDate(openDate.getDate() + 1);
workOrderOpenDateStringElement.valueAsDate = openDate;
}
resetOffsetAndGetWorkOrders();
});
*/
getWorkOrders();
})();

View File

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

View File

@ -0,0 +1,37 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
(() => {
const los = exports.los;
const reopenWorkOrderButtonElement = document.querySelector('#button--reopenWorkOrder');
if (reopenWorkOrderButtonElement !== null) {
const workOrderId = reopenWorkOrderButtonElement.dataset.workOrderId ?? '';
reopenWorkOrderButtonElement.addEventListener('click', () => {
function doReopen() {
cityssm.postJSON(`${los.urlPrefix}/workOrders/doReopenWorkOrder`, {
workOrderId
}, (rawResponseJSON) => {
const responseJSON = rawResponseJSON;
if (responseJSON.success) {
globalThis.location.href = los.getWorkOrderURL(workOrderId, true, true);
}
else {
bulmaJS.alert({
title: 'Error Reopening Work Order',
message: responseJSON.errorMessage ?? '',
contextualColorName: 'danger'
});
}
});
}
bulmaJS.confirm({
title: 'Reopen Work Order',
message: 'Are you sure you want to remove the close date from this work order and reopen it?',
contextualColorName: 'warning',
okButton: {
text: 'Yes, Reopen Work Order',
callbackFunction: doReopen
}
});
});
}
})();

View File

@ -1,24 +1,25 @@
/* eslint-disable max-lines */
import fs from 'node:fs'; import fs from 'node:fs';
import { dateIntegerToString, dateToString } from '@cityssm/utils-datetime'; import { dateIntegerToString, dateToString } from '@cityssm/utils-datetime';
import sqlite from 'better-sqlite3'; import sqlite from 'better-sqlite3';
import papa from 'papaparse'; import papa from 'papaparse';
import { sunriseDB as databasePath } from '../data/databasePaths.js'; import { sunriseDB as databasePath } from '../helpers/database.helpers.js';
import addLot from '../database/addLot.js'; import addBurialSite from '../database/addBurialSite.js';
import addBurialSiteContract from '../database/addBurialSiteContract.js'; import addBurialSiteContract from '../database/addBurialSiteContract.js';
import addBurialSiteContractComment from '../database/addBurialSiteContractComment.js'; import addBurialSiteContractComment from '../database/addBurialSiteContractComment.js';
import addBurialSiteContractFee from '../database/addBurialSiteContractFee.js'; import addBurialSiteContractFee from '../database/addBurialSiteContractFee.js';
import addBurialSiteContractOccupant from '../database/addBurialSiteContractOccupant.js'; import addBurialSiteContractOccupant from '../database/addBurialSiteContractOccupant.js';
import addBurialSiteContractTransaction from '../database/addBurialSiteContractTransaction.js'; import addBurialSiteContractTransaction from '../database/addBurialSiteContractTransaction.js';
import addMap from '../database/addMap.js'; import addCemetery from '../database/addCemetery.js';
import addOrUpdateLotOccupancyField from '../database/addOrUpdateLotOccupancyField.js'; import addOrUpdateBurialSiteContractField from '../database/addOrUpdateBurialSiteContractField.js';
import addWorkOrder from '../database/addWorkOrder.js'; import addWorkOrder from '../database/addWorkOrder.js';
import addWorkOrderLot from '../database/addWorkOrderLot.js'; import addWorkOrderBurialSite from '../database/addWorkOrderBurialSite.js';
import addWorkOrderBurialSiteContract from '../database/addWorkOrderBurialSiteContract.js'; import addWorkOrderBurialSiteContract from '../database/addWorkOrderBurialSiteContract.js';
import addWorkOrderMilestone from '../database/addWorkOrderMilestone.js'; import addWorkOrderMilestone from '../database/addWorkOrderMilestone.js';
import closeWorkOrder from '../database/closeWorkOrder.js'; import closeWorkOrder from '../database/closeWorkOrder.js';
import getLot, { getLotByLotName } from '../database/getLot.js'; import getBurialSite from '../database/getBurialSite.js';
import getBurialSiteContracts from '../database/getBurialSiteContracts.js'; import getBurialSiteContracts from '../database/getBurialSiteContracts.js';
import getMapFromDatabase from '../database/getMap.js'; import getCemeteryFromDatabase from '../database/getCemetery.js';
import getWorkOrder, { getWorkOrderByWorkOrderNumber } from '../database/getWorkOrder.js'; import getWorkOrder, { getWorkOrderByWorkOrderNumber } from '../database/getWorkOrder.js';
import reopenWorkOrder from '../database/reopenWorkOrder.js'; import reopenWorkOrder from '../database/reopenWorkOrder.js';
import { updateBurialSiteStatus } from '../database/updateBurialSite.js'; import { updateBurialSiteStatus } from '../database/updateBurialSite.js';
@ -37,18 +38,18 @@ function purgeTables() {
const tablesToPurge = [ const tablesToPurge = [
'WorkOrderMilestones', 'WorkOrderMilestones',
'WorkOrderComments', 'WorkOrderComments',
'WorkOrderLots', 'WorkOrderBurialSites',
'WorkOrderLotOccupancies', 'WorkOrderBurialSiteContracts',
'WorkOrders', 'WorkOrders',
'LotOccupancyTransactions', 'BurialSiteContractTransactions',
'LotOccupancyFees', 'BurialSiteContractFees',
'LotOccupancyFields', 'BurialSiteContractFields',
'LotOccupancyComments', 'BurialSiteContractComments',
'LotOccupancyOccupants', 'BurialSiteContractInterments',
'LotOccupancies', 'BurialSiteContracts',
'LotFields', 'BurialSiteFields',
'LotComments', 'BurialSiteComments',
'Lots' 'BurialSites'
]; ];
const database = sqlite(databasePath); const database = sqlite(databasePath);
for (const tableName of tablesToPurge) { for (const tableName of tablesToPurge) {
@ -63,20 +64,20 @@ function purgeTables() {
function purgeConfigTables() { function purgeConfigTables() {
console.time('purgeConfigTables'); console.time('purgeConfigTables');
const database = sqlite(databasePath); const database = sqlite(databasePath);
database.prepare('delete from Maps').run(); database.prepare('delete from Cemeteries').run();
database.prepare("delete from sqlite_sequence where name in ('Maps')").run(); database.prepare("delete from sqlite_sequence where name in ('Cemeteries')").run();
database.close(); database.close();
console.timeEnd('purgeConfigTables'); console.timeEnd('purgeConfigTables');
} }
function getMapByMapDescription(mapDescription) { function getCemeteryByDescription(cemeteryDescription) {
const database = sqlite(databasePath, { const database = sqlite(databasePath, {
readonly: true readonly: true
}); });
const map = database const cemetery = database
.prepare('select * from Maps where mapDescription = ?') .prepare('select * from Cemeteries where cemeteryDescription = ?')
.get(mapDescription); .get(cemeteryDescription);
database.close(); database.close();
return map; return cemetery;
} }
function formatDateString(year, month, day) { function formatDateString(year, month, day) {
const formattedYear = `0000${year}`.slice(-4); const formattedYear = `0000${year}`.slice(-4);
@ -102,8 +103,8 @@ const cemeteryTocemeteryName = {
UG: 'New Greenwood - Urn Garden', UG: 'New Greenwood - Urn Garden',
WK: 'West Korah' WK: 'West Korah'
}; };
const mapCache = new Map(); const cemeteryCache = new Map();
async function getMap(dataRow) { async function getCemetery(dataRow) {
const mapCacheKey = dataRow.cemetery; const mapCacheKey = dataRow.cemetery;
/* /*
if (masterRow.CM_CEMETERY === "HS" && if (masterRow.CM_CEMETERY === "HS" &&
@ -111,29 +112,29 @@ async function getMap(dataRow) {
mapCacheKey += "-" + masterRow.CM_BLOCK; mapCacheKey += "-" + masterRow.CM_BLOCK;
} }
*/ */
if (mapCache.has(mapCacheKey)) { if (cemeteryCache.has(mapCacheKey)) {
return mapCache.get(mapCacheKey); return cemeteryCache.get(mapCacheKey);
} }
let map = getMapByMapDescription(mapCacheKey); let cemetery = getCemeteryByDescription(mapCacheKey);
if (!map) { if (cemetery === undefined) {
console.log(`Creating map: ${dataRow.cemetery}`); console.log(`Creating cemetery: ${dataRow.cemetery}`);
const cemeteryId = await addMap({ const cemeteryId = await addCemetery({
cemeteryName: cemeteryTocemeteryName[dataRow.cemetery] ?? dataRow.cemetery, cemeteryName: cemeteryTocemeteryName[dataRow.cemetery] ?? dataRow.cemetery,
mapDescription: dataRow.cemetery, cemeteryDescription: dataRow.cemetery,
mapSVG: '', cemeterySvg: '',
mapLatitude: '', cemeteryLatitude: '',
mapLongitude: '', cemeteryLongitude: '',
mapAddress1: '', cemeteryAddress1: '',
mapAddress2: '', cemeteryAddress2: '',
mapCity: 'Sault Ste. Marie', cemeteryCity: 'Sault Ste. Marie',
mapProvince: 'ON', cemeteryProvince: 'ON',
mapPostalCode: '', cemeteryPostalCode: '',
mapPhoneNumber: '' cemeteryPhoneNumber: ''
}, user); }, user);
map = (await getMapFromDatabase(cemeteryId)); cemetery = (await getCemeteryFromDatabase(cemeteryId));
} }
mapCache.set(mapCacheKey, map); cemeteryCache.set(mapCacheKey, cemetery);
return map; return cemetery;
} }
async function importFromMasterCSV() { async function importFromMasterCSV() {
console.time('importFromMasterCSV'); console.time('importFromMasterCSV');
@ -149,31 +150,20 @@ async function importFromMasterCSV() {
} }
try { try {
for (masterRow of cmmaster.data) { for (masterRow of cmmaster.data) {
const map = await getMap({ const cemetery = await getCemetery({
cemetery: masterRow.CM_CEMETERY cemetery: masterRow.CM_CEMETERY
}); });
const lotName = importData.buildLotName({
cemetery: masterRow.CM_CEMETERY,
block: masterRow.CM_BLOCK,
range1: masterRow.CM_RANGE1,
range2: masterRow.CM_RANGE2,
lot1: masterRow.CM_LOT1,
lot2: masterRow.CM_LOT2,
grave1: masterRow.CM_GRAVE1,
grave2: masterRow.CM_GRAVE2,
interment: masterRow.CM_INTERMENT
});
const burialSiteTypeId = importIds.getburialSiteTypeId({ const burialSiteTypeId = importIds.getburialSiteTypeId({
cemetery: masterRow.CM_CEMETERY cemetery: masterRow.CM_CEMETERY
}); });
let lotId; let burialSiteId;
if (masterRow.CM_CEMETERY !== '00') { if (masterRow.CM_CEMETERY !== '00') {
lotId = await addLot({ burialSiteId = await addBurialSite({
lotName, lotName,
burialSiteTypeId, burialSiteTypeId,
burialSiteStatusId: importIds.availableburialSiteStatusId, burialSiteStatusId: importIds.availableBurialSiteStatusId,
cemeteryId: map.cemeteryId, cemeteryId: cemetery.cemeteryId,
mapKey: lotName.includes(',') ? lotName.split(',')[0] : lotName, cemeterySvgId: '',
burialSiteLatitude: '', burialSiteLatitude: '',
burialSiteLongitude: '' burialSiteLongitude: ''
}, user); }, user);
@ -209,7 +199,7 @@ async function importFromMasterCSV() {
} }
preneedburialSiteContractId = await addBurialSiteContract({ preneedburialSiteContractId = await addBurialSiteContract({
contractTypeId: importIds.preneedOccupancyType.contractTypeId, contractTypeId: importIds.preneedOccupancyType.contractTypeId,
lotId: lotId ?? '', lotId: burialSiteId ?? '',
contractStartDateString: preneedcontractStartDateString, contractStartDateString: preneedcontractStartDateString,
contractEndDateString, contractEndDateString,
contractTypeFieldIds: '' contractTypeFieldIds: ''
@ -253,7 +243,7 @@ async function importFromMasterCSV() {
}, user); }, user);
} }
if (contractEndDateString === '') { if (contractEndDateString === '') {
await updateBurialSiteStatus(lotId ?? '', importIds.reservedburialSiteStatusId, user); await updateBurialSiteStatus(burialSiteId ?? '', importIds.reservedburialSiteStatusId, user);
} }
} }
let deceasedcontractStartDateString; let deceasedcontractStartDateString;
@ -270,15 +260,15 @@ async function importFromMasterCSV() {
deceasedcontractStartDateString === '0000-00-00') { deceasedcontractStartDateString === '0000-00-00') {
deceasedcontractStartDateString = '0001-01-01'; deceasedcontractStartDateString = '0001-01-01';
} }
const deceasedcontractEndDateString = lotId const deceasedcontractEndDateString = burialSiteId
? '' ? ''
: deceasedcontractStartDateString; : deceasedcontractStartDateString;
const occupancyType = lotId const occupancyType = burialSiteId
? importIds.deceasedOccupancyType ? importIds.deceasedOccupancyType
: importIds.cremationOccupancyType; : importIds.cremationOccupancyType;
deceasedburialSiteContractId = await addBurialSiteContract({ deceasedburialSiteContractId = await addBurialSiteContract({
contractTypeId: occupancyType.contractTypeId, contractTypeId: occupancyType.contractTypeId,
lotId: lotId ?? '', lotId: burialSiteId ?? '',
contractStartDateString: deceasedcontractStartDateString, contractStartDateString: deceasedcontractStartDateString,
contractEndDateString: deceasedcontractEndDateString, contractEndDateString: deceasedcontractEndDateString,
contractTypeFieldIds: '' contractTypeFieldIds: ''
@ -299,14 +289,14 @@ async function importFromMasterCSV() {
}, user); }, user);
if (masterRow.CM_DEATH_YR !== '') { if (masterRow.CM_DEATH_YR !== '') {
const burialSiteContractFieldValue = formatDateString(masterRow.CM_DEATH_YR, masterRow.CM_DEATH_MON, masterRow.CM_DEATH_DAY); const burialSiteContractFieldValue = formatDateString(masterRow.CM_DEATH_YR, masterRow.CM_DEATH_MON, masterRow.CM_DEATH_DAY);
await addOrUpdateLotOccupancyField({ await addOrUpdateBurialSiteContractField({
burialSiteContractId: deceasedburialSiteContractId, burialSiteContractId: deceasedburialSiteContractId,
contractTypeFieldId: occupancyType.ContractTypeFields.find((occupancyTypeField) => occupancyTypeField.occupancyTypeField === 'Death Date').contractTypeFieldId, contractTypeFieldId: occupancyType.ContractTypeFields.find((occupancyTypeField) => occupancyTypeField.occupancyTypeField === 'Death Date').contractTypeFieldId,
burialSiteContractFieldValue burialSiteContractFieldValue
}, user); }, user);
} }
if (masterRow.CM_AGE !== '') { if (masterRow.CM_AGE !== '') {
await addOrUpdateLotOccupancyField({ await addOrUpdateBurialSiteContractField({
burialSiteContractId: deceasedburialSiteContractId, burialSiteContractId: deceasedburialSiteContractId,
contractTypeFieldId: occupancyType.ContractTypeFields.find((occupancyTypeField) => occupancyTypeField.occupancyTypeField === 'Death Age').contractTypeFieldId, contractTypeFieldId: occupancyType.ContractTypeFields.find((occupancyTypeField) => occupancyTypeField.occupancyTypeField === 'Death Age').contractTypeFieldId,
burialSiteContractFieldValue: masterRow.CM_AGE burialSiteContractFieldValue: masterRow.CM_AGE
@ -314,9 +304,9 @@ async function importFromMasterCSV() {
} }
if (masterRow.CM_PERIOD !== '') { if (masterRow.CM_PERIOD !== '') {
const period = importData.getDeathAgePeriod(masterRow.CM_PERIOD); const period = importData.getDeathAgePeriod(masterRow.CM_PERIOD);
await addOrUpdateLotOccupancyField({ await addOrUpdateBurialSiteContractField({
burialSiteContractId: deceasedburialSiteContractId, burialSiteContractId: deceasedburialSiteContractId,
contractTypeFieldId: occupancyType.ContractTypeFields.find((occupancyTypeField) => (occupancyTypeField.occupancyTypeField === 'Death Age Period')).contractTypeFieldId, contractTypeFieldId: occupancyType.ContractTypeFields.find((occupancyTypeField) => occupancyTypeField.occupancyTypeField === 'Death Age Period').contractTypeFieldId,
burialSiteContractFieldValue: period burialSiteContractFieldValue: period
}, user); }, user);
} }
@ -336,7 +326,7 @@ async function importFromMasterCSV() {
occupantEmailAddress: funeralHomeOccupant.occupantEmailAddress ?? '' occupantEmailAddress: funeralHomeOccupant.occupantEmailAddress ?? ''
}, user); }, user);
/* /*
addOrUpdateLotOccupancyField( addOrUpdateBurialSiteContractField(
{ {
burialSiteContractId: deceasedburialSiteContractId, burialSiteContractId: deceasedburialSiteContractId,
contractTypeFieldId: allContractTypeFields.find( contractTypeFieldId: allContractTypeFields.find(
@ -352,17 +342,17 @@ async function importFromMasterCSV() {
} }
if (masterRow.CM_FUNERAL_YR !== '') { if (masterRow.CM_FUNERAL_YR !== '') {
const burialSiteContractFieldValue = formatDateString(masterRow.CM_FUNERAL_YR, masterRow.CM_FUNERAL_MON, masterRow.CM_FUNERAL_DAY); const burialSiteContractFieldValue = formatDateString(masterRow.CM_FUNERAL_YR, masterRow.CM_FUNERAL_MON, masterRow.CM_FUNERAL_DAY);
await addOrUpdateLotOccupancyField({ await addOrUpdateBurialSiteContractField({
burialSiteContractId: deceasedburialSiteContractId, burialSiteContractId: deceasedburialSiteContractId,
contractTypeFieldId: occupancyType.ContractTypeFields.find((occupancyTypeField) => (occupancyTypeField.occupancyTypeField === 'Funeral Date')).contractTypeFieldId, contractTypeFieldId: occupancyType.ContractTypeFields.find((occupancyTypeField) => occupancyTypeField.occupancyTypeField === 'Funeral Date').contractTypeFieldId,
burialSiteContractFieldValue burialSiteContractFieldValue
}, user); }, user);
} }
if (occupancyType.occupancyType !== 'Cremation') { if (occupancyType.occupancyType !== 'Cremation') {
if (masterRow.CM_CONTAINER_TYPE !== '') { if (masterRow.CM_CONTAINER_TYPE !== '') {
await addOrUpdateLotOccupancyField({ await addOrUpdateBurialSiteContractField({
burialSiteContractId: deceasedburialSiteContractId, burialSiteContractId: deceasedburialSiteContractId,
contractTypeFieldId: occupancyType.ContractTypeFields.find((occupancyTypeField) => (occupancyTypeField.occupancyTypeField === 'Container Type')).contractTypeFieldId, contractTypeFieldId: occupancyType.ContractTypeFields.find((occupancyTypeField) => occupancyTypeField.occupancyTypeField === 'Container Type').contractTypeFieldId,
burialSiteContractFieldValue: masterRow.CM_CONTAINER_TYPE burialSiteContractFieldValue: masterRow.CM_CONTAINER_TYPE
}, user); }, user);
} }
@ -371,9 +361,9 @@ async function importFromMasterCSV() {
if (commitalType === 'GS') { if (commitalType === 'GS') {
commitalType = 'Graveside'; commitalType = 'Graveside';
} }
await addOrUpdateLotOccupancyField({ await addOrUpdateBurialSiteContractField({
burialSiteContractId: deceasedburialSiteContractId, burialSiteContractId: deceasedburialSiteContractId,
contractTypeFieldId: occupancyType.ContractTypeFields.find((occupancyTypeField) => (occupancyTypeField.occupancyTypeField === 'Committal Type')).contractTypeFieldId, contractTypeFieldId: occupancyType.ContractTypeFields.find((occupancyTypeField) => occupancyTypeField.occupancyTypeField === 'Committal Type').contractTypeFieldId,
burialSiteContractFieldValue: commitalType burialSiteContractFieldValue: commitalType
}, user); }, user);
} }
@ -402,7 +392,7 @@ async function importFromMasterCSV() {
burialSiteContractComment: `Imported Contract #${masterRow.CM_WORK_ORDER}` burialSiteContractComment: `Imported Contract #${masterRow.CM_WORK_ORDER}`
}, user); }, user);
} }
await updateBurialSiteStatus(lotId ?? '', importIds.takenburialSiteStatusId, user); await updateBurialSiteStatus(burialSiteId ?? '', importIds.takenburialSiteStatusId, user);
if (masterRow.CM_PRENEED_OWNER !== '') { if (masterRow.CM_PRENEED_OWNER !== '') {
await addBurialSiteContractOccupant({ await addBurialSiteContractOccupant({
burialSiteContractId: deceasedburialSiteContractId, burialSiteContractId: deceasedburialSiteContractId,
@ -450,7 +440,7 @@ async function importFromPrepaidCSV() {
} }
let lot; let lot;
if (cemetery !== '') { if (cemetery !== '') {
const map = await getMap({ const map = await getCemetery({
cemetery cemetery
}); });
const lotName = importData.buildLotName({ const lotName = importData.buildLotName({
@ -464,12 +454,12 @@ async function importFromPrepaidCSV() {
grave2: prepaidRow.CMPP_GRAVE2, grave2: prepaidRow.CMPP_GRAVE2,
interment: prepaidRow.CMPP_INTERMENT interment: prepaidRow.CMPP_INTERMENT
}); });
lot = await getLotByLotName(lotName); lot = await getBurialSiteByLotName(lotName);
if (!lot) { if (!lot) {
const burialSiteTypeId = importIds.getburialSiteTypeId({ const burialSiteTypeId = importIds.getburialSiteTypeId({
cemetery cemetery
}); });
const lotId = await addLot({ const lotId = await addBurialSite({
lotName, lotName,
burialSiteTypeId, burialSiteTypeId,
burialSiteStatusId: importIds.reservedburialSiteStatusId, burialSiteStatusId: importIds.reservedburialSiteStatusId,
@ -478,10 +468,11 @@ async function importFromPrepaidCSV() {
burialSiteLatitude: '', burialSiteLatitude: '',
burialSiteLongitude: '' burialSiteLongitude: ''
}, user); }, user);
lot = await getLot(lotId); lot = await getBurialSite(lotId);
} }
} }
if (lot && lot.burialSiteStatusId === importIds.availableburialSiteStatusId) { if (lot &&
lot.burialSiteStatusId === importIds.availableburialSiteStatusId) {
await updateBurialSiteStatus(lot.lotId, importIds.reservedburialSiteStatusId, user); await updateBurialSiteStatus(lot.lotId, importIds.reservedburialSiteStatusId, user);
} }
const contractStartDateString = formatDateString(prepaidRow.CMPP_PURCH_YR, prepaidRow.CMPP_PURCH_MON, prepaidRow.CMPP_PURCH_DAY); const contractStartDateString = formatDateString(prepaidRow.CMPP_PURCH_YR, prepaidRow.CMPP_PURCH_MON, prepaidRow.CMPP_PURCH_DAY);
@ -711,16 +702,16 @@ async function importFromWorkOrderCSV() {
grave2: workOrderRow.WO_GRAVE2, grave2: workOrderRow.WO_GRAVE2,
interment: workOrderRow.WO_INTERMENT interment: workOrderRow.WO_INTERMENT
}); });
lot = await getLotByLotName(lotName); lot = await getBurialSiteByLotName(lotName);
if (lot) { if (lot) {
await updateBurialSiteStatus(lot.lotId, importIds.takenburialSiteStatusId, user); await updateBurialSiteStatus(lot.lotId, importIds.takenburialSiteStatusId, user);
} }
else { else {
const map = await getMap({ cemetery: workOrderRow.WO_CEMETERY }); const map = await getCemetery({ cemetery: workOrderRow.WO_CEMETERY });
const burialSiteTypeId = importIds.getburialSiteTypeId({ const burialSiteTypeId = importIds.getburialSiteTypeId({
cemetery: workOrderRow.WO_CEMETERY cemetery: workOrderRow.WO_CEMETERY
}); });
const lotId = await addLot({ const lotId = await addBurialSite({
cemeteryId: map.cemeteryId, cemeteryId: map.cemeteryId,
lotName, lotName,
mapKey: lotName.includes(',') ? lotName.split(',')[0] : lotName, mapKey: lotName.includes(',') ? lotName.split(',')[0] : lotName,
@ -729,11 +720,11 @@ async function importFromWorkOrderCSV() {
burialSiteLatitude: '', burialSiteLatitude: '',
burialSiteLongitude: '' burialSiteLongitude: ''
}, user); }, user);
lot = await getLot(lotId); lot = await getBurialSite(lotId);
} }
const workOrderContainsLot = workOrder.workOrderLots.find((possibleLot) => (possibleLot.lotId = lot.lotId)); const workOrderContainsLot = workOrder.workOrderLots.find((possibleLot) => (possibleLot.lotId = lot.lotId));
if (!workOrderContainsLot) { if (!workOrderContainsLot) {
await addWorkOrderLot({ await addWorkOrderBurialSite({
workOrderId: workOrder.workOrderId, workOrderId: workOrder.workOrderId,
lotId: lot.lotId lotId: lot.lotId
}, user); }, user);
@ -768,21 +759,21 @@ async function importFromWorkOrderCSV() {
}, user); }, user);
if (workOrderRow.WO_DEATH_YR !== '') { if (workOrderRow.WO_DEATH_YR !== '') {
const burialSiteContractFieldValue = formatDateString(workOrderRow.WO_DEATH_YR, workOrderRow.WO_DEATH_MON, workOrderRow.WO_DEATH_DAY); const burialSiteContractFieldValue = formatDateString(workOrderRow.WO_DEATH_YR, workOrderRow.WO_DEATH_MON, workOrderRow.WO_DEATH_DAY);
await addOrUpdateLotOccupancyField({ await addOrUpdateBurialSiteContractField({
burialSiteContractId, burialSiteContractId,
contractTypeFieldId: occupancyType.ContractTypeFields.find((occupancyTypeField) => occupancyTypeField.occupancyTypeField === 'Death Date').contractTypeFieldId, contractTypeFieldId: occupancyType.ContractTypeFields.find((occupancyTypeField) => occupancyTypeField.occupancyTypeField === 'Death Date').contractTypeFieldId,
burialSiteContractFieldValue burialSiteContractFieldValue
}, user); }, user);
} }
if (workOrderRow.WO_DEATH_PLACE !== '') { if (workOrderRow.WO_DEATH_PLACE !== '') {
await addOrUpdateLotOccupancyField({ await addOrUpdateBurialSiteContractField({
burialSiteContractId, burialSiteContractId,
contractTypeFieldId: occupancyType.ContractTypeFields.find((occupancyTypeField) => occupancyTypeField.occupancyTypeField === 'Death Place').contractTypeFieldId, contractTypeFieldId: occupancyType.ContractTypeFields.find((occupancyTypeField) => occupancyTypeField.occupancyTypeField === 'Death Place').contractTypeFieldId,
burialSiteContractFieldValue: workOrderRow.WO_DEATH_PLACE burialSiteContractFieldValue: workOrderRow.WO_DEATH_PLACE
}, user); }, user);
} }
if (workOrderRow.WO_AGE !== '') { if (workOrderRow.WO_AGE !== '') {
await addOrUpdateLotOccupancyField({ await addOrUpdateBurialSiteContractField({
burialSiteContractId, burialSiteContractId,
contractTypeFieldId: occupancyType.ContractTypeFields.find((occupancyTypeField) => occupancyTypeField.occupancyTypeField === 'Death Age').contractTypeFieldId, contractTypeFieldId: occupancyType.ContractTypeFields.find((occupancyTypeField) => occupancyTypeField.occupancyTypeField === 'Death Age').contractTypeFieldId,
burialSiteContractFieldValue: workOrderRow.WO_AGE burialSiteContractFieldValue: workOrderRow.WO_AGE
@ -790,9 +781,9 @@ async function importFromWorkOrderCSV() {
} }
if (workOrderRow.WO_PERIOD !== '') { if (workOrderRow.WO_PERIOD !== '') {
const period = importData.getDeathAgePeriod(workOrderRow.WO_PERIOD); const period = importData.getDeathAgePeriod(workOrderRow.WO_PERIOD);
await addOrUpdateLotOccupancyField({ await addOrUpdateBurialSiteContractField({
burialSiteContractId, burialSiteContractId,
contractTypeFieldId: occupancyType.ContractTypeFields.find((occupancyTypeField) => (occupancyTypeField.occupancyTypeField === 'Death Age Period')).contractTypeFieldId, contractTypeFieldId: occupancyType.ContractTypeFields.find((occupancyTypeField) => occupancyTypeField.occupancyTypeField === 'Death Age Period').contractTypeFieldId,
burialSiteContractFieldValue: period burialSiteContractFieldValue: period
}, user); }, user);
} }
@ -812,7 +803,7 @@ async function importFromWorkOrderCSV() {
occupantEmailAddress: funeralHomeOccupant.occupantEmailAddress occupantEmailAddress: funeralHomeOccupant.occupantEmailAddress
}, user); }, user);
/* /*
addOrUpdateLotOccupancyField( addOrUpdateBurialSiteContractField(
{ {
burialSiteContractId: burialSiteContractId, burialSiteContractId: burialSiteContractId,
contractTypeFieldId: allContractTypeFields.find((occupancyTypeField) => { contractTypeFieldId: allContractTypeFields.find((occupancyTypeField) => {
@ -826,7 +817,7 @@ async function importFromWorkOrderCSV() {
} }
if (workOrderRow.WO_FUNERAL_YR !== '') { if (workOrderRow.WO_FUNERAL_YR !== '') {
const burialSiteContractFieldValue = formatDateString(workOrderRow.WO_FUNERAL_YR, workOrderRow.WO_FUNERAL_MON, workOrderRow.WO_FUNERAL_DAY); const burialSiteContractFieldValue = formatDateString(workOrderRow.WO_FUNERAL_YR, workOrderRow.WO_FUNERAL_MON, workOrderRow.WO_FUNERAL_DAY);
await addOrUpdateLotOccupancyField({ await addOrUpdateBurialSiteContractField({
burialSiteContractId, burialSiteContractId,
contractTypeFieldId: occupancyType.ContractTypeFields.find((occupancyTypeField) => occupancyTypeField.occupancyTypeField === 'Funeral Date').contractTypeFieldId, contractTypeFieldId: occupancyType.ContractTypeFields.find((occupancyTypeField) => occupancyTypeField.occupancyTypeField === 'Funeral Date').contractTypeFieldId,
burialSiteContractFieldValue burialSiteContractFieldValue
@ -834,9 +825,9 @@ async function importFromWorkOrderCSV() {
} }
if (occupancyType.occupancyType !== 'Cremation') { if (occupancyType.occupancyType !== 'Cremation') {
if (workOrderRow.WO_CONTAINER_TYPE !== '') { if (workOrderRow.WO_CONTAINER_TYPE !== '') {
await addOrUpdateLotOccupancyField({ await addOrUpdateBurialSiteContractField({
burialSiteContractId, burialSiteContractId,
contractTypeFieldId: occupancyType.ContractTypeFields.find((occupancyTypeField) => (occupancyTypeField.occupancyTypeField === 'Container Type')).contractTypeFieldId, contractTypeFieldId: occupancyType.ContractTypeFields.find((occupancyTypeField) => occupancyTypeField.occupancyTypeField === 'Container Type').contractTypeFieldId,
burialSiteContractFieldValue: workOrderRow.WO_CONTAINER_TYPE burialSiteContractFieldValue: workOrderRow.WO_CONTAINER_TYPE
}, user); }, user);
} }
@ -845,9 +836,9 @@ async function importFromWorkOrderCSV() {
if (commitalType === 'GS') { if (commitalType === 'GS') {
commitalType = 'Graveside'; commitalType = 'Graveside';
} }
await addOrUpdateLotOccupancyField({ await addOrUpdateBurialSiteContractField({
burialSiteContractId, burialSiteContractId,
contractTypeFieldId: occupancyType.ContractTypeFields.find((occupancyTypeField) => (occupancyTypeField.occupancyTypeField === 'Committal Type')).contractTypeFieldId, contractTypeFieldId: occupancyType.ContractTypeFields.find((occupancyTypeField) => occupancyTypeField.occupancyTypeField === 'Committal Type').contractTypeFieldId,
burialSiteContractFieldValue: commitalType burialSiteContractFieldValue: commitalType
}, user); }, user);
} }

View File

@ -1,3 +1,5 @@
/* eslint-disable max-lines */
import fs from 'node:fs' import fs from 'node:fs'
import { import {
@ -9,23 +11,25 @@ import {
import sqlite from 'better-sqlite3' import sqlite from 'better-sqlite3'
import papa from 'papaparse' import papa from 'papaparse'
import { sunriseDB as databasePath } from '../data/databasePaths.js' import { sunriseDB as databasePath } from '../helpers/database.helpers.js'
import addLot from '../database/addLot.js' import addBurialSite from '../database/addBurialSite.js'
import addBurialSiteContract from '../database/addBurialSiteContract.js' import addBurialSiteContract from '../database/addBurialSiteContract.js'
import addBurialSiteContractComment from '../database/addBurialSiteContractComment.js' import addBurialSiteContractComment from '../database/addBurialSiteContractComment.js'
import addBurialSiteContractFee from '../database/addBurialSiteContractFee.js' import addBurialSiteContractFee from '../database/addBurialSiteContractFee.js'
import addBurialSiteContractOccupant from '../database/addBurialSiteContractOccupant.js' import addBurialSiteContractOccupant from '../database/addBurialSiteContractOccupant.js'
import addBurialSiteContractTransaction from '../database/addBurialSiteContractTransaction.js' import addBurialSiteContractTransaction from '../database/addBurialSiteContractTransaction.js'
import addMap from '../database/addMap.js' import addCemetery from '../database/addCemetery.js'
import addOrUpdateLotOccupancyField from '../database/addOrUpdateLotOccupancyField.js' import addOrUpdateBurialSiteContractField from '../database/addOrUpdateBurialSiteContractField.js'
import addWorkOrder from '../database/addWorkOrder.js' import addWorkOrder from '../database/addWorkOrder.js'
import addWorkOrderLot from '../database/addWorkOrderLot.js' import addWorkOrderBurialSite from '../database/addWorkOrderBurialSite.js'
import addWorkOrderBurialSiteContract from '../database/addWorkOrderBurialSiteContract.js' import addWorkOrderBurialSiteContract from '../database/addWorkOrderBurialSiteContract.js'
import addWorkOrderMilestone from '../database/addWorkOrderMilestone.js' import addWorkOrderMilestone from '../database/addWorkOrderMilestone.js'
import closeWorkOrder from '../database/closeWorkOrder.js' import closeWorkOrder from '../database/closeWorkOrder.js'
import getLot, { getLotByLotName } from '../database/getLot.js' import getBurialSite, {
getBurialSiteByBurialSiteName
} from '../database/getBurialSite.js'
import getBurialSiteContracts from '../database/getBurialSiteContracts.js' import getBurialSiteContracts from '../database/getBurialSiteContracts.js'
import getMapFromDatabase from '../database/getMap.js' import getCemeteryFromDatabase from '../database/getCemetery.js'
import getWorkOrder, { import getWorkOrder, {
getWorkOrderByWorkOrderNumber getWorkOrderByWorkOrderNumber
} from '../database/getWorkOrder.js' } from '../database/getWorkOrder.js'
@ -194,18 +198,18 @@ function purgeTables(): void {
const tablesToPurge = [ const tablesToPurge = [
'WorkOrderMilestones', 'WorkOrderMilestones',
'WorkOrderComments', 'WorkOrderComments',
'WorkOrderLots', 'WorkOrderBurialSites',
'WorkOrderLotOccupancies', 'WorkOrderBurialSiteContracts',
'WorkOrders', 'WorkOrders',
'LotOccupancyTransactions', 'BurialSiteContractTransactions',
'LotOccupancyFees', 'BurialSiteContractFees',
'LotOccupancyFields', 'BurialSiteContractFields',
'LotOccupancyComments', 'BurialSiteContractComments',
'LotOccupancyOccupants', 'BurialSiteContractInterments',
'LotOccupancies', 'BurialSiteContracts',
'LotFields', 'BurialSiteFields',
'LotComments', 'BurialSiteComments',
'Lots' 'BurialSites'
] ]
const database = sqlite(databasePath) const database = sqlite(databasePath)
@ -226,25 +230,27 @@ function purgeConfigTables(): void {
console.time('purgeConfigTables') console.time('purgeConfigTables')
const database = sqlite(databasePath) const database = sqlite(databasePath)
database.prepare('delete from Maps').run() database.prepare('delete from Cemeteries').run()
database.prepare("delete from sqlite_sequence where name in ('Maps')").run() database.prepare("delete from sqlite_sequence where name in ('Cemeteries')").run()
database.close() database.close()
console.timeEnd('purgeConfigTables') console.timeEnd('purgeConfigTables')
} }
function getMapByMapDescription(mapDescription: string): recordTypes.MapRecord { function getCemeteryByDescription(
cemeteryDescription: string
): recordTypes.Cemetery | undefined {
const database = sqlite(databasePath, { const database = sqlite(databasePath, {
readonly: true readonly: true
}) })
const map = database const cemetery = database
.prepare('select * from Maps where mapDescription = ?') .prepare('select * from Cemeteries where cemeteryDescription = ?')
.get(mapDescription) as recordTypes.MapRecord .get(cemeteryDescription) as recordTypes.Cemetery
database.close() database.close()
return map return cemetery
} }
function formatDateString( function formatDateString(
@ -280,11 +286,11 @@ const cemeteryTocemeteryName = {
WK: 'West Korah' WK: 'West Korah'
} }
const mapCache = new Map<string, recordTypes.MapRecord>() const cemeteryCache = new Map<string, recordTypes.Cemetery>()
async function getMap(dataRow: { async function getCemetery(dataRow: {
cemetery: string cemetery: string
}): Promise<recordTypes.MapRecord> { }): Promise<recordTypes.Cemetery> {
const mapCacheKey = dataRow.cemetery const mapCacheKey = dataRow.cemetery
/* /*
@ -294,38 +300,39 @@ async function getMap(dataRow: {
} }
*/ */
if (mapCache.has(mapCacheKey)) { if (cemeteryCache.has(mapCacheKey)) {
return mapCache.get(mapCacheKey)! return cemeteryCache.get(mapCacheKey)!
} }
let map = getMapByMapDescription(mapCacheKey) let cemetery = getCemeteryByDescription(mapCacheKey)
if (!map) { if (cemetery === undefined) {
console.log(`Creating map: ${dataRow.cemetery}`) console.log(`Creating cemetery: ${dataRow.cemetery}`)
const cemeteryId = await addMap( const cemeteryId = await addCemetery(
{ {
cemeteryName: cemeteryTocemeteryName[dataRow.cemetery] ?? dataRow.cemetery, cemeteryName:
mapDescription: dataRow.cemetery, cemeteryTocemeteryName[dataRow.cemetery] ?? dataRow.cemetery,
mapSVG: '', cemeteryDescription: dataRow.cemetery,
mapLatitude: '', cemeterySvg: '',
mapLongitude: '', cemeteryLatitude: '',
mapAddress1: '', cemeteryLongitude: '',
mapAddress2: '', cemeteryAddress1: '',
mapCity: 'Sault Ste. Marie', cemeteryAddress2: '',
mapProvince: 'ON', cemeteryCity: 'Sault Ste. Marie',
mapPostalCode: '', cemeteryProvince: 'ON',
mapPhoneNumber: '' cemeteryPostalCode: '',
cemeteryPhoneNumber: ''
}, },
user user
) )
map = (await getMapFromDatabase(cemeteryId)) as recordTypes.MapRecord cemetery = (await getCemeteryFromDatabase(cemeteryId)) as recordTypes.Cemetery
} }
mapCache.set(mapCacheKey, map) cemeteryCache.set(mapCacheKey, cemetery)
return map return cemetery
} }
async function importFromMasterCSV(): Promise<void> { async function importFromMasterCSV(): Promise<void> {
@ -347,36 +354,24 @@ async function importFromMasterCSV(): Promise<void> {
try { try {
for (masterRow of cmmaster.data) { for (masterRow of cmmaster.data) {
const map = await getMap({ const cemetery = await getCemetery({
cemetery: masterRow.CM_CEMETERY cemetery: masterRow.CM_CEMETERY
})! })!
const lotName = importData.buildLotName({
cemetery: masterRow.CM_CEMETERY,
block: masterRow.CM_BLOCK,
range1: masterRow.CM_RANGE1,
range2: masterRow.CM_RANGE2,
lot1: masterRow.CM_LOT1,
lot2: masterRow.CM_LOT2,
grave1: masterRow.CM_GRAVE1,
grave2: masterRow.CM_GRAVE2,
interment: masterRow.CM_INTERMENT
})
const burialSiteTypeId = importIds.getburialSiteTypeId({ const burialSiteTypeId = importIds.getburialSiteTypeId({
cemetery: masterRow.CM_CEMETERY cemetery: masterRow.CM_CEMETERY
})! })!
let lotId: number | undefined let burialSiteId: number | undefined
if (masterRow.CM_CEMETERY !== '00') { if (masterRow.CM_CEMETERY !== '00') {
lotId = await addLot( burialSiteId = await addBurialSite(
{ {
lotName, lotName,
burialSiteTypeId, burialSiteTypeId,
burialSiteStatusId: importIds.availableburialSiteStatusId, burialSiteStatusId: importIds.availableBurialSiteStatusId,
cemeteryId: map.cemeteryId!, cemeteryId: cemetery.cemeteryId!,
mapKey: lotName.includes(',') ? lotName.split(',')[0] : lotName, cemeterySvgId: '',
burialSiteLatitude: '', burialSiteLatitude: '',
burialSiteLongitude: '' burialSiteLongitude: ''
}, },
@ -446,7 +441,7 @@ async function importFromMasterCSV(): Promise<void> {
preneedburialSiteContractId = await addBurialSiteContract( preneedburialSiteContractId = await addBurialSiteContract(
{ {
contractTypeId: importIds.preneedOccupancyType.contractTypeId, contractTypeId: importIds.preneedOccupancyType.contractTypeId,
lotId: lotId ?? '', lotId: burialSiteId ?? '',
contractStartDateString: preneedcontractStartDateString, contractStartDateString: preneedcontractStartDateString,
contractEndDateString, contractEndDateString,
contractTypeFieldIds: '' contractTypeFieldIds: ''
@ -478,7 +473,8 @@ async function importFromMasterCSV(): Promise<void> {
await addBurialSiteContractComment( await addBurialSiteContractComment(
{ {
burialSiteContractId: preneedburialSiteContractId, burialSiteContractId: preneedburialSiteContractId,
burialSiteContractCommentDateString: preneedcontractStartDateString, burialSiteContractCommentDateString:
preneedcontractStartDateString,
burialSiteContractCommentTimeString: '00:00', burialSiteContractCommentTimeString: '00:00',
burialSiteContractComment: masterRow.CM_REMARK1 burialSiteContractComment: masterRow.CM_REMARK1
}, },
@ -490,7 +486,8 @@ async function importFromMasterCSV(): Promise<void> {
await addBurialSiteContractComment( await addBurialSiteContractComment(
{ {
burialSiteContractId: preneedburialSiteContractId, burialSiteContractId: preneedburialSiteContractId,
burialSiteContractCommentDateString: preneedcontractStartDateString, burialSiteContractCommentDateString:
preneedcontractStartDateString,
burialSiteContractCommentTimeString: '00:00', burialSiteContractCommentTimeString: '00:00',
burialSiteContractComment: masterRow.CM_REMARK2 burialSiteContractComment: masterRow.CM_REMARK2
}, },
@ -502,7 +499,8 @@ async function importFromMasterCSV(): Promise<void> {
await addBurialSiteContractComment( await addBurialSiteContractComment(
{ {
burialSiteContractId: preneedburialSiteContractId, burialSiteContractId: preneedburialSiteContractId,
burialSiteContractCommentDateString: preneedcontractStartDateString, burialSiteContractCommentDateString:
preneedcontractStartDateString,
burialSiteContractCommentTimeString: '00:00', burialSiteContractCommentTimeString: '00:00',
burialSiteContractComment: `Imported Contract #${masterRow.CM_WORK_ORDER}` burialSiteContractComment: `Imported Contract #${masterRow.CM_WORK_ORDER}`
}, },
@ -512,7 +510,7 @@ async function importFromMasterCSV(): Promise<void> {
if (contractEndDateString === '') { if (contractEndDateString === '') {
await updateBurialSiteStatus( await updateBurialSiteStatus(
lotId ?? '', burialSiteId ?? '',
importIds.reservedburialSiteStatusId, importIds.reservedburialSiteStatusId,
user user
) )
@ -549,18 +547,18 @@ async function importFromMasterCSV(): Promise<void> {
deceasedcontractStartDateString = '0001-01-01' deceasedcontractStartDateString = '0001-01-01'
} }
const deceasedcontractEndDateString = lotId const deceasedcontractEndDateString = burialSiteId
? '' ? ''
: deceasedcontractStartDateString : deceasedcontractStartDateString
const occupancyType = lotId const occupancyType = burialSiteId
? importIds.deceasedOccupancyType ? importIds.deceasedOccupancyType
: importIds.cremationOccupancyType : importIds.cremationOccupancyType
deceasedburialSiteContractId = await addBurialSiteContract( deceasedburialSiteContractId = await addBurialSiteContract(
{ {
contractTypeId: occupancyType.contractTypeId, contractTypeId: occupancyType.contractTypeId,
lotId: lotId ?? '', lotId: burialSiteId ?? '',
contractStartDateString: deceasedcontractStartDateString, contractStartDateString: deceasedcontractStartDateString,
contractEndDateString: deceasedcontractEndDateString, contractEndDateString: deceasedcontractEndDateString,
contractTypeFieldIds: '' contractTypeFieldIds: ''
@ -595,11 +593,12 @@ async function importFromMasterCSV(): Promise<void> {
masterRow.CM_DEATH_DAY masterRow.CM_DEATH_DAY
) )
await addOrUpdateLotOccupancyField( await addOrUpdateBurialSiteContractField(
{ {
burialSiteContractId: deceasedburialSiteContractId, burialSiteContractId: deceasedburialSiteContractId,
contractTypeFieldId: occupancyType.ContractTypeFields!.find( contractTypeFieldId: occupancyType.ContractTypeFields!.find(
(occupancyTypeField) => occupancyTypeField.occupancyTypeField === 'Death Date' (occupancyTypeField) =>
occupancyTypeField.occupancyTypeField === 'Death Date'
)!.contractTypeFieldId!, )!.contractTypeFieldId!,
burialSiteContractFieldValue burialSiteContractFieldValue
}, },
@ -608,11 +607,12 @@ async function importFromMasterCSV(): Promise<void> {
} }
if (masterRow.CM_AGE !== '') { if (masterRow.CM_AGE !== '') {
await addOrUpdateLotOccupancyField( await addOrUpdateBurialSiteContractField(
{ {
burialSiteContractId: deceasedburialSiteContractId, burialSiteContractId: deceasedburialSiteContractId,
contractTypeFieldId: occupancyType.ContractTypeFields!.find( contractTypeFieldId: occupancyType.ContractTypeFields!.find(
(occupancyTypeField) => occupancyTypeField.occupancyTypeField === 'Death Age' (occupancyTypeField) =>
occupancyTypeField.occupancyTypeField === 'Death Age'
)!.contractTypeFieldId!, )!.contractTypeFieldId!,
burialSiteContractFieldValue: masterRow.CM_AGE burialSiteContractFieldValue: masterRow.CM_AGE
}, },
@ -623,13 +623,12 @@ async function importFromMasterCSV(): Promise<void> {
if (masterRow.CM_PERIOD !== '') { if (masterRow.CM_PERIOD !== '') {
const period = importData.getDeathAgePeriod(masterRow.CM_PERIOD) const period = importData.getDeathAgePeriod(masterRow.CM_PERIOD)
await addOrUpdateLotOccupancyField( await addOrUpdateBurialSiteContractField(
{ {
burialSiteContractId: deceasedburialSiteContractId, burialSiteContractId: deceasedburialSiteContractId,
contractTypeFieldId: occupancyType.ContractTypeFields!.find( contractTypeFieldId: occupancyType.ContractTypeFields!.find(
(occupancyTypeField) => ( (occupancyTypeField) =>
occupancyTypeField.occupancyTypeField === 'Death Age Period' occupancyTypeField.occupancyTypeField === 'Death Age Period'
)
)!.contractTypeFieldId!, )!.contractTypeFieldId!,
burialSiteContractFieldValue: period burialSiteContractFieldValue: period
}, },
@ -654,14 +653,16 @@ async function importFromMasterCSV(): Promise<void> {
occupantCity: funeralHomeOccupant.occupantCity ?? '', occupantCity: funeralHomeOccupant.occupantCity ?? '',
occupantProvince: funeralHomeOccupant.occupantProvince ?? '', occupantProvince: funeralHomeOccupant.occupantProvince ?? '',
occupantPostalCode: funeralHomeOccupant.occupantPostalCode ?? '', occupantPostalCode: funeralHomeOccupant.occupantPostalCode ?? '',
occupantPhoneNumber: funeralHomeOccupant.occupantPhoneNumber ?? '', occupantPhoneNumber:
occupantEmailAddress: funeralHomeOccupant.occupantEmailAddress ?? '' funeralHomeOccupant.occupantPhoneNumber ?? '',
occupantEmailAddress:
funeralHomeOccupant.occupantEmailAddress ?? ''
}, },
user user
) )
/* /*
addOrUpdateLotOccupancyField( addOrUpdateBurialSiteContractField(
{ {
burialSiteContractId: deceasedburialSiteContractId, burialSiteContractId: deceasedburialSiteContractId,
contractTypeFieldId: allContractTypeFields.find( contractTypeFieldId: allContractTypeFields.find(
@ -683,13 +684,12 @@ async function importFromMasterCSV(): Promise<void> {
masterRow.CM_FUNERAL_DAY masterRow.CM_FUNERAL_DAY
) )
await addOrUpdateLotOccupancyField( await addOrUpdateBurialSiteContractField(
{ {
burialSiteContractId: deceasedburialSiteContractId, burialSiteContractId: deceasedburialSiteContractId,
contractTypeFieldId: occupancyType.ContractTypeFields!.find( contractTypeFieldId: occupancyType.ContractTypeFields!.find(
(occupancyTypeField) => ( (occupancyTypeField) =>
occupancyTypeField.occupancyTypeField === 'Funeral Date' occupancyTypeField.occupancyTypeField === 'Funeral Date'
)
)!.contractTypeFieldId!, )!.contractTypeFieldId!,
burialSiteContractFieldValue burialSiteContractFieldValue
}, },
@ -699,13 +699,12 @@ async function importFromMasterCSV(): Promise<void> {
if (occupancyType.occupancyType !== 'Cremation') { if (occupancyType.occupancyType !== 'Cremation') {
if (masterRow.CM_CONTAINER_TYPE !== '') { if (masterRow.CM_CONTAINER_TYPE !== '') {
await addOrUpdateLotOccupancyField( await addOrUpdateBurialSiteContractField(
{ {
burialSiteContractId: deceasedburialSiteContractId, burialSiteContractId: deceasedburialSiteContractId,
contractTypeFieldId: occupancyType.ContractTypeFields!.find( contractTypeFieldId: occupancyType.ContractTypeFields!.find(
(occupancyTypeField) => ( (occupancyTypeField) =>
occupancyTypeField.occupancyTypeField === 'Container Type' occupancyTypeField.occupancyTypeField === 'Container Type'
)
)!.contractTypeFieldId!, )!.contractTypeFieldId!,
burialSiteContractFieldValue: masterRow.CM_CONTAINER_TYPE burialSiteContractFieldValue: masterRow.CM_CONTAINER_TYPE
}, },
@ -720,13 +719,12 @@ async function importFromMasterCSV(): Promise<void> {
commitalType = 'Graveside' commitalType = 'Graveside'
} }
await addOrUpdateLotOccupancyField( await addOrUpdateBurialSiteContractField(
{ {
burialSiteContractId: deceasedburialSiteContractId, burialSiteContractId: deceasedburialSiteContractId,
contractTypeFieldId: occupancyType.ContractTypeFields!.find( contractTypeFieldId: occupancyType.ContractTypeFields!.find(
(occupancyTypeField) => ( (occupancyTypeField) =>
occupancyTypeField.occupancyTypeField === 'Committal Type' occupancyTypeField.occupancyTypeField === 'Committal Type'
)
)!.contractTypeFieldId!, )!.contractTypeFieldId!,
burialSiteContractFieldValue: commitalType burialSiteContractFieldValue: commitalType
}, },
@ -739,7 +737,8 @@ async function importFromMasterCSV(): Promise<void> {
await addBurialSiteContractComment( await addBurialSiteContractComment(
{ {
burialSiteContractId: deceasedburialSiteContractId, burialSiteContractId: deceasedburialSiteContractId,
burialSiteContractCommentDateString: deceasedcontractStartDateString, burialSiteContractCommentDateString:
deceasedcontractStartDateString,
burialSiteContractCommentTimeString: '00:00', burialSiteContractCommentTimeString: '00:00',
burialSiteContractComment: masterRow.CM_REMARK1 burialSiteContractComment: masterRow.CM_REMARK1
}, },
@ -751,7 +750,8 @@ async function importFromMasterCSV(): Promise<void> {
await addBurialSiteContractComment( await addBurialSiteContractComment(
{ {
burialSiteContractId: deceasedburialSiteContractId, burialSiteContractId: deceasedburialSiteContractId,
burialSiteContractCommentDateString: deceasedcontractStartDateString, burialSiteContractCommentDateString:
deceasedcontractStartDateString,
burialSiteContractCommentTimeString: '00:00', burialSiteContractCommentTimeString: '00:00',
burialSiteContractComment: masterRow.CM_REMARK2 burialSiteContractComment: masterRow.CM_REMARK2
}, },
@ -763,7 +763,8 @@ async function importFromMasterCSV(): Promise<void> {
await addBurialSiteContractComment( await addBurialSiteContractComment(
{ {
burialSiteContractId: deceasedburialSiteContractId, burialSiteContractId: deceasedburialSiteContractId,
burialSiteContractCommentDateString: deceasedcontractStartDateString, burialSiteContractCommentDateString:
deceasedcontractStartDateString,
burialSiteContractCommentTimeString: '00:00', burialSiteContractCommentTimeString: '00:00',
burialSiteContractComment: `Imported Contract #${masterRow.CM_WORK_ORDER}` burialSiteContractComment: `Imported Contract #${masterRow.CM_WORK_ORDER}`
}, },
@ -771,7 +772,11 @@ async function importFromMasterCSV(): Promise<void> {
) )
} }
await updateBurialSiteStatus(lotId ?? '', importIds.takenburialSiteStatusId, user) await updateBurialSiteStatus(
burialSiteId ?? '',
importIds.takenburialSiteStatusId,
user
)
if (masterRow.CM_PRENEED_OWNER !== '') { if (masterRow.CM_PRENEED_OWNER !== '') {
await addBurialSiteContractOccupant( await addBurialSiteContractOccupant(
@ -833,7 +838,7 @@ async function importFromPrepaidCSV(): Promise<void> {
let lot: recordTypes.Lot | undefined let lot: recordTypes.Lot | undefined
if (cemetery !== '') { if (cemetery !== '') {
const map = await getMap({ const map = await getCemetery({
cemetery cemetery
}) })
@ -849,14 +854,14 @@ async function importFromPrepaidCSV(): Promise<void> {
interment: prepaidRow.CMPP_INTERMENT interment: prepaidRow.CMPP_INTERMENT
}) })
lot = await getLotByLotName(lotName) lot = await getBurialSiteByLotName(lotName)
if (!lot) { if (!lot) {
const burialSiteTypeId = importIds.getburialSiteTypeId({ const burialSiteTypeId = importIds.getburialSiteTypeId({
cemetery cemetery
}) })
const lotId = await addLot( const lotId = await addBurialSite(
{ {
lotName, lotName,
burialSiteTypeId, burialSiteTypeId,
@ -869,12 +874,19 @@ async function importFromPrepaidCSV(): Promise<void> {
user user
) )
lot = await getLot(lotId) lot = await getBurialSite(lotId)
} }
} }
if (lot && lot.burialSiteStatusId === importIds.availableburialSiteStatusId) { if (
await updateBurialSiteStatus(lot.lotId, importIds.reservedburialSiteStatusId, user) lot &&
lot.burialSiteStatusId === importIds.availableburialSiteStatusId
) {
await updateBurialSiteStatus(
lot.lotId,
importIds.reservedburialSiteStatusId,
user
)
} }
const contractStartDateString = formatDateString( const contractStartDateString = formatDateString(
@ -916,7 +928,7 @@ async function importFromPrepaidCSV(): Promise<void> {
contractEndDateString: '' contractEndDateString: ''
}, },
user user
); )
await addBurialSiteContractOccupant( await addBurialSiteContractOccupant(
{ {
@ -1197,18 +1209,22 @@ async function importFromWorkOrderCSV(): Promise<void> {
interment: workOrderRow.WO_INTERMENT interment: workOrderRow.WO_INTERMENT
}) })
lot = await getLotByLotName(lotName) lot = await getBurialSiteByLotName(lotName)
if (lot) { if (lot) {
await updateBurialSiteStatus(lot.lotId, importIds.takenburialSiteStatusId, user) await updateBurialSiteStatus(
lot.lotId,
importIds.takenburialSiteStatusId,
user
)
} else { } else {
const map = await getMap({ cemetery: workOrderRow.WO_CEMETERY }) const map = await getCemetery({ cemetery: workOrderRow.WO_CEMETERY })
const burialSiteTypeId = importIds.getburialSiteTypeId({ const burialSiteTypeId = importIds.getburialSiteTypeId({
cemetery: workOrderRow.WO_CEMETERY cemetery: workOrderRow.WO_CEMETERY
}) })
const lotId = await addLot( const lotId = await addBurialSite(
{ {
cemeteryId: map.cemeteryId!, cemeteryId: map.cemeteryId!,
lotName, lotName,
@ -1221,7 +1237,7 @@ async function importFromWorkOrderCSV(): Promise<void> {
user user
) )
lot = await getLot(lotId) lot = await getBurialSite(lotId)
} }
const workOrderContainsLot = workOrder.workOrderLots!.find( const workOrderContainsLot = workOrder.workOrderLots!.find(
@ -1229,7 +1245,7 @@ async function importFromWorkOrderCSV(): Promise<void> {
) )
if (!workOrderContainsLot) { if (!workOrderContainsLot) {
await addWorkOrderLot( await addWorkOrderBurialSite(
{ {
workOrderId: workOrder.workOrderId!, workOrderId: workOrder.workOrderId!,
lotId: lot.lotId lotId: lot.lotId
@ -1289,11 +1305,12 @@ async function importFromWorkOrderCSV(): Promise<void> {
workOrderRow.WO_DEATH_DAY workOrderRow.WO_DEATH_DAY
) )
await addOrUpdateLotOccupancyField( await addOrUpdateBurialSiteContractField(
{ {
burialSiteContractId, burialSiteContractId,
contractTypeFieldId: occupancyType.ContractTypeFields!.find( contractTypeFieldId: occupancyType.ContractTypeFields!.find(
(occupancyTypeField) => occupancyTypeField.occupancyTypeField === 'Death Date' (occupancyTypeField) =>
occupancyTypeField.occupancyTypeField === 'Death Date'
)!.contractTypeFieldId!, )!.contractTypeFieldId!,
burialSiteContractFieldValue burialSiteContractFieldValue
}, },
@ -1302,11 +1319,12 @@ async function importFromWorkOrderCSV(): Promise<void> {
} }
if (workOrderRow.WO_DEATH_PLACE !== '') { if (workOrderRow.WO_DEATH_PLACE !== '') {
await addOrUpdateLotOccupancyField( await addOrUpdateBurialSiteContractField(
{ {
burialSiteContractId, burialSiteContractId,
contractTypeFieldId: occupancyType.ContractTypeFields!.find( contractTypeFieldId: occupancyType.ContractTypeFields!.find(
(occupancyTypeField) => occupancyTypeField.occupancyTypeField === 'Death Place' (occupancyTypeField) =>
occupancyTypeField.occupancyTypeField === 'Death Place'
)!.contractTypeFieldId!, )!.contractTypeFieldId!,
burialSiteContractFieldValue: workOrderRow.WO_DEATH_PLACE burialSiteContractFieldValue: workOrderRow.WO_DEATH_PLACE
}, },
@ -1315,11 +1333,12 @@ async function importFromWorkOrderCSV(): Promise<void> {
} }
if (workOrderRow.WO_AGE !== '') { if (workOrderRow.WO_AGE !== '') {
await addOrUpdateLotOccupancyField( await addOrUpdateBurialSiteContractField(
{ {
burialSiteContractId, burialSiteContractId,
contractTypeFieldId: occupancyType.ContractTypeFields!.find( contractTypeFieldId: occupancyType.ContractTypeFields!.find(
(occupancyTypeField) => occupancyTypeField.occupancyTypeField === 'Death Age' (occupancyTypeField) =>
occupancyTypeField.occupancyTypeField === 'Death Age'
)!.contractTypeFieldId!, )!.contractTypeFieldId!,
burialSiteContractFieldValue: workOrderRow.WO_AGE burialSiteContractFieldValue: workOrderRow.WO_AGE
}, },
@ -1330,13 +1349,12 @@ async function importFromWorkOrderCSV(): Promise<void> {
if (workOrderRow.WO_PERIOD !== '') { if (workOrderRow.WO_PERIOD !== '') {
const period = importData.getDeathAgePeriod(workOrderRow.WO_PERIOD) const period = importData.getDeathAgePeriod(workOrderRow.WO_PERIOD)
await addOrUpdateLotOccupancyField( await addOrUpdateBurialSiteContractField(
{ {
burialSiteContractId, burialSiteContractId,
contractTypeFieldId: occupancyType.ContractTypeFields!.find( contractTypeFieldId: occupancyType.ContractTypeFields!.find(
(occupancyTypeField) => ( (occupancyTypeField) =>
occupancyTypeField.occupancyTypeField === 'Death Age Period' occupancyTypeField.occupancyTypeField === 'Death Age Period'
)
)!.contractTypeFieldId!, )!.contractTypeFieldId!,
burialSiteContractFieldValue: period burialSiteContractFieldValue: period
}, },
@ -1368,7 +1386,7 @@ async function importFromWorkOrderCSV(): Promise<void> {
) )
/* /*
addOrUpdateLotOccupancyField( addOrUpdateBurialSiteContractField(
{ {
burialSiteContractId: burialSiteContractId, burialSiteContractId: burialSiteContractId,
contractTypeFieldId: allContractTypeFields.find((occupancyTypeField) => { contractTypeFieldId: allContractTypeFields.find((occupancyTypeField) => {
@ -1388,11 +1406,12 @@ async function importFromWorkOrderCSV(): Promise<void> {
workOrderRow.WO_FUNERAL_DAY workOrderRow.WO_FUNERAL_DAY
) )
await addOrUpdateLotOccupancyField( await addOrUpdateBurialSiteContractField(
{ {
burialSiteContractId, burialSiteContractId,
contractTypeFieldId: occupancyType.ContractTypeFields!.find( contractTypeFieldId: occupancyType.ContractTypeFields!.find(
(occupancyTypeField) => occupancyTypeField.occupancyTypeField === 'Funeral Date' (occupancyTypeField) =>
occupancyTypeField.occupancyTypeField === 'Funeral Date'
)!.contractTypeFieldId!, )!.contractTypeFieldId!,
burialSiteContractFieldValue burialSiteContractFieldValue
}, },
@ -1402,13 +1421,12 @@ async function importFromWorkOrderCSV(): Promise<void> {
if (occupancyType.occupancyType !== 'Cremation') { if (occupancyType.occupancyType !== 'Cremation') {
if (workOrderRow.WO_CONTAINER_TYPE !== '') { if (workOrderRow.WO_CONTAINER_TYPE !== '') {
await addOrUpdateLotOccupancyField( await addOrUpdateBurialSiteContractField(
{ {
burialSiteContractId, burialSiteContractId,
contractTypeFieldId: occupancyType.ContractTypeFields!.find( contractTypeFieldId: occupancyType.ContractTypeFields!.find(
(occupancyTypeField) => ( (occupancyTypeField) =>
occupancyTypeField.occupancyTypeField === 'Container Type' occupancyTypeField.occupancyTypeField === 'Container Type'
)
)!.contractTypeFieldId!, )!.contractTypeFieldId!,
burialSiteContractFieldValue: workOrderRow.WO_CONTAINER_TYPE burialSiteContractFieldValue: workOrderRow.WO_CONTAINER_TYPE
}, },
@ -1423,13 +1441,12 @@ async function importFromWorkOrderCSV(): Promise<void> {
commitalType = 'Graveside' commitalType = 'Graveside'
} }
await addOrUpdateLotOccupancyField( await addOrUpdateBurialSiteContractField(
{ {
burialSiteContractId, burialSiteContractId,
contractTypeFieldId: occupancyType.ContractTypeFields!.find( contractTypeFieldId: occupancyType.ContractTypeFields!.find(
(occupancyTypeField) => ( (occupancyTypeField) =>
occupancyTypeField.occupancyTypeField === 'Committal Type' occupancyTypeField.occupancyTypeField === 'Committal Type'
)
)!.contractTypeFieldId!, )!.contractTypeFieldId!,
burialSiteContractFieldValue: commitalType burialSiteContractFieldValue: commitalType
}, },

View File

@ -1,14 +1,3 @@
import type { LotOccupancyOccupant } from '../types/recordTypes.js'; import type { LotOccupancyOccupant } from '../types/recordTypes.js';
export declare function buildLotName(lotNamePieces: {
cemetery: string;
block: string;
range1: string;
range2: string;
lot1: string;
lot2: string;
grave1: string;
grave2: string;
interment: string;
}): string;
export declare function getFuneralHomeLotOccupancyOccupantData(funeralHomeKey: string): LotOccupancyOccupant; export declare function getFuneralHomeLotOccupancyOccupantData(funeralHomeKey: string): LotOccupancyOccupant;
export declare function getDeathAgePeriod(legacyDeathAgePeriod: string): string; export declare function getDeathAgePeriod(legacyDeathAgePeriod: string): string;

View File

@ -1,18 +1,6 @@
// eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair
/* eslint-disable @cspell/spellchecker */
import * as importIds from './legacy.importFromCsv.ids.js'; import * as importIds from './legacy.importFromCsv.ids.js';
export function buildLotName(lotNamePieces) {
let lotName = `${lotNamePieces.cemetery}-`;
if (lotNamePieces.block !== '') {
lotName += `B${lotNamePieces.block}-`;
}
if (lotNamePieces.range1 !== '0' || lotNamePieces.range2 !== '') {
lotName += `R${lotNamePieces.range1 === '0' ? '' : lotNamePieces.range1}${lotNamePieces.range2}-`;
}
if (lotNamePieces.lot1 !== '0' || lotNamePieces.lot2 === '') {
lotName += `L${lotNamePieces.lot1}${lotNamePieces.lot2}-`;
}
lotName += `G${lotNamePieces.grave1}${lotNamePieces.grave2}, Interment ${lotNamePieces.interment}`;
return lotName;
}
export function getFuneralHomeLotOccupancyOccupantData(funeralHomeKey) { export function getFuneralHomeLotOccupancyOccupantData(funeralHomeKey) {
switch (funeralHomeKey) { switch (funeralHomeKey) {
case 'AR': { case 'AR': {

View File

@ -1,39 +1,10 @@
// eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair
/* eslint-disable @cspell/spellchecker */
import type { LotOccupancyOccupant } from '../types/recordTypes.js' import type { LotOccupancyOccupant } from '../types/recordTypes.js'
import * as importIds from './legacy.importFromCsv.ids.js' import * as importIds from './legacy.importFromCsv.ids.js'
export function buildLotName(lotNamePieces: {
cemetery: string
block: string
range1: string
range2: string
lot1: string
lot2: string
grave1: string
grave2: string
interment: string
}): string {
let lotName = `${lotNamePieces.cemetery}-`
if (lotNamePieces.block !== '') {
lotName += `B${lotNamePieces.block}-`
}
if (lotNamePieces.range1 !== '0' || lotNamePieces.range2 !== '') {
lotName += `R${lotNamePieces.range1 === '0' ? '' : lotNamePieces.range1}${
lotNamePieces.range2
}-`
}
if (lotNamePieces.lot1 !== '0' || lotNamePieces.lot2 === '') {
lotName += `L${lotNamePieces.lot1}${lotNamePieces.lot2}-`
}
lotName += `G${lotNamePieces.grave1}${lotNamePieces.grave2}, Interment ${lotNamePieces.interment}`
return lotName
}
export function getFuneralHomeLotOccupancyOccupantData( export function getFuneralHomeLotOccupancyOccupantData(
funeralHomeKey: string funeralHomeKey: string
): LotOccupancyOccupant { ): LotOccupancyOccupant {

View File

@ -25,19 +25,19 @@ export function getFeeIdByFeeDescription(feeDescription) {
/* /*
* Lot Occupant Type IDs * Lot Occupant Type IDs
*/ */
export const preneedOwnerLotOccupantTypeId = (await cacheFunctions.getLotOccupantTypeByLotOccupantType('Preneed Owner')) export const preneedOwnerLotOccupantTypeId = (await cacheFunctions.getBurialSiteOccupantTypeByLotOccupantType('Preneed Owner'))
.lotOccupantTypeId; .lotOccupantTypeId;
export const funeralDirectorLotOccupantTypeId = (await cacheFunctions.getLotOccupantTypeByLotOccupantType('Funeral Director')).lotOccupantTypeId; export const funeralDirectorLotOccupantTypeId = (await cacheFunctions.getBurialSiteOccupantTypeByLotOccupantType('Funeral Director')).lotOccupantTypeId;
export const deceasedLotOccupantTypeId = (await cacheFunctions.getLotOccupantTypeByLotOccupantType('Deceased')) export const deceasedLotOccupantTypeId = (await cacheFunctions.getBurialSiteOccupantTypeByLotOccupantType('Deceased'))
.lotOccupantTypeId; .lotOccupantTypeId;
export const purchaserLotOccupantTypeId = (await cacheFunctions.getLotOccupantTypeByLotOccupantType('Purchaser')) export const purchaserLotOccupantTypeId = (await cacheFunctions.getBurialSiteOccupantTypeByLotOccupantType('Purchaser'))
.lotOccupantTypeId; .lotOccupantTypeId;
/* /*
* Lot Status IDs * Lot Status IDs
*/ */
export const availableburialSiteStatusId = (await cacheFunctions.getLotStatusByLotStatus('Available')).burialSiteStatusId; export const availableburialSiteStatusId = (await cacheFunctions.getBurialSiteStatusByLotStatus('Available')).burialSiteStatusId;
export const reservedburialSiteStatusId = (await cacheFunctions.getLotStatusByLotStatus('Reserved')).burialSiteStatusId; export const reservedburialSiteStatusId = (await cacheFunctions.getBurialSiteStatusByLotStatus('Reserved')).burialSiteStatusId;
export const takenburialSiteStatusId = (await cacheFunctions.getLotStatusByLotStatus('Taken')).burialSiteStatusId; export const takenburialSiteStatusId = (await cacheFunctions.getBurialSiteStatusByLotStatus('Taken')).burialSiteStatusId;
/* /*
* Lot Type IDs * Lot Type IDs
*/ */

View File

@ -42,20 +42,20 @@ export function getFeeIdByFeeDescription(feeDescription: string): number {
*/ */
export const preneedOwnerLotOccupantTypeId = export const preneedOwnerLotOccupantTypeId =
(await cacheFunctions.getLotOccupantTypeByLotOccupantType('Preneed Owner'))! (await cacheFunctions.getBurialSiteOccupantTypeByLotOccupantType('Preneed Owner'))!
.lotOccupantTypeId .lotOccupantTypeId
export const funeralDirectorLotOccupantTypeId = export const funeralDirectorLotOccupantTypeId =
(await cacheFunctions.getLotOccupantTypeByLotOccupantType( (await cacheFunctions.getBurialSiteOccupantTypeByLotOccupantType(
'Funeral Director' 'Funeral Director'
))!.lotOccupantTypeId ))!.lotOccupantTypeId
export const deceasedLotOccupantTypeId = export const deceasedLotOccupantTypeId =
(await cacheFunctions.getLotOccupantTypeByLotOccupantType('Deceased'))! (await cacheFunctions.getBurialSiteOccupantTypeByLotOccupantType('Deceased'))!
.lotOccupantTypeId .lotOccupantTypeId
export const purchaserLotOccupantTypeId = export const purchaserLotOccupantTypeId =
(await cacheFunctions.getLotOccupantTypeByLotOccupantType('Purchaser'))! (await cacheFunctions.getBurialSiteOccupantTypeByLotOccupantType('Purchaser'))!
.lotOccupantTypeId .lotOccupantTypeId
/* /*
@ -63,10 +63,10 @@ export const purchaserLotOccupantTypeId =
*/ */
export const availableburialSiteStatusId = export const availableburialSiteStatusId =
(await cacheFunctions.getLotStatusByLotStatus('Available'))!.burialSiteStatusId (await cacheFunctions.getBurialSiteStatusByLotStatus('Available'))!.burialSiteStatusId
export const reservedburialSiteStatusId = export const reservedburialSiteStatusId =
(await cacheFunctions.getLotStatusByLotStatus('Reserved'))!.burialSiteStatusId (await cacheFunctions.getBurialSiteStatusByLotStatus('Reserved'))!.burialSiteStatusId
export const takenburialSiteStatusId = (await cacheFunctions.getLotStatusByLotStatus( export const takenburialSiteStatusId = (await cacheFunctions.getBurialSiteStatusByLotStatus(
'Taken' 'Taken'
))!.burialSiteStatusId ))!.burialSiteStatusId

View File

@ -19,18 +19,18 @@ describe('functions.cache', () => {
const lotStatuses = await cacheFunctions.getBurialSiteStatuses(); const lotStatuses = await cacheFunctions.getBurialSiteStatuses();
assert.ok(lotStatuses.length > 0); assert.ok(lotStatuses.length > 0);
for (const lotStatus of lotStatuses) { for (const lotStatus of lotStatuses) {
const byId = await cacheFunctions.getLotStatusById(lotStatus.burialSiteStatusId); const byId = await cacheFunctions.getBurialSiteStatusById(lotStatus.burialSiteStatusId);
assert.strictEqual(lotStatus.burialSiteStatusId, byId?.burialSiteStatusId); assert.strictEqual(lotStatus.burialSiteStatusId, byId?.burialSiteStatusId);
const byName = await cacheFunctions.getLotStatusByLotStatus(lotStatus.lotStatus); const byName = await cacheFunctions.getBurialSiteStatusByLotStatus(lotStatus.lotStatus);
assert.strictEqual(lotStatus.lotStatus, byName?.lotStatus); assert.strictEqual(lotStatus.lotStatus, byName?.lotStatus);
} }
}); });
it('returns undefined with a bad burialSiteStatusId', async () => { it('returns undefined with a bad burialSiteStatusId', async () => {
const byBadId = await cacheFunctions.getLotStatusById(badId); const byBadId = await cacheFunctions.getBurialSiteStatusById(badId);
assert.ok(byBadId === undefined); assert.ok(byBadId === undefined);
}); });
it('returns undefined with a bad lotStatus', async () => { it('returns undefined with a bad lotStatus', async () => {
const byBadName = await cacheFunctions.getLotStatusByLotStatus(badName); const byBadName = await cacheFunctions.getBurialSiteStatusByLotStatus(badName);
assert.ok(byBadName === undefined); assert.ok(byBadName === undefined);
}); });
}); });
@ -40,14 +40,14 @@ describe('functions.cache', () => {
const lotTypes = await cacheFunctions.getBurialSiteTypes(); const lotTypes = await cacheFunctions.getBurialSiteTypes();
assert.ok(lotTypes.length > 0); assert.ok(lotTypes.length > 0);
for (const lotType of lotTypes) { for (const lotType of lotTypes) {
const byId = await cacheFunctions.getLotTypeById(lotType.burialSiteTypeId); const byId = await cacheFunctions.getBurialSiteTypeById(lotType.burialSiteTypeId);
assert.strictEqual(lotType.burialSiteTypeId, byId?.burialSiteTypeId); assert.strictEqual(lotType.burialSiteTypeId, byId?.burialSiteTypeId);
const byName = await cacheFunctions.getBurialSiteTypesByBurialSiteType(lotType.lotType); const byName = await cacheFunctions.getBurialSiteTypesByBurialSiteType(lotType.lotType);
assert.strictEqual(lotType.lotType, byName?.lotType); assert.strictEqual(lotType.lotType, byName?.lotType);
} }
}); });
it('returns undefined with a bad burialSiteTypeId', async () => { it('returns undefined with a bad burialSiteTypeId', async () => {
const byBadId = await cacheFunctions.getLotTypeById(badId); const byBadId = await cacheFunctions.getBurialSiteTypeById(badId);
assert.ok(byBadId === undefined); assert.ok(byBadId === undefined);
}); });
it('returns undefined with a bad lotType', async () => { it('returns undefined with a bad lotType', async () => {

View File

@ -26,12 +26,12 @@ describe('functions.cache', () => {
assert.ok(lotStatuses.length > 0) assert.ok(lotStatuses.length > 0)
for (const lotStatus of lotStatuses) { for (const lotStatus of lotStatuses) {
const byId = await cacheFunctions.getLotStatusById( const byId = await cacheFunctions.getBurialSiteStatusById(
lotStatus.burialSiteStatusId lotStatus.burialSiteStatusId
) )
assert.strictEqual(lotStatus.burialSiteStatusId, byId?.burialSiteStatusId) assert.strictEqual(lotStatus.burialSiteStatusId, byId?.burialSiteStatusId)
const byName = await cacheFunctions.getLotStatusByLotStatus( const byName = await cacheFunctions.getBurialSiteStatusByLotStatus(
lotStatus.lotStatus lotStatus.lotStatus
) )
assert.strictEqual(lotStatus.lotStatus, byName?.lotStatus) assert.strictEqual(lotStatus.lotStatus, byName?.lotStatus)
@ -39,12 +39,12 @@ describe('functions.cache', () => {
}) })
it('returns undefined with a bad burialSiteStatusId', async () => { it('returns undefined with a bad burialSiteStatusId', async () => {
const byBadId = await cacheFunctions.getLotStatusById(badId) const byBadId = await cacheFunctions.getBurialSiteStatusById(badId)
assert.ok(byBadId === undefined) assert.ok(byBadId === undefined)
}) })
it('returns undefined with a bad lotStatus', async () => { it('returns undefined with a bad lotStatus', async () => {
const byBadName = await cacheFunctions.getLotStatusByLotStatus(badName) const byBadName = await cacheFunctions.getBurialSiteStatusByLotStatus(badName)
assert.ok(byBadName === undefined) assert.ok(byBadName === undefined)
}) })
}) })
@ -58,7 +58,7 @@ describe('functions.cache', () => {
assert.ok(lotTypes.length > 0) assert.ok(lotTypes.length > 0)
for (const lotType of lotTypes) { for (const lotType of lotTypes) {
const byId = await cacheFunctions.getLotTypeById(lotType.burialSiteTypeId) const byId = await cacheFunctions.getBurialSiteTypeById(lotType.burialSiteTypeId)
assert.strictEqual(lotType.burialSiteTypeId, byId?.burialSiteTypeId) assert.strictEqual(lotType.burialSiteTypeId, byId?.burialSiteTypeId)
const byName = await cacheFunctions.getBurialSiteTypesByBurialSiteType( const byName = await cacheFunctions.getBurialSiteTypesByBurialSiteType(
@ -69,7 +69,7 @@ describe('functions.cache', () => {
}) })
it('returns undefined with a bad burialSiteTypeId', async () => { it('returns undefined with a bad burialSiteTypeId', async () => {
const byBadId = await cacheFunctions.getLotTypeById(badId) const byBadId = await cacheFunctions.getBurialSiteTypeById(badId)
assert.ok(byBadId === undefined) assert.ok(byBadId === undefined)
}) })

View File

@ -14,15 +14,6 @@
<script> <script>
window.exports = window.exports || {}; window.exports = window.exports || {};
exports.aliases = { exports.aliases = {
map: "<%= configFunctions.getConfigProperty('aliases.map') %>",
maps: "<%= configFunctions.getConfigProperty('aliases.maps') %>",
lot: "<%= configFunctions.getConfigProperty('aliases.lot') %>",
lots: "<%= configFunctions.getConfigProperty('aliases.lots') %>",
occupancy: "<%= configFunctions.getConfigProperty('aliases.occupancy') %>",
occupancies: "<%= configFunctions.getConfigProperty('aliases.occupancies') %>",
occupancyStartDate: "<%= configFunctions.getConfigProperty('aliases.occupancyStartDate') %>",
occupant: "<%= configFunctions.getConfigProperty('aliases.occupant') %>",
occupants: "<%= configFunctions.getConfigProperty('aliases.occupants') %>",
externalReceiptNumber: "<%= configFunctions.getConfigProperty('aliases.externalReceiptNumber') %>", externalReceiptNumber: "<%= configFunctions.getConfigProperty('aliases.externalReceiptNumber') %>",
workOrderOpenDate: "<%= configFunctions.getConfigProperty('aliases.workOrderOpenDate') %>", workOrderOpenDate: "<%= configFunctions.getConfigProperty('aliases.workOrderOpenDate') %>",
workOrderCloseDate: "<%= configFunctions.getConfigProperty('aliases.workOrderCloseDate') %>" workOrderCloseDate: "<%= configFunctions.getConfigProperty('aliases.workOrderCloseDate') %>"

View File

@ -45,14 +45,14 @@
<span>Work Orders</span> <span>Work Orders</span>
</a> </a>
<a class="navbar-item" href="<%= urlPrefix %>/lotOccupancies" accesskey="2"> <a class="navbar-item" href="<%= urlPrefix %>/contracts" accesskey="2">
<span class="icon mr-1"> <span class="icon mr-1">
<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.getConfigProperty("aliases.occupancies") %></span> <span>Contracts</span>
</a> </a>
<div class="navbar-item has-dropdown"> <div class="navbar-item has-dropdown">
@ -63,17 +63,17 @@
</span> </span>
</a> </a>
<div class="navbar-dropdown"> <div class="navbar-dropdown">
<a class="navbar-item" href="<%= urlPrefix %>/lots" accesskey="3"> <a class="navbar-item" href="<%= urlPrefix %>/burialSites" accesskey="3">
<span class="icon mr-1"> <span class="icon mr-1">
<i class="fas fa-fw fa-vector-square" aria-hidden="true"></i> <i class="fas fa-fw fa-vector-square" aria-hidden="true"></i>
</span> </span>
<span><%= configFunctions.getConfigProperty("aliases.lots") %></span> <span>Burial Sites</span>
</a> </a>
<a class="navbar-item" href="<%= urlPrefix %>/maps" accesskey="4"> <a class="navbar-item" href="<%= urlPrefix %>/cemeteries" accesskey="4">
<span class="icon mr-1"> <span class="icon mr-1">
<i class="far fa-fw fa-map" aria-hidden="true"></i> <i class="far fa-fw fa-map" aria-hidden="true"></i>
</span> </span>
<span><%= configFunctions.getConfigProperty("aliases.maps") %></span> <span>Cemeteries</span>
</a> </a>
<hr class="navbar-divider" /> <hr class="navbar-divider" />
<a class="navbar-item" href="<%= urlPrefix %>/reports"> <a class="navbar-item" href="<%= urlPrefix %>/reports">

View File

@ -4,22 +4,22 @@
<ul> <ul>
<li><a href="<%= urlPrefix %>/dashboard">Home</a></li> <li><a href="<%= urlPrefix %>/dashboard">Home</a></li>
<li> <li>
<a href="<%= urlPrefix %>/maps"> <a href="<%= urlPrefix %>/cemeteries">
<span class="icon is-small"><i class="far fa-map" aria-hidden="true"></i></span> <span class="icon is-small"><i class="far fa-map" aria-hidden="true"></i></span>
<span><%= configFunctions.getConfigProperty("aliases.maps") %></span> <span>Cemeteries</span>
</a> </a>
</li> </li>
<% if (!isCreate) { %> <% if (!isCreate) { %>
<li> <li>
<a href="<%= urlPrefix %>/maps/<%= map.mapId %>" accesskey="v"> <a href="<%= urlPrefix %>/cemeteries/<%= cemetery.cemeteryId %>" accesskey="v">
<%= map.mapName || "(No Name)" %> <%= cemetery.cemeteryName || "(No Name)" %>
</a> </a>
</li> </li>
<% } %> <% } %>
<li class="is-active"> <li class="is-active">
<a href="#" aria-current="page"> <a href="#" aria-current="page">
<% if (isCreate) { %> <% if (isCreate) { %>
Create a New <%= configFunctions.getConfigProperty("aliases.map") %> Create a New Cemetery
<% } else { %> <% } else { %>
Update Update
<% } %> <% } %>
@ -30,9 +30,9 @@
<h1 class="title is-1"> <h1 class="title is-1">
<% if (isCreate) { %> <% if (isCreate) { %>
Create a New <%= configFunctions.getConfigProperty("aliases.map") %> Create a New Cemetery
<% } else { %> <% } else { %>
Update <%= configFunctions.getConfigProperty("aliases.map") %> Update Cemetery
<% } %> <% } %>
</h1> </h1>
@ -40,14 +40,14 @@
<div class="level-left"> <div class="level-left">
<% if (!isCreate) { %> <% if (!isCreate) { %>
<span class="level-item has-text-weight-bold"> <span class="level-item has-text-weight-bold">
<%= map.mapName || "(No Name)" %> <%= cemetery.cemeteryName || "(No Name)" %>
</span> </span>
<% } %> <% } %>
</div> </div>
<div class="level-right"> <div class="level-right">
<% if (isCreate) { %> <% if (isCreate) { %>
<div class="level-item"> <div class="level-item">
<a class="button is-danger is-inverted" href="<%= urlPrefix %>/maps"> <a class="button is-danger is-inverted" href="<%= urlPrefix %>/cemeteries">
Cancel Cancel
</a> </a>
</div> </div>
@ -64,9 +64,9 @@
</div> </div>
<div class="dropdown-menu"> <div class="dropdown-menu">
<div class="dropdown-content"> <div class="dropdown-content">
<a class="dropdown-item" id="button--deleteMap" href="#"> <a class="dropdown-item" id="button--deleteCemetery" href="#">
<span class="icon is-small"><i class="fas fa-trash has-text-danger" aria-hidden="true"></i></span> <span class="icon is-small"><i class="fas fa-trash has-text-danger" aria-hidden="true"></i></span>
<span>Delete <%= configFunctions.getConfigProperty("aliases.map") %></span> <span>Delete Cemetery</span>
</a> </a>
</div> </div>
</div> </div>
@ -74,11 +74,11 @@
</div> </div>
<% } %> <% } %>
<div class="level-item"> <div class="level-item">
<button class="button is-primary is-light" type="submit" form="form--map"> <button class="button is-primary is-light" type="submit" form="form--cemetery">
<span class="icon is-small"><i class="fas fa-save" aria-hidden="true"></i></span> <span class="icon is-small"><i class="fas fa-save" aria-hidden="true"></i></span>
<span> <span>
<%= (isCreate ? "Create": "Update") %> <%= (isCreate ? "Create": "Update") %>
<%= configFunctions.getConfigProperty("aliases.map") %> Cemetery
</span> </span>
</button> </button>
</div> </div>
@ -86,26 +86,33 @@
</div> </div>
<form id="form--map"> <form id="form--cemetery">
<input id="map--mapId" name="mapId" type="hidden" value="<%= map.mapId %>" /> <input id="cemetery--cemeteryId" name="cemeteryId" type="hidden" value="<%= cemetery.cemeteryId %>" />
<div class="columns"> <div class="columns">
<div class="column"> <div class="column">
<div class="panel"> <div class="panel">
<div class="panel-block is-block"> <div class="panel-block is-block">
<div class="field"> <div class="field">
<label class="label" for="map--mapName"><%= configFunctions.getConfigProperty("aliases.map") %> Name</label> <label class="label" for="cemetery--cemeteryName">Cemetery Name</label>
<div class="control"> <div class="control">
<input class="input" id="map--mapName" name="mapName" type="text" <input class="input" id="cemetery--cemeteryName" name="cemeteryName" type="text"
value="<%= map.mapName %>" maxlength="200" required value="<%= cemetery.cemeteryName %>" maxlength="200" required
accesskey="f" accesskey="f"
<%= (isCreate ? " autofocus" : "") %> /> <%= (isCreate ? " autofocus" : "") %> />
</div> </div>
</div> </div>
<div class="field"> <div class="field">
<label class="label" for="map--mapDescription"><%= configFunctions.getConfigProperty("aliases.map") %> Description</label> <label class="label" for="cemetery--cemeteryKey">Cemetery Key</label>
<div class="control"> <div class="control">
<textarea class="textarea" id="map--mapDescription" name="mapDescription"><%= map.mapDescription %></textarea> <input class="input" id="cemetery--cemeteryKey" name="cemeteryKey" type="text"
value="<%= cemetery.cemeteryKey %>" maxlength="20" required />
</div>
</div>
<div class="field">
<label class="label" for="cemetery--cemeteryDescription">Cemetery Description</label>
<div class="control">
<textarea class="textarea" id="cemetery--cemeteryDescription" name="cemeteryDescription"><%= cemetery.cemeteryDescription %></textarea>
</div> </div>
</div> </div>
</div> </div>
@ -116,30 +123,30 @@
<h2 class="panel-heading">Address</h2> <h2 class="panel-heading">Address</h2>
<div class="panel-block is-block"> <div class="panel-block is-block">
<div class="field"> <div class="field">
<label class="label" for="map--mapAddress1">Address</label> <label class="label" for="cemetery--cemeteryAddress1">Address</label>
<div class="control"> <div class="control">
<input class="input" id="map--mapAddress1" name="mapAddress1" type="text" value="<%= map.mapAddress1 %>" maxlength="50" placeholder="Line 1" /> <input class="input" id="cemetery--cemeteryAddress1" name="cemeteryAddress1" type="text" value="<%= cemetery.cemeteryAddress1 %>" maxlength="50" placeholder="Line 1" />
</div> </div>
</div> </div>
<div class="field"> <div class="field">
<div class="control"> <div class="control">
<input class="input" id="map--mapAddress2" name="mapAddress2" type="text" value="<%= map.mapAddress2 %>" maxlength="50" placeholder="Line 2" aria-label="Address Line 2" /> <input class="input" id="cemetery--cemeteryAddress2" name="cemeteryAddress2" type="text" value="<%= cemetery.cemeteryAddress2 %>" maxlength="50" placeholder="Line 2" aria-label="Address Line 2" />
</div> </div>
</div> </div>
<div class="columns"> <div class="columns">
<div class="column is-8"> <div class="column is-8">
<div class="field"> <div class="field">
<label class="label" for="map--mapCity">City</label> <label class="label" for="cemetery--cemeteryCity">City</label>
<div class="control"> <div class="control">
<input class="input" id="map--mapCity" name="mapCity" value="<%= map.mapCity %>" maxlength="20" /> <input class="input" id="cemetery--cemeteryCity" name="cemeteryCity" value="<%= cemetery.cemeteryCity %>" maxlength="20" />
</div> </div>
</div> </div>
</div> </div>
<div class="column"> <div class="column">
<div class="field"> <div class="field">
<label class="label" for="map--mapProvince">Province</label> <label class="label" for="cemetery--cemeteryProvince">Province</label>
<div class="control"> <div class="control">
<input class="input" id="map--mapProvince" name="mapProvince" value="<%= map.mapProvince %>" maxlength="2" /> <input class="input" id="cemetery--cemeteryProvince" name="cemeteryProvince" value="<%= cemetery.cemeteryProvince %>" maxlength="2" />
</div> </div>
</div> </div>
</div> </div>
@ -147,17 +154,17 @@
<div class="columns"> <div class="columns">
<div class="column"> <div class="column">
<div class="field"> <div class="field">
<label class="label" for="map--mapPostalCode">Postal Code</label> <label class="label" for="cemetery--cemeteryPostalCode">Postal Code</label>
<div class="control"> <div class="control">
<input class="input" id="map--mapPostalCode" name="mapPostalCode" value="<%= map.mapPostalCode %>" maxlength="7" /> <input class="input" id="cemetery--cemeteryPostalCode" name="cemeteryPostalCode" value="<%= cemetery.cemeteryPostalCode %>" maxlength="7" />
</div> </div>
</div> </div>
</div> </div>
<div class="column"> <div class="column">
<div class="field"> <div class="field">
<label class="label" for="map--mapPhoneNumber">Phone Number</label> <label class="label" for="cemetery--cemeteryPhoneNumber">Phone Number</label>
<div class="control"> <div class="control">
<input class="input" id="map--mapPhoneNumber" name="mapPhoneNumber" value="<%= map.mapPhoneNumber %>" maxlength="30" /> <input class="input" id="cemetery--cemeteryPhoneNumber" name="cemeteryPhoneNumber" value="<%= cemetery.cemeteryPhoneNumber %>" maxlength="30" />
</div> </div>
</div> </div>
</div> </div>
@ -172,15 +179,15 @@
<h2 class="panel-heading">Geographic Location</h2> <h2 class="panel-heading">Geographic Location</h2>
<div class="panel-block is-block"> <div class="panel-block is-block">
<div class="field"> <div class="field">
<label class="label" for="map--mapLatitude">Latitude</label> <label class="label" for="cemetery--cemeteryLatitude">Latitude</label>
<div class="control"> <div class="control">
<input class="input" id="map--mapLatitude" name="mapLatitude" type="number" min="-90" max="90" step="0.00000001" value="<%= map.mapLatitude %>" /> <input class="input" id="cemetery--cemeteryLatitude" name="cemeteryLatitude" type="number" min="-90" max="90" step="0.00000001" value="<%= cemetery.cemeteryLatitude %>" />
</div> </div>
</div> </div>
<div class="field"> <div class="field">
<label class="label" for="map--mapLongitude">Longitude</label> <label class="label" for="cemetery--cemeteryLongitude">Longitude</label>
<div class="control"> <div class="control">
<input class="input" id="map--mapLongitude" name="mapLongitude" type="number" min="-180" max="180" step="0.00000001" value="<%= map.mapLongitude %>" /> <input class="input" id="cemetery--cemeteryLongitude" name="cemeteryLongitude" type="number" min="-180" max="180" step="0.00000001" value="<%= cemetery.cemeteryLongitude %>" />
</div> </div>
</div> </div>
</div> </div>
@ -191,14 +198,14 @@
<h2 class="panel-heading">Image</h2> <h2 class="panel-heading">Image</h2>
<div class="panel-block is-block"> <div class="panel-block is-block">
<div class="field"> <div class="field">
<label class="label" for="map--mapSVG">SVG File</label> <label class="label" for="cemetery--cemeterySvg">SVG File</label>
<div class="control"> <div class="control">
<div class="select is-fullwidth"> <div class="select is-fullwidth">
<select id="map--mapSVG" name="mapSVG"> <select id="cemetery--cemeterySvg" name="cemeterySvg">
<option value="">(Select a File)</option> <option value="">(Select a File)</option>
<% for (const mapSVG of mapSVGs) { %> <% for (const cemeterySVG of cemeterySVGs) { %>
<option value="<%= mapSVG %>" <%= (map.mapSVG === mapSVG) ? " selected" : "" %>> <option value="<%= cemeterySVG %>" <%= (cemetery.cemeterySvg === cemeterySVG) ? " selected" : "" %>>
<%= mapSVG %> <%= cemeterySVG %>
</option> </option>
<% } %> <% } %>
</select> </select>
@ -214,29 +221,29 @@
</form> </form>
<% if (!isCreate) { %> <% if (!isCreate) { %>
<% const lotSearchUrl = urlPrefix + "/lots?mapId=" + map.mapId; %> <% const burialSiteSearchUrl = urlPrefix + "/burialSites?cemeteryId=" + cemetery.cemeteryId; %>
<div class="panel mt-4"> <div class="panel mt-4">
<div class="panel-heading"> <div class="panel-heading">
<div class="level is-mobile"> <div class="level is-mobile">
<div class="level-left"> <div class="level-left">
<div class="level-item"> <div class="level-item">
<h2 class="title is-5 has-text-weight-bold"> <h2 class="title is-5 has-text-weight-bold">
<%= configFunctions.getConfigProperty("aliases.lot") %> Summaries Burial Site Summaries
<a class="tag is-link ml-2" href="<%= lotSearchUrl %>"> <a class="tag is-link ml-2" href="<%= burialSiteSearchUrl %>">
<%= map.lotCount %> <%= cemetery.burialSiteCount %>
</a> </a>
</h2> </h2>
</div> </div>
</div> </div>
<div class="level-right"> <div class="level-right">
<div class="level-item"> <div class="level-item">
<a class="button is-small is-success has-text-weight-normal" href="<%=urlPrefix %>/lots/new?mapId=<%= map.mapId %>"> <a class="button is-small is-success has-text-weight-normal" href="<%=urlPrefix %>/burialSites/new?cemeteryId=<%= cemetery.cemeteryId %>">
<span class="icon"><i class="fas fa-plus" aria-hidden="true"></i></span> <span class="icon"><i class="fas fa-plus" aria-hidden="true"></i></span>
<span>Create a <%= configFunctions.getConfigProperty("aliases.lot") %></span> <span>Create a Burial Site</span>
</a> </a>
</div> </div>
<div class="level-item"> <div class="level-item">
<a class="button is-small is-link has-text-weight-normal" href="<%=urlPrefix %>/reports/lots-byMapId?mapId=<%= map.mapId %>" download> <a class="button is-small is-link has-text-weight-normal" href="<%=urlPrefix %>/reports/burialSites-byCemeteryId?cemeteryId=<%= cemetery.cemeteryId %>" download>
<span class="icon"><i class="fas fa-download" aria-hidden="true"></i></span> <span class="icon"><i class="fas fa-download" aria-hidden="true"></i></span>
<span>Export All</span> <span>Export All</span>
</a> </a>
@ -245,11 +252,11 @@
</div> </div>
</div> </div>
<div class="panel-block is-block"> <div class="panel-block is-block">
<% if (map.lotCount === 0) { %> <% if (cemetery.burialSiteCount === 0) { %>
<div class="message is-info"> <div class="message is-info">
<p class="message-body"> <p class="message-body">
There are no <%= configFunctions.getConfigProperty("aliases.lots").toLowerCase() %> There are no burial sites
associated with this <%= configFunctions.getConfigProperty("aliases.map").toLowerCase() %>. associated with this cemetery.
</p> </p>
</div> </div>
<% } else { %> <% } else { %>
@ -260,24 +267,24 @@
<tr> <tr>
<th>Type</th> <th>Type</th>
<th class="has-text-right"> <th class="has-text-right">
<%= configFunctions.getConfigProperty("aliases.lot") %> Count Burial Site Count
</th> </th>
<th class="has-text-right">Percentage</th> <th class="has-text-right">Percentage</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<% for (const lotType of lotTypeSummary) { %> <% for (const burialSiteType of burialSiteTypeSummary) { %>
<tr> <tr>
<td> <td>
<a class="has-text-weight-bold" href="<%= lotSearchUrl %>&burialSiteTypeId=<%= lotType.burialSiteTypeId %>"> <a class="has-text-weight-bold" href="<%= burialSiteSearchUrl %>&burialSiteTypeId=<%= burialSiteType.burialSiteTypeId %>">
<%= lotType.lotType %> <%= burialSiteType.burialSiteType %>
</a> </a>
</td> </td>
<td class="has-text-right"> <td class="has-text-right">
<%= lotType.lotCount %> <%= burialSiteType.burialSiteCount %>
</td> </td>
<td class="has-text-right"> <td class="has-text-right">
<%= ((lotType.lotCount / map.lotCount) * 100).toFixed(1) %>% <%= ((burialSiteType.burialSiteCount / cemetery.burialSiteCount) * 100).toFixed(1) %>%
</td> </td>
</tr> </tr>
<% } %> <% } %>
@ -290,24 +297,24 @@
<tr> <tr>
<th>Status</th> <th>Status</th>
<th class="has-text-right"> <th class="has-text-right">
<%= configFunctions.getConfigProperty("aliases.lot") %> Count Burial Site Count
</th> </th>
<th class="has-text-right">Percentage</th> <th class="has-text-right">Percentage</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<% for (const lotStatus of lotStatusSummary) { %> <% for (const burialSiteStatus of burialSiteStatusSummary) { %>
<tr> <tr>
<td> <td>
<a class="has-text-weight-bold" href="<%= lotSearchUrl %>&burialSiteStatusId=<%= lotStatus.burialSiteStatusId %>"> <a class="has-text-weight-bold" href="<%= burialSiteSearchUrl %>&burialSiteStatusId=<%= burialSiteStatus.burialSiteStatusId %>">
<%= lotStatus.lotStatus %> <%= burialSiteStatus.burialSiteStatus %>
</a> </a>
</td> </td>
<td class="has-text-right"> <td class="has-text-right">
<%= lotStatus.lotCount %> <%= burialSiteStatus.burialSiteCount %>
</td> </td>
<td class="has-text-right"> <td class="has-text-right">
<%= ((lotStatus.lotCount / map.lotCount) * 100).toFixed(1) %>% <%= ((burialSiteStatus.burialSiteCount / cemetery.burialSiteCount) * 100).toFixed(1) %>%
</td> </td>
</tr> </tr>
<% } %> <% } %>
@ -322,6 +329,6 @@
<%- include('_footerA'); -%> <%- include('_footerA'); -%>
<script src="<%= urlPrefix %>/javascripts/mapEdit.js"></script> <script src="<%= urlPrefix %>/javascripts/cemetery.edit.js"></script>
<%- include('_footerB'); -%> <%- include('_footerB'); -%>

View File

@ -6,7 +6,7 @@
<li class="is-active"> <li class="is-active">
<a href="#" aria-current="page"> <a href="#" aria-current="page">
<span class="icon is-small"><i class="far fa-map" aria-hidden="true"></i></span> <span class="icon is-small"><i class="far fa-map" aria-hidden="true"></i></span>
<span><%= configFunctions.getConfigProperty("aliases.maps") %></span> <span>Cemeteries</span>
</a> </a>
</li> </li>
</ul> </ul>
@ -15,11 +15,11 @@
<div class="columns is-vcentered"> <div class="columns is-vcentered">
<div class="column"> <div class="column">
<h1 class="title is-1"> <h1 class="title is-1">
Find a <%= configFunctions.getConfigProperty("aliases.map") %> Find a Cemetery
</h1> </h1>
</div> </div>
<div class="column has-text-right is-narrow"> <div class="column has-text-right is-narrow">
<a class="button" href="<%= urlPrefix %>/reports/maps-formatted" target="_blank" download> <a class="button" href="<%= urlPrefix %>/reports/cemeteries-formatted" target="_blank" download>
<span class="icon is-small"><i class="fas fa-download" aria-hidden="true"></i></span> <span class="icon is-small"><i class="fas fa-download" aria-hidden="true"></i></span>
<span>Export</span> <span>Export</span>
</a> </a>
@ -29,11 +29,11 @@
<% 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" <a class="button is-circle is-primary has-tooltip-left"
data-tooltip="Create a New <%= configFunctions.getConfigProperty("aliases.map") %>" data-tooltip="Create a New Cemetery"
href="<%= urlPrefix %>/maps/new" href="<%= urlPrefix %>/cemeteries/new"
accesskey="n"> accesskey="n">
<i class="fas fa-plus" aria-hidden="true"></i> <i class="fas fa-plus" aria-hidden="true"></i>
<span class="sr-only">Create a New <%= configFunctions.getConfigProperty("aliases.map") %></span> <span class="sr-only">Create a New Cemetery</span>
</a> </a>
</div> </div>
<% } %> <% } %>
@ -42,8 +42,8 @@
<form id="form--searchFilters"> <form id="form--searchFilters">
<div class="field"> <div class="field">
<div class="control has-icons-left"> <div class="control has-icons-left">
<input class="input" id="searchFilter--map" type="text" <input class="input" id="searchFilter--cemetery" type="text"
placeholder="Search <%= configFunctions.getConfigProperty("aliases.map").toLowerCase() %> name, description, and address" placeholder="Search cemetery name, description, and address"
accesskey="f" /> accesskey="f" />
<span class="icon is-small is-left"> <span class="icon is-small is-left">
<i class="fas fa-search" aria-hidden="true"></i> <i class="fas fa-search" aria-hidden="true"></i>
@ -58,8 +58,8 @@
<%- include('_footerA'); -%> <%- include('_footerA'); -%>
<script> <script>
exports.maps = <%- JSON.stringify(maps) %>; exports.cemeteries = <%- JSON.stringify(cemeteries) %>;
</script> </script>
<script src="<%= urlPrefix %>/javascripts/mapSearch.js"></script> <script src="<%= urlPrefix %>/javascripts/cemetery.search.js"></script>
<%- include('_footerB'); -%> <%- include('_footerB'); -%>

View File

@ -6,42 +6,42 @@
<li> <li>
<a href="<%= urlPrefix %>/maps"> <a href="<%= urlPrefix %>/maps">
<span class="icon is-small"><i class="far fa-map" aria-hidden="true"></i></span> <span class="icon is-small"><i class="far fa-map" aria-hidden="true"></i></span>
<span><%= configFunctions.getConfigProperty("aliases.maps") %></span> <span>Cemeteries</span>
</a> </a>
</li> </li>
<li class="is-active"> <li class="is-active">
<a href="#" aria-current="page"> <a href="#" aria-current="page">
<%= map.mapName || "(No Name)" %> <%= cemetery.cemeteryName || "(No Name)" %>
</a> </a>
</li> </li>
</ul> </ul>
</nav> </nav>
<h1 class="title is-1"> <h1 class="title is-1">
<%= map.mapName || "(No Name)" %> <%= cemetery.cemeteryName || "(No Name)" %>
</h1> </h1>
<div class="level is-fixed-bottom is-mobile has-background-white has-shadow is-hidden-print"> <div class="level is-fixed-bottom is-mobile has-background-white has-shadow is-hidden-print">
<div class="level-left"> <div class="level-left">
<span class="level-item has-text-weight-bold"> <span class="level-item has-text-weight-bold">
<%= map.mapName || "(No Name)" %> <%= cemetery.cemeteryName || "(No Name)" %>
</span> </span>
</div> </div>
<div class="level-right"> <div class="level-right">
<div class="level-item"> <div class="level-item">
<a class="button is-link is-outlined has-tooltip-left" <a class="button is-link is-outlined has-tooltip-left"
data-tooltip="Previous <%= configFunctions.getConfigProperty("aliases.map") %>" data-tooltip="Previous Cemetery"
href="<%= urlPrefix %>/maps/<%= map.mapId %>/previous" href="<%= urlPrefix %>/cemeteries/<%= cemetery.cemeteryId %>/previous"
accesskey=","> accesskey=",">
<i class="fas fa-arrow-left" aria-hidden="true"></i> <i class="fas fa-arrow-left" aria-hidden="true"></i>
<span class="sr-only">Previous <%= configFunctions.getConfigProperty("aliases.map") %></span> <span class="sr-only">Previous Cemetery</span>
</a> </a>
</div> </div>
<div class="level-item"> <div class="level-item">
<a class="button is-link has-tooltip-left" <a class="button is-link has-tooltip-left"
data-tooltip="Next <%= configFunctions.getConfigProperty("aliases.map") %>" data-tooltip="Next Cemetery"
href="<%= urlPrefix %>/maps/<%= map.mapId %>/next" href="<%= urlPrefix %>/cemeteries/<%= cemetery.cemeteryId %>/next"
accesskey="."> accesskey=".">
<span>Next</span> <span>Next</span>
<span class="icon"><i class="fas fa-arrow-right" aria-hidden="true"></i></span> <span class="icon"><i class="fas fa-arrow-right" aria-hidden="true"></i></span>
@ -50,7 +50,7 @@
<% if (user.userProperties.canUpdate) { %> <% if (user.userProperties.canUpdate) { %>
<div class="level-item"> <div class="level-item">
<a class="button is-primary" <a class="button is-primary"
href="<%= urlPrefix %>/maps/<%= map.mapId %>/edit" href="<%= urlPrefix %>/cemeteries/<%= cemetery.cemeteryId %>/edit"
accesskey="e"> accesskey="e">
<span class="icon"><i class="fas fa-pencil-alt" aria-hidden="true"></i></span> <span class="icon"><i class="fas fa-pencil-alt" aria-hidden="true"></i></span>
<span>Switch to Edit Mode</span> <span>Switch to Edit Mode</span>
@ -63,27 +63,27 @@
<div class="panel"> <div class="panel">
<div class="panel-block is-block"> <div class="panel-block is-block">
<div class="columns"> <div class="columns">
<% if (map.mapDescription && map.mapDescription !== "") { %> <% if (cemetery.cemeteryDescription && cemetery.cemeteryDescription !== "") { %>
<div class="column"> <div class="column">
<strong>Description</strong><br /> <strong>Description</strong><br />
<%= map.mapDescription %> <%= cemetery.cemeteryDescription %>
</div> </div>
<% } %> <% } %>
<div class="column"> <div class="column">
<strong>Address</strong><br /> <strong>Address</strong><br />
<% if (map.mapAddress1 !== "") { %> <% if (cemetery.cemeteryAddress1 !== "") { %>
<%= map.mapAddress1 %><br /> <%= cemetery.cemeteryAddress1 %><br />
<% } %> <% } %>
<% if (map.mapAddress2 !== "") { %> <% if (cemetery.cemeteryAddress2 !== "") { %>
<%= map.mapAddress2 %><br /> <%= cemetery.cemeteryAddress2 %><br />
<% } %> <% } %>
<%= map.mapCity %>, <%= map.mapProvince %><br /> <%= cemetery.cemeteryCity %>, <%= cemetery.cemeteryProvince %><br />
<%= map.mapPostalCode %> <%= cemetery.cemeteryPostalCode %>
</div> </div>
<% if (map.mapPhoneNumber !== "") { %> <% if (cemetery.cemeteryPhoneNumber !== "") { %>
<div class="column"> <div class="column">
<strong>Phone Number</strong><br /> <strong>Phone Number</strong><br />
<%= map.mapPhoneNumber %> <%= cemetery.cemeteryPhoneNumber %>
</div> </div>
<% } %> <% } %>
</div> </div>
@ -95,11 +95,11 @@
<div class="panel"> <div class="panel">
<h2 class="panel-heading">Geographic Location</h2> <h2 class="panel-heading">Geographic Location</h2>
<div class="panel-block is-block"> <div class="panel-block is-block">
<% if (map.mapLatitude && map.mapLongitude) { %> <% if (cemetery.cemeteryLatitude && cemetery.cemeteryLongitude) { %>
<div id="map--leaflet" data-map-latitude="<%= map.mapLatitude %>" data-map-longitude="<%= map.mapLongitude %>" style="height:300px"></div> <div id="cemetery--leaflet" data-cemetery-latitude="<%= cemetery.cemeteryLatitude %>" data-cemetery-longitude="<%= cemetery.cemeteryLongitude %>" style="height:300px"></div>
<% } else { %> <% } else { %>
<div class="message is-info"> <div class="message is-info">
<p class="message-body">There are no geographic coordinates associated with this <%= configFunctions.getConfigProperty("aliases.map").toLowerCase() %>.</p> <p class="message-body">There are no geographic coordinates associated with this cemetery.</p>
</div> </div>
<% } %> <% } %>
</div> </div>
@ -109,14 +109,14 @@
<div class="panel"> <div class="panel">
<h2 class="panel-heading">Image</h2> <h2 class="panel-heading">Image</h2>
<div class="panel-block is-block"> <div class="panel-block is-block">
<% if (map.mapSVG) { %> <% if (cemetery.cemeterySvg) { %>
<% const imageURL = urlPrefix + "/images/maps/" + map.mapSVG %> <% const imageURL = urlPrefix + "/images/cemeteries/" + cemetery.cemeterySvg %>
<a class="image" href="<%= urlPrefix %>/images/maps/<%= map.mapSVG %>" target="_blank"> <a class="image" href="<%= urlPrefix %>/images/cemeteries/<%= cemetery.cemeterySvg %>" target="_blank">
<%- include('../public/images/maps/' + map.mapSVG); -%> <%- include('../public/images/cemeteries/' + cemetery.cemeterySvg); -%>
</a> </a>
<% } else { %> <% } else { %>
<div class="message is-info"> <div class="message is-info">
<p class="message-body">There are no image associated with this <%= configFunctions.getConfigProperty("aliases.map").toLowerCase() %>.</p> <p class="message-body">There are no image associated with this cemetery.</p>
</div> </div>
<% } %> <% } %>
</div> </div>
@ -124,23 +124,23 @@
</div> </div>
</div> </div>
<% const lotSearchUrl = urlPrefix + "/lots?mapId=" + map.mapId; %> <% const burialSiteSearchUrl = urlPrefix + "/burialSites?cemeteryId=" + cemetery.cemeteryId; %>
<div class="panel"> <div class="panel">
<div class="panel-heading"> <div class="panel-heading">
<div class="level is-mobile"> <div class="level is-mobile">
<div class="level-left"> <div class="level-left">
<div class="level-item"> <div class="level-item">
<h2 class="title is-5 has-text-weight-bold"> <h2 class="title is-5 has-text-weight-bold">
<%= configFunctions.getConfigProperty("aliases.lot") %> Summaries Burial Site Summaries
<a class="tag is-link ml-2" href="<%= lotSearchUrl %>"> <a class="tag is-link ml-2" href="<%= burialSiteSearchUrl %>">
<%= map.lotCount %> <%= cemetery.burialSiteCount %>
</a> </a>
</h2> </h2>
</div> </div>
</div> </div>
<div class="level-right"> <div class="level-right">
<div class="level-item"> <div class="level-item">
<a class="button is-small is-link has-text-weight-normal" href="<%=urlPrefix %>/reports/lots-byMapId?mapId=<%= map.mapId %>" download> <a class="button is-small is-link has-text-weight-normal" href="<%=urlPrefix %>/reports/burialSites-byCemeteryId?cemeteryId=<%= cemetery.cemeteryId %>" download>
<span class="icon"><i class="fas fa-download" aria-hidden="true"></i></span> <span class="icon"><i class="fas fa-download" aria-hidden="true"></i></span>
<span>Export All</span> <span>Export All</span>
</a> </a>
@ -149,11 +149,10 @@
</div> </div>
</div> </div>
<div class="panel-block is-block"> <div class="panel-block is-block">
<% if (map.lotCount === 0) { %> <% if (cemetery.burialSiteCount === 0) { %>
<div class="message is-info"> <div class="message is-info">
<p class="message-body"> <p class="message-body">
There are no <%= configFunctions.getConfigProperty("aliases.lots").toLowerCase() %> There are no burial sites associated with this cemetery.
associated with this <%= configFunctions.getConfigProperty("aliases.map").toLowerCase() %>.
</p> </p>
</div> </div>
<% } else { %> <% } else { %>
@ -164,24 +163,24 @@
<tr> <tr>
<th>Type</th> <th>Type</th>
<th class="has-text-right"> <th class="has-text-right">
<%= configFunctions.getConfigProperty("aliases.lot") %> Count Burial Site Count
</th> </th>
<th class="has-text-right">Percentage</th> <th class="has-text-right">Percentage</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<% for (const lotType of lotTypeSummary) { %> <% for (const burialSiteType of burialSiteTypeSummary) { %>
<tr> <tr>
<td> <td>
<a class="has-text-weight-bold" href="<%= lotSearchUrl %>&burialSiteTypeId=<%= lotType.burialSiteTypeId %>"> <a class="has-text-weight-bold" href="<%= lotSearchUrl %>&burialSiteTypeId=<%= burialSiteType.burialSiteTypeId %>">
<%= lotType.lotType %> <%= burialSiteType.burialSiteType %>
</a> </a>
</td> </td>
<td class="has-text-right"> <td class="has-text-right">
<%= lotType.lotCount %> <%= burialSiteType.burialSiteCount %>
</td> </td>
<td class="has-text-right"> <td class="has-text-right">
<%= ((lotType.lotCount / map.lotCount) * 100).toFixed(1) %>% <%= ((burialSiteType.burialSiteCount / cemetery.burialSiteCount) * 100).toFixed(1) %>%
</td> </td>
</tr> </tr>
<% } %> <% } %>
@ -194,24 +193,24 @@
<tr> <tr>
<th>Status</th> <th>Status</th>
<th class="has-text-right"> <th class="has-text-right">
<%= configFunctions.getConfigProperty("aliases.lot") %> Count Burial Site Count
</th> </th>
<th class="has-text-right">Percentage</th> <th class="has-text-right">Percentage</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<% for (const lotStatus of lotStatusSummary) { %> <% for (const burialSiteStatus of burialSiteStatusSummary) { %>
<tr> <tr>
<td> <td>
<a class="has-text-weight-bold" href="<%= lotSearchUrl %>&burialSiteStatusId=<%= lotStatus.burialSiteStatusId %>"> <a class="has-text-weight-bold" href="<%= lotSearchUrl %>&burialSiteStatusId=<%= burialSiteStatus.burialSiteStatusId %>">
<%= lotStatus.lotStatus %> <%= burialSiteStatus.burialSiteStatus %>
</a> </a>
</td> </td>
<td class="has-text-right"> <td class="has-text-right">
<%= lotStatus.lotCount %> <%= burialSiteStatus.burialSiteCount %>
</td> </td>
<td class="has-text-right"> <td class="has-text-right">
<%= ((lotStatus.lotCount / map.lotCount) * 100).toFixed(1) %>% <%= ((burialSiteStatus.burialSiteCount / map.burialSiteCount) * 100).toFixed(1) %>%
</td> </td>
</tr> </tr>
<% } %> <% } %>
@ -225,6 +224,6 @@
<%- include('_footerA'); -%> <%- include('_footerA'); -%>
<script src="<%= urlPrefix %>/javascripts/mapView.js"></script> <script src="<%= urlPrefix %>/javascripts/cemetery.view.js"></script>
<%- include('_footerB'); -%> <%- include('_footerB'); -%>

View File

@ -59,25 +59,24 @@
<%= milestone.workOrderNumber %> <%= milestone.workOrderNumber %>
</a><br /> </a><br />
<% <%
if (milestone.workOrderLots.length > 0) { if (milestone.workOrderBurialSites.length > 0) {
for (const lot of milestone.workOrderLots) { for (const burialSite of milestone.workOrderBurialSites) {
%> %>
<span class="has-tooltip-right" data-tooltip="<%= lot.mapName %>"> <span class="has-tooltip-right" data-tooltip="<%= burialSite.cemeteryName %>">
<i class="fas fa-fw fa-vector-square" aria-label="<%= configFunctions.getConfigProperty("aliases.lot") %>"></i> <i class="fas fa-fw fa-vector-square" aria-label="Burial Site"></i>
<%= lot.lotName %> <%= burialSite.burialSiteName %>
</span><br /> </span><br />
<% <%
} }
} }
if (milestone.workOrderLotOccupancies.length > 0) { if (milestone.workOrderBurialSiteContracts.length > 0) {
for (const occupancy of milestone.workOrderLotOccupancies) { for (const burialSiteContract of milestone.workOrderBurialSiteContracts) {
for (const occupant of occupancy.lotOccupancyOccupants) { for (const interment of burialSiteContract.lotOccupancyInterments) {
%> %>
<span class="has-tooltip-right" data-tooltip="<%= occupant.lotOccupantType %>"> <span class="has-tooltip-right" data-tooltip="Interment">
<i class="fas fa-fw fa-<%= occupant.fontAwesomeIconClass || 'user' %>" aria-label="<%= configFunctions.getConfigProperty("aliases.occupancy") %>"></i> <i class="fas fa-fw fa-user" aria-label="Contract"></i>
<%= occupant.occupantName %> <%= interment.deceasedName %>
<%= occupant.occupantFamilyName %>
</span><br /> </span><br />
<% <%
} }
@ -145,18 +144,17 @@
<span class="fa-layers fa-4x fa-fw" aria-hidden="true"> <span class="fa-layers fa-4x 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>
<% if (lotOccupancyCount > 0) { %> <% if (burialSiteContractCount > 0) { %>
<span class="fa-layers-counter has-background-success"><%= lotOccupancyCount %></span> <span class="fa-layers-counter has-background-success"><%= burialSiteContractCount %></span>
<% } %> <% } %>
</span> </span>
</div> </div>
<a class="media-content" href="<%= urlPrefix %>/lotOccupancies"> <a class="media-content" href="<%= urlPrefix %>/contracts">
<h2 class="title is-4 is-marginless has-text-link"> <h2 class="title is-4 is-marginless has-text-link">
<%= configFunctions.getConfigProperty("aliases.occupancies") %> Contracts
</h2> </h2>
<p> <p>
View and maintain current and past View and maintain current and past contracts.<br />
<%= configFunctions.getConfigProperty("aliases.occupancies").toLowerCase() %>.<br />
<span class="tags has-addons is-invisible is-visible-hover"> <span class="tags has-addons is-invisible is-visible-hover">
<span class="tag is-link is-light">Shortcut</span> <span class="tag is-link is-light">Shortcut</span>
<kbd class="tag">2</kbd> <kbd class="tag">2</kbd>
@ -165,11 +163,11 @@
</a> </a>
</div> </div>
<% if (user.userProperties.canUpdate) { %> <% if (user.userProperties.canUpdate) { %>
<a class="button is-fullwidth is-success is-light" href="<%= urlPrefix %>/lotOccupancies/new"> <a class="button is-fullwidth is-success is-light" href="<%= urlPrefix %>/contracts/new">
<span class="icon"> <span class="icon">
<i class="fas fa-plus" aria-hidden="true"></i> <i class="fas fa-plus" aria-hidden="true"></i>
</span> </span>
<span>New <%= configFunctions.getConfigProperty("aliases.occupancy") %></span> <span>New Contract</span>
</a> </a>
<% } %> <% } %>
</div> </div>
@ -184,14 +182,12 @@
<div class="media-left"> <div class="media-left">
<i class="fas fa-4x fa-fw fa-vector-square" aria-hidden="true"></i> <i class="fas fa-4x fa-fw fa-vector-square" aria-hidden="true"></i>
</div> </div>
<a class="media-content" href="<%= urlPrefix %>/lots"> <a class="media-content" href="<%= urlPrefix %>/burialSites">
<h2 class="title is-4 is-marginless has-text-link"> <h2 class="title is-4 is-marginless has-text-link">
<%= configFunctions.getConfigProperty("aliases.lots") %> Burial Sites
</h2> </h2>
<p> <p>
View and maintain View and maintain burial sites within a cemetery.<br />
<%= configFunctions.getConfigProperty("aliases.lots").toLowerCase() %> within a
<%= configFunctions.getConfigProperty("aliases.map").toLowerCase() %>.<br />
<span class="tags has-addons is-invisible is-visible-hover"> <span class="tags has-addons is-invisible is-visible-hover">
<span class="tag is-link is-light">Shortcut</span> <span class="tag is-link is-light">Shortcut</span>
<kbd class="tag">3</kbd> <kbd class="tag">3</kbd>
@ -200,11 +196,11 @@
</a> </a>
</div> </div>
<% if (user.userProperties.canUpdate) { %> <% if (user.userProperties.canUpdate) { %>
<a class="button is-fullwidth is-success is-light" href="<%= urlPrefix %>/lots/new"> <a class="button is-fullwidth is-success is-light" href="<%= urlPrefix %>/burialSites/new">
<span class="icon"> <span class="icon">
<i class="fas fa-plus" aria-hidden="true"></i> <i class="fas fa-plus" aria-hidden="true"></i>
</span> </span>
<span>New <%= configFunctions.getConfigProperty("aliases.lot") %></span> <span>New Burial Site</span>
</a> </a>
<% } %> <% } %>
</div> </div>
@ -217,12 +213,12 @@
<div class="media-left"> <div class="media-left">
<i class="far fa-4x fa-fw fa-map" aria-hidden="true"></i> <i class="far fa-4x fa-fw fa-map" aria-hidden="true"></i>
</div> </div>
<a class="media-content" href="<%= urlPrefix %>/maps"> <a class="media-content" href="<%= urlPrefix %>/cemeteries">
<h2 class="title is-4 is-marginless has-text-link"> <h2 class="title is-4 is-marginless has-text-link">
<%= configFunctions.getConfigProperty("aliases.maps") %> Cemeteries
</h2> </h2>
<p> <p>
View and maintain <%= configFunctions.getConfigProperty("aliases.maps").toLowerCase() %>. View and maintain cemeteries.
<span class="tags has-addons is-invisible is-visible-hover"> <span class="tags has-addons is-invisible is-visible-hover">
<span class="tag is-link is-light">Shortcut</span> <span class="tag is-link is-light">Shortcut</span>
<kbd class="tag">4</kbd> <kbd class="tag">4</kbd>
@ -231,11 +227,11 @@
</a> </a>
</div> </div>
<% if (user.userProperties.canUpdate) { %> <% if (user.userProperties.canUpdate) { %>
<a class="button is-fullwidth is-success is-light" href="<%= urlPrefix %>/maps/new"> <a class="button is-fullwidth is-success is-light" href="<%= urlPrefix %>/cemeteries/new">
<span class="icon"> <span class="icon">
<i class="fas fa-plus" aria-hidden="true"></i> <i class="fas fa-plus" aria-hidden="true"></i>
</span> </span>
<span>New <%= configFunctions.getConfigProperty("aliases.map") %></span> <span>New Cemetery</span>
</a> </a>
<% } %> <% } %>
</div> </div>
@ -262,6 +258,7 @@
</div> </div>
<div class="column"> <div class="column">
<div class="card is-hover-container"> <div class="card is-hover-container">
<div class="card-content">
<a class="button is-fullwidth is-link is-light has-tooltip-bottom" data-tooltip="Latest Updates, Issue Tracker, Say Hello" <a class="button is-fullwidth is-link is-light has-tooltip-bottom" data-tooltip="Latest Updates, Issue Tracker, Say Hello"
href="https://github.com/cityssm/sunrise-cms" target="_blank" rel="noreferrer"> href="https://github.com/cityssm/sunrise-cms" target="_blank" rel="noreferrer">
<span class="icon"> <span class="icon">
@ -291,11 +288,8 @@
Fee Management Fee Management
</h2> </h2>
<p> <p>
Manage fees for Manage fees for contracts
<%= configFunctions.getConfigProperty("aliases.lot").toLowerCase() %> and specific burial site types.
<%= configFunctions.getConfigProperty("aliases.occupancy").toLowerCase() %>
and specific
<%= configFunctions.getConfigProperty("aliases.lot").toLowerCase() %> types.
</p> </p>
</a> </a>
</div> </div>
@ -308,13 +302,12 @@
<i class="fas fa-cog" data-fa-transform="shrink-8 right-8 down-5" data-fa-glow="10"></i> <i class="fas fa-cog" data-fa-transform="shrink-8 right-8 down-5" data-fa-glow="10"></i>
</span> </span>
</div> </div>
<a class="media-content" href="<%= urlPrefix %>/admin/occupancyTypes"> <a class="media-content" href="<%= urlPrefix %>/admin/contractTypes">
<h2 class="title is-4 is-marginless has-text-link"> <h2 class="title is-4 is-marginless has-text-link">
<%= configFunctions.getConfigProperty("aliases.occupancy") %> Type Management Contract Type Management
</h2> </h2>
<p> <p>
Manage Manage contract types,
<%= configFunctions.getConfigProperty("aliases.occupancy").toLowerCase() %> types,
the fields associated with them, the fields associated with them,
and their available print options. and their available print options.
</p> </p>
@ -329,14 +322,12 @@
<i class="fas fa-cog" data-fa-transform="shrink-8 right-8 down-5" data-fa-glow="10"></i> <i class="fas fa-cog" data-fa-transform="shrink-8 right-8 down-5" data-fa-glow="10"></i>
</span> </span>
</div> </div>
<a class="media-content" href="<%= urlPrefix %>/admin/lotTypes"> <a class="media-content" href="<%= urlPrefix %>/admin/burialSiteTypes">
<h2 class="title is-4 is-marginless has-text-link"> <h2 class="title is-4 is-marginless has-text-link">
<%= configFunctions.getConfigProperty("aliases.lot") %> Type Management Burial Site Type Management
</h2> </h2>
<p> <p>
Manage Manage burial site types and fields associated with them.
<%= configFunctions.getConfigProperty("aliases.lot").toLowerCase() %> types
and fields associated with them.
</p> </p>
</a> </a>
</div> </div>
@ -355,9 +346,8 @@
</h2> </h2>
<p> <p>
Manage simple configuration tables fees for Manage simple configuration tables fees for
work order types, work order types
<%= configFunctions.getConfigProperty("aliases.lot").toLowerCase() %> statuses, and burial site statuses.
and <%= configFunctions.getConfigProperty("aliases.lot").toLowerCase() %> <%= configFunctions.getConfigProperty("aliases.occupant").toLowerCase() %> types.
</p> </p>
</a> </a>
</div> </div>