development
- add latitude and longitude bounds - add purchaser relationship suggestions - clean up dashboard - switch to native node testing - lintingpull/3/head
parent
28fe138fb5
commit
0dbbd3f750
|
|
@ -1,5 +1,9 @@
|
||||||
import { config as baseConfig } from './config.base.js';
|
import { config as baseConfig } from './config.base.js';
|
||||||
export const config = Object.assign({}, baseConfig);
|
export const config = Object.assign({}, baseConfig);
|
||||||
config.settings.provinceDefault = 'ON';
|
config.settings.provinceDefault = 'ON';
|
||||||
|
config.settings.latitudeMax = 56.85;
|
||||||
|
config.settings.latitudeMin = 41.68;
|
||||||
|
config.settings.longitudeMax = -74;
|
||||||
|
config.settings.longitudeMin = -95.15;
|
||||||
config.settings.fees.taxPercentageDefault = 13;
|
config.settings.fees.taxPercentageDefault = 13;
|
||||||
export default config;
|
export default config;
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,12 @@ export const config = Object.assign({}, baseConfig)
|
||||||
|
|
||||||
config.settings.provinceDefault = 'ON'
|
config.settings.provinceDefault = 'ON'
|
||||||
|
|
||||||
|
config.settings.latitudeMax = 56.85
|
||||||
|
config.settings.latitudeMin = 41.68
|
||||||
|
|
||||||
|
config.settings.longitudeMax = -74
|
||||||
|
config.settings.longitudeMin = -95.15
|
||||||
|
|
||||||
config.settings.fees.taxPercentageDefault = 13
|
config.settings.fees.taxPercentageDefault = 13
|
||||||
|
|
||||||
export default config
|
export default config
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ config.settings.burialSites.burialSiteNameSegments = {
|
||||||
maxLength: 1
|
maxLength: 1
|
||||||
},
|
},
|
||||||
2: {
|
2: {
|
||||||
isRequired: true,
|
isRequired: false,
|
||||||
isAvailable: true,
|
isAvailable: true,
|
||||||
label: 'Range',
|
label: 'Range',
|
||||||
minLength: 1,
|
minLength: 1,
|
||||||
|
|
@ -36,6 +36,10 @@ config.settings.burialSites.burialSiteNameSegments = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
config.settings.cityDefault = 'Sault Ste. Marie';
|
config.settings.cityDefault = 'Sault Ste. Marie';
|
||||||
|
config.settings.latitudeMax = 46.75;
|
||||||
|
config.settings.latitudeMin = 46.4;
|
||||||
|
config.settings.longitudeMax = -84.2;
|
||||||
|
config.settings.longitudeMin = -84.5;
|
||||||
config.settings.contracts.prints = [
|
config.settings.contracts.prints = [
|
||||||
'pdf/ssm.cemetery.burialPermit',
|
'pdf/ssm.cemetery.burialPermit',
|
||||||
'pdf/ssm.cemetery.contract'
|
'pdf/ssm.cemetery.contract'
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ config.settings.burialSites.burialSiteNameSegments = {
|
||||||
maxLength: 1
|
maxLength: 1
|
||||||
},
|
},
|
||||||
2: {
|
2: {
|
||||||
isRequired: true,
|
isRequired: false,
|
||||||
isAvailable: true,
|
isAvailable: true,
|
||||||
label: 'Range',
|
label: 'Range',
|
||||||
minLength: 1,
|
minLength: 1,
|
||||||
|
|
@ -43,6 +43,11 @@ config.settings.burialSites.burialSiteNameSegments = {
|
||||||
|
|
||||||
config.settings.cityDefault = 'Sault Ste. Marie'
|
config.settings.cityDefault = 'Sault Ste. Marie'
|
||||||
|
|
||||||
|
config.settings.latitudeMax = 46.75
|
||||||
|
config.settings.latitudeMin = 46.4
|
||||||
|
config.settings.longitudeMax = -84.2
|
||||||
|
config.settings.longitudeMin = -84.5
|
||||||
|
|
||||||
config.settings.contracts.prints = [
|
config.settings.contracts.prints = [
|
||||||
'pdf/ssm.cemetery.burialPermit',
|
'pdf/ssm.cemetery.burialPermit',
|
||||||
'pdf/ssm.cemetery.contract'
|
'pdf/ssm.cemetery.contract'
|
||||||
|
|
|
||||||
|
|
@ -26,9 +26,15 @@ export declare const configDefaultValues: {
|
||||||
'aliases.workOrderCloseDate': string;
|
'aliases.workOrderCloseDate': string;
|
||||||
'settings.cityDefault': string;
|
'settings.cityDefault': string;
|
||||||
'settings.provinceDefault': string;
|
'settings.provinceDefault': string;
|
||||||
|
'settings.latitudeMin': number;
|
||||||
|
'settings.latitudeMax': number;
|
||||||
|
'settings.longitudeMin': number;
|
||||||
|
'settings.longitudeMax': number;
|
||||||
'settings.burialSites.burialSiteNameSegments': ConfigBurialSiteNameSegments;
|
'settings.burialSites.burialSiteNameSegments': ConfigBurialSiteNameSegments;
|
||||||
|
'settings.burialSites.burialSiteNameSegments.includeCemeteryKey': boolean;
|
||||||
'settings.contracts.burialSiteIdIsRequired': boolean;
|
'settings.contracts.burialSiteIdIsRequired': boolean;
|
||||||
'settings.contracts.contractEndDateIsRequired': boolean;
|
'settings.contracts.contractEndDateIsRequired': boolean;
|
||||||
|
'settings.contracts.purchaserRelationships': string[];
|
||||||
'settings.contracts.deathAgePeriods': string[];
|
'settings.contracts.deathAgePeriods': string[];
|
||||||
'settings.contracts.prints': string[];
|
'settings.contracts.prints': string[];
|
||||||
'settings.fees.taxPercentageDefault': number;
|
'settings.fees.taxPercentageDefault': number;
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,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/sunrise-cms.svg',
|
'application.logoURL': '/images/sunrise-cms.svg',
|
||||||
'application.httpPort': 7000,
|
'application.httpPort': 9000,
|
||||||
'application.userDomain': '',
|
'application.userDomain': '',
|
||||||
'application.useTestDatabases': false,
|
'application.useTestDatabases': false,
|
||||||
'application.maximumProcesses': 4,
|
'application.maximumProcesses': 4,
|
||||||
|
|
@ -25,8 +25,13 @@ export const configDefaultValues = {
|
||||||
'aliases.workOrderCloseDate': 'Completion Date',
|
'aliases.workOrderCloseDate': 'Completion Date',
|
||||||
'settings.cityDefault': '',
|
'settings.cityDefault': '',
|
||||||
'settings.provinceDefault': '',
|
'settings.provinceDefault': '',
|
||||||
|
'settings.latitudeMin': -90,
|
||||||
|
'settings.latitudeMax': 90,
|
||||||
|
'settings.longitudeMin': -180,
|
||||||
|
'settings.longitudeMax': 180,
|
||||||
'settings.burialSites.burialSiteNameSegments': {
|
'settings.burialSites.burialSiteNameSegments': {
|
||||||
separator: '-',
|
separator: '-',
|
||||||
|
includeCemeteryKey: false,
|
||||||
segments: {
|
segments: {
|
||||||
1: {
|
1: {
|
||||||
isRequired: true,
|
isRequired: true,
|
||||||
|
|
@ -37,9 +42,23 @@ export const configDefaultValues = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
'settings.burialSites.burialSiteNameSegments.includeCemeteryKey': false,
|
||||||
'settings.contracts.burialSiteIdIsRequired': true,
|
'settings.contracts.burialSiteIdIsRequired': true,
|
||||||
'settings.contracts.contractEndDateIsRequired': false,
|
'settings.contracts.contractEndDateIsRequired': false,
|
||||||
'settings.contracts.deathAgePeriods': ['Years', 'Months', 'Days', 'Stillborn'],
|
'settings.contracts.purchaserRelationships': [
|
||||||
|
'Spouse',
|
||||||
|
'Child',
|
||||||
|
'Parent',
|
||||||
|
'Sibling',
|
||||||
|
'Friend',
|
||||||
|
'Self'
|
||||||
|
],
|
||||||
|
'settings.contracts.deathAgePeriods': [
|
||||||
|
'Years',
|
||||||
|
'Months',
|
||||||
|
'Days',
|
||||||
|
'Stillborn'
|
||||||
|
],
|
||||||
'settings.contracts.prints': ['screen/contract'],
|
'settings.contracts.prints': ['screen/contract'],
|
||||||
'settings.fees.taxPercentageDefault': 0,
|
'settings.fees.taxPercentageDefault': 0,
|
||||||
'settings.workOrders.workOrderNumberLength': 6,
|
'settings.workOrders.workOrderNumberLength': 6,
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,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/sunrise-cms.svg',
|
'application.logoURL': '/images/sunrise-cms.svg',
|
||||||
'application.httpPort': 7000,
|
'application.httpPort': 9000,
|
||||||
'application.userDomain': '',
|
'application.userDomain': '',
|
||||||
'application.useTestDatabases': false,
|
'application.useTestDatabases': false,
|
||||||
'application.maximumProcesses': 4,
|
'application.maximumProcesses': 4,
|
||||||
|
|
@ -42,8 +42,14 @@ export const configDefaultValues = {
|
||||||
'settings.cityDefault': '',
|
'settings.cityDefault': '',
|
||||||
'settings.provinceDefault': '',
|
'settings.provinceDefault': '',
|
||||||
|
|
||||||
|
'settings.latitudeMin': -90,
|
||||||
|
'settings.latitudeMax': 90,
|
||||||
|
'settings.longitudeMin': -180,
|
||||||
|
'settings.longitudeMax': 180,
|
||||||
|
|
||||||
'settings.burialSites.burialSiteNameSegments': {
|
'settings.burialSites.burialSiteNameSegments': {
|
||||||
separator: '-',
|
separator: '-',
|
||||||
|
includeCemeteryKey: false,
|
||||||
segments: {
|
segments: {
|
||||||
1: {
|
1: {
|
||||||
isRequired: true,
|
isRequired: true,
|
||||||
|
|
@ -55,10 +61,24 @@ export const configDefaultValues = {
|
||||||
}
|
}
|
||||||
} as unknown as ConfigBurialSiteNameSegments,
|
} as unknown as ConfigBurialSiteNameSegments,
|
||||||
|
|
||||||
|
'settings.burialSites.burialSiteNameSegments.includeCemeteryKey': false,
|
||||||
|
|
||||||
'settings.contracts.burialSiteIdIsRequired': true,
|
'settings.contracts.burialSiteIdIsRequired': true,
|
||||||
'settings.contracts.contractEndDateIsRequired': false,
|
'settings.contracts.contractEndDateIsRequired': false,
|
||||||
'settings.contracts.deathAgePeriods': ['Years', 'Months', 'Days', 'Stillborn'],
|
'settings.contracts.purchaserRelationships': [
|
||||||
|
'Spouse',
|
||||||
|
'Child',
|
||||||
|
'Parent',
|
||||||
|
'Sibling',
|
||||||
|
'Friend',
|
||||||
|
'Self'
|
||||||
|
],
|
||||||
|
'settings.contracts.deathAgePeriods': [
|
||||||
|
'Years',
|
||||||
|
'Months',
|
||||||
|
'Days',
|
||||||
|
'Stillborn'
|
||||||
|
],
|
||||||
'settings.contracts.prints': ['screen/contract'],
|
'settings.contracts.prints': ['screen/contract'],
|
||||||
|
|
||||||
'settings.fees.taxPercentageDefault': 0,
|
'settings.fees.taxPercentageDefault': 0,
|
||||||
|
|
|
||||||
|
|
@ -1,224 +1,182 @@
|
||||||
import { dateIntegerToString, dateStringToInteger, dateToInteger, timeIntegerToString } from '@cityssm/utils-datetime';
|
import { dateIntegerToString, dateStringToInteger, dateToInteger, timeIntegerToString } from '@cityssm/utils-datetime';
|
||||||
import { acquireConnection } from './pool.js';
|
import { acquireConnection } from './pool.js';
|
||||||
// eslint-disable-next-line complexity
|
const simpleReports = {
|
||||||
|
'burialSiteComments-all': 'select * from BurialSiteComments',
|
||||||
|
'burialSiteFields-all': 'select * from BurialSiteFields',
|
||||||
|
'burialSites-all': 'select * from BurialSites',
|
||||||
|
'burialSiteStatuses-all': 'select * from BurialSiteStatuses',
|
||||||
|
'burialSiteTypeFields-all': 'select * from BurialSiteTypeFields',
|
||||||
|
'burialSiteTypes-all': 'select * from BurialSiteTypes',
|
||||||
|
'cemeteries-all': 'select * from Cemeteries',
|
||||||
|
'cemeteries-formatted': `select cemeteryName,
|
||||||
|
cemeteryDescription,
|
||||||
|
cemeteryAddress1, cemeteryAddress2,
|
||||||
|
cemeteryCity, cemeteryProvince,
|
||||||
|
cemeteryPostalCode,
|
||||||
|
cemeteryPhoneNumber
|
||||||
|
from Cemeteries
|
||||||
|
where recordDelete_timeMillis is null
|
||||||
|
order by cemeteryName`,
|
||||||
|
'contractComments-all': 'select * from ContractComments',
|
||||||
|
'contractFees-all': 'select * from ContractFees',
|
||||||
|
'contractFields-all': 'select * from ContractFields',
|
||||||
|
'contractInterments-all': 'select * from ContractInterments',
|
||||||
|
'contracts-all': 'select * from Contracts',
|
||||||
|
'contractTransactions-all': 'select * from ContractTransactions',
|
||||||
|
'contractTypeFields-all': 'select * from ContractTypeFields',
|
||||||
|
'contractTypes-all': 'select * from ContractTypes',
|
||||||
|
'feeCategories-all': 'select * from FeeCategories',
|
||||||
|
'fees-all': 'select * from Fees',
|
||||||
|
'funeralHomes-all': 'select * from FuneralHomes',
|
||||||
|
'funeralHomes-formatted': `select funeralHomeName,
|
||||||
|
funeralHomeAddress1, funeralHomeAddress2,
|
||||||
|
funeralHomeCity, funeralHomeProvince,
|
||||||
|
funeralHomePostalCode,
|
||||||
|
funeralHomePhoneNumber
|
||||||
|
from FuneralHomes
|
||||||
|
where recordDelete_timeMillis is null`,
|
||||||
|
'intermentContainerTypes-all': 'select * from IntermentContainerTypes',
|
||||||
|
'workOrderBurialSites-all': 'select * from WorkOrderBurialSites',
|
||||||
|
'workOrderComments-all': 'select * from WorkOrderComments',
|
||||||
|
'workOrderMilestones-all': 'select * from WorkOrderMilestones',
|
||||||
|
'workOrderMilestoneTypes-all': 'select * from WorkOrderMilestoneTypes',
|
||||||
|
'workOrders-all': 'select * from WorkOrders',
|
||||||
|
'workOrderTypes-all': 'select * from WorkOrderTypes'
|
||||||
|
};
|
||||||
export default async function getReportData(reportName, reportParameters = {}) {
|
export default async function getReportData(reportName, reportParameters = {}) {
|
||||||
let sql = '';
|
let sql = '';
|
||||||
const sqlParameters = [];
|
const sqlParameters = [];
|
||||||
switch (reportName) {
|
// eslint-disable-next-line security/detect-object-injection
|
||||||
case 'cemeteries-all': {
|
if (simpleReports[reportName] === undefined) {
|
||||||
sql = 'select * from Cemeteries';
|
switch (reportName) {
|
||||||
break;
|
case 'burialSites-byBurialSiteTypeId': {
|
||||||
}
|
sql = `select l.burialSiteId,
|
||||||
case 'cemeteries-formatted': {
|
m.cemeteryName,
|
||||||
sql = `select cemeteryName,
|
l.burialSiteName,
|
||||||
cemeteryDescription,
|
t.burialSiteType,
|
||||||
cemeteryAddress1, cemeteryAddress2,
|
s.burialSiteStatus
|
||||||
cemeteryCity, cemeteryProvince,
|
from BurialSites l
|
||||||
cemeteryPostalCode,
|
left join BurialSiteTypes t on l.burialSiteTypeId = t.burialSiteTypeId
|
||||||
cemeteryPhoneNumber
|
left join BurialSiteStatuses s on l.burialSiteStatusId = s.burialSiteStatusId
|
||||||
from Cemeteries
|
left join Cemeteries m on l.cemeteryId = m.cemeteryId
|
||||||
where recordDelete_timeMillis is null
|
where l.recordDelete_timeMillis is null
|
||||||
order by cemeteryName`;
|
and l.burialSiteTypeId = ?`;
|
||||||
break;
|
sqlParameters.push(reportParameters.burialSiteTypeId);
|
||||||
}
|
break;
|
||||||
case 'burialSites-all': {
|
}
|
||||||
sql = 'select * from BurialSites';
|
case 'burialSites-byBurialSiteStatusId': {
|
||||||
break;
|
sql = `select l.burialSiteId,
|
||||||
}
|
m.cemeteryName,
|
||||||
case 'burialSites-byBurialSiteTypeId': {
|
l.burialSiteName,
|
||||||
sql = `select l.burialSiteId,
|
t.burialSiteType,
|
||||||
m.cemeteryName,
|
s.burialSiteStatus
|
||||||
l.burialSiteName,
|
from BurialSites l
|
||||||
t.burialSiteType,
|
left join BurialSiteTypes t on l.burialSiteTypeId = t.burialSiteTypeId
|
||||||
s.burialSiteStatus
|
left join BurialSiteStatuses s on l.burialSiteStatusId = s.burialSiteStatusId
|
||||||
from BurialSites l
|
left join Cemeteries m on l.cemeteryId = m.cemeteryId
|
||||||
left join BurialSiteTypes t on l.burialSiteTypeId = t.burialSiteTypeId
|
where l.recordDelete_timeMillis is null
|
||||||
left join BurialSiteStatuses s on l.burialSiteStatusId = s.burialSiteStatusId
|
and l.burialSiteStatusId = ?`;
|
||||||
left join Cemeteries m on l.cemeteryId = m.cemeteryId
|
sqlParameters.push(reportParameters.burialSiteStatusId);
|
||||||
where l.recordDelete_timeMillis is null
|
break;
|
||||||
and l.burialSiteTypeId = ?`;
|
}
|
||||||
sqlParameters.push(reportParameters.burialSiteTypeId);
|
case 'burialSites-byCemeteryId': {
|
||||||
break;
|
sql = `select l.burialSiteId,
|
||||||
}
|
m.cemeteryName,
|
||||||
case 'burialSites-byBurialSiteStatusId': {
|
l.burialSiteName,
|
||||||
sql = `select l.burialSiteId,
|
t.burialSiteType,
|
||||||
m.cemeteryName,
|
s.burialSiteStatus
|
||||||
l.burialSiteName,
|
from BurialSites l
|
||||||
t.burialSiteType,
|
left join BurialSiteTypes t on l.burialSiteTypeId = t.burialSiteTypeId
|
||||||
s.burialSiteStatus
|
left join BurialSiteStatuses s on l.burialSiteStatusId = s.burialSiteStatusId
|
||||||
from BurialSites l
|
left join Cemeteries m on l.cemeteryId = m.cemeteryId
|
||||||
left join BurialSiteTypes t on l.burialSiteTypeId = t.burialSiteTypeId
|
where l.recordDelete_timeMillis is null
|
||||||
left join BurialSiteStatuses s on l.burialSiteStatusId = s.burialSiteStatusId
|
and l.cemeteryId = ?`;
|
||||||
left join Cemeteries m on l.cemeteryId = m.cemeteryId
|
sqlParameters.push(reportParameters.cemeteryId);
|
||||||
where l.recordDelete_timeMillis is null
|
break;
|
||||||
and l.burialSiteStatusId = ?`;
|
}
|
||||||
sqlParameters.push(reportParameters.burialSiteStatusId);
|
case 'contracts-current-byCemeteryId': {
|
||||||
break;
|
sql = `select o.contractId,
|
||||||
}
|
l.burialSiteName,
|
||||||
case 'burialSites-byCemeteryId': {
|
m.cemeteryName,
|
||||||
sql = `select l.burialSiteId,
|
ot.contractType,
|
||||||
m.cemeteryName,
|
o.contractStartDate,
|
||||||
l.burialSiteName,
|
o.contractEndDate
|
||||||
t.burialSiteType,
|
from Contracts o
|
||||||
s.burialSiteStatus
|
left join ContractTypes ot on o.contractTypeId = ot.contractTypeId
|
||||||
from BurialSites l
|
left join BurialSites l on o.burialSiteId = l.burialSiteId
|
||||||
left join BurialSiteTypes t on l.burialSiteTypeId = t.burialSiteTypeId
|
left join Cemeteries m on l.cemeteryId = m.cemeteryId
|
||||||
left join BurialSiteStatuses s on l.burialSiteStatusId = s.burialSiteStatusId
|
where o.recordDelete_timeMillis is null
|
||||||
left join Cemeteries m on l.cemeteryId = m.cemeteryId
|
and (o.contractEndDate is null or o.contractEndDate >= ?)
|
||||||
where l.recordDelete_timeMillis is null
|
and l.cemeteryId = ?`;
|
||||||
and l.cemeteryId = ?`;
|
sqlParameters.push(dateToInteger(new Date()), reportParameters.cemeteryId);
|
||||||
sqlParameters.push(reportParameters.cemeteryId);
|
break;
|
||||||
break;
|
}
|
||||||
}
|
case 'contractInterments-byContractId': {
|
||||||
case 'burialSiteComments-all': {
|
sql = `select i.contractId, i.intermentNumber,
|
||||||
sql = 'select * from BurialSiteComments';
|
i.deceasedName, i.deceasedAddress1, i.deceasedAddress2,
|
||||||
break;
|
i.deceasedCity, i.deceasedProvince, i.deceasedPostalCode,
|
||||||
}
|
i.birthDate, i.birthPlace,
|
||||||
case 'burialSiteFields-all': {
|
i.deathDate, i.deathPlace,
|
||||||
sql = 'select * from BurialSiteFields';
|
i.deathAge, i.deathAgePeriod
|
||||||
break;
|
from ContractInterments i
|
||||||
}
|
left join IntermentContainerTypes t on i.intermentContainerTypeId = t.intermentContainerTypeId
|
||||||
case 'contracts-all': {
|
where i.recordDelete_timeMillis is null
|
||||||
sql = 'select * from Contracts';
|
and i.contractId = ?`;
|
||||||
break;
|
sqlParameters.push(reportParameters.contractId);
|
||||||
}
|
break;
|
||||||
case 'contracts-current-byCemeteryId': {
|
}
|
||||||
sql = `select o.contractId,
|
case 'contractTransactions-byTransactionDateString': {
|
||||||
l.burialSiteName,
|
sql = `select t.contractId, t.transactionIndex,
|
||||||
m.cemeteryName,
|
t.transactionDate, t.transactionTime,
|
||||||
ot.contractType,
|
t.transactionAmount,
|
||||||
o.contractStartDate,
|
t.externalReceiptNumber, t.transactionNote
|
||||||
o.contractEndDate
|
from ContractTransactions t
|
||||||
from Contracts o
|
where t.recordDelete_timeMillis is null
|
||||||
left join ContractTypes ot on o.contractTypeId = ot.contractTypeId
|
and t.transactionDate = ?`;
|
||||||
left join BurialSites l on o.burialSiteId = l.burialSiteId
|
sqlParameters.push(dateStringToInteger(reportParameters.transactionDateString));
|
||||||
left join Cemeteries m on l.cemeteryId = m.cemeteryId
|
break;
|
||||||
where o.recordDelete_timeMillis is null
|
}
|
||||||
and (o.contractEndDate is null or o.contractEndDate >= ?)
|
case 'workOrders-open': {
|
||||||
and l.cemeteryId = ?`;
|
sql = `select w.workOrderId, w.workOrderNumber,
|
||||||
sqlParameters.push(dateToInteger(new Date()), reportParameters.cemeteryId);
|
t.workOrderType, w.workOrderDescription,
|
||||||
break;
|
w.workOrderOpenDate,
|
||||||
}
|
m.workOrderMilestoneCount, m.workOrderMilestoneCompletionCount
|
||||||
case 'contractComments-all': {
|
from WorkOrders w
|
||||||
sql = 'select * from ContractComments';
|
left join WorkOrderTypes t on w.workOrderTypeId = t.workOrderTypeId
|
||||||
break;
|
left join (
|
||||||
}
|
select m.workOrderId,
|
||||||
case 'contractFees-all': {
|
count(m.workOrderMilestoneId) as workOrderMilestoneCount,
|
||||||
sql = 'select * from ContractFees';
|
sum(case when m.workOrderMilestoneCompletionDate is null then 0 else 1 end) as workOrderMilestoneCompletionCount
|
||||||
break;
|
from WorkOrderMilestones m
|
||||||
}
|
where m.recordDelete_timeMillis is null
|
||||||
case 'contractFields-all': {
|
group by m.workOrderId
|
||||||
sql = 'select * from ContractFields';
|
) m on w.workOrderId = m.workOrderId
|
||||||
break;
|
where w.recordDelete_timeMillis is null
|
||||||
}
|
and w.workOrderCloseDate is null`;
|
||||||
case 'contractInterments-all': {
|
break;
|
||||||
sql = 'select * from ContractInterments';
|
}
|
||||||
break;
|
case 'workOrderMilestones-byWorkOrderId': {
|
||||||
}
|
sql = `select t.workOrderMilestoneType,
|
||||||
case 'contractTransactions-all': {
|
m.workOrderMilestoneDate,
|
||||||
sql = 'select * from ContractTransactions';
|
m.workOrderMilestoneTime,
|
||||||
break;
|
m.workOrderMilestoneDescription,
|
||||||
}
|
m.workOrderMilestoneCompletionDate,
|
||||||
case 'contractTransactions-byTransactionDateString': {
|
m.workOrderMilestoneCompletionTime
|
||||||
sql = `select t.contractId, t.transactionIndex,
|
|
||||||
t.transactionDate, t.transactionTime,
|
|
||||||
t.transactionAmount,
|
|
||||||
t.externalReceiptNumber, t.transactionNote
|
|
||||||
from ContractTransactions t
|
|
||||||
where t.recordDelete_timeMillis is null
|
|
||||||
and t.transactionDate = ?`;
|
|
||||||
sqlParameters.push(dateStringToInteger(reportParameters.transactionDateString));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'workOrders-all': {
|
|
||||||
sql = 'select * from WorkOrders';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'workOrders-open': {
|
|
||||||
sql = `select w.workOrderId, w.workOrderNumber,
|
|
||||||
t.workOrderType, w.workOrderDescription,
|
|
||||||
w.workOrderOpenDate,
|
|
||||||
m.workOrderMilestoneCount, m.workOrderMilestoneCompletionCount
|
|
||||||
from WorkOrders w
|
|
||||||
left join WorkOrderTypes t on w.workOrderTypeId = t.workOrderTypeId
|
|
||||||
left join (
|
|
||||||
select m.workOrderId,
|
|
||||||
count(m.workOrderMilestoneId) as workOrderMilestoneCount,
|
|
||||||
sum(case when m.workOrderMilestoneCompletionDate is null then 0 else 1 end) as workOrderMilestoneCompletionCount
|
|
||||||
from WorkOrderMilestones m
|
from WorkOrderMilestones m
|
||||||
|
left join WorkOrderMilestoneTypes t on m.workOrderMilestoneTypeId = t.workOrderMilestoneTypeId
|
||||||
where m.recordDelete_timeMillis is null
|
where m.recordDelete_timeMillis is null
|
||||||
group by m.workOrderId
|
and m.workOrderId = ?`;
|
||||||
) m on w.workOrderId = m.workOrderId
|
sqlParameters.push(reportParameters.workOrderId);
|
||||||
where w.recordDelete_timeMillis is null
|
break;
|
||||||
and w.workOrderCloseDate is null`;
|
}
|
||||||
break;
|
default: {
|
||||||
}
|
return undefined;
|
||||||
case 'workOrderComments-all': {
|
}
|
||||||
sql = 'select * from WorkOrderComments';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'workOrderBurialSites-all': {
|
|
||||||
sql = 'select * from WorkOrderBurialSites';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'workOrderMilestones-all': {
|
|
||||||
sql = 'select * from WorkOrderMilestones';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'workOrderMilestones-byWorkOrderId': {
|
|
||||||
sql = `select t.workOrderMilestoneType,
|
|
||||||
m.workOrderMilestoneDate,
|
|
||||||
m.workOrderMilestoneTime,
|
|
||||||
m.workOrderMilestoneDescription,
|
|
||||||
m.workOrderMilestoneCompletionDate,
|
|
||||||
m.workOrderMilestoneCompletionTime
|
|
||||||
from WorkOrderMilestones m
|
|
||||||
left join WorkOrderMilestoneTypes t on m.workOrderMilestoneTypeId = t.workOrderMilestoneTypeId
|
|
||||||
where m.recordDelete_timeMillis is null
|
|
||||||
and m.workOrderId = ?`;
|
|
||||||
sqlParameters.push(reportParameters.workOrderId);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'fees-all': {
|
|
||||||
sql = 'select * from Fees';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'feeCategories-all': {
|
|
||||||
sql = 'select * from FeeCategories';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'burialSiteTypes-all': {
|
|
||||||
sql = 'select * from BurialSiteTypes';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'burialSiteTypeFields-all': {
|
|
||||||
sql = 'select * from BurialSiteTypeFields';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'burialSiteStatuses-all': {
|
|
||||||
sql = 'select * from BurialSiteStatuses';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'contractTypes-all': {
|
|
||||||
sql = 'select * from ContractTypes';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'contractTypeFields-all': {
|
|
||||||
sql = 'select * from ContractTypeFields';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'workOrderTypes-all': {
|
|
||||||
sql = 'select * from WorkOrderTypes';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'workOrderMilestoneTypes-all': {
|
|
||||||
sql = 'select * from WorkOrderMilestoneTypes';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
return undefined;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
sql = simpleReports[reportName];
|
||||||
|
}
|
||||||
const database = await acquireConnection();
|
const database = await acquireConnection();
|
||||||
database.function('userFn_dateIntegerToString', dateIntegerToString);
|
database.function('userFn_dateIntegerToString', dateIntegerToString);
|
||||||
database.function('userFn_timeIntegerToString', timeIntegerToString);
|
database.function('userFn_timeIntegerToString', timeIntegerToString);
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,54 @@ import { acquireConnection } from './pool.js'
|
||||||
|
|
||||||
export type ReportParameters = Record<string, string | number>
|
export type ReportParameters = Record<string, string | number>
|
||||||
|
|
||||||
// eslint-disable-next-line complexity
|
const simpleReports: Record<`${string}-all` | `${string}-formatted`, string> = {
|
||||||
|
'burialSiteComments-all': 'select * from BurialSiteComments',
|
||||||
|
'burialSiteFields-all': 'select * from BurialSiteFields',
|
||||||
|
'burialSites-all': 'select * from BurialSites',
|
||||||
|
'burialSiteStatuses-all': 'select * from BurialSiteStatuses',
|
||||||
|
'burialSiteTypeFields-all': 'select * from BurialSiteTypeFields',
|
||||||
|
'burialSiteTypes-all': 'select * from BurialSiteTypes',
|
||||||
|
|
||||||
|
'cemeteries-all': 'select * from Cemeteries',
|
||||||
|
'cemeteries-formatted': `select cemeteryName,
|
||||||
|
cemeteryDescription,
|
||||||
|
cemeteryAddress1, cemeteryAddress2,
|
||||||
|
cemeteryCity, cemeteryProvince,
|
||||||
|
cemeteryPostalCode,
|
||||||
|
cemeteryPhoneNumber
|
||||||
|
from Cemeteries
|
||||||
|
where recordDelete_timeMillis is null
|
||||||
|
order by cemeteryName`,
|
||||||
|
|
||||||
|
'contractComments-all': 'select * from ContractComments',
|
||||||
|
'contractFees-all': 'select * from ContractFees',
|
||||||
|
'contractFields-all': 'select * from ContractFields',
|
||||||
|
'contractInterments-all': 'select * from ContractInterments',
|
||||||
|
'contracts-all': 'select * from Contracts',
|
||||||
|
'contractTransactions-all': 'select * from ContractTransactions',
|
||||||
|
'contractTypeFields-all': 'select * from ContractTypeFields',
|
||||||
|
'contractTypes-all': 'select * from ContractTypes',
|
||||||
|
'feeCategories-all': 'select * from FeeCategories',
|
||||||
|
'fees-all': 'select * from Fees',
|
||||||
|
|
||||||
|
'funeralHomes-all': 'select * from FuneralHomes',
|
||||||
|
'funeralHomes-formatted': `select funeralHomeName,
|
||||||
|
funeralHomeAddress1, funeralHomeAddress2,
|
||||||
|
funeralHomeCity, funeralHomeProvince,
|
||||||
|
funeralHomePostalCode,
|
||||||
|
funeralHomePhoneNumber
|
||||||
|
from FuneralHomes
|
||||||
|
where recordDelete_timeMillis is null`,
|
||||||
|
|
||||||
|
'intermentContainerTypes-all': 'select * from IntermentContainerTypes',
|
||||||
|
'workOrderBurialSites-all': 'select * from WorkOrderBurialSites',
|
||||||
|
'workOrderComments-all': 'select * from WorkOrderComments',
|
||||||
|
'workOrderMilestones-all': 'select * from WorkOrderMilestones',
|
||||||
|
'workOrderMilestoneTypes-all': 'select * from WorkOrderMilestoneTypes',
|
||||||
|
'workOrders-all': 'select * from WorkOrders',
|
||||||
|
'workOrderTypes-all': 'select * from WorkOrderTypes'
|
||||||
|
}
|
||||||
|
|
||||||
export default async function getReportData(
|
export default async function getReportData(
|
||||||
reportName: string,
|
reportName: string,
|
||||||
reportParameters: ReportParameters = {}
|
reportParameters: ReportParameters = {}
|
||||||
|
|
@ -18,265 +65,163 @@ export default async function getReportData(
|
||||||
let sql = ''
|
let sql = ''
|
||||||
const sqlParameters: unknown[] = []
|
const sqlParameters: unknown[] = []
|
||||||
|
|
||||||
switch (reportName) {
|
// eslint-disable-next-line security/detect-object-injection
|
||||||
case 'cemeteries-all': {
|
if (simpleReports[reportName] === undefined) {
|
||||||
sql = 'select * from Cemeteries'
|
switch (reportName) {
|
||||||
break
|
case 'burialSites-byBurialSiteTypeId': {
|
||||||
}
|
sql = `select l.burialSiteId,
|
||||||
|
m.cemeteryName,
|
||||||
|
l.burialSiteName,
|
||||||
|
t.burialSiteType,
|
||||||
|
s.burialSiteStatus
|
||||||
|
from BurialSites l
|
||||||
|
left join BurialSiteTypes t on l.burialSiteTypeId = t.burialSiteTypeId
|
||||||
|
left join BurialSiteStatuses s on l.burialSiteStatusId = s.burialSiteStatusId
|
||||||
|
left join Cemeteries m on l.cemeteryId = m.cemeteryId
|
||||||
|
where l.recordDelete_timeMillis is null
|
||||||
|
and l.burialSiteTypeId = ?`
|
||||||
|
|
||||||
case 'cemeteries-formatted': {
|
sqlParameters.push(reportParameters.burialSiteTypeId)
|
||||||
sql = `select cemeteryName,
|
|
||||||
cemeteryDescription,
|
|
||||||
cemeteryAddress1, cemeteryAddress2,
|
|
||||||
cemeteryCity, cemeteryProvince,
|
|
||||||
cemeteryPostalCode,
|
|
||||||
cemeteryPhoneNumber
|
|
||||||
from Cemeteries
|
|
||||||
where recordDelete_timeMillis is null
|
|
||||||
order by cemeteryName`
|
|
||||||
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'burialSites-all': {
|
case 'burialSites-byBurialSiteStatusId': {
|
||||||
sql = 'select * from BurialSites'
|
sql = `select l.burialSiteId,
|
||||||
break
|
m.cemeteryName,
|
||||||
}
|
l.burialSiteName,
|
||||||
|
t.burialSiteType,
|
||||||
|
s.burialSiteStatus
|
||||||
|
from BurialSites l
|
||||||
|
left join BurialSiteTypes t on l.burialSiteTypeId = t.burialSiteTypeId
|
||||||
|
left join BurialSiteStatuses s on l.burialSiteStatusId = s.burialSiteStatusId
|
||||||
|
left join Cemeteries m on l.cemeteryId = m.cemeteryId
|
||||||
|
where l.recordDelete_timeMillis is null
|
||||||
|
and l.burialSiteStatusId = ?`
|
||||||
|
|
||||||
case 'burialSites-byBurialSiteTypeId': {
|
sqlParameters.push(reportParameters.burialSiteStatusId)
|
||||||
sql = `select l.burialSiteId,
|
|
||||||
m.cemeteryName,
|
|
||||||
l.burialSiteName,
|
|
||||||
t.burialSiteType,
|
|
||||||
s.burialSiteStatus
|
|
||||||
from BurialSites l
|
|
||||||
left join BurialSiteTypes t on l.burialSiteTypeId = t.burialSiteTypeId
|
|
||||||
left join BurialSiteStatuses s on l.burialSiteStatusId = s.burialSiteStatusId
|
|
||||||
left join Cemeteries m on l.cemeteryId = m.cemeteryId
|
|
||||||
where l.recordDelete_timeMillis is null
|
|
||||||
and l.burialSiteTypeId = ?`
|
|
||||||
|
|
||||||
sqlParameters.push(reportParameters.burialSiteTypeId)
|
break
|
||||||
|
}
|
||||||
|
|
||||||
break
|
case 'burialSites-byCemeteryId': {
|
||||||
}
|
sql = `select l.burialSiteId,
|
||||||
|
m.cemeteryName,
|
||||||
|
l.burialSiteName,
|
||||||
|
t.burialSiteType,
|
||||||
|
s.burialSiteStatus
|
||||||
|
from BurialSites l
|
||||||
|
left join BurialSiteTypes t on l.burialSiteTypeId = t.burialSiteTypeId
|
||||||
|
left join BurialSiteStatuses s on l.burialSiteStatusId = s.burialSiteStatusId
|
||||||
|
left join Cemeteries m on l.cemeteryId = m.cemeteryId
|
||||||
|
where l.recordDelete_timeMillis is null
|
||||||
|
and l.cemeteryId = ?`
|
||||||
|
|
||||||
case 'burialSites-byBurialSiteStatusId': {
|
sqlParameters.push(reportParameters.cemeteryId)
|
||||||
sql = `select l.burialSiteId,
|
|
||||||
m.cemeteryName,
|
|
||||||
l.burialSiteName,
|
|
||||||
t.burialSiteType,
|
|
||||||
s.burialSiteStatus
|
|
||||||
from BurialSites l
|
|
||||||
left join BurialSiteTypes t on l.burialSiteTypeId = t.burialSiteTypeId
|
|
||||||
left join BurialSiteStatuses s on l.burialSiteStatusId = s.burialSiteStatusId
|
|
||||||
left join Cemeteries m on l.cemeteryId = m.cemeteryId
|
|
||||||
where l.recordDelete_timeMillis is null
|
|
||||||
and l.burialSiteStatusId = ?`
|
|
||||||
|
|
||||||
sqlParameters.push(reportParameters.burialSiteStatusId)
|
break
|
||||||
|
}
|
||||||
|
|
||||||
break
|
case 'contracts-current-byCemeteryId': {
|
||||||
}
|
sql = `select o.contractId,
|
||||||
|
l.burialSiteName,
|
||||||
|
m.cemeteryName,
|
||||||
|
ot.contractType,
|
||||||
|
o.contractStartDate,
|
||||||
|
o.contractEndDate
|
||||||
|
from Contracts o
|
||||||
|
left join ContractTypes ot on o.contractTypeId = ot.contractTypeId
|
||||||
|
left join BurialSites l on o.burialSiteId = l.burialSiteId
|
||||||
|
left join Cemeteries m on l.cemeteryId = m.cemeteryId
|
||||||
|
where o.recordDelete_timeMillis is null
|
||||||
|
and (o.contractEndDate is null or o.contractEndDate >= ?)
|
||||||
|
and l.cemeteryId = ?`
|
||||||
|
|
||||||
case 'burialSites-byCemeteryId': {
|
sqlParameters.push(
|
||||||
sql = `select l.burialSiteId,
|
dateToInteger(new Date()),
|
||||||
m.cemeteryName,
|
reportParameters.cemeteryId
|
||||||
l.burialSiteName,
|
|
||||||
t.burialSiteType,
|
|
||||||
s.burialSiteStatus
|
|
||||||
from BurialSites l
|
|
||||||
left join BurialSiteTypes t on l.burialSiteTypeId = t.burialSiteTypeId
|
|
||||||
left join BurialSiteStatuses s on l.burialSiteStatusId = s.burialSiteStatusId
|
|
||||||
left join Cemeteries m on l.cemeteryId = m.cemeteryId
|
|
||||||
where l.recordDelete_timeMillis is null
|
|
||||||
and l.cemeteryId = ?`
|
|
||||||
|
|
||||||
sqlParameters.push(reportParameters.cemeteryId)
|
|
||||||
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'burialSiteComments-all': {
|
|
||||||
sql = 'select * from BurialSiteComments'
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'burialSiteFields-all': {
|
|
||||||
sql = 'select * from BurialSiteFields'
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'contracts-all': {
|
|
||||||
sql = 'select * from Contracts'
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'contracts-current-byCemeteryId': {
|
|
||||||
sql = `select o.contractId,
|
|
||||||
l.burialSiteName,
|
|
||||||
m.cemeteryName,
|
|
||||||
ot.contractType,
|
|
||||||
o.contractStartDate,
|
|
||||||
o.contractEndDate
|
|
||||||
from Contracts o
|
|
||||||
left join ContractTypes ot on o.contractTypeId = ot.contractTypeId
|
|
||||||
left join BurialSites l on o.burialSiteId = l.burialSiteId
|
|
||||||
left join Cemeteries m on l.cemeteryId = m.cemeteryId
|
|
||||||
where o.recordDelete_timeMillis is null
|
|
||||||
and (o.contractEndDate is null or o.contractEndDate >= ?)
|
|
||||||
and l.cemeteryId = ?`
|
|
||||||
|
|
||||||
sqlParameters.push(dateToInteger(new Date()), reportParameters.cemeteryId)
|
|
||||||
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'contractComments-all': {
|
|
||||||
sql = 'select * from ContractComments'
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'contractFees-all': {
|
|
||||||
sql = 'select * from ContractFees'
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'contractFields-all': {
|
|
||||||
sql = 'select * from ContractFields'
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'contractInterments-all': {
|
|
||||||
sql = 'select * from ContractInterments'
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'contractTransactions-all': {
|
|
||||||
sql = 'select * from ContractTransactions'
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'contractTransactions-byTransactionDateString': {
|
|
||||||
sql = `select t.contractId, t.transactionIndex,
|
|
||||||
t.transactionDate, t.transactionTime,
|
|
||||||
t.transactionAmount,
|
|
||||||
t.externalReceiptNumber, t.transactionNote
|
|
||||||
from ContractTransactions t
|
|
||||||
where t.recordDelete_timeMillis is null
|
|
||||||
and t.transactionDate = ?`
|
|
||||||
|
|
||||||
sqlParameters.push(
|
|
||||||
dateStringToInteger(
|
|
||||||
reportParameters.transactionDateString as DateString
|
|
||||||
)
|
)
|
||||||
)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'workOrders-all': {
|
break
|
||||||
sql = 'select * from WorkOrders'
|
}
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'workOrders-open': {
|
case 'contractInterments-byContractId': {
|
||||||
sql = `select w.workOrderId, w.workOrderNumber,
|
sql = `select i.contractId, i.intermentNumber,
|
||||||
t.workOrderType, w.workOrderDescription,
|
i.deceasedName, i.deceasedAddress1, i.deceasedAddress2,
|
||||||
w.workOrderOpenDate,
|
i.deceasedCity, i.deceasedProvince, i.deceasedPostalCode,
|
||||||
m.workOrderMilestoneCount, m.workOrderMilestoneCompletionCount
|
i.birthDate, i.birthPlace,
|
||||||
from WorkOrders w
|
i.deathDate, i.deathPlace,
|
||||||
left join WorkOrderTypes t on w.workOrderTypeId = t.workOrderTypeId
|
i.deathAge, i.deathAgePeriod
|
||||||
left join (
|
from ContractInterments i
|
||||||
select m.workOrderId,
|
left join IntermentContainerTypes t on i.intermentContainerTypeId = t.intermentContainerTypeId
|
||||||
count(m.workOrderMilestoneId) as workOrderMilestoneCount,
|
where i.recordDelete_timeMillis is null
|
||||||
sum(case when m.workOrderMilestoneCompletionDate is null then 0 else 1 end) as workOrderMilestoneCompletionCount
|
and i.contractId = ?`
|
||||||
|
|
||||||
|
sqlParameters.push(reportParameters.contractId)
|
||||||
|
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'contractTransactions-byTransactionDateString': {
|
||||||
|
sql = `select t.contractId, t.transactionIndex,
|
||||||
|
t.transactionDate, t.transactionTime,
|
||||||
|
t.transactionAmount,
|
||||||
|
t.externalReceiptNumber, t.transactionNote
|
||||||
|
from ContractTransactions t
|
||||||
|
where t.recordDelete_timeMillis is null
|
||||||
|
and t.transactionDate = ?`
|
||||||
|
|
||||||
|
sqlParameters.push(
|
||||||
|
dateStringToInteger(
|
||||||
|
reportParameters.transactionDateString as DateString
|
||||||
|
)
|
||||||
|
)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'workOrders-open': {
|
||||||
|
sql = `select w.workOrderId, w.workOrderNumber,
|
||||||
|
t.workOrderType, w.workOrderDescription,
|
||||||
|
w.workOrderOpenDate,
|
||||||
|
m.workOrderMilestoneCount, m.workOrderMilestoneCompletionCount
|
||||||
|
from WorkOrders w
|
||||||
|
left join WorkOrderTypes t on w.workOrderTypeId = t.workOrderTypeId
|
||||||
|
left join (
|
||||||
|
select m.workOrderId,
|
||||||
|
count(m.workOrderMilestoneId) as workOrderMilestoneCount,
|
||||||
|
sum(case when m.workOrderMilestoneCompletionDate is null then 0 else 1 end) as workOrderMilestoneCompletionCount
|
||||||
|
from WorkOrderMilestones m
|
||||||
|
where m.recordDelete_timeMillis is null
|
||||||
|
group by m.workOrderId
|
||||||
|
) m on w.workOrderId = m.workOrderId
|
||||||
|
where w.recordDelete_timeMillis is null
|
||||||
|
and w.workOrderCloseDate is null`
|
||||||
|
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'workOrderMilestones-byWorkOrderId': {
|
||||||
|
sql = `select t.workOrderMilestoneType,
|
||||||
|
m.workOrderMilestoneDate,
|
||||||
|
m.workOrderMilestoneTime,
|
||||||
|
m.workOrderMilestoneDescription,
|
||||||
|
m.workOrderMilestoneCompletionDate,
|
||||||
|
m.workOrderMilestoneCompletionTime
|
||||||
from WorkOrderMilestones m
|
from WorkOrderMilestones m
|
||||||
|
left join WorkOrderMilestoneTypes t on m.workOrderMilestoneTypeId = t.workOrderMilestoneTypeId
|
||||||
where m.recordDelete_timeMillis is null
|
where m.recordDelete_timeMillis is null
|
||||||
group by m.workOrderId
|
and m.workOrderId = ?`
|
||||||
) m on w.workOrderId = m.workOrderId
|
|
||||||
where w.recordDelete_timeMillis is null
|
|
||||||
and w.workOrderCloseDate is null`
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'workOrderComments-all': {
|
sqlParameters.push(reportParameters.workOrderId)
|
||||||
sql = 'select * from WorkOrderComments'
|
break
|
||||||
break
|
}
|
||||||
}
|
|
||||||
|
|
||||||
case 'workOrderBurialSites-all': {
|
default: {
|
||||||
sql = 'select * from WorkOrderBurialSites'
|
return undefined
|
||||||
break
|
}
|
||||||
}
|
|
||||||
|
|
||||||
case 'workOrderMilestones-all': {
|
|
||||||
sql = 'select * from WorkOrderMilestones'
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'workOrderMilestones-byWorkOrderId': {
|
|
||||||
sql = `select t.workOrderMilestoneType,
|
|
||||||
m.workOrderMilestoneDate,
|
|
||||||
m.workOrderMilestoneTime,
|
|
||||||
m.workOrderMilestoneDescription,
|
|
||||||
m.workOrderMilestoneCompletionDate,
|
|
||||||
m.workOrderMilestoneCompletionTime
|
|
||||||
from WorkOrderMilestones m
|
|
||||||
left join WorkOrderMilestoneTypes t on m.workOrderMilestoneTypeId = t.workOrderMilestoneTypeId
|
|
||||||
where m.recordDelete_timeMillis is null
|
|
||||||
and m.workOrderId = ?`
|
|
||||||
sqlParameters.push(reportParameters.workOrderId)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'fees-all': {
|
|
||||||
sql = 'select * from Fees'
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'feeCategories-all': {
|
|
||||||
sql = 'select * from FeeCategories'
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'burialSiteTypes-all': {
|
|
||||||
sql = 'select * from BurialSiteTypes'
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'burialSiteTypeFields-all': {
|
|
||||||
sql = 'select * from BurialSiteTypeFields'
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'burialSiteStatuses-all': {
|
|
||||||
sql = 'select * from BurialSiteStatuses'
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'contractTypes-all': {
|
|
||||||
sql = 'select * from ContractTypes'
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'contractTypeFields-all': {
|
|
||||||
sql = 'select * from ContractTypeFields'
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'workOrderTypes-all': {
|
|
||||||
sql = 'select * from WorkOrderTypes'
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'workOrderMilestoneTypes-all': {
|
|
||||||
sql = 'select * from WorkOrderMilestoneTypes'
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
default: {
|
|
||||||
return undefined
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
sql = simpleReports[reportName]
|
||||||
}
|
}
|
||||||
|
|
||||||
const database = await acquireConnection()
|
const database = await acquireConnection()
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
[Home](https://cityssm.github.io/sunrise-csm/)
|
||||||
|
|
||||||
|
# Help Documentation
|
||||||
|
|
||||||
|
**Thank you for taking the time to read the documentation.**
|
||||||
|
|
||||||
|
**Coming soon.**
|
||||||
|
|
@ -9,7 +9,7 @@ export default async function handler(request, response) {
|
||||||
}
|
}
|
||||||
const contractTypePrints = await getContractTypePrintsById(contract.contractTypeId);
|
const contractTypePrints = await getContractTypePrintsById(contract.contractTypeId);
|
||||||
response.render('contract-view', {
|
response.render('contract-view', {
|
||||||
headTitle: 'Contract View',
|
headTitle: `Contract #${contract.contractId.toString()}`,
|
||||||
contract,
|
contract,
|
||||||
contractTypePrints
|
contractTypePrints
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ export default async function handler(
|
||||||
)
|
)
|
||||||
|
|
||||||
response.render('contract-view', {
|
response.render('contract-view', {
|
||||||
headTitle: 'Contract View',
|
headTitle: `Contract #${contract.contractId.toString()}`,
|
||||||
contract,
|
contract,
|
||||||
contractTypePrints
|
contractTypePrints
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,5 @@
|
||||||
import { dateToString } from '@cityssm/utils-datetime';
|
import { dateToString } from '@cityssm/utils-datetime';
|
||||||
import getContracts from '../../database/getContracts.js';
|
|
||||||
import getWorkOrderMilestones from '../../database/getWorkOrderMilestones.js';
|
import getWorkOrderMilestones from '../../database/getWorkOrderMilestones.js';
|
||||||
import { getWorkOrders } from '../../database/getWorkOrders.js';
|
|
||||||
export default async function handler(_request, response) {
|
export default async function handler(_request, response) {
|
||||||
const currentDateString = dateToString(new Date());
|
const currentDateString = dateToString(new Date());
|
||||||
const workOrderMilestones = await getWorkOrderMilestones({
|
const workOrderMilestones = await getWorkOrderMilestones({
|
||||||
|
|
@ -11,25 +9,8 @@ export default async function handler(_request, response) {
|
||||||
orderBy: 'completion',
|
orderBy: 'completion',
|
||||||
includeWorkOrders: true
|
includeWorkOrders: true
|
||||||
});
|
});
|
||||||
const workOrderResults = await getWorkOrders({
|
|
||||||
workOrderOpenDateString: currentDateString
|
|
||||||
}, {
|
|
||||||
limit: 1, // only using the count
|
|
||||||
offset: 0
|
|
||||||
});
|
|
||||||
const contractResults = await getContracts({
|
|
||||||
contractStartDateString: currentDateString
|
|
||||||
}, {
|
|
||||||
limit: 1, // only using the count
|
|
||||||
offset: 0,
|
|
||||||
includeFees: false,
|
|
||||||
includeInterments: false,
|
|
||||||
includeTransactions: false
|
|
||||||
});
|
|
||||||
response.render('dashboard', {
|
response.render('dashboard', {
|
||||||
headTitle: 'Dashboard',
|
headTitle: 'Dashboard',
|
||||||
workOrderMilestones,
|
workOrderMilestones
|
||||||
workOrderCount: workOrderResults.count,
|
|
||||||
contractCount: contractResults.count
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,7 @@
|
||||||
import { dateToString } from '@cityssm/utils-datetime'
|
import { dateToString } from '@cityssm/utils-datetime'
|
||||||
import type { Request, Response } from 'express'
|
import type { Request, Response } from 'express'
|
||||||
|
|
||||||
import getContracts from '../../database/getContracts.js'
|
|
||||||
import getWorkOrderMilestones from '../../database/getWorkOrderMilestones.js'
|
import getWorkOrderMilestones from '../../database/getWorkOrderMilestones.js'
|
||||||
import { getWorkOrders } from '../../database/getWorkOrders.js'
|
|
||||||
|
|
||||||
export default async function handler(
|
export default async function handler(
|
||||||
_request: Request,
|
_request: Request,
|
||||||
|
|
@ -22,33 +20,8 @@ export default async function handler(
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
const workOrderResults = await getWorkOrders(
|
|
||||||
{
|
|
||||||
workOrderOpenDateString: currentDateString
|
|
||||||
},
|
|
||||||
{
|
|
||||||
limit: 1, // only using the count
|
|
||||||
offset: 0
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
const contractResults = await getContracts(
|
|
||||||
{
|
|
||||||
contractStartDateString: currentDateString
|
|
||||||
},
|
|
||||||
{
|
|
||||||
limit: 1, // only using the count
|
|
||||||
offset: 0,
|
|
||||||
includeFees: false,
|
|
||||||
includeInterments: false,
|
|
||||||
includeTransactions: false
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
response.render('dashboard', {
|
response.render('dashboard', {
|
||||||
headTitle: 'Dashboard',
|
headTitle: 'Dashboard',
|
||||||
workOrderMilestones,
|
workOrderMilestones
|
||||||
workOrderCount: workOrderResults.count,
|
|
||||||
contractCount: contractResults.count
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,9 @@ function cacheBurialSiteIds(burialSiteId, nextBurialSiteId, relayMessage = true)
|
||||||
process.send(workerMessage);
|
process.send(workerMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch { }
|
catch {
|
||||||
|
// Ignore
|
||||||
|
}
|
||||||
}
|
}
|
||||||
export async function getNextBurialSiteId(burialSiteId) {
|
export async function getNextBurialSiteId(burialSiteId) {
|
||||||
let nextBurialSiteId = nextBurialSiteIdCache.get(burialSiteId);
|
let nextBurialSiteId = nextBurialSiteIdCache.get(burialSiteId);
|
||||||
|
|
@ -82,7 +84,9 @@ export function clearNextPreviousBurialSiteIdCache(burialSiteId = -1, relayMessa
|
||||||
process.send(workerMessage);
|
process.send(workerMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch { }
|
catch {
|
||||||
|
// Ignore
|
||||||
|
}
|
||||||
}
|
}
|
||||||
const segmentConfig = getConfigProperty('settings.burialSites.burialSiteNameSegments');
|
const segmentConfig = getConfigProperty('settings.burialSites.burialSiteNameSegments');
|
||||||
export function buildBurialSiteName(cemeteryKey, segments) {
|
export function buildBurialSiteName(cemeteryKey, segments) {
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,9 @@ function cacheBurialSiteIds(
|
||||||
|
|
||||||
process.send(workerMessage)
|
process.send(workerMessage)
|
||||||
}
|
}
|
||||||
} catch {}
|
} catch {
|
||||||
|
// Ignore
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getNextBurialSiteId(
|
export async function getNextBurialSiteId(
|
||||||
|
|
@ -131,7 +133,9 @@ export function clearNextPreviousBurialSiteIdCache(
|
||||||
|
|
||||||
process.send(workerMessage)
|
process.send(workerMessage)
|
||||||
}
|
}
|
||||||
} catch {}
|
} catch {
|
||||||
|
// Ignore
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const segmentConfig = getConfigProperty(
|
const segmentConfig = getConfigProperty(
|
||||||
|
|
|
||||||
|
|
@ -59,14 +59,12 @@
|
||||||
"@types/express-session": "^1.18.1",
|
"@types/express-session": "^1.18.1",
|
||||||
"@types/http-errors": "^2.0.4",
|
"@types/http-errors": "^2.0.4",
|
||||||
"@types/leaflet": "^1.9.16",
|
"@types/leaflet": "^1.9.16",
|
||||||
"@types/mocha": "^10.0.10",
|
|
||||||
"@types/mssql": "^9.1.7",
|
"@types/mssql": "^9.1.7",
|
||||||
"@types/node-windows": "^0.1.6",
|
"@types/node-windows": "^0.1.6",
|
||||||
"@types/papaparse": "^5.3.15",
|
"@types/papaparse": "^5.3.15",
|
||||||
"@types/randomcolor": "^0.5.9",
|
"@types/randomcolor": "^0.5.9",
|
||||||
"@types/session-file-store": "^1.2.5",
|
"@types/session-file-store": "^1.2.5",
|
||||||
"axe-core": "^4.10.3",
|
"axe-core": "^4.10.3",
|
||||||
"bulma": "^1.0.3",
|
|
||||||
"cypress": "^14.2.0",
|
"cypress": "^14.2.0",
|
||||||
"cypress-axe": "^1.6.0",
|
"cypress-axe": "^1.6.0",
|
||||||
"eslint-config-cityssm": "^20.0.0",
|
"eslint-config-cityssm": "^20.0.0",
|
||||||
|
|
@ -1831,8 +1829,9 @@
|
||||||
"version": "10.0.10",
|
"version": "10.0.10",
|
||||||
"resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.10.tgz",
|
"resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.10.tgz",
|
||||||
"integrity": "sha512-xPyYSz1cMPnJQhl0CLMH68j3gprKZaTjG3s5Vi+fDgx+uhG9NOXwbVt52eFS8ECyXhyKcjDLCBEqBExKuiZb7Q==",
|
"integrity": "sha512-xPyYSz1cMPnJQhl0CLMH68j3gprKZaTjG3s5Vi+fDgx+uhG9NOXwbVt52eFS8ECyXhyKcjDLCBEqBExKuiZb7Q==",
|
||||||
"devOptional": true,
|
"license": "MIT",
|
||||||
"license": "MIT"
|
"optional": true,
|
||||||
|
"peer": true
|
||||||
},
|
},
|
||||||
"node_modules/@types/ms": {
|
"node_modules/@types/ms": {
|
||||||
"version": "0.7.31",
|
"version": "0.7.31",
|
||||||
|
|
@ -3081,13 +3080,6 @@
|
||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/bulma": {
|
|
||||||
"version": "1.0.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/bulma/-/bulma-1.0.3.tgz",
|
|
||||||
"integrity": "sha512-9eVXBrXwlU337XUXBjIIq7i88A+tRbJYAjXQjT/21lwam+5tpvKF0R7dCesre9N+HV9c6pzCNEPKrtgvBBes2g==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT"
|
|
||||||
},
|
|
||||||
"node_modules/bulma-tooltip": {
|
"node_modules/bulma-tooltip": {
|
||||||
"version": "3.0.2",
|
"version": "3.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/bulma-tooltip/-/bulma-tooltip-3.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/bulma-tooltip/-/bulma-tooltip-3.0.2.tgz",
|
||||||
|
|
|
||||||
|
|
@ -15,9 +15,9 @@
|
||||||
"cy:open": "cypress open --config-file cypress.config.js",
|
"cy:open": "cypress open --config-file cypress.config.js",
|
||||||
"cy:run": "cypress run --config-file cypress.config.js",
|
"cy:run": "cypress run --config-file cypress.config.js",
|
||||||
"cy:run:firefox": "cypress run --config-file cypress.config.js --browser firefox",
|
"cy:run:firefox": "cypress run --config-file cypress.config.js --browser firefox",
|
||||||
"test": "cross-env NODE_ENV=dev DEBUG=sunrise:* TEST_DATABASES=true mocha --timeout 30000 --exit",
|
"test": "cross-env NODE_ENV=dev DEBUG=sunrise:* TEST_DATABASES=true node --test",
|
||||||
"test:startup": "cross-env NODE_ENV=dev DEBUG=sunrise:* TEST_DATABASES=true STARTUP_TEST=true node ./bin/www.js",
|
"test:startup": "cross-env NODE_ENV=dev DEBUG=sunrise:* TEST_DATABASES=true STARTUP_TEST=true node ./bin/www.js",
|
||||||
"coverage": "cross-env NODE_ENV=dev DEBUG=sunrise:* TEST_DATABASES=true c8 --reporter=lcov --reporter=text --reporter=text-summary mocha --timeout 30000 --exit",
|
"coverage": "cross-env NODE_ENV=dev DEBUG=sunrise:* TEST_DATABASES=true c8 --reporter=lcov --reporter=text --reporter=text-summary node --test",
|
||||||
"temp:legacyImportFromCsv": "cross-env NODE_ENV=dev DEBUG=sunrise:* TEST_DATABASES=true node ./temp/legacyImportFromCsv/index.js"
|
"temp:legacyImportFromCsv": "cross-env NODE_ENV=dev DEBUG=sunrise:* TEST_DATABASES=true node ./temp/legacyImportFromCsv/index.js"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
|
|
@ -82,14 +82,12 @@
|
||||||
"@types/express-session": "^1.18.1",
|
"@types/express-session": "^1.18.1",
|
||||||
"@types/http-errors": "^2.0.4",
|
"@types/http-errors": "^2.0.4",
|
||||||
"@types/leaflet": "^1.9.16",
|
"@types/leaflet": "^1.9.16",
|
||||||
"@types/mocha": "^10.0.10",
|
|
||||||
"@types/mssql": "^9.1.7",
|
"@types/mssql": "^9.1.7",
|
||||||
"@types/node-windows": "^0.1.6",
|
"@types/node-windows": "^0.1.6",
|
||||||
"@types/papaparse": "^5.3.15",
|
"@types/papaparse": "^5.3.15",
|
||||||
"@types/randomcolor": "^0.5.9",
|
"@types/randomcolor": "^0.5.9",
|
||||||
"@types/session-file-store": "^1.2.5",
|
"@types/session-file-store": "^1.2.5",
|
||||||
"axe-core": "^4.10.3",
|
"axe-core": "^4.10.3",
|
||||||
"bulma": "^1.0.3",
|
|
||||||
"cypress": "^14.2.0",
|
"cypress": "^14.2.0",
|
||||||
"cypress-axe": "^1.6.0",
|
"cypress-axe": "^1.6.0",
|
||||||
"eslint-config-cityssm": "^20.0.0",
|
"eslint-config-cityssm": "^20.0.0",
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,9 @@
|
||||||
id="svg3"
|
id="svg3"
|
||||||
sodipodi:docname="sunrise-cms.svg"
|
sodipodi:docname="sunrise-cms.svg"
|
||||||
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
|
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
|
||||||
|
inkscape:export-filename="sunrise-cms.png"
|
||||||
|
inkscape:export-xdpi="2.6444559"
|
||||||
|
inkscape:export-ydpi="2.6444559"
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
|
@ -23,15 +26,16 @@
|
||||||
inkscape:pagecheckerboard="0"
|
inkscape:pagecheckerboard="0"
|
||||||
inkscape:deskcolor="#d1d1d1"
|
inkscape:deskcolor="#d1d1d1"
|
||||||
inkscape:document-units="mm"
|
inkscape:document-units="mm"
|
||||||
inkscape:zoom="0.44790474"
|
inkscape:zoom="0.07917912"
|
||||||
inkscape:cx="10007.708"
|
inkscape:cx="4868.7078"
|
||||||
inkscape:cy="6998.1399"
|
inkscape:cy="10880.394"
|
||||||
inkscape:window-width="1920"
|
inkscape:window-width="1920"
|
||||||
inkscape:window-height="1009"
|
inkscape:window-height="1009"
|
||||||
inkscape:window-x="-8"
|
inkscape:window-x="-8"
|
||||||
inkscape:window-y="-8"
|
inkscape:window-y="-8"
|
||||||
inkscape:window-maximized="1"
|
inkscape:window-maximized="1"
|
||||||
inkscape:current-layer="svg3" />
|
inkscape:current-layer="svg3"
|
||||||
|
showgrid="false" />
|
||||||
<path
|
<path
|
||||||
fill="#16272f"
|
fill="#16272f"
|
||||||
d="M95 3826c-44-23-66-45-81-81l-14-32v-216l11-39c6-22 22-57 35-78l24-38 41-29 40-30 68-17 67-18 2-520 2-521 12-50c27-122 67-220 131-315l29-45 82-80 82-80 89-47 90-46 90-29 90-28h350l90 28 90 29 74 39c164 88 273 202 360 377l41 81 20 86 20 86v1036l168 6 167 5 43 16 44 16 38 30 39 31 30 61 31 61v237l-15.922 78.571-30.507 50.95L1530 3842H125Z"
|
d="M95 3826c-44-23-66-45-81-81l-14-32v-216l11-39c6-22 22-57 35-78l24-38 41-29 40-30 68-17 67-18 2-520 2-521 12-50c27-122 67-220 131-315l29-45 82-80 82-80 89-47 90-46 90-29 90-28h350l90 28 90 29 74 39c164 88 273 202 360 377l41 81 20 86 20 86v1036l168 6 167 5 43 16 44 16 38 30 39 31 30 61 31 61v237l-15.922 78.571-30.507 50.95L1530 3842H125Z"
|
||||||
|
|
|
||||||
|
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 4.7 KiB |
|
|
@ -213,8 +213,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
cityssm.openHtmlModal('burialSite-editComment', {
|
cityssm.openHtmlModal('burialSite-editComment', {
|
||||||
onshow(modalElement) {
|
onshow(modalElement) {
|
||||||
sunrise.populateAliases(modalElement);
|
sunrise.populateAliases(modalElement);
|
||||||
modalElement.querySelector('#burialSiteCommentEdit--burialSiteId').value = burialSiteId;
|
modalElement
|
||||||
modalElement.querySelector('#burialSiteCommentEdit--burialSiteCommentId').value = burialSiteCommentId.toString();
|
.querySelector('#burialSiteCommentEdit--burialSiteId')
|
||||||
|
?.setAttribute('value', burialSiteId);
|
||||||
|
modalElement
|
||||||
|
.querySelector('#burialSiteCommentEdit--burialSiteCommentId')
|
||||||
|
?.setAttribute('value', burialSiteCommentId.toString());
|
||||||
modalElement.querySelector('#burialSiteCommentEdit--comment').value = burialSiteComment.comment ?? '';
|
modalElement.querySelector('#burialSiteCommentEdit--comment').value = burialSiteComment.comment ?? '';
|
||||||
const commentDateStringElement = modalElement.querySelector('#burialSiteCommentEdit--commentDateString');
|
const commentDateStringElement = modalElement.querySelector('#burialSiteCommentEdit--commentDateString');
|
||||||
commentDateStringElement.value =
|
commentDateStringElement.value =
|
||||||
|
|
@ -339,7 +343,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
cityssm.openHtmlModal('burialSite-addComment', {
|
cityssm.openHtmlModal('burialSite-addComment', {
|
||||||
onshow(modalElement) {
|
onshow(modalElement) {
|
||||||
sunrise.populateAliases(modalElement);
|
sunrise.populateAliases(modalElement);
|
||||||
modalElement.querySelector('#burialSiteCommentAdd--burialSiteId').value = burialSiteId;
|
modalElement
|
||||||
|
.querySelector('#burialSiteCommentAdd--burialSiteId')
|
||||||
|
?.setAttribute('value', burialSiteId);
|
||||||
modalElement
|
modalElement
|
||||||
.querySelector('form')
|
.querySelector('form')
|
||||||
?.addEventListener('submit', doAddComment);
|
?.addEventListener('submit', doAddComment);
|
||||||
|
|
|
||||||
|
|
@ -333,20 +333,18 @@ declare const exports: Record<string, unknown>
|
||||||
cityssm.openHtmlModal('burialSite-editComment', {
|
cityssm.openHtmlModal('burialSite-editComment', {
|
||||||
onshow(modalElement) {
|
onshow(modalElement) {
|
||||||
sunrise.populateAliases(modalElement)
|
sunrise.populateAliases(modalElement)
|
||||||
;(
|
|
||||||
modalElement.querySelector(
|
modalElement
|
||||||
'#burialSiteCommentEdit--burialSiteId'
|
.querySelector('#burialSiteCommentEdit--burialSiteId')
|
||||||
) as HTMLInputElement
|
?.setAttribute('value', burialSiteId)
|
||||||
).value = burialSiteId
|
|
||||||
;(
|
modalElement
|
||||||
modalElement.querySelector(
|
.querySelector('#burialSiteCommentEdit--burialSiteCommentId')
|
||||||
'#burialSiteCommentEdit--burialSiteCommentId'
|
?.setAttribute('value', burialSiteCommentId.toString())
|
||||||
) as HTMLInputElement
|
|
||||||
).value = burialSiteCommentId.toString()
|
|
||||||
;(
|
;(
|
||||||
modalElement.querySelector(
|
modalElement.querySelector(
|
||||||
'#burialSiteCommentEdit--comment'
|
'#burialSiteCommentEdit--comment'
|
||||||
) as HTMLInputElement
|
) as HTMLTextAreaElement
|
||||||
).value = burialSiteComment.comment ?? ''
|
).value = burialSiteComment.comment ?? ''
|
||||||
|
|
||||||
const commentDateStringElement = modalElement.querySelector(
|
const commentDateStringElement = modalElement.querySelector(
|
||||||
|
|
@ -526,11 +524,11 @@ declare const exports: Record<string, unknown>
|
||||||
cityssm.openHtmlModal('burialSite-addComment', {
|
cityssm.openHtmlModal('burialSite-addComment', {
|
||||||
onshow(modalElement) {
|
onshow(modalElement) {
|
||||||
sunrise.populateAliases(modalElement)
|
sunrise.populateAliases(modalElement)
|
||||||
;(
|
|
||||||
modalElement.querySelector(
|
modalElement
|
||||||
'#burialSiteCommentAdd--burialSiteId'
|
.querySelector('#burialSiteCommentAdd--burialSiteId')
|
||||||
) as HTMLInputElement
|
?.setAttribute('value', burialSiteId)
|
||||||
).value = burialSiteId
|
|
||||||
modalElement
|
modalElement
|
||||||
.querySelector('form')
|
.querySelector('form')
|
||||||
?.addEventListener('submit', doAddComment)
|
?.addEventListener('submit', doAddComment)
|
||||||
|
|
|
||||||
|
|
@ -9,15 +9,17 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
const contractCommentId = Number.parseInt(clickEvent.currentTarget.closest('tr')?.dataset
|
const contractCommentId = Number.parseInt(clickEvent.currentTarget.closest('tr')?.dataset
|
||||||
.contractCommentId ?? '', 10);
|
.contractCommentId ?? '', 10);
|
||||||
const contractComment = contractComments.find((currentComment) => currentComment.contractCommentId === contractCommentId);
|
const contractComment = contractComments.find((currentComment) => currentComment.contractCommentId === contractCommentId);
|
||||||
let editFormElement;
|
let editFormElement = undefined;
|
||||||
let editCloseModalFunction;
|
let editCloseModalFunction = undefined;
|
||||||
function editContractComment(submitEvent) {
|
function editContractComment(submitEvent) {
|
||||||
submitEvent.preventDefault();
|
submitEvent.preventDefault();
|
||||||
cityssm.postJSON(`${sunrise.urlPrefix}/contracts/doUpdateContractComment`, editFormElement, (rawResponseJSON) => {
|
cityssm.postJSON(`${sunrise.urlPrefix}/contracts/doUpdateContractComment`, editFormElement, (rawResponseJSON) => {
|
||||||
const responseJSON = rawResponseJSON;
|
const responseJSON = rawResponseJSON;
|
||||||
if (responseJSON.success) {
|
if (responseJSON.success) {
|
||||||
contractComments = responseJSON.contractComments ?? [];
|
contractComments = responseJSON.contractComments ?? [];
|
||||||
editCloseModalFunction();
|
if (editCloseModalFunction !== undefined) {
|
||||||
|
editCloseModalFunction();
|
||||||
|
}
|
||||||
renderContractComments();
|
renderContractComments();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
@ -32,18 +34,23 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
cityssm.openHtmlModal('contract-editComment', {
|
cityssm.openHtmlModal('contract-editComment', {
|
||||||
onshow(modalElement) {
|
onshow(modalElement) {
|
||||||
sunrise.populateAliases(modalElement);
|
sunrise.populateAliases(modalElement);
|
||||||
modalElement.querySelector('#contractCommentEdit--contractId').value = contractId;
|
modalElement
|
||||||
modalElement.querySelector('#contractCommentEdit--contractCommentId').value = contractCommentId.toString();
|
.querySelector('#contractCommentEdit--contractId')
|
||||||
modalElement.querySelector('#contractCommentEdit--comment').value = contractComment.comment ?? '';
|
?.setAttribute('value', contractId);
|
||||||
|
modalElement
|
||||||
|
.querySelector('#contractCommentEdit--contractCommentId')
|
||||||
|
?.setAttribute('value', contractCommentId.toString());
|
||||||
|
modalElement.querySelector('#contractCommentEdit--comment').value = contractComment.comment;
|
||||||
const contractCommentDateStringElement = modalElement.querySelector('#contractCommentEdit--commentDateString');
|
const contractCommentDateStringElement = modalElement.querySelector('#contractCommentEdit--commentDateString');
|
||||||
contractCommentDateStringElement.value =
|
contractCommentDateStringElement.value =
|
||||||
contractComment.commentDateString ?? '';
|
contractComment.commentDateString;
|
||||||
const currentDateString = cityssm.dateToString(new Date());
|
const currentDateString = cityssm.dateToString(new Date());
|
||||||
contractCommentDateStringElement.max =
|
contractCommentDateStringElement.max =
|
||||||
|
// eslint-disable-next-line unicorn/prefer-math-min-max
|
||||||
contractComment.commentDateString <= currentDateString
|
contractComment.commentDateString <= currentDateString
|
||||||
? currentDateString
|
? currentDateString
|
||||||
: contractComment.commentDateString ?? '';
|
: contractComment.commentDateString;
|
||||||
modalElement.querySelector('#contractCommentEdit--commentTimeString').value = contractComment.commentTimeString ?? '';
|
modalElement.querySelector('#contractCommentEdit--commentTimeString').value = contractComment.commentTimeString;
|
||||||
},
|
},
|
||||||
onshown(modalElement, closeModalFunction) {
|
onshown(modalElement, closeModalFunction) {
|
||||||
bulmaJS.toggleHtmlClipped();
|
bulmaJS.toggleHtmlClipped();
|
||||||
|
|
@ -109,15 +116,15 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
for (const contractComment of contractComments) {
|
for (const contractComment of contractComments) {
|
||||||
const tableRowElement = document.createElement('tr');
|
const tableRowElement = document.createElement('tr');
|
||||||
tableRowElement.dataset.contractCommentId =
|
tableRowElement.dataset.contractCommentId =
|
||||||
contractComment.contractCommentId?.toString();
|
contractComment.contractCommentId.toString();
|
||||||
tableRowElement.innerHTML = `<td>${cityssm.escapeHTML(contractComment.recordCreate_userName ?? '')}</td>
|
tableRowElement.innerHTML = `<td>${cityssm.escapeHTML(contractComment.recordCreate_userName ?? '')}</td>
|
||||||
<td>
|
<td>
|
||||||
${cityssm.escapeHTML(contractComment.commentDateString ?? '')}
|
${cityssm.escapeHTML(contractComment.commentDateString)}
|
||||||
${cityssm.escapeHTML(contractComment.commentTime === 0
|
${cityssm.escapeHTML(contractComment.commentTime === 0
|
||||||
? ''
|
? ''
|
||||||
: contractComment.commentTimePeriodString ?? '')}
|
: contractComment.commentTimePeriodString)}
|
||||||
</td>
|
</td>
|
||||||
<td>${cityssm.escapeHTML(contractComment.comment ?? '')}</td>
|
<td>${cityssm.escapeHTML(contractComment.comment)}</td>
|
||||||
<td class="is-hidden-print">
|
<td class="is-hidden-print">
|
||||||
<div class="buttons are-small is-justify-content-end">
|
<div class="buttons are-small is-justify-content-end">
|
||||||
<button class="button is-primary button--edit" type="button">
|
<button class="button is-primary button--edit" type="button">
|
||||||
|
|
@ -151,7 +158,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
const responseJSON = rawResponseJSON;
|
const responseJSON = rawResponseJSON;
|
||||||
if (responseJSON.success) {
|
if (responseJSON.success) {
|
||||||
contractComments = responseJSON.contractComments;
|
contractComments = responseJSON.contractComments;
|
||||||
addCloseModalFunction();
|
if (addCloseModalFunction !== undefined) {
|
||||||
|
addCloseModalFunction();
|
||||||
|
}
|
||||||
renderContractComments();
|
renderContractComments();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
||||||
|
|
@ -29,8 +29,8 @@ declare const exports: Record<string, unknown>
|
||||||
(currentComment) => currentComment.contractCommentId === contractCommentId
|
(currentComment) => currentComment.contractCommentId === contractCommentId
|
||||||
) as ContractComment
|
) as ContractComment
|
||||||
|
|
||||||
let editFormElement: HTMLFormElement
|
let editFormElement: HTMLFormElement | undefined = undefined
|
||||||
let editCloseModalFunction: () => void
|
let editCloseModalFunction: (() => void) | undefined = undefined
|
||||||
|
|
||||||
function editContractComment(submitEvent: SubmitEvent): void {
|
function editContractComment(submitEvent: SubmitEvent): void {
|
||||||
submitEvent.preventDefault()
|
submitEvent.preventDefault()
|
||||||
|
|
@ -47,7 +47,11 @@ declare const exports: Record<string, unknown>
|
||||||
|
|
||||||
if (responseJSON.success) {
|
if (responseJSON.success) {
|
||||||
contractComments = responseJSON.contractComments ?? []
|
contractComments = responseJSON.contractComments ?? []
|
||||||
editCloseModalFunction()
|
|
||||||
|
if (editCloseModalFunction !== undefined) {
|
||||||
|
editCloseModalFunction()
|
||||||
|
}
|
||||||
|
|
||||||
renderContractComments()
|
renderContractComments()
|
||||||
} else {
|
} else {
|
||||||
bulmaJS.alert({
|
bulmaJS.alert({
|
||||||
|
|
@ -63,44 +67,42 @@ declare const exports: Record<string, unknown>
|
||||||
cityssm.openHtmlModal('contract-editComment', {
|
cityssm.openHtmlModal('contract-editComment', {
|
||||||
onshow(modalElement) {
|
onshow(modalElement) {
|
||||||
sunrise.populateAliases(modalElement)
|
sunrise.populateAliases(modalElement)
|
||||||
;(
|
|
||||||
modalElement.querySelector(
|
modalElement
|
||||||
'#contractCommentEdit--contractId'
|
.querySelector('#contractCommentEdit--contractId')
|
||||||
) as HTMLInputElement
|
?.setAttribute('value', contractId)
|
||||||
).value = contractId
|
|
||||||
;(
|
modalElement
|
||||||
modalElement.querySelector(
|
.querySelector('#contractCommentEdit--contractCommentId')
|
||||||
'#contractCommentEdit--contractCommentId'
|
?.setAttribute('value', contractCommentId.toString())
|
||||||
) as HTMLInputElement
|
|
||||||
).value = contractCommentId.toString()
|
|
||||||
;(
|
;(
|
||||||
modalElement.querySelector(
|
modalElement.querySelector(
|
||||||
'#contractCommentEdit--comment'
|
'#contractCommentEdit--comment'
|
||||||
) as HTMLInputElement
|
) as HTMLTextAreaElement
|
||||||
).value = contractComment.comment ?? ''
|
).value = contractComment.comment
|
||||||
|
|
||||||
const contractCommentDateStringElement = modalElement.querySelector(
|
const contractCommentDateStringElement = modalElement.querySelector(
|
||||||
'#contractCommentEdit--commentDateString'
|
'#contractCommentEdit--commentDateString'
|
||||||
) as HTMLInputElement
|
) as HTMLInputElement
|
||||||
|
|
||||||
contractCommentDateStringElement.value =
|
contractCommentDateStringElement.value =
|
||||||
contractComment.commentDateString ?? ''
|
contractComment.commentDateString
|
||||||
|
|
||||||
const currentDateString = cityssm.dateToString(new Date())
|
const currentDateString = cityssm.dateToString(new Date())
|
||||||
|
|
||||||
contractCommentDateStringElement.max =
|
contractCommentDateStringElement.max =
|
||||||
contractComment.commentDateString! <= currentDateString
|
// eslint-disable-next-line unicorn/prefer-math-min-max
|
||||||
|
contractComment.commentDateString <= currentDateString
|
||||||
? currentDateString
|
? currentDateString
|
||||||
: contractComment.commentDateString ?? ''
|
: contractComment.commentDateString
|
||||||
;(
|
;(
|
||||||
modalElement.querySelector(
|
modalElement.querySelector(
|
||||||
'#contractCommentEdit--commentTimeString'
|
'#contractCommentEdit--commentTimeString'
|
||||||
) as HTMLInputElement
|
) as HTMLInputElement
|
||||||
).value = contractComment.commentTimeString ?? ''
|
).value = contractComment.commentTimeString
|
||||||
},
|
},
|
||||||
onshown(modalElement, closeModalFunction) {
|
onshown(modalElement, closeModalFunction) {
|
||||||
bulmaJS.toggleHtmlClipped()
|
bulmaJS.toggleHtmlClipped()
|
||||||
|
|
||||||
;(
|
;(
|
||||||
modalElement.querySelector(
|
modalElement.querySelector(
|
||||||
'#contractCommentEdit--comment'
|
'#contractCommentEdit--comment'
|
||||||
|
|
@ -190,18 +192,18 @@ declare const exports: Record<string, unknown>
|
||||||
for (const contractComment of contractComments) {
|
for (const contractComment of contractComments) {
|
||||||
const tableRowElement = document.createElement('tr')
|
const tableRowElement = document.createElement('tr')
|
||||||
tableRowElement.dataset.contractCommentId =
|
tableRowElement.dataset.contractCommentId =
|
||||||
contractComment.contractCommentId?.toString()
|
contractComment.contractCommentId.toString()
|
||||||
|
|
||||||
tableRowElement.innerHTML = `<td>${cityssm.escapeHTML(contractComment.recordCreate_userName ?? '')}</td>
|
tableRowElement.innerHTML = `<td>${cityssm.escapeHTML(contractComment.recordCreate_userName ?? '')}</td>
|
||||||
<td>
|
<td>
|
||||||
${cityssm.escapeHTML(contractComment.commentDateString ?? '')}
|
${cityssm.escapeHTML(contractComment.commentDateString)}
|
||||||
${cityssm.escapeHTML(
|
${cityssm.escapeHTML(
|
||||||
contractComment.commentTime === 0
|
contractComment.commentTime === 0
|
||||||
? ''
|
? ''
|
||||||
: contractComment.commentTimePeriodString ?? ''
|
: contractComment.commentTimePeriodString
|
||||||
)}
|
)}
|
||||||
</td>
|
</td>
|
||||||
<td>${cityssm.escapeHTML(contractComment.comment ?? '')}</td>
|
<td>${cityssm.escapeHTML(contractComment.comment)}</td>
|
||||||
<td class="is-hidden-print">
|
<td class="is-hidden-print">
|
||||||
<div class="buttons are-small is-justify-content-end">
|
<div class="buttons are-small is-justify-content-end">
|
||||||
<button class="button is-primary button--edit" type="button">
|
<button class="button is-primary button--edit" type="button">
|
||||||
|
|
@ -232,8 +234,8 @@ declare const exports: Record<string, unknown>
|
||||||
document
|
document
|
||||||
.querySelector('#button--addComment')
|
.querySelector('#button--addComment')
|
||||||
?.addEventListener('click', () => {
|
?.addEventListener('click', () => {
|
||||||
let addFormElement: HTMLFormElement
|
let addFormElement: HTMLFormElement | undefined
|
||||||
let addCloseModalFunction: () => void
|
let addCloseModalFunction: (() => void) | undefined
|
||||||
|
|
||||||
function addComment(submitEvent: SubmitEvent): void {
|
function addComment(submitEvent: SubmitEvent): void {
|
||||||
submitEvent.preventDefault()
|
submitEvent.preventDefault()
|
||||||
|
|
@ -250,7 +252,11 @@ declare const exports: Record<string, unknown>
|
||||||
|
|
||||||
if (responseJSON.success) {
|
if (responseJSON.success) {
|
||||||
contractComments = responseJSON.contractComments
|
contractComments = responseJSON.contractComments
|
||||||
addCloseModalFunction()
|
|
||||||
|
if (addCloseModalFunction !== undefined) {
|
||||||
|
addCloseModalFunction()
|
||||||
|
}
|
||||||
|
|
||||||
renderContractComments()
|
renderContractComments()
|
||||||
} else {
|
} else {
|
||||||
bulmaJS.alert({
|
bulmaJS.alert({
|
||||||
|
|
|
||||||
|
|
@ -497,7 +497,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
function doDelete() {
|
function doDelete() {
|
||||||
cityssm.postJSON(`${sunrise.urlPrefix}/admin/doDeleteFee`, {
|
cityssm.postJSON(`${sunrise.urlPrefix}/admin/doDeleteFee`, {
|
||||||
feeId
|
feeId
|
||||||
}, (rawResponseJSON) => {
|
},
|
||||||
|
// eslint-disable-next-line sonarjs/no-nested-functions
|
||||||
|
(rawResponseJSON) => {
|
||||||
const responseJSON = rawResponseJSON;
|
const responseJSON = rawResponseJSON;
|
||||||
if (responseJSON.success) {
|
if (responseJSON.success) {
|
||||||
feeCategories = responseJSON.feeCategories;
|
feeCategories = responseJSON.feeCategories;
|
||||||
|
|
|
||||||
|
|
@ -791,6 +791,7 @@ declare const exports: Record<string, unknown>
|
||||||
{
|
{
|
||||||
feeId
|
feeId
|
||||||
},
|
},
|
||||||
|
// eslint-disable-next-line sonarjs/no-nested-functions
|
||||||
(rawResponseJSON) => {
|
(rawResponseJSON) => {
|
||||||
const responseJSON = rawResponseJSON as ResponseJSON
|
const responseJSON = rawResponseJSON as ResponseJSON
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -310,16 +310,21 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
tableRowElement
|
tableRowElement
|
||||||
.querySelector('form')
|
.querySelector('form')
|
||||||
?.addEventListener('submit', updateWorkOrderMilestoneType);
|
?.addEventListener('submit', updateWorkOrderMilestoneType);
|
||||||
tableRowElement.querySelector('.button--moveWorkOrderMilestoneTypeUp').addEventListener('click', moveWorkOrderMilestoneType);
|
tableRowElement
|
||||||
tableRowElement.querySelector('.button--moveWorkOrderMilestoneTypeDown').addEventListener('click', moveWorkOrderMilestoneType);
|
.querySelector('.button--moveWorkOrderMilestoneTypeUp')
|
||||||
|
?.addEventListener('click', moveWorkOrderMilestoneType);
|
||||||
|
tableRowElement
|
||||||
|
.querySelector('.button--moveWorkOrderMilestoneTypeDown')
|
||||||
|
?.addEventListener('click', moveWorkOrderMilestoneType);
|
||||||
tableRowElement
|
tableRowElement
|
||||||
.querySelector('.button--deleteWorkOrderMilestoneType')
|
.querySelector('.button--deleteWorkOrderMilestoneType')
|
||||||
?.addEventListener('click', deleteWorkOrderMilestoneType);
|
?.addEventListener('click', deleteWorkOrderMilestoneType);
|
||||||
containerElement.append(tableRowElement);
|
containerElement.append(tableRowElement);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
;
|
document
|
||||||
document.querySelector('#form--addWorkOrderMilestoneType').addEventListener('submit', (submitEvent) => {
|
.querySelector('#form--addWorkOrderMilestoneType')
|
||||||
|
?.addEventListener('submit', (submitEvent) => {
|
||||||
submitEvent.preventDefault();
|
submitEvent.preventDefault();
|
||||||
const formElement = submitEvent.currentTarget;
|
const formElement = submitEvent.currentTarget;
|
||||||
cityssm.postJSON(`${sunrise.urlPrefix}/admin/doAddWorkOrderMilestoneType`, formElement, (rawResponseJSON) => {
|
cityssm.postJSON(`${sunrise.urlPrefix}/admin/doAddWorkOrderMilestoneType`, formElement, (rawResponseJSON) => {
|
||||||
|
|
|
||||||
|
|
@ -457,16 +457,14 @@ declare const bulmaJS: BulmaJS
|
||||||
tableRowElement
|
tableRowElement
|
||||||
.querySelector('form')
|
.querySelector('form')
|
||||||
?.addEventListener('submit', updateWorkOrderMilestoneType)
|
?.addEventListener('submit', updateWorkOrderMilestoneType)
|
||||||
;(
|
|
||||||
tableRowElement.querySelector(
|
tableRowElement
|
||||||
'.button--moveWorkOrderMilestoneTypeUp'
|
.querySelector('.button--moveWorkOrderMilestoneTypeUp')
|
||||||
) as HTMLButtonElement
|
?.addEventListener('click', moveWorkOrderMilestoneType)
|
||||||
).addEventListener('click', moveWorkOrderMilestoneType)
|
|
||||||
;(
|
tableRowElement
|
||||||
tableRowElement.querySelector(
|
.querySelector('.button--moveWorkOrderMilestoneTypeDown')
|
||||||
'.button--moveWorkOrderMilestoneTypeDown'
|
?.addEventListener('click', moveWorkOrderMilestoneType)
|
||||||
) as HTMLButtonElement
|
|
||||||
).addEventListener('click', moveWorkOrderMilestoneType)
|
|
||||||
|
|
||||||
tableRowElement
|
tableRowElement
|
||||||
.querySelector('.button--deleteWorkOrderMilestoneType')
|
.querySelector('.button--deleteWorkOrderMilestoneType')
|
||||||
|
|
@ -475,37 +473,36 @@ declare const bulmaJS: BulmaJS
|
||||||
containerElement.append(tableRowElement)
|
containerElement.append(tableRowElement)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
;(
|
|
||||||
document.querySelector(
|
|
||||||
'#form--addWorkOrderMilestoneType'
|
|
||||||
) as HTMLFormElement
|
|
||||||
).addEventListener('submit', (submitEvent: SubmitEvent) => {
|
|
||||||
submitEvent.preventDefault()
|
|
||||||
|
|
||||||
const formElement = submitEvent.currentTarget as HTMLFormElement
|
document
|
||||||
|
.querySelector('#form--addWorkOrderMilestoneType')
|
||||||
|
?.addEventListener('submit', (submitEvent: SubmitEvent) => {
|
||||||
|
submitEvent.preventDefault()
|
||||||
|
|
||||||
cityssm.postJSON(
|
const formElement = submitEvent.currentTarget as HTMLFormElement
|
||||||
`${sunrise.urlPrefix}/admin/doAddWorkOrderMilestoneType`,
|
|
||||||
formElement,
|
|
||||||
(rawResponseJSON) => {
|
|
||||||
const responseJSON =
|
|
||||||
rawResponseJSON as WorkOrderMilestoneTypeResponseJSON
|
|
||||||
|
|
||||||
if (responseJSON.success) {
|
cityssm.postJSON(
|
||||||
workOrderMilestoneTypes = responseJSON.workOrderMilestoneTypes
|
`${sunrise.urlPrefix}/admin/doAddWorkOrderMilestoneType`,
|
||||||
renderWorkOrderMilestoneTypes()
|
formElement,
|
||||||
formElement.reset()
|
(rawResponseJSON) => {
|
||||||
formElement.querySelector('input')?.focus()
|
const responseJSON =
|
||||||
} else {
|
rawResponseJSON as WorkOrderMilestoneTypeResponseJSON
|
||||||
bulmaJS.alert({
|
|
||||||
title: 'Error Adding Work Order Milestone Type',
|
if (responseJSON.success) {
|
||||||
message: responseJSON.errorMessage ?? '',
|
workOrderMilestoneTypes = responseJSON.workOrderMilestoneTypes
|
||||||
contextualColorName: 'danger'
|
renderWorkOrderMilestoneTypes()
|
||||||
})
|
formElement.reset()
|
||||||
|
formElement.querySelector('input')?.focus()
|
||||||
|
} else {
|
||||||
|
bulmaJS.alert({
|
||||||
|
title: 'Error Adding Work Order Milestone Type',
|
||||||
|
message: responseJSON.errorMessage ?? '',
|
||||||
|
contextualColorName: 'danger'
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
)
|
||||||
)
|
})
|
||||||
})
|
|
||||||
|
|
||||||
renderWorkOrderMilestoneTypes()
|
renderWorkOrderMilestoneTypes()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
function doLogout() {
|
function doLogout() {
|
||||||
const urlPrefix = document.querySelector('main')?.getAttribute('data-url-prefix') ?? '';
|
const urlPrefix = document.querySelector('main')?.getAttribute('data-url-prefix') ?? '';
|
||||||
globalThis.localStorage.clear();
|
globalThis.localStorage.clear();
|
||||||
globalThis.location.href = urlPrefix + '/logout';
|
globalThis.location.href = `${urlPrefix}/logout`;
|
||||||
}
|
}
|
||||||
document
|
document
|
||||||
.querySelector('#cityssm-theme--logout-button')
|
.querySelector('#cityssm-theme--logout-button')
|
||||||
|
|
@ -27,7 +27,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
.querySelector('main')
|
.querySelector('main')
|
||||||
?.getAttribute('data-session-keep-alive-millis');
|
?.getAttribute('data-session-keep-alive-millis');
|
||||||
function doKeepAlive() {
|
function doKeepAlive() {
|
||||||
cityssm.postJSON(urlPrefix + '/keepAlive', {
|
cityssm.postJSON(`${urlPrefix}/keepAlive`, {
|
||||||
t: Date.now()
|
t: Date.now()
|
||||||
}, () => {
|
}, () => {
|
||||||
// Do nothing
|
// Do nothing
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ declare const bulmaJS: BulmaJS
|
||||||
document.querySelector('main')?.getAttribute('data-url-prefix') ?? ''
|
document.querySelector('main')?.getAttribute('data-url-prefix') ?? ''
|
||||||
|
|
||||||
globalThis.localStorage.clear()
|
globalThis.localStorage.clear()
|
||||||
globalThis.location.href = urlPrefix + '/logout'
|
globalThis.location.href = `${urlPrefix}/logout`
|
||||||
}
|
}
|
||||||
|
|
||||||
document
|
document
|
||||||
|
|
@ -46,7 +46,7 @@ declare const bulmaJS: BulmaJS
|
||||||
|
|
||||||
function doKeepAlive(): void {
|
function doKeepAlive(): void {
|
||||||
cityssm.postJSON(
|
cityssm.postJSON(
|
||||||
urlPrefix + '/keepAlive',
|
`${urlPrefix}/keepAlive`,
|
||||||
{
|
{
|
||||||
t: Date.now()
|
t: Date.now()
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,11 @@
|
||||||
/* eslint-disable unicorn/filename-case, @eslint-community/eslint-comments/disable-enable-pair */
|
/* eslint-disable unicorn/filename-case, @eslint-community/eslint-comments/disable-enable-pair */
|
||||||
import assert from 'node:assert';
|
import assert from 'node:assert';
|
||||||
import fs from 'node:fs/promises';
|
import fs from 'node:fs/promises';
|
||||||
|
import { describe, it } from 'node:test';
|
||||||
import { initializeDatabase } from '../database/initializeDatabase.js';
|
import { initializeDatabase } from '../database/initializeDatabase.js';
|
||||||
import { sunriseDB as databasePath, useTestDatabases } from '../helpers/database.helpers.js';
|
import { sunriseDB as databasePath, useTestDatabases } from '../helpers/database.helpers.js';
|
||||||
describe('Initialize Database', () => {
|
await describe('Initialize Database', async () => {
|
||||||
it('initializes the database', async () => {
|
await it('initializes the database', async () => {
|
||||||
if (!useTestDatabases) {
|
if (!useTestDatabases) {
|
||||||
assert.fail('Test database must be used!');
|
assert.fail('Test database must be used!');
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
import assert from 'node:assert'
|
import assert from 'node:assert'
|
||||||
import fs from 'node:fs/promises'
|
import fs from 'node:fs/promises'
|
||||||
|
import { describe, it } from 'node:test'
|
||||||
|
|
||||||
import { initializeDatabase } from '../database/initializeDatabase.js'
|
import { initializeDatabase } from '../database/initializeDatabase.js'
|
||||||
import {
|
import {
|
||||||
|
|
@ -9,8 +10,8 @@ import {
|
||||||
useTestDatabases
|
useTestDatabases
|
||||||
} from '../helpers/database.helpers.js'
|
} from '../helpers/database.helpers.js'
|
||||||
|
|
||||||
describe('Initialize Database', () => {
|
await describe('Initialize Database', async () => {
|
||||||
it('initializes the database', async () => {
|
await it('initializes the database', async () => {
|
||||||
if (!useTestDatabases) {
|
if (!useTestDatabases) {
|
||||||
assert.fail('Test database must be used!')
|
assert.fail('Test database must be used!')
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
/* eslint-disable unicorn/filename-case, @eslint-community/eslint-comments/disable-enable-pair */
|
/* eslint-disable no-console, unicorn/filename-case, @eslint-community/eslint-comments/disable-enable-pair */
|
||||||
import assert from 'node:assert';
|
import assert from 'node:assert';
|
||||||
import { exec } from 'node:child_process';
|
import { exec } from 'node:child_process';
|
||||||
import http from 'node:http';
|
import http from 'node:http';
|
||||||
import { minutesToMillis } from '@cityssm/to-millis';
|
import { after, before, describe, it } from 'node:test';
|
||||||
|
import { hoursToMillis } from '@cityssm/to-millis';
|
||||||
import { app } from '../app.js';
|
import { app } from '../app.js';
|
||||||
import { portNumber } from './_globals.js';
|
import { portNumber } from './_globals.js';
|
||||||
function runCypress(browser, done) {
|
function runCypress(browser, done) {
|
||||||
|
|
@ -23,7 +24,7 @@ function runCypress(browser, done) {
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
describe('sunrise-cms', () => {
|
await describe('sunrise-cms', async () => {
|
||||||
const httpServer = http.createServer(app);
|
const httpServer = http.createServer(app);
|
||||||
let serverStarted = false;
|
let serverStarted = false;
|
||||||
before(() => {
|
before(() => {
|
||||||
|
|
@ -40,15 +41,19 @@ describe('sunrise-cms', () => {
|
||||||
// ignore
|
// ignore
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
it(`Ensure server starts on port ${portNumber.toString()}`, () => {
|
await it(`Ensure server starts on port ${portNumber.toString()}`, () => {
|
||||||
assert.ok(serverStarted);
|
assert.ok(serverStarted);
|
||||||
});
|
});
|
||||||
describe('Cypress tests', () => {
|
await describe('Cypress tests', async () => {
|
||||||
it('Should run Cypress tests in Chrome', (done) => {
|
await it('Should run Cypress tests in Chrome', {
|
||||||
|
timeout: hoursToMillis(1)
|
||||||
|
}, (context, done) => {
|
||||||
runCypress('chrome', done);
|
runCypress('chrome', done);
|
||||||
}).timeout(minutesToMillis(30));
|
});
|
||||||
it('Should run Cypress tests in Firefox', (done) => {
|
await it('Should run Cypress tests in Firefox', {
|
||||||
|
timeout: hoursToMillis(1)
|
||||||
|
}, (context, done) => {
|
||||||
runCypress('firefox', done);
|
runCypress('firefox', done);
|
||||||
}).timeout(minutesToMillis(30));
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,11 @@
|
||||||
/* eslint-disable unicorn/filename-case, @eslint-community/eslint-comments/disable-enable-pair */
|
/* eslint-disable no-console, unicorn/filename-case, @eslint-community/eslint-comments/disable-enable-pair */
|
||||||
|
|
||||||
import assert from 'node:assert'
|
import assert from 'node:assert'
|
||||||
import { exec } from 'node:child_process'
|
import { exec } from 'node:child_process'
|
||||||
import http from 'node:http'
|
import http from 'node:http'
|
||||||
|
import { after, before, describe, it } from 'node:test'
|
||||||
|
|
||||||
import { minutesToMillis } from '@cityssm/to-millis'
|
import { hoursToMillis } from '@cityssm/to-millis'
|
||||||
|
|
||||||
import { app } from '../app.js'
|
import { app } from '../app.js'
|
||||||
|
|
||||||
|
|
@ -34,7 +35,7 @@ function runCypress(browser: 'chrome' | 'firefox', done: () => void): void {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
describe('sunrise-cms', () => {
|
await describe('sunrise-cms', async () => {
|
||||||
const httpServer = http.createServer(app)
|
const httpServer = http.createServer(app)
|
||||||
|
|
||||||
let serverStarted = false
|
let serverStarted = false
|
||||||
|
|
@ -55,17 +56,29 @@ describe('sunrise-cms', () => {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
it(`Ensure server starts on port ${portNumber.toString()}`, () => {
|
await it(`Ensure server starts on port ${portNumber.toString()}`, () => {
|
||||||
assert.ok(serverStarted)
|
assert.ok(serverStarted)
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('Cypress tests', () => {
|
await describe('Cypress tests', async () => {
|
||||||
it('Should run Cypress tests in Chrome', (done) => {
|
await it(
|
||||||
runCypress('chrome', done)
|
'Should run Cypress tests in Chrome',
|
||||||
}).timeout(minutesToMillis(30))
|
{
|
||||||
|
timeout: hoursToMillis(1)
|
||||||
|
},
|
||||||
|
(context, done) => {
|
||||||
|
runCypress('chrome', done)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
it('Should run Cypress tests in Firefox', (done) => {
|
await it(
|
||||||
runCypress('firefox', done)
|
'Should run Cypress tests in Firefox',
|
||||||
}).timeout(minutesToMillis(30))
|
{
|
||||||
|
timeout: hoursToMillis(1)
|
||||||
|
},
|
||||||
|
(context, done) => {
|
||||||
|
runCypress('firefox', done)
|
||||||
|
}
|
||||||
|
)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -1,20 +1,18 @@
|
||||||
import assert from 'node:assert';
|
import assert from 'node:assert';
|
||||||
import fs from 'node:fs';
|
import fs from 'node:fs';
|
||||||
// skipcq: JS-C1003 - Testing functions
|
import { before, describe, it } from 'node:test';
|
||||||
import * as cacheFunctions from '../helpers/functions.cache.js';
|
import * as cacheFunctions from '../helpers/functions.cache.js';
|
||||||
// skipcq: JS-C1003 - Testing functions
|
|
||||||
import * as sqlFilterFunctions from '../helpers/functions.sqlFilters.js';
|
import * as sqlFilterFunctions from '../helpers/functions.sqlFilters.js';
|
||||||
// skipcq: JS-C1003 - Testing functions
|
|
||||||
import * as userFunctions from '../helpers/functions.user.js';
|
import * as userFunctions from '../helpers/functions.user.js';
|
||||||
describe('functions.cache', () => {
|
await describe('functions.cache', async () => {
|
||||||
const badId = -3;
|
const badId = -3;
|
||||||
// eslint-disable-next-line no-secrets/no-secrets
|
// eslint-disable-next-line no-secrets/no-secrets
|
||||||
const badName = 'qwertyuiopasdfghjklzxcvbnm';
|
const badName = 'qwertyuiopasdfghjklzxcvbnm';
|
||||||
before(() => {
|
before(() => {
|
||||||
cacheFunctions.clearCaches();
|
cacheFunctions.clearCaches();
|
||||||
});
|
});
|
||||||
describe('Burial Site Statuses', () => {
|
await describe('Burial Site Statuses', async () => {
|
||||||
it('returns Burial Site Statuses', async () => {
|
await it('returns Burial Site Statuses', async () => {
|
||||||
cacheFunctions.clearCacheByTableName('BurialSiteStatuses');
|
cacheFunctions.clearCacheByTableName('BurialSiteStatuses');
|
||||||
const burialSiteStatuses = await cacheFunctions.getBurialSiteStatuses();
|
const burialSiteStatuses = await cacheFunctions.getBurialSiteStatuses();
|
||||||
assert.ok(burialSiteStatuses.length > 0);
|
assert.ok(burialSiteStatuses.length > 0);
|
||||||
|
|
@ -25,17 +23,17 @@ describe('functions.cache', () => {
|
||||||
assert.strictEqual(burialSiteStatus.burialSiteStatus, byName?.burialSiteStatus);
|
assert.strictEqual(burialSiteStatus.burialSiteStatus, byName?.burialSiteStatus);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
it('returns undefined with a bad burialSiteStatusId', async () => {
|
await it('returns undefined with a bad burialSiteStatusId', async () => {
|
||||||
const byBadId = await cacheFunctions.getBurialSiteStatusById(badId);
|
const byBadId = await cacheFunctions.getBurialSiteStatusById(badId);
|
||||||
assert.ok(byBadId === undefined);
|
assert.ok(byBadId === undefined);
|
||||||
});
|
});
|
||||||
it('returns undefined with a bad lotStatus', async () => {
|
await it('returns undefined with a bad lotStatus', async () => {
|
||||||
const byBadName = await cacheFunctions.getBurialSiteStatusByBurialSiteStatus(badName);
|
const byBadName = await cacheFunctions.getBurialSiteStatusByBurialSiteStatus(badName);
|
||||||
assert.ok(byBadName === undefined);
|
assert.ok(byBadName === undefined);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('Lot Types', () => {
|
await describe('Burial Site Types', async () => {
|
||||||
it('returns Lot Types', async () => {
|
await it('returns Burial Site Types', async () => {
|
||||||
cacheFunctions.clearCacheByTableName('BurialSiteTypes');
|
cacheFunctions.clearCacheByTableName('BurialSiteTypes');
|
||||||
const burialSiteTypes = await cacheFunctions.getBurialSiteTypes();
|
const burialSiteTypes = await cacheFunctions.getBurialSiteTypes();
|
||||||
assert.ok(burialSiteTypes.length > 0);
|
assert.ok(burialSiteTypes.length > 0);
|
||||||
|
|
@ -46,17 +44,17 @@ describe('functions.cache', () => {
|
||||||
assert.strictEqual(burialSiteType.burialSiteType, byName?.burialSiteType);
|
assert.strictEqual(burialSiteType.burialSiteType, byName?.burialSiteType);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
it('returns undefined with a bad burialSiteTypeId', async () => {
|
await it('returns undefined with a bad burialSiteTypeId', async () => {
|
||||||
const byBadId = await cacheFunctions.getBurialSiteTypeById(badId);
|
const byBadId = await cacheFunctions.getBurialSiteTypeById(badId);
|
||||||
assert.ok(byBadId === undefined);
|
assert.ok(byBadId === undefined);
|
||||||
});
|
});
|
||||||
it('returns undefined with a bad lotType', async () => {
|
await it('returns undefined with a bad lotType', async () => {
|
||||||
const byBadName = await cacheFunctions.getBurialSiteTypesByBurialSiteType(badName);
|
const byBadName = await cacheFunctions.getBurialSiteTypesByBurialSiteType(badName);
|
||||||
assert.ok(byBadName === undefined);
|
assert.ok(byBadName === undefined);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('Occupancy Types', () => {
|
await describe('Contract Types', async () => {
|
||||||
it('returns Contract Types', async () => {
|
await it('returns Contract Types', async () => {
|
||||||
cacheFunctions.clearCacheByTableName('ContractTypes');
|
cacheFunctions.clearCacheByTableName('ContractTypes');
|
||||||
const contractTypes = await cacheFunctions.getContractTypes();
|
const contractTypes = await cacheFunctions.getContractTypes();
|
||||||
assert.ok(contractTypes.length > 0);
|
assert.ok(contractTypes.length > 0);
|
||||||
|
|
@ -67,17 +65,17 @@ describe('functions.cache', () => {
|
||||||
assert.strictEqual(contractType.contractType, byName?.contractType);
|
assert.strictEqual(contractType.contractType, byName?.contractType);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
it('returns undefined with a bad contractTypeId', async () => {
|
await it('returns undefined with a bad contractTypeId', async () => {
|
||||||
const byBadId = await cacheFunctions.getContractTypeById(badId);
|
const byBadId = await cacheFunctions.getContractTypeById(badId);
|
||||||
assert.ok(byBadId === undefined);
|
assert.ok(byBadId === undefined);
|
||||||
});
|
});
|
||||||
it('returns undefined with a bad contractType', async () => {
|
await it('returns undefined with a bad contractType', async () => {
|
||||||
const byBadName = await cacheFunctions.getContractTypeByContractType(badName);
|
const byBadName = await cacheFunctions.getContractTypeByContractType(badName);
|
||||||
assert.ok(byBadName === undefined);
|
assert.ok(byBadName === undefined);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('Work Order Types', () => {
|
await describe('Work Order Types', async () => {
|
||||||
it('returns Work Order Types', async () => {
|
await it('returns Work Order Types', async () => {
|
||||||
cacheFunctions.clearCacheByTableName('WorkOrderTypes');
|
cacheFunctions.clearCacheByTableName('WorkOrderTypes');
|
||||||
const workOrderTypes = await cacheFunctions.getWorkOrderTypes();
|
const workOrderTypes = await cacheFunctions.getWorkOrderTypes();
|
||||||
assert.ok(workOrderTypes.length > 0);
|
assert.ok(workOrderTypes.length > 0);
|
||||||
|
|
@ -86,13 +84,13 @@ describe('functions.cache', () => {
|
||||||
assert.strictEqual(workOrderType.workOrderTypeId, byId?.workOrderTypeId);
|
assert.strictEqual(workOrderType.workOrderTypeId, byId?.workOrderTypeId);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
it('returns undefined with a bad workOrderTypeId', async () => {
|
await it('returns undefined with a bad workOrderTypeId', async () => {
|
||||||
const byBadId = await cacheFunctions.getWorkOrderTypeById(badId);
|
const byBadId = await cacheFunctions.getWorkOrderTypeById(badId);
|
||||||
assert.ok(byBadId === undefined);
|
assert.ok(byBadId === undefined);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('Work Order Milestone Types', () => {
|
await describe('Work Order Milestone Types', async () => {
|
||||||
it('returns Work Order Milestone Types', async () => {
|
await it('returns Work Order Milestone Types', async () => {
|
||||||
cacheFunctions.clearCacheByTableName('WorkOrderMilestoneTypes');
|
cacheFunctions.clearCacheByTableName('WorkOrderMilestoneTypes');
|
||||||
const workOrderMilestoneTypes = await cacheFunctions.getWorkOrderMilestoneTypes();
|
const workOrderMilestoneTypes = await cacheFunctions.getWorkOrderMilestoneTypes();
|
||||||
assert.ok(workOrderMilestoneTypes.length > 0);
|
assert.ok(workOrderMilestoneTypes.length > 0);
|
||||||
|
|
@ -103,49 +101,49 @@ describe('functions.cache', () => {
|
||||||
assert.strictEqual(workOrderMilestoneType.workOrderMilestoneType, byName?.workOrderMilestoneType);
|
assert.strictEqual(workOrderMilestoneType.workOrderMilestoneType, byName?.workOrderMilestoneType);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
it('returns undefined with a bad workOrderMilestoneTypeId', async () => {
|
await it('returns undefined with a bad workOrderMilestoneTypeId', async () => {
|
||||||
const byBadId = await cacheFunctions.getWorkOrderMilestoneTypeById(badId);
|
const byBadId = await cacheFunctions.getWorkOrderMilestoneTypeById(badId);
|
||||||
assert.ok(byBadId === undefined);
|
assert.ok(byBadId === undefined);
|
||||||
});
|
});
|
||||||
it('returns undefined with a bad workOrderMilestoneType', async () => {
|
await it('returns undefined with a bad workOrderMilestoneType', async () => {
|
||||||
const byBadName = await cacheFunctions.getWorkOrderMilestoneTypeByWorkOrderMilestoneType(badName);
|
const byBadName = await cacheFunctions.getWorkOrderMilestoneTypeByWorkOrderMilestoneType(badName);
|
||||||
assert.ok(byBadName === undefined);
|
assert.ok(byBadName === undefined);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('functions.sqlFilters', () => {
|
await describe('functions.sqlFilters', async () => {
|
||||||
describe('BurialSiteName filter', () => {
|
await describe('BurialSiteName filter', async () => {
|
||||||
it('returns startsWith filter', () => {
|
await it('returns startsWith filter', () => {
|
||||||
const filter = sqlFilterFunctions.getBurialSiteNameWhereClause('TEST1 TEST2', 'startsWith', 'l');
|
const filter = sqlFilterFunctions.getBurialSiteNameWhereClause('TEST1 TEST2', 'startsWith', 'l');
|
||||||
assert.strictEqual(filter.sqlWhereClause, " and l.burialSiteName like ? || '%'");
|
assert.strictEqual(filter.sqlWhereClause, " and l.burialSiteName like ? || '%'");
|
||||||
assert.strictEqual(filter.sqlParameters.length, 1);
|
assert.strictEqual(filter.sqlParameters.length, 1);
|
||||||
assert.ok(filter.sqlParameters.includes('TEST1 TEST2'));
|
assert.ok(filter.sqlParameters.includes('TEST1 TEST2'));
|
||||||
});
|
});
|
||||||
it('returns endsWith filter', () => {
|
await it('returns endsWith filter', () => {
|
||||||
const filter = sqlFilterFunctions.getBurialSiteNameWhereClause('TEST1 TEST2', 'endsWith', 'l');
|
const filter = sqlFilterFunctions.getBurialSiteNameWhereClause('TEST1 TEST2', 'endsWith', 'l');
|
||||||
assert.strictEqual(filter.sqlWhereClause, " and l.burialSiteName like '%' || ?");
|
assert.strictEqual(filter.sqlWhereClause, " and l.burialSiteName like '%' || ?");
|
||||||
assert.strictEqual(filter.sqlParameters.length, 1);
|
assert.strictEqual(filter.sqlParameters.length, 1);
|
||||||
assert.strictEqual(filter.sqlParameters[0], 'TEST1 TEST2');
|
assert.strictEqual(filter.sqlParameters[0], 'TEST1 TEST2');
|
||||||
});
|
});
|
||||||
it('returns contains filter', () => {
|
await it('returns contains filter', () => {
|
||||||
const filter = sqlFilterFunctions.getBurialSiteNameWhereClause('TEST1 TEST2', '', 'l');
|
const filter = sqlFilterFunctions.getBurialSiteNameWhereClause('TEST1 TEST2', '', 'l');
|
||||||
assert.strictEqual(filter.sqlWhereClause, ' and instr(lower(l.burialSiteName), ?) and instr(lower(l.burialSiteName), ?)');
|
assert.strictEqual(filter.sqlWhereClause, ' and instr(lower(l.burialSiteName), ?) and instr(lower(l.burialSiteName), ?)');
|
||||||
assert.ok(filter.sqlParameters.includes('test1'));
|
assert.ok(filter.sqlParameters.includes('test1'));
|
||||||
assert.ok(filter.sqlParameters.includes('test2'));
|
assert.ok(filter.sqlParameters.includes('test2'));
|
||||||
});
|
});
|
||||||
it('handles empty filter', () => {
|
await it('handles empty filter', () => {
|
||||||
const filter = sqlFilterFunctions.getBurialSiteNameWhereClause('', '');
|
const filter = sqlFilterFunctions.getBurialSiteNameWhereClause('', '');
|
||||||
assert.strictEqual(filter.sqlWhereClause, '');
|
assert.strictEqual(filter.sqlWhereClause, '');
|
||||||
assert.strictEqual(filter.sqlParameters.length, 0);
|
assert.strictEqual(filter.sqlParameters.length, 0);
|
||||||
});
|
});
|
||||||
it('handles undefined filter', () => {
|
await it('handles undefined filter', () => {
|
||||||
const filter = sqlFilterFunctions.getBurialSiteNameWhereClause(undefined, undefined, 'l');
|
const filter = sqlFilterFunctions.getBurialSiteNameWhereClause(undefined, undefined, 'l');
|
||||||
assert.strictEqual(filter.sqlWhereClause, '');
|
assert.strictEqual(filter.sqlWhereClause, '');
|
||||||
assert.strictEqual(filter.sqlParameters.length, 0);
|
assert.strictEqual(filter.sqlParameters.length, 0);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('OccupancyTime filter', () => {
|
await describe('OccupancyTime filter', async () => {
|
||||||
it('creates three different filters', () => {
|
await it('creates three different filters', () => {
|
||||||
const currentFilter = sqlFilterFunctions.getContractTimeWhereClause('current');
|
const currentFilter = sqlFilterFunctions.getContractTimeWhereClause('current');
|
||||||
assert.notStrictEqual(currentFilter.sqlWhereClause, '');
|
assert.notStrictEqual(currentFilter.sqlWhereClause, '');
|
||||||
const pastFilter = sqlFilterFunctions.getContractTimeWhereClause('past');
|
const pastFilter = sqlFilterFunctions.getContractTimeWhereClause('past');
|
||||||
|
|
@ -156,50 +154,50 @@ describe('functions.sqlFilters', () => {
|
||||||
assert.notStrictEqual(currentFilter.sqlWhereClause, futureFilter.sqlWhereClause);
|
assert.notStrictEqual(currentFilter.sqlWhereClause, futureFilter.sqlWhereClause);
|
||||||
assert.notStrictEqual(pastFilter.sqlWhereClause, futureFilter.sqlWhereClause);
|
assert.notStrictEqual(pastFilter.sqlWhereClause, futureFilter.sqlWhereClause);
|
||||||
});
|
});
|
||||||
it('handles empty filter', () => {
|
await it('handles empty filter', () => {
|
||||||
const filter = sqlFilterFunctions.getContractTimeWhereClause('');
|
const filter = sqlFilterFunctions.getContractTimeWhereClause('');
|
||||||
assert.strictEqual(filter.sqlWhereClause, '');
|
assert.strictEqual(filter.sqlWhereClause, '');
|
||||||
assert.strictEqual(filter.sqlParameters.length, 0);
|
assert.strictEqual(filter.sqlParameters.length, 0);
|
||||||
});
|
});
|
||||||
it('handles undefined filter', () => {
|
await it('handles undefined filter', () => {
|
||||||
const filter = sqlFilterFunctions.getContractTimeWhereClause(undefined, 'o');
|
const filter = sqlFilterFunctions.getContractTimeWhereClause(undefined, 'o');
|
||||||
assert.strictEqual(filter.sqlWhereClause, '');
|
assert.strictEqual(filter.sqlWhereClause, '');
|
||||||
assert.strictEqual(filter.sqlParameters.length, 0);
|
assert.strictEqual(filter.sqlParameters.length, 0);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('DeceasedName filter', () => {
|
await describe('DeceasedName filter', async () => {
|
||||||
it('returns filter', () => {
|
await it('returns filter', () => {
|
||||||
const filter = sqlFilterFunctions.getDeceasedNameWhereClause('TEST1 TEST2', 'o');
|
const filter = sqlFilterFunctions.getDeceasedNameWhereClause('TEST1 TEST2', 'o');
|
||||||
assert.strictEqual(filter.sqlWhereClause, ' and instr(lower(o.deceasedName), ?) and instr(lower(o.deceasedName), ?)');
|
assert.strictEqual(filter.sqlWhereClause, ' and instr(lower(o.deceasedName), ?) and instr(lower(o.deceasedName), ?)');
|
||||||
assert.ok(filter.sqlParameters.length === 2);
|
assert.ok(filter.sqlParameters.length === 2);
|
||||||
assert.ok(filter.sqlParameters.includes('test1'));
|
assert.ok(filter.sqlParameters.includes('test1'));
|
||||||
assert.ok(filter.sqlParameters.includes('test2'));
|
assert.ok(filter.sqlParameters.includes('test2'));
|
||||||
});
|
});
|
||||||
it('handles empty filter', () => {
|
await it('handles empty filter', () => {
|
||||||
const filter = sqlFilterFunctions.getDeceasedNameWhereClause('');
|
const filter = sqlFilterFunctions.getDeceasedNameWhereClause('');
|
||||||
assert.strictEqual(filter.sqlWhereClause, '');
|
assert.strictEqual(filter.sqlWhereClause, '');
|
||||||
assert.strictEqual(filter.sqlParameters.length, 0);
|
assert.strictEqual(filter.sqlParameters.length, 0);
|
||||||
});
|
});
|
||||||
it('handles undefined filter', () => {
|
await it('handles undefined filter', () => {
|
||||||
const filter = sqlFilterFunctions.getDeceasedNameWhereClause(undefined, 'o');
|
const filter = sqlFilterFunctions.getDeceasedNameWhereClause(undefined, 'o');
|
||||||
assert.strictEqual(filter.sqlWhereClause, '');
|
assert.strictEqual(filter.sqlWhereClause, '');
|
||||||
assert.strictEqual(filter.sqlParameters.length, 0);
|
assert.strictEqual(filter.sqlParameters.length, 0);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('functions.user', () => {
|
await describe('functions.user', async () => {
|
||||||
describe('unauthenticated, no user in session', () => {
|
await describe('unauthenticated, no user in session', async () => {
|
||||||
const noUserRequest = {
|
const noUserRequest = {
|
||||||
session: {}
|
session: {}
|
||||||
};
|
};
|
||||||
it('can not update', () => {
|
await it('can not update', () => {
|
||||||
assert.strictEqual(userFunctions.userCanUpdate(noUserRequest), false);
|
assert.strictEqual(userFunctions.userCanUpdate(noUserRequest), false);
|
||||||
});
|
});
|
||||||
it('is not admin', () => {
|
await it('is not admin', () => {
|
||||||
assert.strictEqual(userFunctions.userIsAdmin(noUserRequest), false);
|
assert.strictEqual(userFunctions.userIsAdmin(noUserRequest), false);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('read only user, no update, no admin', () => {
|
await describe('read only user, no update, no admin', async () => {
|
||||||
const readOnlyRequest = {
|
const readOnlyRequest = {
|
||||||
session: {
|
session: {
|
||||||
user: {
|
user: {
|
||||||
|
|
@ -212,14 +210,14 @@ describe('functions.user', () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
it('can not update', () => {
|
await it('can not update', () => {
|
||||||
assert.strictEqual(userFunctions.userCanUpdate(readOnlyRequest), false);
|
assert.strictEqual(userFunctions.userCanUpdate(readOnlyRequest), false);
|
||||||
});
|
});
|
||||||
it('is not admin', () => {
|
await it('is not admin', () => {
|
||||||
assert.strictEqual(userFunctions.userIsAdmin(readOnlyRequest), false);
|
assert.strictEqual(userFunctions.userIsAdmin(readOnlyRequest), false);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('update only user, no admin', () => {
|
await describe('update only user, no admin', async () => {
|
||||||
const updateOnlyRequest = {
|
const updateOnlyRequest = {
|
||||||
session: {
|
session: {
|
||||||
user: {
|
user: {
|
||||||
|
|
@ -232,14 +230,14 @@ describe('functions.user', () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
it('can update', () => {
|
await it('can update', () => {
|
||||||
assert.strictEqual(userFunctions.userCanUpdate(updateOnlyRequest), true);
|
assert.strictEqual(userFunctions.userCanUpdate(updateOnlyRequest), true);
|
||||||
});
|
});
|
||||||
it('is not admin', () => {
|
await it('is not admin', () => {
|
||||||
assert.strictEqual(userFunctions.userIsAdmin(updateOnlyRequest), false);
|
assert.strictEqual(userFunctions.userIsAdmin(updateOnlyRequest), false);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('admin only user, no update', () => {
|
await describe('admin only user, no update', async () => {
|
||||||
const adminOnlyRequest = {
|
const adminOnlyRequest = {
|
||||||
session: {
|
session: {
|
||||||
user: {
|
user: {
|
||||||
|
|
@ -252,14 +250,14 @@ describe('functions.user', () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
it('can not update', () => {
|
await it('can not update', () => {
|
||||||
assert.strictEqual(userFunctions.userCanUpdate(adminOnlyRequest), false);
|
assert.strictEqual(userFunctions.userCanUpdate(adminOnlyRequest), false);
|
||||||
});
|
});
|
||||||
it('is admin', () => {
|
await it('is admin', () => {
|
||||||
assert.strictEqual(userFunctions.userIsAdmin(adminOnlyRequest), true);
|
assert.strictEqual(userFunctions.userIsAdmin(adminOnlyRequest), true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('update admin user', () => {
|
await describe('update admin user', async () => {
|
||||||
const updateAdminRequest = {
|
const updateAdminRequest = {
|
||||||
session: {
|
session: {
|
||||||
user: {
|
user: {
|
||||||
|
|
@ -272,15 +270,15 @@ describe('functions.user', () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
it('can update', () => {
|
await it('can update', () => {
|
||||||
assert.strictEqual(userFunctions.userCanUpdate(updateAdminRequest), true);
|
assert.strictEqual(userFunctions.userCanUpdate(updateAdminRequest), true);
|
||||||
});
|
});
|
||||||
it('is admin', () => {
|
await it('is admin', () => {
|
||||||
assert.strictEqual(userFunctions.userIsAdmin(updateAdminRequest), true);
|
assert.strictEqual(userFunctions.userIsAdmin(updateAdminRequest), true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('API key check', () => {
|
await describe('API key check', async () => {
|
||||||
it('authenticates with a valid API key', async () => {
|
await it('authenticates with a valid API key', async () => {
|
||||||
const apiKeysJSON = JSON.parse(fs.readFileSync('data/apiKeys.json', 'utf8'));
|
const apiKeysJSON = JSON.parse(fs.readFileSync('data/apiKeys.json', 'utf8'));
|
||||||
const apiKey = Object.values(apiKeysJSON)[0];
|
const apiKey = Object.values(apiKeysJSON)[0];
|
||||||
const apiRequest = {
|
const apiRequest = {
|
||||||
|
|
@ -290,7 +288,7 @@ describe('functions.user', () => {
|
||||||
};
|
};
|
||||||
assert.strictEqual(await userFunctions.apiKeyIsValid(apiRequest), true);
|
assert.strictEqual(await userFunctions.apiKeyIsValid(apiRequest), true);
|
||||||
});
|
});
|
||||||
it('fails to authenticate with an invalid API key', async () => {
|
await it('fails to authenticate with an invalid API key', async () => {
|
||||||
const apiRequest = {
|
const apiRequest = {
|
||||||
params: {
|
params: {
|
||||||
apiKey: 'badKey'
|
apiKey: 'badKey'
|
||||||
|
|
@ -298,7 +296,7 @@ describe('functions.user', () => {
|
||||||
};
|
};
|
||||||
assert.strictEqual(await userFunctions.apiKeyIsValid(apiRequest), false);
|
assert.strictEqual(await userFunctions.apiKeyIsValid(apiRequest), false);
|
||||||
});
|
});
|
||||||
it('fails to authenticate with no API key', async () => {
|
await it('fails to authenticate with no API key', async () => {
|
||||||
const apiRequest = {
|
const apiRequest = {
|
||||||
params: {}
|
params: {}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,12 @@
|
||||||
import assert from 'node:assert'
|
import assert from 'node:assert'
|
||||||
import fs from 'node:fs'
|
import fs from 'node:fs'
|
||||||
|
import { before, describe, it } from 'node:test'
|
||||||
|
|
||||||
// skipcq: JS-C1003 - Testing functions
|
|
||||||
import * as cacheFunctions from '../helpers/functions.cache.js'
|
import * as cacheFunctions from '../helpers/functions.cache.js'
|
||||||
// skipcq: JS-C1003 - Testing functions
|
|
||||||
import * as sqlFilterFunctions from '../helpers/functions.sqlFilters.js'
|
import * as sqlFilterFunctions from '../helpers/functions.sqlFilters.js'
|
||||||
// skipcq: JS-C1003 - Testing functions
|
|
||||||
import * as userFunctions from '../helpers/functions.user.js'
|
import * as userFunctions from '../helpers/functions.user.js'
|
||||||
|
|
||||||
describe('functions.cache', () => {
|
await describe('functions.cache', async () => {
|
||||||
const badId = -3
|
const badId = -3
|
||||||
// eslint-disable-next-line no-secrets/no-secrets
|
// eslint-disable-next-line no-secrets/no-secrets
|
||||||
const badName = 'qwertyuiopasdfghjklzxcvbnm'
|
const badName = 'qwertyuiopasdfghjklzxcvbnm'
|
||||||
|
|
@ -17,8 +15,8 @@ describe('functions.cache', () => {
|
||||||
cacheFunctions.clearCaches()
|
cacheFunctions.clearCaches()
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('Burial Site Statuses', () => {
|
await describe('Burial Site Statuses', async () => {
|
||||||
it('returns Burial Site Statuses', async () => {
|
await it('returns Burial Site Statuses', async () => {
|
||||||
cacheFunctions.clearCacheByTableName('BurialSiteStatuses')
|
cacheFunctions.clearCacheByTableName('BurialSiteStatuses')
|
||||||
|
|
||||||
const burialSiteStatuses = await cacheFunctions.getBurialSiteStatuses()
|
const burialSiteStatuses = await cacheFunctions.getBurialSiteStatuses()
|
||||||
|
|
@ -29,28 +27,36 @@ describe('functions.cache', () => {
|
||||||
const byId = await cacheFunctions.getBurialSiteStatusById(
|
const byId = await cacheFunctions.getBurialSiteStatusById(
|
||||||
burialSiteStatus.burialSiteStatusId
|
burialSiteStatus.burialSiteStatusId
|
||||||
)
|
)
|
||||||
assert.strictEqual(burialSiteStatus.burialSiteStatusId, byId?.burialSiteStatusId)
|
assert.strictEqual(
|
||||||
|
burialSiteStatus.burialSiteStatusId,
|
||||||
const byName = await cacheFunctions.getBurialSiteStatusByBurialSiteStatus(
|
byId?.burialSiteStatusId
|
||||||
burialSiteStatus.burialSiteStatus
|
)
|
||||||
|
|
||||||
|
const byName =
|
||||||
|
await cacheFunctions.getBurialSiteStatusByBurialSiteStatus(
|
||||||
|
burialSiteStatus.burialSiteStatus
|
||||||
|
)
|
||||||
|
assert.strictEqual(
|
||||||
|
burialSiteStatus.burialSiteStatus,
|
||||||
|
byName?.burialSiteStatus
|
||||||
)
|
)
|
||||||
assert.strictEqual(burialSiteStatus.burialSiteStatus, byName?.burialSiteStatus)
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
it('returns undefined with a bad burialSiteStatusId', async () => {
|
await it('returns undefined with a bad burialSiteStatusId', async () => {
|
||||||
const byBadId = await cacheFunctions.getBurialSiteStatusById(badId)
|
const byBadId = await cacheFunctions.getBurialSiteStatusById(badId)
|
||||||
assert.ok(byBadId === undefined)
|
assert.ok(byBadId === undefined)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('returns undefined with a bad lotStatus', async () => {
|
await it('returns undefined with a bad lotStatus', async () => {
|
||||||
const byBadName = await cacheFunctions.getBurialSiteStatusByBurialSiteStatus(badName)
|
const byBadName =
|
||||||
|
await cacheFunctions.getBurialSiteStatusByBurialSiteStatus(badName)
|
||||||
assert.ok(byBadName === undefined)
|
assert.ok(byBadName === undefined)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('Lot Types', () => {
|
await describe('Burial Site Types', async () => {
|
||||||
it('returns Lot Types', async () => {
|
await it('returns Burial Site Types', async () => {
|
||||||
cacheFunctions.clearCacheByTableName('BurialSiteTypes')
|
cacheFunctions.clearCacheByTableName('BurialSiteTypes')
|
||||||
|
|
||||||
const burialSiteTypes = await cacheFunctions.getBurialSiteTypes()
|
const burialSiteTypes = await cacheFunctions.getBurialSiteTypes()
|
||||||
|
|
@ -58,29 +64,38 @@ describe('functions.cache', () => {
|
||||||
assert.ok(burialSiteTypes.length > 0)
|
assert.ok(burialSiteTypes.length > 0)
|
||||||
|
|
||||||
for (const burialSiteType of burialSiteTypes) {
|
for (const burialSiteType of burialSiteTypes) {
|
||||||
const byId = await cacheFunctions.getBurialSiteTypeById(burialSiteType.burialSiteTypeId)
|
const byId = await cacheFunctions.getBurialSiteTypeById(
|
||||||
assert.strictEqual(burialSiteType.burialSiteTypeId, byId?.burialSiteTypeId)
|
burialSiteType.burialSiteTypeId
|
||||||
|
)
|
||||||
|
assert.strictEqual(
|
||||||
|
burialSiteType.burialSiteTypeId,
|
||||||
|
byId?.burialSiteTypeId
|
||||||
|
)
|
||||||
|
|
||||||
const byName = await cacheFunctions.getBurialSiteTypesByBurialSiteType(
|
const byName = await cacheFunctions.getBurialSiteTypesByBurialSiteType(
|
||||||
burialSiteType.burialSiteType
|
burialSiteType.burialSiteType
|
||||||
)
|
)
|
||||||
assert.strictEqual(burialSiteType.burialSiteType, byName?.burialSiteType)
|
assert.strictEqual(
|
||||||
|
burialSiteType.burialSiteType,
|
||||||
|
byName?.burialSiteType
|
||||||
|
)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
it('returns undefined with a bad burialSiteTypeId', async () => {
|
await it('returns undefined with a bad burialSiteTypeId', async () => {
|
||||||
const byBadId = await cacheFunctions.getBurialSiteTypeById(badId)
|
const byBadId = await cacheFunctions.getBurialSiteTypeById(badId)
|
||||||
assert.ok(byBadId === undefined)
|
assert.ok(byBadId === undefined)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('returns undefined with a bad lotType', async () => {
|
await it('returns undefined with a bad lotType', async () => {
|
||||||
const byBadName = await cacheFunctions.getBurialSiteTypesByBurialSiteType(badName)
|
const byBadName =
|
||||||
|
await cacheFunctions.getBurialSiteTypesByBurialSiteType(badName)
|
||||||
assert.ok(byBadName === undefined)
|
assert.ok(byBadName === undefined)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('Occupancy Types', () => {
|
await describe('Contract Types', async () => {
|
||||||
it('returns Contract Types', async () => {
|
await it('returns Contract Types', async () => {
|
||||||
cacheFunctions.clearCacheByTableName('ContractTypes')
|
cacheFunctions.clearCacheByTableName('ContractTypes')
|
||||||
|
|
||||||
const contractTypes = await cacheFunctions.getContractTypes()
|
const contractTypes = await cacheFunctions.getContractTypes()
|
||||||
|
|
@ -100,21 +115,20 @@ describe('functions.cache', () => {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
it('returns undefined with a bad contractTypeId', async () => {
|
await it('returns undefined with a bad contractTypeId', async () => {
|
||||||
const byBadId = await cacheFunctions.getContractTypeById(badId)
|
const byBadId = await cacheFunctions.getContractTypeById(badId)
|
||||||
assert.ok(byBadId === undefined)
|
assert.ok(byBadId === undefined)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('returns undefined with a bad contractType', async () => {
|
await it('returns undefined with a bad contractType', async () => {
|
||||||
const byBadName = await cacheFunctions.getContractTypeByContractType(
|
const byBadName =
|
||||||
badName
|
await cacheFunctions.getContractTypeByContractType(badName)
|
||||||
)
|
|
||||||
assert.ok(byBadName === undefined)
|
assert.ok(byBadName === undefined)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('Work Order Types', () => {
|
await describe('Work Order Types', async () => {
|
||||||
it('returns Work Order Types', async () => {
|
await it('returns Work Order Types', async () => {
|
||||||
cacheFunctions.clearCacheByTableName('WorkOrderTypes')
|
cacheFunctions.clearCacheByTableName('WorkOrderTypes')
|
||||||
|
|
||||||
const workOrderTypes = await cacheFunctions.getWorkOrderTypes()
|
const workOrderTypes = await cacheFunctions.getWorkOrderTypes()
|
||||||
|
|
@ -129,14 +143,14 @@ describe('functions.cache', () => {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
it('returns undefined with a bad workOrderTypeId', async () => {
|
await it('returns undefined with a bad workOrderTypeId', async () => {
|
||||||
const byBadId = await cacheFunctions.getWorkOrderTypeById(badId)
|
const byBadId = await cacheFunctions.getWorkOrderTypeById(badId)
|
||||||
assert.ok(byBadId === undefined)
|
assert.ok(byBadId === undefined)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('Work Order Milestone Types', () => {
|
await describe('Work Order Milestone Types', async () => {
|
||||||
it('returns Work Order Milestone Types', async () => {
|
await it('returns Work Order Milestone Types', async () => {
|
||||||
cacheFunctions.clearCacheByTableName('WorkOrderMilestoneTypes')
|
cacheFunctions.clearCacheByTableName('WorkOrderMilestoneTypes')
|
||||||
|
|
||||||
const workOrderMilestoneTypes =
|
const workOrderMilestoneTypes =
|
||||||
|
|
@ -164,12 +178,12 @@ describe('functions.cache', () => {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
it('returns undefined with a bad workOrderMilestoneTypeId', async () => {
|
await it('returns undefined with a bad workOrderMilestoneTypeId', async () => {
|
||||||
const byBadId = await cacheFunctions.getWorkOrderMilestoneTypeById(badId)
|
const byBadId = await cacheFunctions.getWorkOrderMilestoneTypeById(badId)
|
||||||
assert.ok(byBadId === undefined)
|
assert.ok(byBadId === undefined)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('returns undefined with a bad workOrderMilestoneType', async () => {
|
await it('returns undefined with a bad workOrderMilestoneType', async () => {
|
||||||
const byBadName =
|
const byBadName =
|
||||||
await cacheFunctions.getWorkOrderMilestoneTypeByWorkOrderMilestoneType(
|
await cacheFunctions.getWorkOrderMilestoneTypeByWorkOrderMilestoneType(
|
||||||
badName
|
badName
|
||||||
|
|
@ -179,33 +193,39 @@ describe('functions.cache', () => {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('functions.sqlFilters', () => {
|
await describe('functions.sqlFilters', async () => {
|
||||||
describe('BurialSiteName filter', () => {
|
await describe('BurialSiteName filter', async () => {
|
||||||
it('returns startsWith filter', () => {
|
await it('returns startsWith filter', () => {
|
||||||
const filter = sqlFilterFunctions.getBurialSiteNameWhereClause(
|
const filter = sqlFilterFunctions.getBurialSiteNameWhereClause(
|
||||||
'TEST1 TEST2',
|
'TEST1 TEST2',
|
||||||
'startsWith',
|
'startsWith',
|
||||||
'l'
|
'l'
|
||||||
)
|
)
|
||||||
|
|
||||||
assert.strictEqual(filter.sqlWhereClause, " and l.burialSiteName like ? || '%'")
|
assert.strictEqual(
|
||||||
|
filter.sqlWhereClause,
|
||||||
|
" and l.burialSiteName like ? || '%'"
|
||||||
|
)
|
||||||
assert.strictEqual(filter.sqlParameters.length, 1)
|
assert.strictEqual(filter.sqlParameters.length, 1)
|
||||||
assert.ok(filter.sqlParameters.includes('TEST1 TEST2'))
|
assert.ok(filter.sqlParameters.includes('TEST1 TEST2'))
|
||||||
})
|
})
|
||||||
|
|
||||||
it('returns endsWith filter', () => {
|
await it('returns endsWith filter', () => {
|
||||||
const filter = sqlFilterFunctions.getBurialSiteNameWhereClause(
|
const filter = sqlFilterFunctions.getBurialSiteNameWhereClause(
|
||||||
'TEST1 TEST2',
|
'TEST1 TEST2',
|
||||||
'endsWith',
|
'endsWith',
|
||||||
'l'
|
'l'
|
||||||
)
|
)
|
||||||
|
|
||||||
assert.strictEqual(filter.sqlWhereClause, " and l.burialSiteName like '%' || ?")
|
assert.strictEqual(
|
||||||
|
filter.sqlWhereClause,
|
||||||
|
" and l.burialSiteName like '%' || ?"
|
||||||
|
)
|
||||||
assert.strictEqual(filter.sqlParameters.length, 1)
|
assert.strictEqual(filter.sqlParameters.length, 1)
|
||||||
assert.strictEqual(filter.sqlParameters[0], 'TEST1 TEST2')
|
assert.strictEqual(filter.sqlParameters[0], 'TEST1 TEST2')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('returns contains filter', () => {
|
await it('returns contains filter', () => {
|
||||||
const filter = sqlFilterFunctions.getBurialSiteNameWhereClause(
|
const filter = sqlFilterFunctions.getBurialSiteNameWhereClause(
|
||||||
'TEST1 TEST2',
|
'TEST1 TEST2',
|
||||||
'',
|
'',
|
||||||
|
|
@ -220,14 +240,14 @@ describe('functions.sqlFilters', () => {
|
||||||
assert.ok(filter.sqlParameters.includes('test2'))
|
assert.ok(filter.sqlParameters.includes('test2'))
|
||||||
})
|
})
|
||||||
|
|
||||||
it('handles empty filter', () => {
|
await it('handles empty filter', () => {
|
||||||
const filter = sqlFilterFunctions.getBurialSiteNameWhereClause('', '')
|
const filter = sqlFilterFunctions.getBurialSiteNameWhereClause('', '')
|
||||||
|
|
||||||
assert.strictEqual(filter.sqlWhereClause, '')
|
assert.strictEqual(filter.sqlWhereClause, '')
|
||||||
assert.strictEqual(filter.sqlParameters.length, 0)
|
assert.strictEqual(filter.sqlParameters.length, 0)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('handles undefined filter', () => {
|
await it('handles undefined filter', () => {
|
||||||
const filter = sqlFilterFunctions.getBurialSiteNameWhereClause(
|
const filter = sqlFilterFunctions.getBurialSiteNameWhereClause(
|
||||||
undefined,
|
undefined,
|
||||||
undefined,
|
undefined,
|
||||||
|
|
@ -239,8 +259,8 @@ describe('functions.sqlFilters', () => {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('OccupancyTime filter', () => {
|
await describe('OccupancyTime filter', async () => {
|
||||||
it('creates three different filters', () => {
|
await it('creates three different filters', () => {
|
||||||
const currentFilter =
|
const currentFilter =
|
||||||
sqlFilterFunctions.getContractTimeWhereClause('current')
|
sqlFilterFunctions.getContractTimeWhereClause('current')
|
||||||
assert.notStrictEqual(currentFilter.sqlWhereClause, '')
|
assert.notStrictEqual(currentFilter.sqlWhereClause, '')
|
||||||
|
|
@ -266,13 +286,13 @@ describe('functions.sqlFilters', () => {
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('handles empty filter', () => {
|
await it('handles empty filter', () => {
|
||||||
const filter = sqlFilterFunctions.getContractTimeWhereClause('')
|
const filter = sqlFilterFunctions.getContractTimeWhereClause('')
|
||||||
assert.strictEqual(filter.sqlWhereClause, '')
|
assert.strictEqual(filter.sqlWhereClause, '')
|
||||||
assert.strictEqual(filter.sqlParameters.length, 0)
|
assert.strictEqual(filter.sqlParameters.length, 0)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('handles undefined filter', () => {
|
await it('handles undefined filter', () => {
|
||||||
const filter = sqlFilterFunctions.getContractTimeWhereClause(
|
const filter = sqlFilterFunctions.getContractTimeWhereClause(
|
||||||
undefined,
|
undefined,
|
||||||
'o'
|
'o'
|
||||||
|
|
@ -282,8 +302,8 @@ describe('functions.sqlFilters', () => {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('DeceasedName filter', () => {
|
await describe('DeceasedName filter', async () => {
|
||||||
it('returns filter', () => {
|
await it('returns filter', () => {
|
||||||
const filter = sqlFilterFunctions.getDeceasedNameWhereClause(
|
const filter = sqlFilterFunctions.getDeceasedNameWhereClause(
|
||||||
'TEST1 TEST2',
|
'TEST1 TEST2',
|
||||||
'o'
|
'o'
|
||||||
|
|
@ -300,14 +320,14 @@ describe('functions.sqlFilters', () => {
|
||||||
assert.ok(filter.sqlParameters.includes('test2'))
|
assert.ok(filter.sqlParameters.includes('test2'))
|
||||||
})
|
})
|
||||||
|
|
||||||
it('handles empty filter', () => {
|
await it('handles empty filter', () => {
|
||||||
const filter = sqlFilterFunctions.getDeceasedNameWhereClause('')
|
const filter = sqlFilterFunctions.getDeceasedNameWhereClause('')
|
||||||
|
|
||||||
assert.strictEqual(filter.sqlWhereClause, '')
|
assert.strictEqual(filter.sqlWhereClause, '')
|
||||||
assert.strictEqual(filter.sqlParameters.length, 0)
|
assert.strictEqual(filter.sqlParameters.length, 0)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('handles undefined filter', () => {
|
await it('handles undefined filter', () => {
|
||||||
const filter = sqlFilterFunctions.getDeceasedNameWhereClause(
|
const filter = sqlFilterFunctions.getDeceasedNameWhereClause(
|
||||||
undefined,
|
undefined,
|
||||||
'o'
|
'o'
|
||||||
|
|
@ -319,22 +339,22 @@ describe('functions.sqlFilters', () => {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('functions.user', () => {
|
await describe('functions.user', async () => {
|
||||||
describe('unauthenticated, no user in session', () => {
|
await describe('unauthenticated, no user in session', async () => {
|
||||||
const noUserRequest = {
|
const noUserRequest = {
|
||||||
session: {}
|
session: {}
|
||||||
}
|
}
|
||||||
|
|
||||||
it('can not update', () => {
|
await it('can not update', () => {
|
||||||
assert.strictEqual(userFunctions.userCanUpdate(noUserRequest), false)
|
assert.strictEqual(userFunctions.userCanUpdate(noUserRequest), false)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('is not admin', () => {
|
await it('is not admin', () => {
|
||||||
assert.strictEqual(userFunctions.userIsAdmin(noUserRequest), false)
|
assert.strictEqual(userFunctions.userIsAdmin(noUserRequest), false)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('read only user, no update, no admin', () => {
|
await describe('read only user, no update, no admin', async () => {
|
||||||
const readOnlyRequest: userFunctions.UserRequest = {
|
const readOnlyRequest: userFunctions.UserRequest = {
|
||||||
session: {
|
session: {
|
||||||
user: {
|
user: {
|
||||||
|
|
@ -348,16 +368,16 @@ describe('functions.user', () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
it('can not update', () => {
|
await it('can not update', () => {
|
||||||
assert.strictEqual(userFunctions.userCanUpdate(readOnlyRequest), false)
|
assert.strictEqual(userFunctions.userCanUpdate(readOnlyRequest), false)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('is not admin', () => {
|
await it('is not admin', () => {
|
||||||
assert.strictEqual(userFunctions.userIsAdmin(readOnlyRequest), false)
|
assert.strictEqual(userFunctions.userIsAdmin(readOnlyRequest), false)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('update only user, no admin', () => {
|
await describe('update only user, no admin', async () => {
|
||||||
const updateOnlyRequest: userFunctions.UserRequest = {
|
const updateOnlyRequest: userFunctions.UserRequest = {
|
||||||
session: {
|
session: {
|
||||||
user: {
|
user: {
|
||||||
|
|
@ -371,16 +391,16 @@ describe('functions.user', () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
it('can update', () => {
|
await it('can update', () => {
|
||||||
assert.strictEqual(userFunctions.userCanUpdate(updateOnlyRequest), true)
|
assert.strictEqual(userFunctions.userCanUpdate(updateOnlyRequest), true)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('is not admin', () => {
|
await it('is not admin', () => {
|
||||||
assert.strictEqual(userFunctions.userIsAdmin(updateOnlyRequest), false)
|
assert.strictEqual(userFunctions.userIsAdmin(updateOnlyRequest), false)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('admin only user, no update', () => {
|
await describe('admin only user, no update', async () => {
|
||||||
const adminOnlyRequest: userFunctions.UserRequest = {
|
const adminOnlyRequest: userFunctions.UserRequest = {
|
||||||
session: {
|
session: {
|
||||||
user: {
|
user: {
|
||||||
|
|
@ -394,16 +414,16 @@ describe('functions.user', () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
it('can not update', () => {
|
await it('can not update', () => {
|
||||||
assert.strictEqual(userFunctions.userCanUpdate(adminOnlyRequest), false)
|
assert.strictEqual(userFunctions.userCanUpdate(adminOnlyRequest), false)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('is admin', () => {
|
await it('is admin', () => {
|
||||||
assert.strictEqual(userFunctions.userIsAdmin(adminOnlyRequest), true)
|
assert.strictEqual(userFunctions.userIsAdmin(adminOnlyRequest), true)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('update admin user', () => {
|
await describe('update admin user', async () => {
|
||||||
const updateAdminRequest: userFunctions.UserRequest = {
|
const updateAdminRequest: userFunctions.UserRequest = {
|
||||||
session: {
|
session: {
|
||||||
user: {
|
user: {
|
||||||
|
|
@ -417,17 +437,17 @@ describe('functions.user', () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
it('can update', () => {
|
await it('can update', () => {
|
||||||
assert.strictEqual(userFunctions.userCanUpdate(updateAdminRequest), true)
|
assert.strictEqual(userFunctions.userCanUpdate(updateAdminRequest), true)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('is admin', () => {
|
await it('is admin', () => {
|
||||||
assert.strictEqual(userFunctions.userIsAdmin(updateAdminRequest), true)
|
assert.strictEqual(userFunctions.userIsAdmin(updateAdminRequest), true)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('API key check', () => {
|
await describe('API key check', async () => {
|
||||||
it('authenticates with a valid API key', async () => {
|
await it('authenticates with a valid API key', async () => {
|
||||||
const apiKeysJSON: Record<string, string> = JSON.parse(
|
const apiKeysJSON: Record<string, string> = JSON.parse(
|
||||||
fs.readFileSync('data/apiKeys.json', 'utf8')
|
fs.readFileSync('data/apiKeys.json', 'utf8')
|
||||||
) as Record<string, string>
|
) as Record<string, string>
|
||||||
|
|
@ -443,7 +463,7 @@ describe('functions.user', () => {
|
||||||
assert.strictEqual(await userFunctions.apiKeyIsValid(apiRequest), true)
|
assert.strictEqual(await userFunctions.apiKeyIsValid(apiRequest), true)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('fails to authenticate with an invalid API key', async () => {
|
await it('fails to authenticate with an invalid API key', async () => {
|
||||||
const apiRequest: userFunctions.APIRequest = {
|
const apiRequest: userFunctions.APIRequest = {
|
||||||
params: {
|
params: {
|
||||||
apiKey: 'badKey'
|
apiKey: 'badKey'
|
||||||
|
|
@ -453,7 +473,7 @@ describe('functions.user', () => {
|
||||||
assert.strictEqual(await userFunctions.apiKeyIsValid(apiRequest), false)
|
assert.strictEqual(await userFunctions.apiKeyIsValid(apiRequest), false)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('fails to authenticate with no API key', async () => {
|
await it('fails to authenticate with no API key', async () => {
|
||||||
const apiRequest: userFunctions.APIRequest = {
|
const apiRequest: userFunctions.APIRequest = {
|
||||||
params: {}
|
params: {}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
import assert from 'node:assert';
|
import assert from 'node:assert';
|
||||||
import fs from 'node:fs';
|
import fs from 'node:fs';
|
||||||
|
import { describe, it } from 'node:test';
|
||||||
import { version } from '../version.js';
|
import { version } from '../version.js';
|
||||||
describe('version', () => {
|
await describe('version', async () => {
|
||||||
it('has a version that matches the package.json', () => {
|
await it('has a version that matches the package.json', () => {
|
||||||
const packageJSON = JSON.parse(fs.readFileSync('package.json', 'utf8'));
|
const packageJSON = JSON.parse(fs.readFileSync('package.json', 'utf8'));
|
||||||
assert.strictEqual(version, packageJSON.version);
|
assert.strictEqual(version, packageJSON.version);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,11 @@
|
||||||
import assert from 'node:assert'
|
import assert from 'node:assert'
|
||||||
import fs from 'node:fs'
|
import fs from 'node:fs'
|
||||||
|
import { describe, it } from 'node:test'
|
||||||
|
|
||||||
import { version } from '../version.js'
|
import { version } from '../version.js'
|
||||||
|
|
||||||
describe('version', () => {
|
await describe('version', async () => {
|
||||||
it('has a version that matches the package.json', () => {
|
await it('has a version that matches the package.json', () => {
|
||||||
const packageJSON = JSON.parse(fs.readFileSync('package.json', 'utf8'))
|
const packageJSON = JSON.parse(fs.readFileSync('package.json', 'utf8'))
|
||||||
assert.strictEqual(version, packageJSON.version)
|
assert.strictEqual(version, packageJSON.version)
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,10 @@ export interface Config {
|
||||||
settings: {
|
settings: {
|
||||||
cityDefault?: string;
|
cityDefault?: string;
|
||||||
provinceDefault?: string;
|
provinceDefault?: string;
|
||||||
|
latitudeMin?: number;
|
||||||
|
latitudeMax?: number;
|
||||||
|
longitudeMin?: number;
|
||||||
|
longitudeMax?: number;
|
||||||
fees: {
|
fees: {
|
||||||
taxPercentageDefault?: number;
|
taxPercentageDefault?: number;
|
||||||
};
|
};
|
||||||
|
|
@ -31,6 +35,7 @@ export interface Config {
|
||||||
contracts: {
|
contracts: {
|
||||||
burialSiteIdIsRequired?: boolean;
|
burialSiteIdIsRequired?: boolean;
|
||||||
contractEndDateIsRequired?: boolean;
|
contractEndDateIsRequired?: boolean;
|
||||||
|
purchaserRelationships?: string[];
|
||||||
deathAgePeriods?: string[];
|
deathAgePeriods?: string[];
|
||||||
prints?: string[];
|
prints?: string[];
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,10 @@ export interface Config {
|
||||||
settings: {
|
settings: {
|
||||||
cityDefault?: string
|
cityDefault?: string
|
||||||
provinceDefault?: string
|
provinceDefault?: string
|
||||||
|
latitudeMin?: number
|
||||||
|
latitudeMax?: number
|
||||||
|
longitudeMin?: number
|
||||||
|
longitudeMax?: number
|
||||||
fees: {
|
fees: {
|
||||||
taxPercentageDefault?: number
|
taxPercentageDefault?: number
|
||||||
}
|
}
|
||||||
|
|
@ -32,6 +36,7 @@ export interface Config {
|
||||||
contracts: {
|
contracts: {
|
||||||
burialSiteIdIsRequired?: boolean
|
burialSiteIdIsRequired?: boolean
|
||||||
contractEndDateIsRequired?: boolean
|
contractEndDateIsRequired?: boolean
|
||||||
|
purchaserRelationships?: string[]
|
||||||
deathAgePeriods?: string[]
|
deathAgePeriods?: string[]
|
||||||
prints?: string[]
|
prints?: string[]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -208,14 +208,14 @@ export interface ContractInterment extends Record {
|
||||||
recordUpdate_timeMillisMax?: number;
|
recordUpdate_timeMillisMax?: number;
|
||||||
}
|
}
|
||||||
export interface ContractComment extends Record {
|
export interface ContractComment extends Record {
|
||||||
contractCommentId?: number;
|
contractCommentId: number;
|
||||||
contractId?: number;
|
contractId?: number;
|
||||||
commentDate?: number;
|
commentDate: number;
|
||||||
commentDateString?: string;
|
commentDateString: string;
|
||||||
commentTime?: number;
|
commentTime: number;
|
||||||
commentTimeString?: string;
|
commentTimeString: string;
|
||||||
commentTimePeriodString?: string;
|
commentTimePeriodString: string;
|
||||||
comment?: string;
|
comment: string;
|
||||||
}
|
}
|
||||||
export interface ContractField extends ContractTypeField, Record {
|
export interface ContractField extends ContractTypeField, Record {
|
||||||
contractId: number;
|
contractId: number;
|
||||||
|
|
|
||||||
|
|
@ -267,17 +267,17 @@ export interface ContractInterment extends Record {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ContractComment extends Record {
|
export interface ContractComment extends Record {
|
||||||
contractCommentId?: number
|
contractCommentId: number
|
||||||
contractId?: number
|
contractId?: number
|
||||||
|
|
||||||
commentDate?: number
|
commentDate: number
|
||||||
commentDateString?: string
|
commentDateString: string
|
||||||
|
|
||||||
commentTime?: number
|
commentTime: number
|
||||||
commentTimeString?: string
|
commentTimeString: string
|
||||||
commentTimePeriodString?: string
|
commentTimePeriodString: string
|
||||||
|
|
||||||
comment?: string
|
comment: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ContractField extends ContractTypeField, Record {
|
export interface ContractField extends ContractTypeField, Record {
|
||||||
|
|
|
||||||
|
|
@ -343,13 +343,19 @@
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label class="label" for="burialSite--burialSiteLatitude">Latitude</label>
|
<label class="label" for="burialSite--burialSiteLatitude">Latitude</label>
|
||||||
<div class="control">
|
<div class="control">
|
||||||
<input class="input" id="burialSite--burialSiteLatitude" name="burialSiteLatitude" type="number" min="-90" max="90" step="0.00000001" value="<%= burialSite.burialSiteLatitude %>" onwheel="return false" />
|
<input class="input" id="burialSite--burialSiteLatitude" name="burialSiteLatitude" type="number"
|
||||||
|
min="<%= configFunctions.getConfigProperty('settings.latitudeMin') %>"
|
||||||
|
max="<%= configFunctions.getConfigProperty('settings.latitudeMax') %>"
|
||||||
|
step="0.00000001" value="<%= burialSite.burialSiteLatitude %>" onwheel="return false" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label class="label" for="burialSite--burialSiteLongitude">Longitude</label>
|
<label class="label" for="burialSite--burialSiteLongitude">Longitude</label>
|
||||||
<div class="control">
|
<div class="control">
|
||||||
<input class="input" id="burialSite--burialSiteLongitude" name="burialSiteLongitude" type="number" min="-180" max="180" step="0.00000001" value="<%= burialSite.burialSiteLongitude %>" onwheel="return false" />
|
<input class="input" id="burialSite--burialSiteLongitude" name="burialSiteLongitude" type="number"
|
||||||
|
min="<%= configFunctions.getConfigProperty('settings.longitudeMin') %>"
|
||||||
|
max="<%= configFunctions.getConfigProperty('settings.longitudeMax') %>"
|
||||||
|
step="0.00000001" value="<%= burialSite.burialSiteLongitude %>" onwheel="return false" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -83,247 +83,257 @@
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<form id="form--cemetery">
|
<form id="form--cemetery">
|
||||||
<input id="cemetery--cemeteryId" name="cemeteryId" type="hidden" value="<%= cemetery.cemeteryId %>" />
|
<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="cemetery--cemeteryName">Cemetery Name</label>
|
<label class="label" for="cemetery--cemeteryName">Cemetery Name</label>
|
||||||
<div class="control">
|
<div class="control">
|
||||||
<input class="input" id="cemetery--cemeteryName" name="cemeteryName" type="text"
|
<input class="input" id="cemetery--cemeteryName" name="cemeteryName" type="text"
|
||||||
value="<%= cemetery.cemeteryName %>" 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="cemetery--cemeteryKey">Cemetery Key</label>
|
<label class="label" for="cemetery--cemeteryKey">Cemetery Key</label>
|
||||||
<div class="control">
|
<div class="control">
|
||||||
<input class="input" id="cemetery--cemeteryKey" name="cemeteryKey" type="text"
|
<input class="input" id="cemetery--cemeteryKey" name="cemeteryKey" type="text"
|
||||||
value="<%= cemetery.cemeteryKey %>" maxlength="20" required />
|
value="<%= cemetery.cemeteryKey %>" maxlength="20"
|
||||||
</div>
|
<%= configFunctions.getConfigProperty('settings.burialSites.burialSiteNameSegments.includeCemeteryKey') ? ' required' : '' %> />
|
||||||
</div>
|
<% if (configFunctions.getConfigProperty('settings.burialSites.burialSiteNameSegments.includeCemeteryKey')) { %>
|
||||||
<div class="field">
|
<p class="help">
|
||||||
<label class="label" for="cemetery--cemeteryDescription">Cemetery Description</label>
|
The cemetery key is prepended to the burial site names.
|
||||||
<div class="control">
|
</p>
|
||||||
<textarea class="textarea" id="cemetery--cemeteryDescription" name="cemeteryDescription"><%= cemetery.cemeteryDescription %></textarea>
|
<% } %>
|
||||||
</div>
|
</div>
|
||||||
</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>
|
||||||
<div class="column">
|
</div>
|
||||||
<div class="panel">
|
|
||||||
<h2 class="panel-heading">Address</h2>
|
|
||||||
<div class="panel-block is-block">
|
|
||||||
<div class="field">
|
|
||||||
<label class="label" for="cemetery--cemeteryAddress1">Address</label>
|
|
||||||
<div class="control">
|
|
||||||
<input class="input" id="cemetery--cemeteryAddress1" name="cemeteryAddress1" type="text" value="<%= cemetery.cemeteryAddress1 %>" maxlength="50" placeholder="Line 1" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="field">
|
|
||||||
<div class="control">
|
|
||||||
<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 class="columns">
|
|
||||||
<div class="column is-8">
|
|
||||||
<div class="field">
|
|
||||||
<label class="label" for="cemetery--cemeteryCity">City</label>
|
|
||||||
<div class="control">
|
|
||||||
<input class="input" id="cemetery--cemeteryCity" name="cemeteryCity" value="<%= cemetery.cemeteryCity %>" maxlength="20" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="column">
|
|
||||||
<div class="field">
|
|
||||||
<label class="label" for="cemetery--cemeteryProvince">Province</label>
|
|
||||||
<div class="control">
|
|
||||||
<input class="input" id="cemetery--cemeteryProvince" name="cemeteryProvince" value="<%= cemetery.cemeteryProvince %>" maxlength="2" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="columns">
|
|
||||||
<div class="column">
|
|
||||||
<div class="field">
|
|
||||||
<label class="label" for="cemetery--cemeteryPostalCode">Postal Code</label>
|
|
||||||
<div class="control">
|
|
||||||
<input class="input" id="cemetery--cemeteryPostalCode" name="cemeteryPostalCode" value="<%= cemetery.cemeteryPostalCode %>" maxlength="7" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="column">
|
|
||||||
<div class="field">
|
|
||||||
<label class="label" for="cemetery--cemeteryPhoneNumber">Phone Number</label>
|
|
||||||
<div class="control">
|
|
||||||
<input class="input" id="cemetery--cemeteryPhoneNumber" name="cemeteryPhoneNumber" value="<%= cemetery.cemeteryPhoneNumber %>" maxlength="30" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="columns">
|
<div class="column">
|
||||||
<div class="column">
|
<div class="panel">
|
||||||
<div class="panel">
|
<h2 class="panel-heading">Address</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="cemetery--cemeteryLatitude">Latitude</label>
|
<label class="label" for="cemetery--cemeteryAddress1">Address</label>
|
||||||
<div class="control">
|
<div class="control">
|
||||||
<input class="input" id="cemetery--cemeteryLatitude" name="cemeteryLatitude" type="number" min="-90" max="90" step="0.00000001" value="<%= cemetery.cemeteryLatitude %>" />
|
<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">
|
||||||
<label class="label" for="cemetery--cemeteryLongitude">Longitude</label>
|
|
||||||
<div class="control">
|
<div class="control">
|
||||||
<input class="input" id="cemetery--cemeteryLongitude" name="cemeteryLongitude" type="number" min="-180" max="180" step="0.00000001" value="<%= cemetery.cemeteryLongitude %>" />
|
<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>
|
<div class="columns">
|
||||||
</div>
|
<div class="column is-8">
|
||||||
</div>
|
<div class="field">
|
||||||
<div class="column">
|
<label class="label" for="cemetery--cemeteryCity">City</label>
|
||||||
<div class="panel">
|
<div class="control">
|
||||||
<h2 class="panel-heading">Image</h2>
|
<input class="input" id="cemetery--cemeteryCity" name="cemeteryCity" value="<%= cemetery.cemeteryCity %>" maxlength="20" />
|
||||||
<div class="panel-block is-block">
|
</div>
|
||||||
<div class="field">
|
</div>
|
||||||
<label class="label" for="cemetery--cemeterySvg">SVG File</label>
|
</div>
|
||||||
<div class="control">
|
<div class="column">
|
||||||
<div class="select is-fullwidth">
|
<div class="field">
|
||||||
<select id="cemetery--cemeterySvg" name="cemeterySvg">
|
<label class="label" for="cemetery--cemeteryProvince">Province</label>
|
||||||
<option value="">(Select a File)</option>
|
<div class="control">
|
||||||
<% for (const cemeterySVG of cemeterySVGs) { %>
|
<input class="input" id="cemetery--cemeteryProvince" name="cemeteryProvince" value="<%= cemetery.cemeteryProvince %>" maxlength="2" />
|
||||||
<option value="<%= cemeterySVG %>" <%= (cemetery.cemeterySvg === cemeterySVG) ? " selected" : "" %>>
|
</div>
|
||||||
<%= cemeterySVG %>
|
|
||||||
</option>
|
|
||||||
<% } %>
|
|
||||||
</select>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="columns">
|
||||||
|
<div class="column">
|
||||||
|
<div class="field">
|
||||||
|
<label class="label" for="cemetery--cemeteryPostalCode">Postal Code</label>
|
||||||
|
<div class="control">
|
||||||
|
<input class="input" id="cemetery--cemeteryPostalCode" name="cemeteryPostalCode" value="<%= cemetery.cemeteryPostalCode %>" maxlength="7" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="column">
|
||||||
|
<div class="field">
|
||||||
|
<label class="label" for="cemetery--cemeteryPhoneNumber">Phone Number</label>
|
||||||
|
<div class="control">
|
||||||
|
<input class="input" id="cemetery--cemeteryPhoneNumber" name="cemeteryPhoneNumber" value="<%= cemetery.cemeteryPhoneNumber %>" maxlength="30" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="columns">
|
||||||
|
<div class="column">
|
||||||
|
<div class="panel">
|
||||||
|
<h2 class="panel-heading">Geographic Location</h2>
|
||||||
|
<div class="panel-block is-block">
|
||||||
|
<div class="field">
|
||||||
|
<label class="label" for="cemetery--cemeteryLatitude">Latitude</label>
|
||||||
|
<div class="control">
|
||||||
|
<input class="input" id="cemetery--cemeteryLatitude" name="cemeteryLatitude" type="number"
|
||||||
|
min="<%= configFunctions.getConfigProperty('settings.latitudeMin') %>"
|
||||||
|
max="<%= configFunctions.getConfigProperty('settings.latitudeMax') %>"
|
||||||
|
step="0.00000001" value="<%= cemetery.cemeteryLatitude %>" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="field">
|
||||||
|
<label class="label" for="cemetery--cemeteryLongitude">Longitude</label>
|
||||||
|
<div class="control">
|
||||||
|
<input class="input" id="cemetery--cemeteryLongitude" name="cemeteryLongitude" type="number"
|
||||||
|
min="<%= configFunctions.getConfigProperty('settings.longitudeMin') %>"
|
||||||
|
max="<%= configFunctions.getConfigProperty('settings.longitudeMax') %>"
|
||||||
|
step="0.00000001" value="<%= cemetery.cemeteryLongitude %>" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="column">
|
||||||
|
<div class="panel">
|
||||||
|
<h2 class="panel-heading">Image</h2>
|
||||||
|
<div class="panel-block is-block">
|
||||||
|
<div class="field">
|
||||||
|
<label class="label" for="cemetery--cemeterySvg">SVG File</label>
|
||||||
|
<div class="control">
|
||||||
|
<div class="select is-fullwidth">
|
||||||
|
<select id="cemetery--cemeterySvg" name="cemeterySvg">
|
||||||
|
<option value="">(Select a File)</option>
|
||||||
|
<% for (const cemeterySVG of cemeterySVGs) { %>
|
||||||
|
<option value="<%= cemeterySVG %>" <%= (cemetery.cemeterySvg === cemeterySVG) ? " selected" : "" %>>
|
||||||
|
<%= cemeterySVG %>
|
||||||
|
</option>
|
||||||
|
<% } %>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<% if (!isCreate) { %>
|
<% if (!isCreate) { %>
|
||||||
<% const burialSiteSearchUrl = urlPrefix + "/burialSites?cemeteryId=" + cemetery.cemeteryId; %>
|
<% 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-white has-text-weight-bold">
|
<h2 class="title is-5 has-text-white has-text-weight-bold">
|
||||||
Burial Site Summaries
|
Burial Site Summaries
|
||||||
<a class="tag is-link ml-2" href="<%= burialSiteSearchUrl %>">
|
<a class="tag is-link ml-2" href="<%= burialSiteSearchUrl %>">
|
||||||
<%= cemetery.burialSiteCount %>
|
<%= cemetery.burialSiteCount %>
|
||||||
</a>
|
|
||||||
</h2>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="level-right">
|
|
||||||
<div class="level-item">
|
|
||||||
<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>Create a Burial Site</span>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div class="level-item">
|
|
||||||
<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>Export All</span>
|
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</h2>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="level-right">
|
||||||
|
<div class="level-item">
|
||||||
|
<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>Create a Burial Site</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="level-item">
|
||||||
|
<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>Export All</span>
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-block is-block">
|
</div>
|
||||||
<% if (cemetery.burialSiteCount === 0) { %>
|
<div class="panel-block is-block">
|
||||||
<div class="message is-info">
|
<% if (cemetery.burialSiteCount === 0) { %>
|
||||||
<p class="message-body">
|
<div class="message is-info">
|
||||||
There are no burial sites
|
<p class="message-body">
|
||||||
associated with this cemetery.
|
There are no burial sites
|
||||||
</p>
|
associated with this cemetery.
|
||||||
</div>
|
</p>
|
||||||
<% } else { %>
|
</div>
|
||||||
<div class="columns">
|
<% } else { %>
|
||||||
<div class="column">
|
<div class="columns">
|
||||||
<table class="table is-fullwidth is-striped is-hoverable">
|
<div class="column">
|
||||||
<thead>
|
<table class="table is-fullwidth is-striped is-hoverable">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Type</th>
|
||||||
|
<th class="has-text-right">
|
||||||
|
Burial Site Count
|
||||||
|
</th>
|
||||||
|
<th class="has-text-right">Percentage</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<% for (const burialSiteType of burialSiteTypeSummary) { %>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Type</th>
|
<td>
|
||||||
<th class="has-text-right">
|
<a class="has-text-weight-bold" href="<%= burialSiteSearchUrl %>&burialSiteTypeId=<%= burialSiteType.burialSiteTypeId %>">
|
||||||
Burial Site Count
|
<%= burialSiteType.burialSiteType %>
|
||||||
</th>
|
</a>
|
||||||
<th class="has-text-right">Percentage</th>
|
</td>
|
||||||
|
<td class="has-text-right">
|
||||||
|
<%= burialSiteType.burialSiteCount %>
|
||||||
|
</td>
|
||||||
|
<td class="has-text-right">
|
||||||
|
<%= ((burialSiteType.burialSiteCount / cemetery.burialSiteCount) * 100).toFixed(1) %>%
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
<% } %>
|
||||||
<tbody>
|
</tbody>
|
||||||
<% for (const burialSiteType of burialSiteTypeSummary) { %>
|
</table>
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<a class="has-text-weight-bold" href="<%= burialSiteSearchUrl %>&burialSiteTypeId=<%= burialSiteType.burialSiteTypeId %>">
|
|
||||||
<%= burialSiteType.burialSiteType %>
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
<td class="has-text-right">
|
|
||||||
<%= burialSiteType.burialSiteCount %>
|
|
||||||
</td>
|
|
||||||
<td class="has-text-right">
|
|
||||||
<%= ((burialSiteType.burialSiteCount / cemetery.burialSiteCount) * 100).toFixed(1) %>%
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<% } %>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
<div class="column">
|
|
||||||
<table class="table is-fullwidth is-striped is-hoverable">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>Status</th>
|
|
||||||
<th class="has-text-right">
|
|
||||||
Burial Site Count
|
|
||||||
</th>
|
|
||||||
<th class="has-text-right">Percentage</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<% for (const burialSiteStatus of burialSiteStatusSummary) { %>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<a class="has-text-weight-bold" href="<%= burialSiteSearchUrl %>&burialSiteStatusId=<%= burialSiteStatus.burialSiteStatusId %>">
|
|
||||||
<%= burialSiteStatus.burialSiteStatus %>
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
<td class="has-text-right">
|
|
||||||
<%= burialSiteStatus.burialSiteCount %>
|
|
||||||
</td>
|
|
||||||
<td class="has-text-right">
|
|
||||||
<%= ((burialSiteStatus.burialSiteCount / cemetery.burialSiteCount) * 100).toFixed(1) %>%
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<% } %>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<% } %>
|
<div class="column">
|
||||||
</div>
|
<table class="table is-fullwidth is-striped is-hoverable">
|
||||||
</div>
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Status</th>
|
||||||
|
<th class="has-text-right">
|
||||||
|
Burial Site Count
|
||||||
|
</th>
|
||||||
|
<th class="has-text-right">Percentage</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<% for (const burialSiteStatus of burialSiteStatusSummary) { %>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<a class="has-text-weight-bold" href="<%= burialSiteSearchUrl %>&burialSiteStatusId=<%= burialSiteStatus.burialSiteStatusId %>">
|
||||||
|
<%= burialSiteStatus.burialSiteStatus %>
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
<td class="has-text-right">
|
||||||
|
<%= burialSiteStatus.burialSiteCount %>
|
||||||
|
</td>
|
||||||
|
<td class="has-text-right">
|
||||||
|
<%= ((burialSiteStatus.burialSiteCount / cemetery.burialSiteCount) * 100).toFixed(1) %>%
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<% } %>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<% } %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<% } %>
|
<% } %>
|
||||||
|
|
||||||
<%- include('_footerA'); -%>
|
<%- include('_footerA'); -%>
|
||||||
|
|
|
||||||
|
|
@ -158,7 +158,7 @@
|
||||||
required accesskey="f"
|
required accesskey="f"
|
||||||
<%= (isCreate ? " autofocus" : "") %>>
|
<%= (isCreate ? " autofocus" : "") %>>
|
||||||
<% if (isCreate) { %>
|
<% if (isCreate) { %>
|
||||||
<option value="" data-is-preneed="false">(No Type)</option>
|
<option value="" data-is-preneed="false">(Select a Type)</option>
|
||||||
<% } %>
|
<% } %>
|
||||||
<% let typeIsFound = false; %>
|
<% let typeIsFound = false; %>
|
||||||
<% for (const contractType of contractTypes) { %>
|
<% for (const contractType of contractTypes) { %>
|
||||||
|
|
@ -498,9 +498,17 @@
|
||||||
</span>
|
</span>
|
||||||
</label>
|
</label>
|
||||||
<div class="control">
|
<div class="control">
|
||||||
<input class="input" id="contract--purchaserRelationship" name="purchaserRelationship" type="text" maxlength="100" autocomplete="off" value="<%= contract.purchaserRelationship %>" />
|
<input class="input" id="contract--purchaserRelationship" name="purchaserRelationship" type="text"
|
||||||
|
maxlength="100" autocomplete="off"
|
||||||
|
list="datalist--purchaserRelationships"
|
||||||
|
value="<%= contract.purchaserRelationship %>" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<datalist id="datalist--purchaserRelationships">
|
||||||
|
<% for (const relationship of configFunctions.getConfigProperty('settings.contracts.purchaserRelationships')) { %>
|
||||||
|
<option value="<%= relationship %>">
|
||||||
|
<% } %>
|
||||||
|
</datalist>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -254,20 +254,28 @@
|
||||||
<strong>Birth:</strong>
|
<strong>Birth:</strong>
|
||||||
</div>
|
</div>
|
||||||
<div class="column">
|
<div class="column">
|
||||||
<%= contractInterment.birthDateString ?? '(No Birth Date)' %><br />
|
<% if (contractInterment.birthDateString === '') { %>
|
||||||
<%= contractInterment.birthPlace ?? '(No Birth Place)' %>
|
<span class="has-text-grey">(No Birth Date)</span>
|
||||||
|
<% } else { %>
|
||||||
|
<%= contractInterment.birthDateString %>
|
||||||
|
<% } %><br />
|
||||||
|
<%= contractInterment.birthPlace %>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="columns">
|
<div class="columns mb-0">
|
||||||
<div class="column">
|
<div class="column">
|
||||||
<strong>Death:</strong>
|
<strong>Death:</strong>
|
||||||
</div>
|
</div>
|
||||||
<div class="column">
|
<div class="column">
|
||||||
<%= contractInterment.deathDateString ?? '(No Death Date)' %><br />
|
<% if (contractInterment.deathDateString === '') { %>
|
||||||
<%= contractInterment.deathPlace ?? '(No Death Place)' %>
|
<span class="has-text-grey">(No Death Date)</span>
|
||||||
|
<% } else { %>
|
||||||
|
<%= contractInterment.deathDateString %>
|
||||||
|
<% } %><br />
|
||||||
|
<%= contractInterment.deathPlace %>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="columns">
|
<div class="columns mb-0">
|
||||||
<div class="column">
|
<div class="column">
|
||||||
<strong>Age:</strong>
|
<strong>Age:</strong>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -94,30 +94,23 @@
|
||||||
<div class="column">
|
<div class="column">
|
||||||
<div class="columns is-desktop">
|
<div class="columns is-desktop">
|
||||||
<div class="column">
|
<div class="column">
|
||||||
<div class="card is-hover-container">
|
<div class="panel">
|
||||||
<div class="card-content">
|
<a class="panel-block" href="<%= urlPrefix %>/workOrders">
|
||||||
<div class="media">
|
<div class="media">
|
||||||
<div class="media-left">
|
<div class="media-left">
|
||||||
<span class="fa-layers fa-4x fa-fw">
|
<i class="fa-solid fa-4x fa-fw fa-hard-hat" aria-hidden="true"></i>
|
||||||
<i class="fas fa-fw fa-hard-hat" aria-hidden="true"></i>
|
|
||||||
<% if (workOrderCount > 0) { %>
|
|
||||||
<a class="fa-layers-counter has-background-success has-text-white" href="<%= urlPrefix %>/workOrders/?workOrderOpenDateString=<%= dateTimeFunctions.dateToString(new Date()) %>"><%= workOrderCount %></a>
|
|
||||||
<% } %>
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
<a class="media-content" href="<%= urlPrefix %>/workOrders">
|
<div class="media-content">
|
||||||
<h2 class="title is-4 mb-0 has-text-link">
|
<h2 class="title is-4 mb-0 has-text-link">
|
||||||
Work Orders
|
Work Orders
|
||||||
</h2>
|
</h2>
|
||||||
<p>
|
<p>
|
||||||
View and maintain work orders.<br />
|
View and maintain work orders.
|
||||||
<span class="tags has-addons is-invisible is-visible-hover">
|
|
||||||
<span class="tag is-link is-light">Shortcut</span>
|
|
||||||
<kbd class="tag">1</kbd>
|
|
||||||
</span>
|
|
||||||
</p>
|
</p>
|
||||||
</a>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</a>
|
||||||
|
<div class="panel-block is-block">
|
||||||
<% if (user.userProperties.canUpdate) { %>
|
<% if (user.userProperties.canUpdate) { %>
|
||||||
<a class="button is-fullwidth is-success is-light mb-2" href="<%= urlPrefix %>/workOrders/new">
|
<a class="button is-fullwidth is-success is-light mb-2" href="<%= urlPrefix %>/workOrders/new">
|
||||||
<span class="icon">
|
<span class="icon">
|
||||||
|
|
@ -137,31 +130,26 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="column">
|
<div class="column">
|
||||||
<div class="card is-hover-container">
|
<div class="panel">
|
||||||
<div class="card-content">
|
<a class="panel-block" href="<%= urlPrefix %>/contracts">
|
||||||
<div class="media">
|
<div class="media">
|
||||||
<div class="media-left">
|
<div class="media-left">
|
||||||
<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 (contractCount > 0) { %>
|
|
||||||
<span class="fa-layers-counter has-background-success"><%= contractCount %></span>
|
|
||||||
<% } %>
|
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<a class="media-content" href="<%= urlPrefix %>/contracts">
|
<div class="media-content">
|
||||||
<h2 class="title is-4 mb-0 has-text-link">
|
<h2 class="title is-4 mb-0 has-text-link">
|
||||||
Contracts
|
Contracts
|
||||||
</h2>
|
</h2>
|
||||||
<p>
|
<p>
|
||||||
View and maintain current and past contracts.<br />
|
View and maintain current and past contracts.
|
||||||
<span class="tags has-addons is-invisible is-visible-hover">
|
|
||||||
<span class="tag is-link is-light">Shortcut</span>
|
|
||||||
<kbd class="tag">2</kbd>
|
|
||||||
</span>
|
|
||||||
</p>
|
</p>
|
||||||
</a>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</a>
|
||||||
|
<div class="panel-block is-block">
|
||||||
<% if (user.userProperties.canUpdate) { %>
|
<% if (user.userProperties.canUpdate) { %>
|
||||||
<a class="button is-fullwidth is-success is-light mb-2" href="<%= urlPrefix %>/contracts/new">
|
<a class="button is-fullwidth is-success is-light mb-2" href="<%= urlPrefix %>/contracts/new">
|
||||||
<span class="icon">
|
<span class="icon">
|
||||||
|
|
@ -182,89 +170,98 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="columns is-desktop">
|
<div class="columns is-desktop">
|
||||||
<div class="column">
|
<div class="column">
|
||||||
<div class="card is-hover-container">
|
<div class="panel">
|
||||||
<div class="card-content">
|
<a class="panel-block" href="<%= urlPrefix %>/burialSites">
|
||||||
<div class="media">
|
<div class="media">
|
||||||
<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 %>/burialSites">
|
<div class="media-content">
|
||||||
<h2 class="title is-4 mb-0 has-text-link">
|
<h2 class="title is-4 mb-0 has-text-link">
|
||||||
Burial Sites
|
Burial Sites
|
||||||
</h2>
|
</h2>
|
||||||
<p>
|
<p>
|
||||||
View and maintain burial sites within a cemetery.<br />
|
View and maintain burial sites within a cemetery.
|
||||||
<span class="tags has-addons is-invisible is-visible-hover">
|
|
||||||
<span class="tag is-link is-light">Shortcut</span>
|
|
||||||
<kbd class="tag">3</kbd>
|
|
||||||
</span>
|
|
||||||
</p>
|
</p>
|
||||||
</a>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<% if (user.userProperties.canUpdate) { %>
|
</a>
|
||||||
|
<% if (user.userProperties.canUpdate) { %>
|
||||||
|
<div class="panel-block is-block">
|
||||||
<a class="button is-fullwidth is-success is-light" href="<%= urlPrefix %>/burialSites/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 Burial Site</span>
|
<span>New Burial Site</span>
|
||||||
</a>
|
</a>
|
||||||
<% } %>
|
</div>
|
||||||
</div>
|
<% } %>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="column">
|
<div class="column">
|
||||||
<div class="card is-hover-container">
|
<div class="panel">
|
||||||
<div class="card-content">
|
<a class="panel-block" href="<%= urlPrefix %>/cemeteries">
|
||||||
<div class="media">
|
<div class="media">
|
||||||
<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 %>/cemeteries">
|
<div class="media-content">
|
||||||
<h2 class="title is-4 mb-0 has-text-link">
|
<h2 class="title is-4 mb-0 has-text-link">
|
||||||
Cemeteries
|
Cemeteries
|
||||||
</h2>
|
</h2>
|
||||||
<p>
|
<p>
|
||||||
View and maintain cemeteries.
|
View and maintain cemeteries.
|
||||||
<span class="tags has-addons is-invisible is-visible-hover">
|
|
||||||
<span class="tag is-link is-light">Shortcut</span>
|
|
||||||
<kbd class="tag">4</kbd>
|
|
||||||
</span>
|
|
||||||
</p>
|
</p>
|
||||||
</a>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<% if (user.userProperties.canUpdate) { %>
|
</a>
|
||||||
|
<% if (user.userProperties.canUpdate) { %>
|
||||||
|
<div class="panel-block is-block">
|
||||||
<a class="button is-fullwidth is-success is-light" href="<%= urlPrefix %>/cemeteries/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 Cemetery</span>
|
<span>New Cemetery</span>
|
||||||
</a>
|
</a>
|
||||||
<% } %>
|
</div>
|
||||||
</div>
|
<% } %>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="columns is-desktop">
|
<div class="columns is-desktop">
|
||||||
<div class="column">
|
<div class="column">
|
||||||
<div class="card">
|
<div class="panel">
|
||||||
<div class="card-content">
|
<a class="panel-block" href="<%= urlPrefix %>/reports">
|
||||||
<div class="media">
|
<div class="media">
|
||||||
<div class="media-left">
|
<div class="media-left">
|
||||||
<i class="fas fa-4x fa-fw fa-file" aria-hidden="true"></i>
|
<i class="fas fa-4x fa-fw fa-file" aria-hidden="true"></i>
|
||||||
</div>
|
</div>
|
||||||
<a class="media-content" href="<%= urlPrefix %>/reports">
|
<div class="media-content">
|
||||||
<h2 class="title is-4 mb-0 has-text-link">
|
<h2 class="title is-4 mb-0 has-text-link">
|
||||||
Report Library
|
Report Library
|
||||||
</h2>
|
</h2>
|
||||||
<p>Produce reports and export data.</p>
|
<p>Produce reports and export data.</p>
|
||||||
</a>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="column">
|
<div class="column">
|
||||||
<div class="card is-hover-container">
|
<div class="panel">
|
||||||
<div class="card-content">
|
<a class="panel-block" href="https://cityssm.github.io/sunrise-cms/docs" rel="noopener noreferrer" target="_blank">
|
||||||
|
<div class="media">
|
||||||
|
<div class="media-left">
|
||||||
|
<i class="fas fa-4x fa-fw fa-circle-question" aria-hidden="true"></i>
|
||||||
|
</div>
|
||||||
|
<div class="media-content">
|
||||||
|
<h2 class="title is-4 mb-0 has-text-link">
|
||||||
|
Help Documentation
|
||||||
|
</h2>
|
||||||
|
<p>Tips and tricks to get the most out of Sunrise CMS.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<div class="panel-block is-block">
|
||||||
<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">
|
||||||
|
|
@ -278,10 +275,11 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<% if (user.userProperties.isAdmin) { %>
|
<% if (user.userProperties.isAdmin) { %>
|
||||||
<h2 class="title is-3">Administrator Tools</h2>
|
<div class="panel">
|
||||||
|
<div class="panel-heading">
|
||||||
<div class="card">
|
Administrator Tools
|
||||||
<div class="card-content">
|
</div>
|
||||||
|
<a class="panel-block" href="<%= urlPrefix %>/admin/fees">
|
||||||
<div class="media">
|
<div class="media">
|
||||||
<div class="media-left">
|
<div class="media-left">
|
||||||
<span class="fa-layers fa-4x fa-fw" aria-hidden="true">
|
<span class="fa-layers fa-4x fa-fw" aria-hidden="true">
|
||||||
|
|
@ -289,7 +287,7 @@
|
||||||
<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/fees">
|
<div class="media-content">
|
||||||
<h2 class="title is-4 mb-0 has-text-link">
|
<h2 class="title is-4 mb-0 has-text-link">
|
||||||
Fee Management
|
Fee Management
|
||||||
</h2>
|
</h2>
|
||||||
|
|
@ -297,10 +295,10 @@
|
||||||
Manage fees for contracts
|
Manage fees for contracts
|
||||||
and specific burial site types.
|
and specific burial site types.
|
||||||
</p>
|
</p>
|
||||||
</a>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</a>
|
||||||
<div class="card-content">
|
<a class="panel-block" href="<%= urlPrefix %>/admin/contractTypes">
|
||||||
<div class="media">
|
<div class="media">
|
||||||
<div class="media-left">
|
<div class="media-left">
|
||||||
<span class="fa-layers fa-4x fa-fw" aria-hidden="true">
|
<span class="fa-layers fa-4x fa-fw" aria-hidden="true">
|
||||||
|
|
@ -308,7 +306,7 @@
|
||||||
<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/contractTypes">
|
<div class="media-content">
|
||||||
<h2 class="title is-4 mb-0 has-text-link">
|
<h2 class="title is-4 mb-0 has-text-link">
|
||||||
Contract Type Management
|
Contract Type Management
|
||||||
</h2>
|
</h2>
|
||||||
|
|
@ -317,10 +315,10 @@
|
||||||
the fields associated with them,
|
the fields associated with them,
|
||||||
and their available print options.
|
and their available print options.
|
||||||
</p>
|
</p>
|
||||||
</a>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</a>
|
||||||
<div class="card-content">
|
<a class="panel-block" href="<%= urlPrefix %>/admin/burialSiteTypes">
|
||||||
<div class="media">
|
<div class="media">
|
||||||
<div class="media-left">
|
<div class="media-left">
|
||||||
<span class="fa-layers fa-4x fa-fw" aria-hidden="true">
|
<span class="fa-layers fa-4x fa-fw" aria-hidden="true">
|
||||||
|
|
@ -328,17 +326,17 @@
|
||||||
<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/burialSiteTypes">
|
<div class="media-content">
|
||||||
<h2 class="title is-4 mb-0 has-text-link">
|
<h2 class="title is-4 mb-0 has-text-link">
|
||||||
Burial Site Type Management
|
Burial Site Type Management
|
||||||
</h2>
|
</h2>
|
||||||
<p>
|
<p>
|
||||||
Manage burial site types and fields associated with them.
|
Manage burial site types and fields associated with them.
|
||||||
</p>
|
</p>
|
||||||
</a>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</a>
|
||||||
<div class="card-content">
|
<a class="panel-block" href="<%= urlPrefix %>/admin/tables">
|
||||||
<div class="media">
|
<div class="media">
|
||||||
<div class="media-left">
|
<div class="media-left">
|
||||||
<span class="fa-layers fa-4x fa-fw" aria-hidden="true">
|
<span class="fa-layers fa-4x fa-fw" aria-hidden="true">
|
||||||
|
|
@ -346,7 +344,7 @@
|
||||||
<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/tables">
|
<div class="media-content">
|
||||||
<h2 class="title is-4 mb-0 has-text-link">
|
<h2 class="title is-4 mb-0 has-text-link">
|
||||||
Config Table Management
|
Config Table Management
|
||||||
</h2>
|
</h2>
|
||||||
|
|
@ -355,15 +353,15 @@
|
||||||
work order types
|
work order types
|
||||||
and burial site statuses.
|
and burial site statuses.
|
||||||
</p>
|
</p>
|
||||||
</a>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</a>
|
||||||
<div class="card-content">
|
<a class="panel-block" href="<%= urlPrefix %>/admin/database">
|
||||||
<div class="media">
|
<div class="media">
|
||||||
<div class="media-left">
|
<div class="media-left">
|
||||||
<i class="fas fa-4x fa-fw fa-database" aria-hidden="true"></i>
|
<i class="fas fa-4x fa-fw fa-database" aria-hidden="true"></i>
|
||||||
</div>
|
</div>
|
||||||
<a class="media-content" href="<%= urlPrefix %>/admin/database">
|
<div class="media-content">
|
||||||
<h2 class="title is-4 mb-0 has-text-link">
|
<h2 class="title is-4 mb-0 has-text-link">
|
||||||
Database Maintenance
|
Database Maintenance
|
||||||
</h2>
|
</h2>
|
||||||
|
|
@ -371,25 +369,25 @@
|
||||||
Backup the database before making significant updates.
|
Backup the database before making significant updates.
|
||||||
Permanently delete records that have been previously deleted from the database.
|
Permanently delete records that have been previously deleted from the database.
|
||||||
</p>
|
</p>
|
||||||
</a>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</a>
|
||||||
<% if (configFunctions.getConfigProperty("application.ntfyStartup")) { %>
|
<% if (configFunctions.getConfigProperty("application.ntfyStartup")) { %>
|
||||||
<div class="card-content">
|
<a class="panel-block" href="<%= urlPrefix %>/admin/ntfyStartup">
|
||||||
<div class="media">
|
<div class="media">
|
||||||
<div class="media-left">
|
<div class="media-left">
|
||||||
<i class="far fa-4x fa-fw fa-comment-alt" aria-hidden="true"></i>
|
<i class="far fa-4x fa-fw fa-comment-alt" aria-hidden="true"></i>
|
||||||
</div>
|
</div>
|
||||||
<a class="media-content" href="<%= urlPrefix %>/admin/ntfyStartup">
|
<div class="media-content">
|
||||||
<h2 class="title is-4 mb-0 has-text-link">
|
<h2 class="title is-4 mb-0 has-text-link">
|
||||||
Ntfy Startup Notification
|
Ntfy Startup Notification
|
||||||
</h2>
|
</h2>
|
||||||
<p>
|
<p>
|
||||||
Subscribe to application startup notifications on a phone or a desktop computer.
|
Subscribe to application startup notifications on a phone or a desktop computer.
|
||||||
</p>
|
</p>
|
||||||
</a>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</a>
|
||||||
<% } %>
|
<% } %>
|
||||||
</div>
|
</div>
|
||||||
<% } %>
|
<% } %>
|
||||||
|
|
|
||||||
|
|
@ -83,7 +83,7 @@
|
||||||
<span class="tag is-info">CSV</span>
|
<span class="tag is-info">CSV</span>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h2 class="title is-5 is-marginless">Open Work Orders</h2>
|
<h2 class="title is-5 mb-0">Open Work Orders</h2>
|
||||||
<p>
|
<p>
|
||||||
All active work orders without completion dates.
|
All active work orders without completion dates.
|
||||||
</p>
|
</p>
|
||||||
|
|
@ -101,7 +101,7 @@
|
||||||
<span class="tag is-info">ICS</span>
|
<span class="tag is-info">ICS</span>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h2 class="title is-5 is-marginless">Work Order Milestone Calendar</h2>
|
<h2 class="title is-5 mb-0">Work Order Milestone Calendar</h2>
|
||||||
<p>
|
<p>
|
||||||
Upcoming and recently passed work order milestones,
|
Upcoming and recently passed work order milestones,
|
||||||
compatible with Microsoft Outlook and other calendar tools.
|
compatible with Microsoft Outlook and other calendar tools.
|
||||||
|
|
@ -118,40 +118,40 @@
|
||||||
|
|
||||||
<div class="panel">
|
<div class="panel">
|
||||||
<form class="panel-block align-items-flex-start" method="get" action="<%= urlPrefix %>/reports/contracts-current-byCemeteryId">
|
<form class="panel-block align-items-flex-start" method="get" action="<%= urlPrefix %>/reports/contracts-current-byCemeteryId">
|
||||||
<div class="has-text-centered my-2 ml-2 mr-3">
|
<div class="has-text-centered my-2 ml-2 mr-3">
|
||||||
<span class="icon has-text-info">
|
<span class="icon has-text-info">
|
||||||
<i class="fas fa-2x fa-file" aria-hidden="true"></i>
|
<i class="fas fa-2x fa-file" aria-hidden="true"></i>
|
||||||
</span><br />
|
</span><br />
|
||||||
<span class="tag is-info">CSV</span>
|
<span class="tag is-info">CSV</span>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h2 class="title is-5 is-marginless">
|
<h2 class="title is-5 mb-0">
|
||||||
Current Contract By Cemetery
|
Current Contract By Cemetery
|
||||||
</h2>
|
</h2>
|
||||||
<div class="field has-addons mt-2">
|
<div class="field has-addons mt-2">
|
||||||
<div class="control">
|
<div class="control">
|
||||||
<label class="button is-small is-static" for="contracts-current-byCemeteryId--cemeteryId">
|
<label class="button is-small is-static" for="contracts-current-byCemeteryId--cemeteryId">
|
||||||
Cemetery
|
Cemetery
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="control is-expanded">
|
<div class="control is-expanded">
|
||||||
<div class="select is-small is-fullwidth">
|
<div class="select is-small is-fullwidth">
|
||||||
<select id="contracts-current-byCemeteryId--cemeteryId" name="cemeteryId">
|
<select id="contracts-current-byCemeteryId--cemeteryId" name="cemeteryId">
|
||||||
<% for (const cemetery of cemeteries) { %>
|
<% for (const cemetery of cemeteries) { %>
|
||||||
<option value="<%= cemetery.cemeteryId %>">
|
<option value="<%= cemetery.cemeteryId %>">
|
||||||
<%= cemetery.cemeteryName || "(No Name)" %>
|
<%= cemetery.cemeteryName || "(No Name)" %>
|
||||||
</option>
|
</option>
|
||||||
<% } %>
|
<% } %>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="control">
|
|
||||||
<button class="button is-small is-primary" type="submit">
|
|
||||||
Export
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="control">
|
||||||
|
<button class="button is-small is-primary" type="submit">
|
||||||
|
Export
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</form>
|
</form>
|
||||||
<form class="panel-block align-items-flex-start" method="get" action="<%= urlPrefix %>/reports/contractTransactions-byTransactionDateString">
|
<form class="panel-block align-items-flex-start" method="get" action="<%= urlPrefix %>/reports/contractTransactions-byTransactionDateString">
|
||||||
<div class="has-text-centered my-2 ml-2 mr-3">
|
<div class="has-text-centered my-2 ml-2 mr-3">
|
||||||
|
|
@ -161,7 +161,7 @@
|
||||||
<span class="tag is-info">CSV</span>
|
<span class="tag is-info">CSV</span>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h2 class="title is-5 is-marginless">Transactions by Date</h2>
|
<h2 class="title is-5 mb-0">Transactions by Date</h2>
|
||||||
<div class="field has-addons mt-2">
|
<div class="field has-addons mt-2">
|
||||||
<div class="control">
|
<div class="control">
|
||||||
<label class="button is-small is-static" for="contractTransactions-byTransactionDateString--transactionDateString">
|
<label class="button is-small is-static" for="contractTransactions-byTransactionDateString--transactionDateString">
|
||||||
|
|
@ -193,7 +193,7 @@
|
||||||
<span class="tag is-info">CSV</span>
|
<span class="tag is-info">CSV</span>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h2 class="title is-5 is-marginless">
|
<h2 class="title is-5 mb-0">
|
||||||
Burial Sites By Cemetery
|
Burial Sites By Cemetery
|
||||||
</h2>
|
</h2>
|
||||||
<div class="field has-addons mt-2">
|
<div class="field has-addons mt-2">
|
||||||
|
|
@ -229,7 +229,7 @@
|
||||||
<span class="tag is-info">CSV</span>
|
<span class="tag is-info">CSV</span>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h2 class="title is-5 is-marginless">Burial Sites By Type</h2>
|
<h2 class="title is-5 mb-0">Burial Sites By Type</h2>
|
||||||
<div class="field has-addons mt-2">
|
<div class="field has-addons mt-2">
|
||||||
<div class="control">
|
<div class="control">
|
||||||
<label class="button is-small is-static" for="burialSites-byBurialSiteTypeId--burialSiteTypeId">
|
<label class="button is-small is-static" for="burialSites-byBurialSiteTypeId--burialSiteTypeId">
|
||||||
|
|
@ -263,29 +263,29 @@
|
||||||
<span class="tag is-info">CSV</span>
|
<span class="tag is-info">CSV</span>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h2 class="title is-5 is-marginless">Burial Sites By Status</h2>
|
<h2 class="title is-5 mb-0">Burial Sites By Status</h2>
|
||||||
<div class="field has-addons mt-2">
|
<div class="field has-addons mt-2">
|
||||||
<div class="control">
|
<div class="control">
|
||||||
<label class="button is-small is-static" for="burialSites-byBurialSiteStatusId--burialSiteStatusId">
|
<label class="button is-small is-static" for="burialSites-byBurialSiteStatusId--burialSiteStatusId">
|
||||||
Burial Site Status
|
Burial Site Status
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="control is-expanded">
|
<div class="control is-expanded">
|
||||||
<div class="select is-small is-fullwidth">
|
<div class="select is-small is-fullwidth">
|
||||||
<select id="burialSites-byBurialSiteStatusId--burialSiteStatusId" name="burialSiteStatusId">
|
<select id="burialSites-byBurialSiteStatusId--burialSiteStatusId" name="burialSiteStatusId">
|
||||||
<% for (const burialSiteStatus of burialSiteStatuses) { %>
|
<% for (const burialSiteStatus of burialSiteStatuses) { %>
|
||||||
<option value="<%= burialSiteStatus.burialSiteStatusId %>">
|
<option value="<%= burialSiteStatus.burialSiteStatusId %>">
|
||||||
<%= burialSiteStatus.burialSiteStatus %>
|
<%= burialSiteStatus.burialSiteStatus %>
|
||||||
</option>
|
</option>
|
||||||
<% } %>
|
<% } %>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="control">
|
|
||||||
<button class="button is-small is-primary" type="submit">
|
|
||||||
Export
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="control">
|
||||||
|
<button class="button is-small is-primary" type="submit">
|
||||||
|
Export
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
@ -302,7 +302,7 @@
|
||||||
<span class="tag is-info">CSV</span>
|
<span class="tag is-info">CSV</span>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h2 class="title is-5 is-marginless">Full Cemetery List</h2>
|
<h2 class="title is-5 mb-0">Full Cemetery List</h2>
|
||||||
<p>
|
<p>
|
||||||
All active cemeteries.
|
All active cemeteries.
|
||||||
</p>
|
</p>
|
||||||
|
|
@ -368,26 +368,37 @@
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
<a class="panel-block align-items-flex-start" href="<%= urlPrefix %>/reports/contractInterments-all" download>
|
<a class="panel-block align-items-flex-start" href="<%= urlPrefix %>/reports/contractInterments-all" download>
|
||||||
<div class="has-text-centered my-2 ml-2 mr-3">
|
<div class="has-text-centered my-2 ml-2 mr-3">
|
||||||
<span class="icon has-text-info">
|
<span class="icon has-text-info">
|
||||||
<i class="fas fa-2x fa-table" aria-hidden="true"></i>
|
<i class="fas fa-2x fa-table" aria-hidden="true"></i>
|
||||||
</span><br />
|
</span><br />
|
||||||
<span class="tag is-info">CSV</span>
|
<span class="tag is-info">CSV</span>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h3 class="title is-5 is-marginless">Full ContractInterments Table</h3>
|
<h3 class="title is-5 is-marginless">Full ContractInterments Table</h3>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
<a class="panel-block align-items-flex-start" href="<%= urlPrefix %>/reports/contractTransactions-all" download>
|
<a class="panel-block align-items-flex-start" href="<%= urlPrefix %>/reports/contractTransactions-all" download>
|
||||||
<div class="has-text-centered my-2 ml-2 mr-3">
|
<div class="has-text-centered my-2 ml-2 mr-3">
|
||||||
<span class="icon has-text-info">
|
<span class="icon has-text-info">
|
||||||
<i class="fas fa-2x fa-table" aria-hidden="true"></i>
|
<i class="fas fa-2x fa-table" aria-hidden="true"></i>
|
||||||
</span><br />
|
</span><br />
|
||||||
<span class="tag is-info">CSV</span>
|
<span class="tag is-info">CSV</span>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h3 class="title is-5 is-marginless">Full ContractTransactions Table</h3>
|
<h3 class="title is-5 is-marginless">Full ContractTransactions Table</h3>
|
||||||
</div>
|
</div>
|
||||||
|
</a>
|
||||||
|
<a class="panel-block align-items-flex-start" href="<%= urlPrefix %>/reports/funeralHomes-all" download>
|
||||||
|
<div class="has-text-centered my-2 ml-2 mr-3">
|
||||||
|
<span class="icon has-text-info">
|
||||||
|
<i class="fas fa-2x fa-table" aria-hidden="true"></i>
|
||||||
|
</span><br />
|
||||||
|
<span class="tag is-info">CSV</span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h3 class="title is-5 is-marginless">Full FuneralHomes Table</h3>
|
||||||
|
</div>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -565,26 +576,37 @@
|
||||||
<div class="panel">
|
<div class="panel">
|
||||||
<h2 class="panel-heading">Contract Tables</h2>
|
<h2 class="panel-heading">Contract Tables</h2>
|
||||||
<a class="panel-block align-items-flex-start" href="<%= urlPrefix %>/reports/contractTypes-all" download>
|
<a class="panel-block align-items-flex-start" href="<%= urlPrefix %>/reports/contractTypes-all" download>
|
||||||
<div class="has-text-centered my-2 ml-2 mr-3">
|
<div class="has-text-centered my-2 ml-2 mr-3">
|
||||||
<span class="icon has-text-info">
|
<span class="icon has-text-info">
|
||||||
<i class="fas fa-2x fa-table" aria-hidden="true"></i>
|
<i class="fas fa-2x fa-table" aria-hidden="true"></i>
|
||||||
</span><br />
|
</span><br />
|
||||||
<span class="tag is-info">CSV</span>
|
<span class="tag is-info">CSV</span>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h3 class="title is-5 is-marginless">Full ContractTypes Table</h3>
|
<h3 class="title is-5 is-marginless">Full ContractTypes Table</h3>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
<a class="panel-block align-items-flex-start" href="<%= urlPrefix %>/reports/contractTypeFields-all" download>
|
<a class="panel-block align-items-flex-start" href="<%= urlPrefix %>/reports/contractTypeFields-all" download>
|
||||||
<div class="has-text-centered my-2 ml-2 mr-3">
|
<div class="has-text-centered my-2 ml-2 mr-3">
|
||||||
<span class="icon has-text-info">
|
<span class="icon has-text-info">
|
||||||
<i class="fas fa-2x fa-table" aria-hidden="true"></i>
|
<i class="fas fa-2x fa-table" aria-hidden="true"></i>
|
||||||
</span><br />
|
</span><br />
|
||||||
<span class="tag is-info">CSV</span>
|
<span class="tag is-info">CSV</span>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h3 class="title is-5 is-marginless">Full ContractTypeFields Table</h3>
|
<h3 class="title is-5 is-marginless">Full ContractTypeFields Table</h3>
|
||||||
</div>
|
</div>
|
||||||
|
</a>
|
||||||
|
<a class="panel-block align-items-flex-start" href="<%= urlPrefix %>/reports/intermentContainerTypes-all" download>
|
||||||
|
<div class="has-text-centered my-2 ml-2 mr-3">
|
||||||
|
<span class="icon has-text-info">
|
||||||
|
<i class="fas fa-2x fa-table" aria-hidden="true"></i>
|
||||||
|
</span><br />
|
||||||
|
<span class="tag is-info">CSV</span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h3 class="title is-5 is-marginless">Full IntermentContainerTypes Table</h3>
|
||||||
|
</div>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="panel">
|
<div class="panel">
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue