major refactoring

mostly finished, see #1
deepsource-autofix-76c6eb20
Dan Gowans 2025-03-07 15:42:38 -05:00
parent 5f6c6a0be5
commit 7dc95ef90f
150 changed files with 6706 additions and 6319 deletions

1
app.js
View File

@ -75,7 +75,6 @@ if (urlPrefix !== '') {
debug(`urlPrefix = ${urlPrefix}`); debug(`urlPrefix = ${urlPrefix}`);
} }
app.use(urlPrefix, express.static(path.join('public'))); app.use(urlPrefix, express.static(path.join('public')));
app.use(`${urlPrefix}/lib/bulma-calendar`, express.static(path.join('node_modules', 'bulma-calendar', 'dist')));
app.use(`${urlPrefix}/lib/cityssm-bulma-js/bulma-js.js`, express.static(path.join('node_modules', '@cityssm', 'bulma-js', 'dist', 'bulma-js.js'))); app.use(`${urlPrefix}/lib/cityssm-bulma-js/bulma-js.js`, express.static(path.join('node_modules', '@cityssm', 'bulma-js', 'dist', 'bulma-js.js')));
app.use(`${urlPrefix}/lib/cityssm-bulma-webapp-js`, express.static(path.join('node_modules', '@cityssm', 'bulma-webapp-js', 'dist'))); app.use(`${urlPrefix}/lib/cityssm-bulma-webapp-js`, express.static(path.join('node_modules', '@cityssm', 'bulma-webapp-js', 'dist')));
app.use(`${urlPrefix}/lib/fa`, express.static(path.join('node_modules', '@fortawesome', 'fontawesome-free'))); app.use(`${urlPrefix}/lib/fa`, express.static(path.join('node_modules', '@fortawesome', 'fontawesome-free')));

5
app.ts
View File

@ -104,11 +104,6 @@ if (urlPrefix !== '') {
app.use(urlPrefix, express.static(path.join('public'))) app.use(urlPrefix, express.static(path.join('public')))
app.use(
`${urlPrefix}/lib/bulma-calendar`,
express.static(path.join('node_modules', 'bulma-calendar', 'dist'))
)
app.use( app.use(
`${urlPrefix}/lib/cityssm-bulma-js/bulma-js.js`, `${urlPrefix}/lib/cityssm-bulma-js/bulma-js.js`,
express.static( express.static(

View File

@ -1,11 +1,11 @@
import { testAdmin } from '../../../test/_globals.js'; import { testAdmin } from '../../../test/_globals.js';
import { login, logout } from '../../support/index.js'; import { login, logout } from '../../support/index.js';
describe('Admin - Lot Type Management', () => { describe('Admin - Burial Site Type Management', () => {
beforeEach('Loads page', () => { beforeEach('Loads page', () => {
logout(); logout();
login(testAdmin); login(testAdmin);
cy.visit('/admin/lotTypes'); cy.visit('/admin/burialSiteTypes');
cy.location('pathname').should('equal', '/admin/lotTypes'); cy.location('pathname').should('equal', '/admin/burialSiteTypes');
}); });
afterEach(logout); afterEach(logout);
it('Has no detectable accessibility issues', () => { it('Has no detectable accessibility issues', () => {

View File

@ -1,12 +1,12 @@
import { testAdmin } from '../../../test/_globals.js' import { testAdmin } from '../../../test/_globals.js'
import { login, logout } from '../../support/index.js' import { login, logout } from '../../support/index.js'
describe('Admin - Lot Type Management', () => { describe('Admin - Burial Site Type Management', () => {
beforeEach('Loads page', () => { beforeEach('Loads page', () => {
logout() logout()
login(testAdmin) login(testAdmin)
cy.visit('/admin/lotTypes') cy.visit('/admin/burialSiteTypes')
cy.location('pathname').should('equal', '/admin/lotTypes') cy.location('pathname').should('equal', '/admin/burialSiteTypes')
}) })
afterEach(logout) afterEach(logout)

View File

@ -1,17 +1,17 @@
import { testUpdate } from '../../../test/_globals.js'; import { testUpdate } from '../../../test/_globals.js';
import { login, logout } from '../../support/index.js'; import { login, logout } from '../../support/index.js';
describe('Update - Lots', () => { describe('Update - Burial Sites', () => {
beforeEach('Loads page', () => { beforeEach('Loads page', () => {
logout(); logout();
login(testUpdate); login(testUpdate);
}); });
afterEach(logout); afterEach(logout);
it('Has a "Create" link on the Lot Search', () => { it('Has a "Create" link on the Burial Site Search', () => {
cy.visit('/lots'); cy.visit('/burialSites');
cy.location('pathname').should('equal', '/lots'); cy.location('pathname').should('equal', '/burialSites');
cy.get("a[href$='/burialSites/new']").should('exist'); cy.get("a[href$='/burialSites/new']").should('exist');
}); });
describe('Update a New Lot', () => { describe('Creates a New Burial Site', () => {
it('Has no detectable accessibility issues', () => { it('Has no detectable accessibility issues', () => {
cy.visit('/burialSites/new'); cy.visit('/burialSites/new');
cy.injectAxe(); cy.injectAxe();

View File

@ -1,7 +1,7 @@
import { testUpdate } from '../../../test/_globals.js' import { testUpdate } from '../../../test/_globals.js'
import { login, logout } from '../../support/index.js' import { login, logout } from '../../support/index.js'
describe('Update - Lots', () => { describe('Update - Burial Sites', () => {
beforeEach('Loads page', () => { beforeEach('Loads page', () => {
logout() logout()
login(testUpdate) login(testUpdate)
@ -9,13 +9,13 @@ describe('Update - Lots', () => {
afterEach(logout) afterEach(logout)
it('Has a "Create" link on the Lot Search', () => { it('Has a "Create" link on the Burial Site Search', () => {
cy.visit('/lots') cy.visit('/burialSites')
cy.location('pathname').should('equal', '/lots') cy.location('pathname').should('equal', '/burialSites')
cy.get("a[href$='/burialSites/new']").should('exist') cy.get("a[href$='/burialSites/new']").should('exist')
}) })
describe('Update a New Lot', () => { describe('Creates a New Burial Site', () => {
it('Has no detectable accessibility issues', () => { it('Has no detectable accessibility issues', () => {
cy.visit('/burialSites/new') cy.visit('/burialSites/new')
cy.injectAxe() cy.injectAxe()

View File

@ -1,17 +1,17 @@
import { testUpdate } from '../../../test/_globals.js'; import { testUpdate } from '../../../test/_globals.js';
import { login, logout } from '../../support/index.js'; import { login, logout } from '../../support/index.js';
describe('Update - Lot Occupancies', () => { describe('Update - Contracts', () => {
beforeEach(() => { beforeEach(() => {
logout(); logout();
login(testUpdate); login(testUpdate);
}); });
afterEach(logout); afterEach(logout);
it('Has a "Create" link on the Lot Occupancy Search', () => { it('Has a "Create" link on the Contract Search', () => {
cy.visit('/lotOccupancies'); cy.visit('/contracts');
cy.location('pathname').should('equal', '/lotOccupancies'); cy.location('pathname').should('equal', '/contracts');
cy.get("a[href$='/contracts/new']").should('exist'); cy.get("a[href$='/contracts/new']").should('exist');
}); });
describe('Update a New Lot Occupancy', () => { describe('Creates a New Contract', () => {
it('Has no detectable accessibility issues', () => { it('Has no detectable accessibility issues', () => {
cy.visit('/contracts/new'); cy.visit('/contracts/new');
cy.injectAxe(); cy.injectAxe();

View File

@ -1,7 +1,7 @@
import { testUpdate } from '../../../test/_globals.js' import { testUpdate } from '../../../test/_globals.js'
import { login, logout } from '../../support/index.js' import { login, logout } from '../../support/index.js'
describe('Update - Lot Occupancies', () => { describe('Update - Contracts', () => {
beforeEach(() => { beforeEach(() => {
logout() logout()
login(testUpdate) login(testUpdate)
@ -9,13 +9,13 @@ describe('Update - Lot Occupancies', () => {
afterEach(logout) afterEach(logout)
it('Has a "Create" link on the Lot Occupancy Search', () => { it('Has a "Create" link on the Contract Search', () => {
cy.visit('/lotOccupancies') cy.visit('/contracts')
cy.location('pathname').should('equal', '/lotOccupancies') cy.location('pathname').should('equal', '/contracts')
cy.get("a[href$='/contracts/new']").should('exist') cy.get("a[href$='/contracts/new']").should('exist')
}) })
describe('Update a New Lot Occupancy', () => { describe('Creates a New Contract', () => {
it('Has no detectable accessibility issues', () => { it('Has no detectable accessibility issues', () => {
cy.visit('/contracts/new') cy.visit('/contracts/new')
cy.injectAxe() cy.injectAxe()

View File

@ -11,7 +11,7 @@ describe('Update - Work Orders', () => {
cy.location('pathname').should('equal', '/workOrders'); cy.location('pathname').should('equal', '/workOrders');
cy.get("a[href$='/workOrders/new']").should('exist'); cy.get("a[href$='/workOrders/new']").should('exist');
}); });
describe('Update a New Work Order', () => { describe('Creates a New Work Order', () => {
it('Has no detectable accessibility issues', () => { it('Has no detectable accessibility issues', () => {
cy.visit('/workOrders/new'); cy.visit('/workOrders/new');
cy.location('pathname').should('equal', '/workOrders/new'); cy.location('pathname').should('equal', '/workOrders/new');

View File

@ -15,7 +15,7 @@ describe('Update - Work Orders', () => {
cy.get("a[href$='/workOrders/new']").should('exist') cy.get("a[href$='/workOrders/new']").should('exist')
}) })
describe('Update a New Work Order', () => { describe('Creates a New Work Order', () => {
it('Has no detectable accessibility issues', () => { it('Has no detectable accessibility issues', () => {
cy.visit('/workOrders/new') cy.visit('/workOrders/new')
cy.location('pathname').should('equal', '/workOrders/new') cy.location('pathname').should('equal', '/workOrders/new')

View File

@ -14,7 +14,7 @@ export default async function addContractComment(commentForm, user) {
} }
const database = await acquireConnection(); const database = await acquireConnection();
const result = database const result = database
.prepare(`insert into BurialSiteContactComments ( .prepare(`insert into ContractComments (
contractId, contractId,
commentDate, commentTime, commentDate, commentTime,
comment, comment,

View File

@ -41,7 +41,7 @@ export default async function addContractComment(
const result = database const result = database
.prepare( .prepare(
`insert into BurialSiteContactComments ( `insert into ContractComments (
contractId, contractId,
commentDate, commentTime, commentDate, commentTime,
comment, comment,

View File

@ -0,0 +1,16 @@
import { type DateString } from '@cityssm/utils-datetime';
export interface AddForm {
contractId: string | number;
deceasedName: string;
deceasedAddress1: string;
deceasedAddress2: string;
deceasedCity: string;
deceasedProvince: string;
deceasedPostalCode: string;
birthDateString: DateString | '';
birthPlace: string;
deathDateString: DateString | '';
deathPlace: string;
intermentContainerTypeId: string | number;
}
export default function addContractInterment(contractForm: AddForm, user: User): Promise<number>;

View File

@ -0,0 +1,30 @@
import { dateStringToInteger } from '@cityssm/utils-datetime';
import { acquireConnection } from './pool.js';
export default async function addContractInterment(contractForm, user) {
const database = await acquireConnection();
const maxIntermentNumber = (database
.prepare(`select max(intermentNumber) as maxIntermentNumber
from ContractInterments
where contractId = ?`)
.pluck()
.get(contractForm.contractId) ?? 0);
const newIntermentNumber = maxIntermentNumber + 1;
const rightNowMillis = Date.now();
database
.prepare(`insert into ContractInterments
(contractId, intermentNumber,
deceasedName, deceasedAddress1, deceasedAddress2, deceasedCity, deceasedProvince, deceasedPostalCode,
birthDate, birthPlace, deathDate, deathPlace, intermentContainerTypeId,
recordCreate_userName, recordCreate_timeMillis,
recordUpdate_userName, recordUpdate_timeMillis)
values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`)
.run(contractForm.contractId, newIntermentNumber, contractForm.deceasedName, contractForm.deceasedAddress1, contractForm.deceasedAddress2, contractForm.deceasedCity, contractForm.deceasedProvince, contractForm.deceasedPostalCode, contractForm.birthDateString === ''
? undefined
: dateStringToInteger(contractForm.birthDateString), contractForm.birthPlace, contractForm.deathDateString === ''
? undefined
: dateStringToInteger(contractForm.deathDateString), contractForm.deathPlace, contractForm.intermentContainerTypeId === ''
? undefined
: contractForm.intermentContainerTypeId, user.userName, rightNowMillis, user.userName, rightNowMillis);
database.release();
return newIntermentNumber;
}

View File

@ -0,0 +1,77 @@
import { type DateString, dateStringToInteger } from '@cityssm/utils-datetime'
import { acquireConnection } from './pool.js'
export interface AddForm {
contractId: string | number
deceasedName: string
deceasedAddress1: string
deceasedAddress2: string
deceasedCity: string
deceasedProvince: string
deceasedPostalCode: string
birthDateString: DateString | ''
birthPlace: string
deathDateString: DateString | ''
deathPlace: string
intermentContainerTypeId: string | number
}
export default async function addContractInterment(
contractForm: AddForm,
user: User
): Promise<number> {
const database = await acquireConnection()
const maxIntermentNumber = (database
.prepare(
`select max(intermentNumber) as maxIntermentNumber
from ContractInterments
where contractId = ?`
)
.pluck()
.get(contractForm.contractId) ?? 0) as number
const newIntermentNumber = maxIntermentNumber + 1
const rightNowMillis = Date.now()
database
.prepare(
`insert into ContractInterments
(contractId, intermentNumber,
deceasedName, deceasedAddress1, deceasedAddress2, deceasedCity, deceasedProvince, deceasedPostalCode,
birthDate, birthPlace, deathDate, deathPlace, intermentContainerTypeId,
recordCreate_userName, recordCreate_timeMillis,
recordUpdate_userName, recordUpdate_timeMillis)
values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
)
.run(
contractForm.contractId,
newIntermentNumber,
contractForm.deceasedName,
contractForm.deceasedAddress1,
contractForm.deceasedAddress2,
contractForm.deceasedCity,
contractForm.deceasedProvince,
contractForm.deceasedPostalCode,
contractForm.birthDateString === ''
? undefined
: dateStringToInteger(contractForm.birthDateString),
contractForm.birthPlace,
contractForm.deathDateString === ''
? undefined
: dateStringToInteger(contractForm.deathDateString),
contractForm.deathPlace,
contractForm.intermentContainerTypeId === ''
? undefined
: contractForm.intermentContainerTypeId,
user.userName,
rightNowMillis,
user.userName,
rightNowMillis
)
database.release()
return newIntermentNumber
}

View File

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

View File

@ -1,12 +1,12 @@
import { acquireConnection } from './pool.js' import { acquireConnection } from './pool.js'
export interface AddWorkOrderLotForm { export interface AddForm {
workOrderId: number | string workOrderId: number | string
burialSiteId: number | string burialSiteId: number | string
} }
export default async function addWorkOrderBurialSite( export default async function addWorkOrderBurialSite(
workOrderLotForm: AddWorkOrderLotForm, workOrderLotForm: AddForm,
user: User user: User
): Promise<boolean> { ): Promise<boolean> {
const database = await acquireConnection() const database = await acquireConnection()

View File

@ -1,5 +1,5 @@
export interface AddWorkOrderCommentForm { export interface AddWorkOrderCommentForm {
workOrderId: string; workOrderId: string;
workOrderComment: string; comment: string;
} }
export default function addWorkOrderComment(workOrderCommentForm: AddWorkOrderCommentForm, user: User): Promise<number>; export default function addWorkOrderComment(workOrderCommentForm: AddWorkOrderCommentForm, user: User): Promise<number>;

View File

@ -6,12 +6,12 @@ export default async function addWorkOrderComment(workOrderCommentForm, user) {
const result = database const result = database
.prepare(`insert into WorkOrderComments ( .prepare(`insert into WorkOrderComments (
workOrderId, workOrderId,
workOrderCommentDate, workOrderCommentTime, commentDate, commentTime,
workOrderComment, comment,
recordCreate_userName, recordCreate_timeMillis, recordCreate_userName, recordCreate_timeMillis,
recordUpdate_userName, recordUpdate_timeMillis) recordUpdate_userName, recordUpdate_timeMillis)
values (?, ?, ?, ?, ?, ?, ?, ?)`) values (?, ?, ?, ?, ?, ?, ?, ?)`)
.run(workOrderCommentForm.workOrderId, dateToInteger(rightNow), dateToTimeInteger(rightNow), workOrderCommentForm.workOrderComment, user.userName, rightNow.getTime(), user.userName, rightNow.getTime()); .run(workOrderCommentForm.workOrderId, dateToInteger(rightNow), dateToTimeInteger(rightNow), workOrderCommentForm.comment, user.userName, rightNow.getTime(), user.userName, rightNow.getTime());
database.release(); database.release();
return result.lastInsertRowid; return result.lastInsertRowid;
} }

View File

@ -4,7 +4,7 @@ import { acquireConnection } from './pool.js'
export interface AddWorkOrderCommentForm { export interface AddWorkOrderCommentForm {
workOrderId: string workOrderId: string
workOrderComment: string comment: string
} }
export default async function addWorkOrderComment( export default async function addWorkOrderComment(
@ -19,8 +19,8 @@ export default async function addWorkOrderComment(
.prepare( .prepare(
`insert into WorkOrderComments ( `insert into WorkOrderComments (
workOrderId, workOrderId,
workOrderCommentDate, workOrderCommentTime, commentDate, commentTime,
workOrderComment, comment,
recordCreate_userName, recordCreate_timeMillis, recordCreate_userName, recordCreate_timeMillis,
recordUpdate_userName, recordUpdate_timeMillis) recordUpdate_userName, recordUpdate_timeMillis)
values (?, ?, ?, ?, ?, ?, ?, ?)` values (?, ?, ?, ?, ?, ?, ?, ?)`
@ -29,7 +29,7 @@ export default async function addWorkOrderComment(
workOrderCommentForm.workOrderId, workOrderCommentForm.workOrderId,
dateToInteger(rightNow), dateToInteger(rightNow),
dateToTimeInteger(rightNow), dateToTimeInteger(rightNow),
workOrderCommentForm.workOrderComment, workOrderCommentForm.comment,
user.userName, user.userName,
rightNow.getTime(), rightNow.getTime(),
user.userName, user.userName,

View File

@ -1,6 +1,6 @@
import type { PoolConnection } from 'better-sqlite-pool'; import type { PoolConnection } from 'better-sqlite-pool';
export interface AddWorkOrderContractOccupancyForm { export interface AddForm {
workOrderId: number | string; workOrderId: number | string;
contractId: number | string; contractId: number | string;
} }
export default function addWorkOrderContract(addForm: AddWorkOrderContractOccupancyForm, user: User, connectedDatabase?: PoolConnection): Promise<boolean>; export default function addWorkOrderContract(addForm: AddForm, user: User, connectedDatabase?: PoolConnection): Promise<boolean>;

View File

@ -2,13 +2,13 @@ import type { PoolConnection } from 'better-sqlite-pool'
import { acquireConnection } from './pool.js' import { acquireConnection } from './pool.js'
export interface AddWorkOrderContractOccupancyForm { export interface AddForm {
workOrderId: number | string workOrderId: number | string
contractId: number | string contractId: number | string
} }
export default async function addWorkOrderContract( export default async function addWorkOrderContract(
addForm: AddWorkOrderContractOccupancyForm, addForm: AddForm,
user: User, user: User,
connectedDatabase?: PoolConnection connectedDatabase?: PoolConnection
): Promise<boolean> { ): Promise<boolean> {

View File

@ -2,7 +2,7 @@ import { acquireConnection } from './pool.js';
export default async function deleteContractFee(contractId, feeId, user) { export default async function deleteContractFee(contractId, feeId, user) {
const database = await acquireConnection(); const database = await acquireConnection();
const result = database const result = database
.prepare(`update BurialSteContractFees .prepare(`update ContractFees
set recordDelete_userName = ?, set recordDelete_userName = ?,
recordDelete_timeMillis = ? recordDelete_timeMillis = ?
where contractId = ? where contractId = ?

View File

@ -9,7 +9,7 @@ export default async function deleteContractFee(
const result = database const result = database
.prepare( .prepare(
`update BurialSteContractFees `update ContractFees
set recordDelete_userName = ?, set recordDelete_userName = ?,
recordDelete_timeMillis = ? recordDelete_timeMillis = ?
where contractId = ? where contractId = ?

View File

@ -21,12 +21,15 @@ export default async function getContract(contractId, connectedDatabase) {
o.purchaserCity, o.purchaserProvince, o.purchaserPostalCode, o.purchaserCity, o.purchaserProvince, o.purchaserPostalCode,
o.purchaserPhoneNumber, o.purchaserEmail, o.purchaserRelationship, o.purchaserPhoneNumber, o.purchaserEmail, o.purchaserRelationship,
o.funeralHomeId, o.funeralDirectorName, o.funeralHomeId, o.funeralDirectorName,
f.funeralHomeName, f.funeralHomeAddress1, f.funeralHomeAddress2,
f.funeralHomeCity, f.funeralHomeProvince, f.funeralHomePostalCode,
o.funeralDate, userFn_dateIntegerToString(o.funeralDate) as funeralDateString, o.funeralDate, userFn_dateIntegerToString(o.funeralDate) as funeralDateString,
o.funeralTime, userFn_timeIntegerToString(o.funeralTime) as funeralTimeString, o.funeralTime, userFn_timeIntegerToString(o.funeralTime) as funeralTimeString,
o.committalTypeId, c.committalType, o.committalTypeId, c.committalType,
o.recordUpdate_timeMillis o.recordUpdate_timeMillis
from Contracts o from Contracts o
left join ContractTypes t on o.contractTypeId = t.contractTypeId left join ContractTypes t on o.contractTypeId = t.contractTypeId
left join FuneralHomes f on o.funeralHomeId = f.funeralHomeId
left join CommittalTypes c on o.committalTypeId = c.committalTypeId left join CommittalTypes c on o.committalTypeId = c.committalTypeId
left join BurialSites l on o.burialSiteId = l.burialSiteId left join BurialSites l on o.burialSiteId = l.burialSiteId
left join Cemeteries m on l.cemeteryId = m.cemeteryId left join Cemeteries m on l.cemeteryId = m.cemeteryId

View File

@ -32,12 +32,15 @@ export default async function getContract(
o.purchaserCity, o.purchaserProvince, o.purchaserPostalCode, o.purchaserCity, o.purchaserProvince, o.purchaserPostalCode,
o.purchaserPhoneNumber, o.purchaserEmail, o.purchaserRelationship, o.purchaserPhoneNumber, o.purchaserEmail, o.purchaserRelationship,
o.funeralHomeId, o.funeralDirectorName, o.funeralHomeId, o.funeralDirectorName,
f.funeralHomeName, f.funeralHomeAddress1, f.funeralHomeAddress2,
f.funeralHomeCity, f.funeralHomeProvince, f.funeralHomePostalCode,
o.funeralDate, userFn_dateIntegerToString(o.funeralDate) as funeralDateString, o.funeralDate, userFn_dateIntegerToString(o.funeralDate) as funeralDateString,
o.funeralTime, userFn_timeIntegerToString(o.funeralTime) as funeralTimeString, o.funeralTime, userFn_timeIntegerToString(o.funeralTime) as funeralTimeString,
o.committalTypeId, c.committalType, o.committalTypeId, c.committalType,
o.recordUpdate_timeMillis o.recordUpdate_timeMillis
from Contracts o from Contracts o
left join ContractTypes t on o.contractTypeId = t.contractTypeId left join ContractTypes t on o.contractTypeId = t.contractTypeId
left join FuneralHomes f on o.funeralHomeId = f.funeralHomeId
left join CommittalTypes c on o.committalTypeId = c.committalTypeId left join CommittalTypes c on o.committalTypeId = c.committalTypeId
left join BurialSites l on o.burialSiteId = l.burialSiteId left join BurialSites l on o.burialSiteId = l.burialSiteId
left join Cemeteries m on l.cemeteryId = m.cemeteryId left join Cemeteries m on l.cemeteryId = m.cemeteryId

View File

@ -3,10 +3,10 @@ import type { PoolConnection } from 'better-sqlite-pool';
import type { Contract } from '../types/recordTypes.js'; import type { Contract } from '../types/recordTypes.js';
export interface GetContractsFilters { export interface GetContractsFilters {
burialSiteId?: number | string; burialSiteId?: number | string;
occupancyTime?: '' | 'past' | 'current' | 'future'; contractTime?: '' | 'past' | 'current' | 'future';
contractStartDateString?: DateString; contractStartDateString?: DateString;
occupancyEffectiveDateString?: string; contractEffectiveDateString?: string;
occupantName?: string; deceasedName?: string;
contractTypeId?: number | string; contractTypeId?: number | string;
cemeteryId?: number | string; cemeteryId?: number | string;
burialSiteNameSearchType?: '' | 'startsWith' | 'endsWith'; burialSiteNameSearchType?: '' | 'startsWith' | 'endsWith';

View File

@ -1,7 +1,7 @@
import { dateIntegerToString, dateStringToInteger, timeIntegerToString } from '@cityssm/utils-datetime'; import { dateIntegerToString, dateStringToInteger, timeIntegerToString } from '@cityssm/utils-datetime';
import { getConfigProperty } from '../helpers/config.helpers.js'; import { getConfigProperty } from '../helpers/config.helpers.js';
import { getContractTypeById } from '../helpers/functions.cache.js'; import { getContractTypeById } from '../helpers/functions.cache.js';
import { getBurialSiteNameWhereClause, getOccupancyTimeWhereClause, getOccupantNameWhereClause } from '../helpers/functions.sqlFilters.js'; import { getBurialSiteNameWhereClause, getContractTimeWhereClause, getDeceasedNameWhereClause, } from '../helpers/functions.sqlFilters.js';
import getContractFees from './getContractFees.js'; import getContractFees from './getContractFees.js';
import getContractInterments from './getContractInterments.js'; import getContractInterments from './getContractInterments.js';
import getContractTransactions from './getContractTransactions.js'; import getContractTransactions from './getContractTransactions.js';
@ -16,31 +16,31 @@ function buildWhereClause(filters) {
const burialSiteNameFilters = getBurialSiteNameWhereClause(filters.burialSiteName, filters.burialSiteNameSearchType ?? '', 'l'); const burialSiteNameFilters = getBurialSiteNameWhereClause(filters.burialSiteName, filters.burialSiteNameSearchType ?? '', 'l');
sqlWhereClause += burialSiteNameFilters.sqlWhereClause; sqlWhereClause += burialSiteNameFilters.sqlWhereClause;
sqlParameters.push(...burialSiteNameFilters.sqlParameters); sqlParameters.push(...burialSiteNameFilters.sqlParameters);
const occupantNameFilters = getOccupantNameWhereClause(filters.occupantName, 'o'); const deceasedNameFilters = getDeceasedNameWhereClause(filters.deceasedName, 'o');
if (occupantNameFilters.sqlParameters.length > 0) { if (deceasedNameFilters.sqlParameters.length > 0) {
sqlWhereClause += ` and o.contractId in ( sqlWhereClause += ` and o.contractId in (
select contractId from LotOccupancyOccupants o select contractId from ContractInterments o
where recordDelete_timeMillis is null where recordDelete_timeMillis is null
${occupantNameFilters.sqlWhereClause})`; ${deceasedNameFilters.sqlWhereClause})`;
sqlParameters.push(...occupantNameFilters.sqlParameters); sqlParameters.push(...deceasedNameFilters.sqlParameters);
} }
if ((filters.contractTypeId ?? '') !== '') { if ((filters.contractTypeId ?? '') !== '') {
sqlWhereClause += ' and o.contractTypeId = ?'; sqlWhereClause += ' and o.contractTypeId = ?';
sqlParameters.push(filters.contractTypeId); sqlParameters.push(filters.contractTypeId);
} }
const occupancyTimeFilters = getOccupancyTimeWhereClause(filters.occupancyTime ?? '', 'o'); const contractTimeFilters = getContractTimeWhereClause(filters.contractTime ?? '', 'o');
sqlWhereClause += occupancyTimeFilters.sqlWhereClause; sqlWhereClause += contractTimeFilters.sqlWhereClause;
sqlParameters.push(...occupancyTimeFilters.sqlParameters); sqlParameters.push(...contractTimeFilters.sqlParameters);
if ((filters.contractStartDateString ?? '') !== '') { if ((filters.contractStartDateString ?? '') !== '') {
sqlWhereClause += ' and o.contractStartDate = ?'; sqlWhereClause += ' and o.contractStartDate = ?';
sqlParameters.push(dateStringToInteger(filters.contractStartDateString)); sqlParameters.push(dateStringToInteger(filters.contractStartDateString));
} }
if ((filters.occupancyEffectiveDateString ?? '') !== '') { if ((filters.contractEffectiveDateString ?? '') !== '') {
sqlWhereClause += ` and ( sqlWhereClause += ` and (
o.contractEndDate is null o.contractEndDate is null
or (o.contractStartDate <= ? and o.contractEndDate >= ?) or (o.contractStartDate <= ? and o.contractEndDate >= ?)
)`; )`;
sqlParameters.push(dateStringToInteger(filters.occupancyEffectiveDateString), dateStringToInteger(filters.occupancyEffectiveDateString)); sqlParameters.push(dateStringToInteger(filters.contractEffectiveDateString), dateStringToInteger(filters.contractEffectiveDateString));
} }
if ((filters.cemeteryId ?? '') !== '') { if ((filters.cemeteryId ?? '') !== '') {
sqlWhereClause += ' and l.cemeteryId = ?'; sqlWhereClause += ' and l.cemeteryId = ?';

View File

@ -10,8 +10,8 @@ import { getConfigProperty } from '../helpers/config.helpers.js'
import { getContractTypeById } from '../helpers/functions.cache.js' import { getContractTypeById } from '../helpers/functions.cache.js'
import { import {
getBurialSiteNameWhereClause, getBurialSiteNameWhereClause,
getOccupancyTimeWhereClause, getContractTimeWhereClause,
getOccupantNameWhereClause getDeceasedNameWhereClause,
} from '../helpers/functions.sqlFilters.js' } from '../helpers/functions.sqlFilters.js'
import type { Contract } from '../types/recordTypes.js' import type { Contract } from '../types/recordTypes.js'
@ -22,10 +22,10 @@ import { acquireConnection } from './pool.js'
export interface GetContractsFilters { export interface GetContractsFilters {
burialSiteId?: number | string burialSiteId?: number | string
occupancyTime?: '' | 'past' | 'current' | 'future' contractTime?: '' | 'past' | 'current' | 'future'
contractStartDateString?: DateString contractStartDateString?: DateString
occupancyEffectiveDateString?: string contractEffectiveDateString?: string
occupantName?: string deceasedName?: string
contractTypeId?: number | string contractTypeId?: number | string
cemeteryId?: number | string cemeteryId?: number | string
burialSiteNameSearchType?: '' | 'startsWith' | 'endsWith' burialSiteNameSearchType?: '' | 'startsWith' | 'endsWith'
@ -64,16 +64,16 @@ function buildWhereClause(filters: GetContractsFilters): {
sqlWhereClause += burialSiteNameFilters.sqlWhereClause sqlWhereClause += burialSiteNameFilters.sqlWhereClause
sqlParameters.push(...burialSiteNameFilters.sqlParameters) sqlParameters.push(...burialSiteNameFilters.sqlParameters)
const occupantNameFilters = getOccupantNameWhereClause( const deceasedNameFilters = getDeceasedNameWhereClause(
filters.occupantName, filters.deceasedName,
'o' 'o'
) )
if (occupantNameFilters.sqlParameters.length > 0) { if (deceasedNameFilters.sqlParameters.length > 0) {
sqlWhereClause += ` and o.contractId in ( sqlWhereClause += ` and o.contractId in (
select contractId from LotOccupancyOccupants o select contractId from ContractInterments o
where recordDelete_timeMillis is null where recordDelete_timeMillis is null
${occupantNameFilters.sqlWhereClause})` ${deceasedNameFilters.sqlWhereClause})`
sqlParameters.push(...occupantNameFilters.sqlParameters) sqlParameters.push(...deceasedNameFilters.sqlParameters)
} }
if ((filters.contractTypeId ?? '') !== '') { if ((filters.contractTypeId ?? '') !== '') {
@ -81,12 +81,12 @@ function buildWhereClause(filters: GetContractsFilters): {
sqlParameters.push(filters.contractTypeId) sqlParameters.push(filters.contractTypeId)
} }
const occupancyTimeFilters = getOccupancyTimeWhereClause( const contractTimeFilters = getContractTimeWhereClause(
filters.occupancyTime ?? '', filters.contractTime ?? '',
'o' 'o'
) )
sqlWhereClause += occupancyTimeFilters.sqlWhereClause sqlWhereClause += contractTimeFilters.sqlWhereClause
sqlParameters.push(...occupancyTimeFilters.sqlParameters) sqlParameters.push(...contractTimeFilters.sqlParameters)
if ((filters.contractStartDateString ?? '') !== '') { if ((filters.contractStartDateString ?? '') !== '') {
sqlWhereClause += ' and o.contractStartDate = ?' sqlWhereClause += ' and o.contractStartDate = ?'
@ -95,14 +95,14 @@ function buildWhereClause(filters: GetContractsFilters): {
) )
} }
if ((filters.occupancyEffectiveDateString ?? '') !== '') { if ((filters.contractEffectiveDateString ?? '') !== '') {
sqlWhereClause += ` and ( sqlWhereClause += ` and (
o.contractEndDate is null o.contractEndDate is null
or (o.contractStartDate <= ? and o.contractEndDate >= ?) or (o.contractStartDate <= ? and o.contractEndDate >= ?)
)` )`
sqlParameters.push( sqlParameters.push(
dateStringToInteger(filters.occupancyEffectiveDateString as DateString), dateStringToInteger(filters.contractEffectiveDateString as DateString),
dateStringToInteger(filters.occupancyEffectiveDateString as DateString) dateStringToInteger(filters.contractEffectiveDateString as DateString)
) )
} }

View File

@ -7,16 +7,16 @@ export default async function getWorkOrderComments(workOrderId, connectedDatabas
database.function('userFn_timeIntegerToPeriodString', timeIntegerToPeriodString); database.function('userFn_timeIntegerToPeriodString', timeIntegerToPeriodString);
const workOrderComments = database const workOrderComments = database
.prepare(`select workOrderCommentId, .prepare(`select workOrderCommentId,
workOrderCommentDate, userFn_dateIntegerToString(workOrderCommentDate) as workOrderCommentDateString, commentDate, userFn_dateIntegerToString(commentDate) as commentDateString,
workOrderCommentTime, commentTime,
userFn_timeIntegerToString(workOrderCommentTime) as workOrderCommentTimeString, userFn_timeIntegerToString(commentTime) as commentTimeString,
userFn_timeIntegerToPeriodString(workOrderCommentTime) as workOrderCommentTimePeriodString, userFn_timeIntegerToPeriodString(commentTime) as commentTimePeriodString,
workOrderComment, comment,
recordCreate_userName, recordUpdate_userName recordCreate_userName, recordUpdate_userName
from WorkOrderComments from WorkOrderComments
where recordDelete_timeMillis is null where recordDelete_timeMillis is null
and workOrderId = ? and workOrderId = ?
order by workOrderCommentDate desc, workOrderCommentTime desc, workOrderCommentId desc`) order by commentDate desc, commentTime desc, workOrderCommentId desc`)
.all(workOrderId); .all(workOrderId);
if (connectedDatabase === undefined) { if (connectedDatabase === undefined) {
database.release(); database.release();

View File

@ -25,16 +25,16 @@ export default async function getWorkOrderComments(
const workOrderComments = database const workOrderComments = database
.prepare( .prepare(
`select workOrderCommentId, `select workOrderCommentId,
workOrderCommentDate, userFn_dateIntegerToString(workOrderCommentDate) as workOrderCommentDateString, commentDate, userFn_dateIntegerToString(commentDate) as commentDateString,
workOrderCommentTime, commentTime,
userFn_timeIntegerToString(workOrderCommentTime) as workOrderCommentTimeString, userFn_timeIntegerToString(commentTime) as commentTimeString,
userFn_timeIntegerToPeriodString(workOrderCommentTime) as workOrderCommentTimePeriodString, userFn_timeIntegerToPeriodString(commentTime) as commentTimePeriodString,
workOrderComment, comment,
recordCreate_userName, recordUpdate_userName recordCreate_userName, recordUpdate_userName
from WorkOrderComments from WorkOrderComments
where recordDelete_timeMillis is null where recordDelete_timeMillis is null
and workOrderId = ? and workOrderId = ?
order by workOrderCommentDate desc, workOrderCommentTime desc, workOrderCommentId desc` order by commentDate desc, commentTime desc, workOrderCommentId desc`
) )
.all(workOrderId) as WorkOrderComment[] .all(workOrderId) as WorkOrderComment[]

View File

@ -4,7 +4,7 @@ export interface GetWorkOrdersFilters {
workOrderTypeId?: number | string; workOrderTypeId?: number | string;
workOrderOpenStatus?: '' | 'open' | 'closed'; workOrderOpenStatus?: '' | 'open' | 'closed';
workOrderOpenDateString?: string; workOrderOpenDateString?: string;
occupantName?: string; deceasedName?: string;
burialSiteName?: string; burialSiteName?: string;
contractId?: number | string; contractId?: number | string;
} }

View File

@ -1,7 +1,7 @@
import { dateIntegerToString, dateStringToInteger } from '@cityssm/utils-datetime'; import { dateIntegerToString, dateStringToInteger } from '@cityssm/utils-datetime';
import { getBurialSiteNameWhereClause, getOccupantNameWhereClause } from '../helpers/functions.sqlFilters.js'; import { getBurialSiteNameWhereClause, getDeceasedNameWhereClause } from '../helpers/functions.sqlFilters.js';
import getContracts from './getContracts.js';
import getBurialSites from './getBurialSites.js'; import getBurialSites from './getBurialSites.js';
import getContracts from './getContracts.js';
import getWorkOrderComments from './getWorkOrderComments.js'; import getWorkOrderComments from './getWorkOrderComments.js';
import getWorkOrderMilestones from './getWorkOrderMilestones.js'; import getWorkOrderMilestones from './getWorkOrderMilestones.js';
import { acquireConnection } from './pool.js'; import { acquireConnection } from './pool.js';
@ -24,17 +24,17 @@ function buildWhereClause(filters) {
sqlWhereClause += ' and w.workOrderOpenDate = ?'; sqlWhereClause += ' and w.workOrderOpenDate = ?';
sqlParameters.push(dateStringToInteger(filters.workOrderOpenDateString)); sqlParameters.push(dateStringToInteger(filters.workOrderOpenDateString));
} }
const occupantNameFilters = getOccupantNameWhereClause(filters.occupantName, 'o'); const deceasedNameFilters = getDeceasedNameWhereClause(filters.deceasedName, 'o');
if (occupantNameFilters.sqlParameters.length > 0) { if (deceasedNameFilters.sqlParameters.length > 0) {
sqlWhereClause += sqlWhereClause +=
` and w.workOrderId in ( ` and w.workOrderId in (
select workOrderId from WorkOrderContracts o select workOrderId from WorkOrderContracts o
where recordDelete_timeMillis is null where recordDelete_timeMillis is null
and o.contractId in ( and o.contractId in (
select contractId from LotOccupancyOccupants o where recordDelete_timeMillis is null select contractId from ContractInterments o where recordDelete_timeMillis is null
${occupantNameFilters.sqlWhereClause} ${deceasedNameFilters.sqlWhereClause}
))`; ))`;
sqlParameters.push(...occupantNameFilters.sqlParameters); sqlParameters.push(...deceasedNameFilters.sqlParameters);
} }
const burialSiteNameFilters = getBurialSiteNameWhereClause(filters.burialSiteName, '', 'l'); const burialSiteNameFilters = getBurialSiteNameWhereClause(filters.burialSiteName, '', 'l');
if (burialSiteNameFilters.sqlParameters.length > 0) { if (burialSiteNameFilters.sqlParameters.length > 0) {
@ -119,7 +119,7 @@ export async function getWorkOrders(filters, options, connectedDatabase) {
w.workOrderCloseDate, userFn_dateIntegerToString(w.workOrderCloseDate) as workOrderCloseDateString, w.workOrderCloseDate, userFn_dateIntegerToString(w.workOrderCloseDate) as workOrderCloseDateString,
ifnull(m.workOrderMilestoneCount, 0) as workOrderMilestoneCount, ifnull(m.workOrderMilestoneCount, 0) as workOrderMilestoneCount,
ifnull(m.workOrderMilestoneCompletionCount, 0) as workOrderMilestoneCompletionCount, ifnull(m.workOrderMilestoneCompletionCount, 0) as workOrderMilestoneCompletionCount,
ifnull(l.workOrderLotCount, 0) as workOrderLotCount ifnull(l.workOrderBurialSiteCount, 0) as workOrderBurialSiteCount
from WorkOrders w from WorkOrders w
left join WorkOrderTypes t on w.workOrderTypeId = t.workOrderTypeId left join WorkOrderTypes t on w.workOrderTypeId = t.workOrderTypeId
left join ( left join (
@ -130,8 +130,8 @@ export async function getWorkOrders(filters, options, connectedDatabase) {
where recordDelete_timeMillis is null where recordDelete_timeMillis is null
group by workOrderId) m on w.workOrderId = m.workOrderId group by workOrderId) m on w.workOrderId = m.workOrderId
left join ( left join (
select workOrderId, count(burialSiteId) as workOrderLotCount select workOrderId, count(burialSiteId) as workOrderBurialSiteCount
from WorkOrderLots from WorkOrderBurialSites
where recordDelete_timeMillis is null where recordDelete_timeMillis is null
group by workOrderId) l on w.workOrderId = l.workOrderId group by workOrderId) l on w.workOrderId = l.workOrderId
${sqlWhereClause} ${sqlWhereClause}

View File

@ -7,12 +7,12 @@ import type { PoolConnection } from 'better-sqlite-pool'
import { import {
getBurialSiteNameWhereClause, getBurialSiteNameWhereClause,
getOccupantNameWhereClause getDeceasedNameWhereClause
} from '../helpers/functions.sqlFilters.js' } from '../helpers/functions.sqlFilters.js'
import type { WorkOrder } from '../types/recordTypes.js' import type { WorkOrder } from '../types/recordTypes.js'
import getContracts from './getContracts.js'
import getBurialSites from './getBurialSites.js' import getBurialSites from './getBurialSites.js'
import getContracts from './getContracts.js'
import getWorkOrderComments from './getWorkOrderComments.js' import getWorkOrderComments from './getWorkOrderComments.js'
import getWorkOrderMilestones from './getWorkOrderMilestones.js' import getWorkOrderMilestones from './getWorkOrderMilestones.js'
import { acquireConnection } from './pool.js' import { acquireConnection } from './pool.js'
@ -21,7 +21,7 @@ export interface GetWorkOrdersFilters {
workOrderTypeId?: number | string workOrderTypeId?: number | string
workOrderOpenStatus?: '' | 'open' | 'closed' workOrderOpenStatus?: '' | 'open' | 'closed'
workOrderOpenDateString?: string workOrderOpenDateString?: string
occupantName?: string deceasedName?: string
burialSiteName?: string burialSiteName?: string
contractId?: number | string contractId?: number | string
} }
@ -61,20 +61,20 @@ function buildWhereClause(filters: GetWorkOrdersFilters): {
) )
} }
const occupantNameFilters = getOccupantNameWhereClause( const deceasedNameFilters = getDeceasedNameWhereClause(
filters.occupantName, filters.deceasedName,
'o' 'o'
) )
if (occupantNameFilters.sqlParameters.length > 0) { if (deceasedNameFilters.sqlParameters.length > 0) {
sqlWhereClause += sqlWhereClause +=
` and w.workOrderId in ( ` and w.workOrderId in (
select workOrderId from WorkOrderContracts o select workOrderId from WorkOrderContracts o
where recordDelete_timeMillis is null where recordDelete_timeMillis is null
and o.contractId in ( and o.contractId in (
select contractId from LotOccupancyOccupants o where recordDelete_timeMillis is null select contractId from ContractInterments o where recordDelete_timeMillis is null
${occupantNameFilters.sqlWhereClause} ${deceasedNameFilters.sqlWhereClause}
))` ))`
sqlParameters.push(...occupantNameFilters.sqlParameters) sqlParameters.push(...deceasedNameFilters.sqlParameters)
} }
const burialSiteNameFilters = getBurialSiteNameWhereClause(filters.burialSiteName, '', 'l') const burialSiteNameFilters = getBurialSiteNameWhereClause(filters.burialSiteName, '', 'l')
@ -202,7 +202,7 @@ export async function getWorkOrders(
w.workOrderCloseDate, userFn_dateIntegerToString(w.workOrderCloseDate) as workOrderCloseDateString, w.workOrderCloseDate, userFn_dateIntegerToString(w.workOrderCloseDate) as workOrderCloseDateString,
ifnull(m.workOrderMilestoneCount, 0) as workOrderMilestoneCount, ifnull(m.workOrderMilestoneCount, 0) as workOrderMilestoneCount,
ifnull(m.workOrderMilestoneCompletionCount, 0) as workOrderMilestoneCompletionCount, ifnull(m.workOrderMilestoneCompletionCount, 0) as workOrderMilestoneCompletionCount,
ifnull(l.workOrderLotCount, 0) as workOrderLotCount ifnull(l.workOrderBurialSiteCount, 0) as workOrderBurialSiteCount
from WorkOrders w from WorkOrders w
left join WorkOrderTypes t on w.workOrderTypeId = t.workOrderTypeId left join WorkOrderTypes t on w.workOrderTypeId = t.workOrderTypeId
left join ( left join (
@ -213,8 +213,8 @@ export async function getWorkOrders(
where recordDelete_timeMillis is null where recordDelete_timeMillis is null
group by workOrderId) m on w.workOrderId = m.workOrderId group by workOrderId) m on w.workOrderId = m.workOrderId
left join ( left join (
select workOrderId, count(burialSiteId) as workOrderLotCount select workOrderId, count(burialSiteId) as workOrderBurialSiteCount
from WorkOrderLots from WorkOrderBurialSites
where recordDelete_timeMillis is null where recordDelete_timeMillis is null
group by workOrderId) l on w.workOrderId = l.workOrderId group by workOrderId) l on w.workOrderId = l.workOrderId
${sqlWhereClause} ${sqlWhereClause}

View File

@ -231,7 +231,7 @@ const createStatements = [
contractId integer not null, contractId integer not null,
intermentNumber integer not null, intermentNumber integer not null,
deceasedName varchar(50) not null, deceasedName varchar(200) not null,
isCremated bit not null default 0, isCremated bit not null default 0,
deceasedAddress1 varchar(50), deceasedAddress1 varchar(50),

View File

@ -270,7 +270,7 @@ const createStatements = [
contractId integer not null, contractId integer not null,
intermentNumber integer not null, intermentNumber integer not null,
deceasedName varchar(50) not null, deceasedName varchar(200) not null,
isCremated bit not null default 0, isCremated bit not null default 0,
deceasedAddress1 varchar(50), deceasedAddress1 varchar(50),

View File

@ -0,0 +1,17 @@
import { type DateString } from '@cityssm/utils-datetime';
export interface UpdateForm {
contractId: string | number;
intermentNumber: string | number;
deceasedName: string;
deceasedAddress1: string;
deceasedAddress2: string;
deceasedCity: string;
deceasedProvince: string;
deceasedPostalCode: string;
birthDateString: DateString | '';
birthPlace: string;
deathDateString: DateString | '';
deathPlace: string;
intermentContainerTypeId: string | number;
}
export default function updateContractInterment(contractForm: UpdateForm, user: User): Promise<boolean>;

View File

@ -0,0 +1,32 @@
import { dateStringToInteger } from '@cityssm/utils-datetime';
import { acquireConnection } from './pool.js';
export default async function updateContractInterment(contractForm, user) {
const database = await acquireConnection();
const results = database
.prepare(`update ContractInterments
set deceasedName = ?,
deceasedAddress1 = ?,
deceasedAddress2 = ?,
deceasedCity = ?,
deceasedProvince = ?,
deceasedPostalCode = ?,
birthDate = ?,
birthPlace = ?,
deathDate = ?,
deathPlace = ?,
intermentContainerTypeId = ?,
recordUpdate_userName = ?,
recordUpdate_timeMillis = ?
where recordDelete_timeMillis is null
and contractId = ?
and intermentNumber = ?`)
.run(contractForm.deceasedName, contractForm.deceasedAddress1, contractForm.deceasedAddress2, contractForm.deceasedCity, contractForm.deceasedProvince, contractForm.deceasedPostalCode, contractForm.birthDateString === ''
? undefined
: dateStringToInteger(contractForm.birthDateString), contractForm.birthPlace, contractForm.deathDateString === ''
? undefined
: dateStringToInteger(contractForm.deathDateString), contractForm.deathPlace, contractForm.intermentContainerTypeId === ''
? undefined
: contractForm.intermentContainerTypeId, user.userName, Date.now(), contractForm.contractId, contractForm.intermentNumber);
database.release();
return results.changes > 0;
}

View File

@ -0,0 +1,74 @@
import { type DateString, dateStringToInteger } from '@cityssm/utils-datetime'
import { acquireConnection } from './pool.js'
export interface UpdateForm {
contractId: string | number
intermentNumber: string | number
deceasedName: string
deceasedAddress1: string
deceasedAddress2: string
deceasedCity: string
deceasedProvince: string
deceasedPostalCode: string
birthDateString: DateString | ''
birthPlace: string
deathDateString: DateString | ''
deathPlace: string
intermentContainerTypeId: string | number
}
export default async function updateContractInterment(
contractForm: UpdateForm,
user: User
): Promise<boolean> {
const database = await acquireConnection()
const results = database
.prepare(
`update ContractInterments
set deceasedName = ?,
deceasedAddress1 = ?,
deceasedAddress2 = ?,
deceasedCity = ?,
deceasedProvince = ?,
deceasedPostalCode = ?,
birthDate = ?,
birthPlace = ?,
deathDate = ?,
deathPlace = ?,
intermentContainerTypeId = ?,
recordUpdate_userName = ?,
recordUpdate_timeMillis = ?
where recordDelete_timeMillis is null
and contractId = ?
and intermentNumber = ?`
)
.run(
contractForm.deceasedName,
contractForm.deceasedAddress1,
contractForm.deceasedAddress2,
contractForm.deceasedCity,
contractForm.deceasedProvince,
contractForm.deceasedPostalCode,
contractForm.birthDateString === ''
? undefined
: dateStringToInteger(contractForm.birthDateString),
contractForm.birthPlace,
contractForm.deathDateString === ''
? undefined
: dateStringToInteger(contractForm.deathDateString),
contractForm.deathPlace,
contractForm.intermentContainerTypeId === ''
? undefined
: contractForm.intermentContainerTypeId,
user.userName,
Date.now(),
contractForm.contractId,
contractForm.intermentNumber
)
database.release()
return results.changes > 0
}

View File

@ -1,16 +0,0 @@
export interface UpdateLotOccupancyOccupantForm {
contractId: string | number;
lotOccupantIndex: string | number;
lotOccupantTypeId: string | number;
occupantName: string;
occupantFamilyName: string;
occupantAddress1: string;
occupantAddress2: string;
occupantCity: string;
occupantProvince: string;
occupantPostalCode: string;
occupantPhoneNumber: string;
occupantEmailAddress: string;
occupantComment: string;
}
export default function updateContractOccupant(contractOccupantForm: UpdateLotOccupancyOccupantForm, user: User): Promise<boolean>;

View File

@ -1,25 +0,0 @@
import { acquireConnection } from './pool.js';
export default async function updateContractOccupant(contractOccupantForm, user) {
const database = await acquireConnection();
const results = database
.prepare(`update LotOccupancyOccupants
set occupantName = ?,
occupantFamilyName = ?,
occupantAddress1 = ?,
occupantAddress2 = ?,
occupantCity = ?,
occupantProvince = ?,
occupantPostalCode = ?,
occupantPhoneNumber = ?,
occupantEmailAddress = ?,
occupantComment = ?,
lotOccupantTypeId = ?,
recordUpdate_userName = ?,
recordUpdate_timeMillis = ?
where recordDelete_timeMillis is null
and contractId = ?
and lotOccupantIndex = ?`)
.run(contractOccupantForm.occupantName, contractOccupantForm.occupantFamilyName, contractOccupantForm.occupantAddress1, contractOccupantForm.occupantAddress2, contractOccupantForm.occupantCity, contractOccupantForm.occupantProvince, contractOccupantForm.occupantPostalCode, contractOccupantForm.occupantPhoneNumber, contractOccupantForm.occupantEmailAddress, contractOccupantForm.occupantComment, contractOccupantForm.lotOccupantTypeId, user.userName, Date.now(), contractOccupantForm.contractId, contractOccupantForm.lotOccupantIndex);
database.release();
return results.changes > 0;
}

View File

@ -1,66 +0,0 @@
import { acquireConnection } from './pool.js'
export interface UpdateLotOccupancyOccupantForm {
contractId: string | number
lotOccupantIndex: string | number
lotOccupantTypeId: string | number
occupantName: string
occupantFamilyName: string
occupantAddress1: string
occupantAddress2: string
occupantCity: string
occupantProvince: string
occupantPostalCode: string
occupantPhoneNumber: string
occupantEmailAddress: string
occupantComment: string
}
export default async function updateContractOccupant(
contractOccupantForm: UpdateLotOccupancyOccupantForm,
user: User
): Promise<boolean> {
const database = await acquireConnection()
const results = database
.prepare(
`update LotOccupancyOccupants
set occupantName = ?,
occupantFamilyName = ?,
occupantAddress1 = ?,
occupantAddress2 = ?,
occupantCity = ?,
occupantProvince = ?,
occupantPostalCode = ?,
occupantPhoneNumber = ?,
occupantEmailAddress = ?,
occupantComment = ?,
lotOccupantTypeId = ?,
recordUpdate_userName = ?,
recordUpdate_timeMillis = ?
where recordDelete_timeMillis is null
and contractId = ?
and lotOccupantIndex = ?`
)
.run(
contractOccupantForm.occupantName,
contractOccupantForm.occupantFamilyName,
contractOccupantForm.occupantAddress1,
contractOccupantForm.occupantAddress2,
contractOccupantForm.occupantCity,
contractOccupantForm.occupantProvince,
contractOccupantForm.occupantPostalCode,
contractOccupantForm.occupantPhoneNumber,
contractOccupantForm.occupantEmailAddress,
contractOccupantForm.occupantComment,
contractOccupantForm.lotOccupantTypeId,
user.userName,
Date.now(),
contractOccupantForm.contractId,
contractOccupantForm.lotOccupantIndex
)
database.release()
return results.changes > 0
}

View File

@ -1,8 +1,8 @@
import { type DateString, type TimeString } from '@cityssm/utils-datetime'; import { type DateString, type TimeString } from '@cityssm/utils-datetime';
export interface UpdateWorkOrderCommentForm { export interface UpdateWorkOrderCommentForm {
workOrderCommentId: string | number; workOrderCommentId: string | number;
workOrderCommentDateString: DateString; commentDateString: DateString;
workOrderCommentTimeString: TimeString; commentTimeString: TimeString;
workOrderComment: string; comment: string;
} }
export default function updateWorkOrderComment(commentForm: UpdateWorkOrderCommentForm, user: User): Promise<boolean>; export default function updateWorkOrderComment(commentForm: UpdateWorkOrderCommentForm, user: User): Promise<boolean>;

View File

@ -4,14 +4,14 @@ export default async function updateWorkOrderComment(commentForm, user) {
const database = await acquireConnection(); const database = await acquireConnection();
const result = database const result = database
.prepare(`update WorkOrderComments .prepare(`update WorkOrderComments
set workOrderCommentDate = ?, set commentDate = ?,
workOrderCommentTime = ?, commentTime = ?,
workOrderComment = ?, comment = ?,
recordUpdate_userName = ?, recordUpdate_userName = ?,
recordUpdate_timeMillis = ? recordUpdate_timeMillis = ?
where recordDelete_timeMillis is null where recordDelete_timeMillis is null
and workOrderCommentId = ?`) and workOrderCommentId = ?`)
.run(dateStringToInteger(commentForm.workOrderCommentDateString), timeStringToInteger(commentForm.workOrderCommentTimeString), commentForm.workOrderComment, user.userName, Date.now(), commentForm.workOrderCommentId); .run(dateStringToInteger(commentForm.commentDateString), timeStringToInteger(commentForm.commentTimeString), commentForm.comment, user.userName, Date.now(), commentForm.workOrderCommentId);
database.release(); database.release();
return result.changes > 0; return result.changes > 0;
} }

View File

@ -9,9 +9,9 @@ import { acquireConnection } from './pool.js'
export interface UpdateWorkOrderCommentForm { export interface UpdateWorkOrderCommentForm {
workOrderCommentId: string | number workOrderCommentId: string | number
workOrderCommentDateString: DateString commentDateString: DateString
workOrderCommentTimeString: TimeString commentTimeString: TimeString
workOrderComment: string comment: string
} }
export default async function updateWorkOrderComment( export default async function updateWorkOrderComment(
@ -23,18 +23,18 @@ export default async function updateWorkOrderComment(
const result = database const result = database
.prepare( .prepare(
`update WorkOrderComments `update WorkOrderComments
set workOrderCommentDate = ?, set commentDate = ?,
workOrderCommentTime = ?, commentTime = ?,
workOrderComment = ?, comment = ?,
recordUpdate_userName = ?, recordUpdate_userName = ?,
recordUpdate_timeMillis = ? recordUpdate_timeMillis = ?
where recordDelete_timeMillis is null where recordDelete_timeMillis is null
and workOrderCommentId = ?` and workOrderCommentId = ?`
) )
.run( .run(
dateStringToInteger(commentForm.workOrderCommentDateString), dateStringToInteger(commentForm.commentDateString),
timeStringToInteger(commentForm.workOrderCommentTimeString), timeStringToInteger(commentForm.commentTimeString),
commentForm.workOrderComment, commentForm.comment,
user.userName, user.userName,
Date.now(), Date.now(),
commentForm.workOrderCommentId commentForm.workOrderCommentId

View File

@ -0,0 +1,3 @@
import type { Request, Response } from 'express';
import { type AddForm } from '../../database/addContractInterment.js';
export default function handler(request: Request<unknown, unknown, AddForm>, response: Response): Promise<void>;

View File

@ -0,0 +1,10 @@
import addContractInterment from '../../database/addContractInterment.js';
import getContractInterments from '../../database/getContractInterments.js';
export default async function handler(request, response) {
await addContractInterment(request.body, request.session.user);
const contractInterments = await getContractInterments(request.body.contractId);
response.json({
success: true,
contractInterments
});
}

View File

@ -0,0 +1,22 @@
import type { Request, Response } from 'express'
import addContractInterment, {
type AddForm
} from '../../database/addContractInterment.js'
import getContractInterments from '../../database/getContractInterments.js'
export default async function handler(
request: Request<unknown, unknown, AddForm>,
response: Response
): Promise<void> {
await addContractInterment(request.body, request.session.user as User)
const contractInterments = await getContractInterments(
request.body.contractId
)
response.json({
success: true,
contractInterments
})
}

View File

@ -0,0 +1,5 @@
import type { Request, Response } from 'express';
export default function handler(request: Request<unknown, unknown, {
contractId: string;
intermentNumber: string;
}>, response: Response): Promise<void>;

View File

@ -0,0 +1,10 @@
import deleteContractInterment from '../../database/deleteContractInterment.js';
import getContractInterments from '../../database/getContractInterments.js';
export default async function handler(request, response) {
const success = await deleteContractInterment(request.body.contractId, request.body.intermentNumber, request.session.user);
const contractInterments = await getContractInterments(request.body.contractId);
response.json({
success,
contractInterments
});
}

View File

@ -0,0 +1,28 @@
import type { Request, Response } from 'express'
import deleteContractInterment from '../../database/deleteContractInterment.js'
import getContractInterments from '../../database/getContractInterments.js'
export default async function handler(
request: Request<
unknown,
unknown,
{ contractId: string; intermentNumber: string }
>,
response: Response
): Promise<void> {
const success = await deleteContractInterment(
request.body.contractId,
request.body.intermentNumber,
request.session.user as User
)
const contractInterments = await getContractInterments(
request.body.contractId
)
response.json({
success,
contractInterments
})
}

View File

@ -0,0 +1,3 @@
import type { Request, Response } from 'express';
import { type UpdateForm } from '../../database/updateContractInterment.js';
export default function handler(request: Request<unknown, unknown, UpdateForm>, response: Response): Promise<void>;

View File

@ -0,0 +1,10 @@
import getContractInterments from '../../database/getContractInterments.js';
import updateContractInterment from '../../database/updateContractInterment.js';
export default async function handler(request, response) {
await updateContractInterment(request.body, request.session.user);
const contractInterments = await getContractInterments(request.body.contractId);
response.json({
success: true,
contractInterments
});
}

View File

@ -0,0 +1,24 @@
import type { Request, Response } from 'express'
import getContractInterments from '../../database/getContractInterments.js'
import updateContractInterment, {
type UpdateForm
} from '../../database/updateContractInterment.js'
export default async function handler(
request: Request<unknown, unknown, UpdateForm>,
response: Response
): Promise<void> {
await updateContractInterment(
request.body,
request.session.user as User
)
const contractInterments =
await getContractInterments(request.body.contractId)
response.json({
success: true,
contractInterments
})
}

View File

@ -17,13 +17,13 @@ export default async function handler(request, response) {
} }
const workOrderTypes = await getWorkOrderTypes(); const workOrderTypes = await getWorkOrderTypes();
const workOrderMilestoneTypes = await getWorkOrderMilestoneTypes(); const workOrderMilestoneTypes = await getWorkOrderMilestoneTypes();
const lotStatuses = await getBurialSiteStatuses(); const burialSiteStatuses = await getBurialSiteStatuses();
response.render('workOrder-edit', { response.render('workOrder-edit', {
headTitle: `Work Order #${workOrder.workOrderNumber}`, headTitle: `Work Order #${workOrder.workOrderNumber}`,
workOrder, workOrder,
isCreate: false, isCreate: false,
workOrderTypes, workOrderTypes,
workOrderMilestoneTypes, workOrderMilestoneTypes,
lotStatuses burialSiteStatuses
}); });
} }

View File

@ -40,7 +40,7 @@ export default async function handler(
const workOrderMilestoneTypes = await getWorkOrderMilestoneTypes() const workOrderMilestoneTypes = await getWorkOrderMilestoneTypes()
const lotStatuses = await getBurialSiteStatuses() const burialSiteStatuses = await getBurialSiteStatuses()
response.render('workOrder-edit', { response.render('workOrder-edit', {
headTitle: `Work Order #${workOrder.workOrderNumber}`, headTitle: `Work Order #${workOrder.workOrderNumber}`,
@ -48,6 +48,6 @@ export default async function handler(
isCreate: false, isCreate: false,
workOrderTypes, workOrderTypes,
workOrderMilestoneTypes, workOrderMilestoneTypes,
lotStatuses burialSiteStatuses
}) })
} }

View File

@ -5,7 +5,7 @@ export default async function handler(request, response) {
workOrderId: request.body.workOrderId, workOrderId: request.body.workOrderId,
burialSiteId: request.body.burialSiteId burialSiteId: request.body.burialSiteId
}, request.session.user); }, request.session.user);
const workOrderLotsResults = await getBurialSites({ const results = await getBurialSites({
workOrderId: request.body.workOrderId workOrderId: request.body.workOrderId
}, { }, {
limit: -1, limit: -1,
@ -14,6 +14,6 @@ export default async function handler(request, response) {
}); });
response.json({ response.json({
success, success,
workOrderBurialSites: workOrderLotsResults.burialSites workOrderBurialSites: results.burialSites
}); });
} }

View File

@ -19,7 +19,7 @@ export default async function handler(
request.session.user as User request.session.user as User
) )
const workOrderLotsResults = await getBurialSites( const results = await getBurialSites(
{ {
workOrderId: request.body.workOrderId workOrderId: request.body.workOrderId
}, },
@ -32,6 +32,6 @@ export default async function handler(
response.json({ response.json({
success, success,
workOrderBurialSites: workOrderLotsResults.burialSites workOrderBurialSites: results.burialSites
}) })
} }

View File

@ -8,12 +8,14 @@ if (getConfigProperty('settings.dynamicsGP.integrationIsEnabled')) {
function filterCashReceipt(cashReceipt) { function filterCashReceipt(cashReceipt) {
const accountCodes = getConfigProperty('settings.dynamicsGP.accountCodes'); const accountCodes = getConfigProperty('settings.dynamicsGP.accountCodes');
if (accountCodes.length > 0) { if (accountCodes.length > 0) {
for (const detail of cashReceipt.details) { // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
for (const detail of cashReceipt?.details ?? []) {
if (accountCodes.includes(detail.accountCode)) { if (accountCodes.includes(detail.accountCode)) {
return cashReceipt; return cashReceipt;
} }
} }
for (const distribution of cashReceipt.distributions) { // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
for (const distribution of cashReceipt?.distributions ?? []) {
if (accountCodes.includes(distribution.accountCode)) { if (accountCodes.includes(distribution.accountCode)) {
return cashReceipt; return cashReceipt;
} }

View File

@ -23,13 +23,15 @@ function filterCashReceipt(
const accountCodes = getConfigProperty('settings.dynamicsGP.accountCodes') const accountCodes = getConfigProperty('settings.dynamicsGP.accountCodes')
if (accountCodes.length > 0) { if (accountCodes.length > 0) {
for (const detail of cashReceipt.details) { // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
for (const detail of cashReceipt?.details ?? []) {
if (accountCodes.includes(detail.accountCode)) { if (accountCodes.includes(detail.accountCode)) {
return cashReceipt return cashReceipt
} }
} }
for (const distribution of cashReceipt.distributions) { // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
for (const distribution of cashReceipt?.distributions ?? []) {
if (accountCodes.includes(distribution.accountCode)) { if (accountCodes.includes(distribution.accountCode)) {
return cashReceipt return cashReceipt
} }

View File

@ -4,7 +4,7 @@ interface WhereClauseReturn {
sqlParameters: unknown[]; sqlParameters: unknown[];
} }
export declare function getBurialSiteNameWhereClause(burialSiteName?: string, burialSiteNameSearchType?: BurialSiteNameSearchType, burialSitesTableAlias?: string): WhereClauseReturn; export declare function getBurialSiteNameWhereClause(burialSiteName?: string, burialSiteNameSearchType?: BurialSiteNameSearchType, burialSitesTableAlias?: string): WhereClauseReturn;
type OccupancyTime = '' | 'current' | 'past' | 'future'; type ContractTime = '' | 'current' | 'past' | 'future';
export declare function getOccupancyTimeWhereClause(occupancyTime: OccupancyTime | undefined, lotOccupanciesTableAlias?: string): WhereClauseReturn; export declare function getContractTimeWhereClause(contractTime: ContractTime | undefined, contractsTableAlias?: string): WhereClauseReturn;
export declare function getOccupantNameWhereClause(occupantName?: string, tableAlias?: string): WhereClauseReturn; export declare function getDeceasedNameWhereClause(deceasedName?: string, tableAlias?: string): WhereClauseReturn;
export {}; export {};

View File

@ -33,27 +33,27 @@ export function getBurialSiteNameWhereClause(burialSiteName = '', burialSiteName
sqlParameters sqlParameters
}; };
} }
export function getOccupancyTimeWhereClause(occupancyTime, lotOccupanciesTableAlias = 'o') { export function getContractTimeWhereClause(contractTime, contractsTableAlias = 'o') {
let sqlWhereClause = ''; let sqlWhereClause = '';
const sqlParameters = []; const sqlParameters = [];
const currentDateString = dateToInteger(new Date()); const currentDateString = dateToInteger(new Date());
// eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check // eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check
switch (occupancyTime ?? '') { switch (contractTime ?? '') {
case 'current': { case 'current': {
sqlWhereClause += ` and ${lotOccupanciesTableAlias}.contractStartDate <= ? sqlWhereClause += ` and ${contractsTableAlias}.contractStartDate <= ?
and (${lotOccupanciesTableAlias}.contractEndDate is null or ${lotOccupanciesTableAlias}.contractEndDate >= ?)`; and (${contractsTableAlias}.contractEndDate is null or ${contractsTableAlias}.contractEndDate >= ?)`;
sqlParameters.push(currentDateString, currentDateString); sqlParameters.push(currentDateString, currentDateString);
break; break;
} }
case 'past': { case 'past': {
sqlWhereClause += sqlWhereClause +=
` and ${lotOccupanciesTableAlias}.contractEndDate < ?`; ` and ${contractsTableAlias}.contractEndDate < ?`;
sqlParameters.push(currentDateString); sqlParameters.push(currentDateString);
break; break;
} }
case 'future': { case 'future': {
sqlWhereClause += sqlWhereClause +=
` and ${lotOccupanciesTableAlias}.contractStartDate > ?`; ` and ${contractsTableAlias}.contractStartDate > ?`;
sqlParameters.push(currentDateString); sqlParameters.push(currentDateString);
break; break;
} }
@ -63,18 +63,18 @@ export function getOccupancyTimeWhereClause(occupancyTime, lotOccupanciesTableAl
sqlParameters sqlParameters
}; };
} }
export function getOccupantNameWhereClause(occupantName = '', tableAlias = 'o') { export function getDeceasedNameWhereClause(deceasedName = '', tableAlias = 'o') {
let sqlWhereClause = ''; let sqlWhereClause = '';
const sqlParameters = []; const sqlParameters = [];
const usedPieces = new Set(); const usedPieces = new Set();
const occupantNamePieces = occupantName.toLowerCase().split(' '); const deceasedNamePieces = deceasedName.toLowerCase().split(' ');
for (const occupantNamePiece of occupantNamePieces) { for (const namePiece of deceasedNamePieces) {
if (occupantNamePiece === '' || usedPieces.has(occupantNamePiece)) { if (namePiece === '' || usedPieces.has(namePiece)) {
continue; continue;
} }
usedPieces.add(occupantNamePiece); usedPieces.add(namePiece);
sqlWhereClause += ` and (instr(lower(${tableAlias}.occupantName), ?) or instr(lower(${tableAlias}.occupantFamilyName), ?))`; sqlWhereClause += ` and instr(lower(${tableAlias}.deceasedName), ?)`;
sqlParameters.push(occupantNamePiece, occupantNamePiece); sqlParameters.push(namePiece);
} }
return { return {
sqlWhereClause, sqlWhereClause,

View File

@ -52,11 +52,11 @@ export function getBurialSiteNameWhereClause(
} }
} }
type OccupancyTime = '' | 'current' | 'past' | 'future' type ContractTime = '' | 'current' | 'past' | 'future'
export function getOccupancyTimeWhereClause( export function getContractTimeWhereClause(
occupancyTime: OccupancyTime | undefined, contractTime: ContractTime | undefined,
lotOccupanciesTableAlias = 'o' contractsTableAlias = 'o'
): WhereClauseReturn { ): WhereClauseReturn {
let sqlWhereClause = '' let sqlWhereClause = ''
const sqlParameters: unknown[] = [] const sqlParameters: unknown[] = []
@ -64,24 +64,24 @@ export function getOccupancyTimeWhereClause(
const currentDateString = dateToInteger(new Date()) const currentDateString = dateToInteger(new Date())
// eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check // eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check
switch (occupancyTime ?? '') { switch (contractTime ?? '') {
case 'current': { case 'current': {
sqlWhereClause += ` and ${lotOccupanciesTableAlias}.contractStartDate <= ? sqlWhereClause += ` and ${contractsTableAlias}.contractStartDate <= ?
and (${lotOccupanciesTableAlias}.contractEndDate is null or ${lotOccupanciesTableAlias}.contractEndDate >= ?)` and (${contractsTableAlias}.contractEndDate is null or ${contractsTableAlias}.contractEndDate >= ?)`
sqlParameters.push(currentDateString, currentDateString) sqlParameters.push(currentDateString, currentDateString)
break break
} }
case 'past': { case 'past': {
sqlWhereClause += sqlWhereClause +=
` and ${lotOccupanciesTableAlias}.contractEndDate < ?` ` and ${contractsTableAlias}.contractEndDate < ?`
sqlParameters.push(currentDateString) sqlParameters.push(currentDateString)
break break
} }
case 'future': { case 'future': {
sqlWhereClause += sqlWhereClause +=
` and ${lotOccupanciesTableAlias}.contractStartDate > ?` ` and ${contractsTableAlias}.contractStartDate > ?`
sqlParameters.push(currentDateString) sqlParameters.push(currentDateString)
break break
} }
@ -93,8 +93,8 @@ export function getOccupancyTimeWhereClause(
} }
} }
export function getOccupantNameWhereClause( export function getDeceasedNameWhereClause(
occupantName = '', deceasedName = '',
tableAlias = 'o' tableAlias = 'o'
): WhereClauseReturn { ): WhereClauseReturn {
let sqlWhereClause = '' let sqlWhereClause = ''
@ -102,16 +102,16 @@ export function getOccupantNameWhereClause(
const usedPieces = new Set<string>() const usedPieces = new Set<string>()
const occupantNamePieces = occupantName.toLowerCase().split(' ') const deceasedNamePieces = deceasedName.toLowerCase().split(' ')
for (const occupantNamePiece of occupantNamePieces) { for (const namePiece of deceasedNamePieces) {
if (occupantNamePiece === '' || usedPieces.has(occupantNamePiece)) { if (namePiece === '' || usedPieces.has(namePiece)) {
continue continue
} }
usedPieces.add(occupantNamePiece) usedPieces.add(namePiece)
sqlWhereClause += ` and (instr(lower(${tableAlias}.occupantName), ?) or instr(lower(${tableAlias}.occupantFamilyName), ?))` sqlWhereClause += ` and instr(lower(${tableAlias}.deceasedName), ?)`
sqlParameters.push(occupantNamePiece, occupantNamePiece) sqlParameters.push(namePiece)
} }
return { return {

27
package-lock.json generated
View File

@ -22,7 +22,6 @@
"activedirectory2": "^2.2.0", "activedirectory2": "^2.2.0",
"better-sqlite-pool": "^0.3.2", "better-sqlite-pool": "^0.3.2",
"better-sqlite3": "^11.8.1", "better-sqlite3": "^11.8.1",
"bulma-calendar": "^6.1.19",
"camelcase": "^8.0.0", "camelcase": "^8.0.0",
"compression": "^1.8.0", "compression": "^1.8.0",
"cookie-parser": "^1.4.7", "cookie-parser": "^1.4.7",
@ -3735,18 +3734,8 @@
"node_modules/bulma": { "node_modules/bulma": {
"version": "0.9.4", "version": "0.9.4",
"resolved": "https://registry.npmjs.org/bulma/-/bulma-0.9.4.tgz", "resolved": "https://registry.npmjs.org/bulma/-/bulma-0.9.4.tgz",
"integrity": "sha512-86FlT5+1GrsgKbPLRRY7cGDg8fsJiP/jzTqXXVqiUZZ2aZT8uemEOHlU1CDU+TxklPEZ11HZNNWclRBBecP4CQ==" "integrity": "sha512-86FlT5+1GrsgKbPLRRY7cGDg8fsJiP/jzTqXXVqiUZZ2aZT8uemEOHlU1CDU+TxklPEZ11HZNNWclRBBecP4CQ==",
}, "dev": true
"node_modules/bulma-calendar": {
"version": "6.1.19",
"resolved": "https://registry.npmjs.org/bulma-calendar/-/bulma-calendar-6.1.19.tgz",
"integrity": "sha512-roosrqoXWGTP7MR5PW151XO4mnarov2qvfzvHfGKzT8rV+SGRZmhzbr4/xmUxRyD+vdn6mSG+ensda4mvvKDow==",
"dependencies": {
"date-fns": "^2.21.3"
},
"peerDependencies": {
"bulma": "^0.9.4"
}
}, },
"node_modules/bulma-divider": { "node_modules/bulma-divider": {
"version": "0.2.0", "version": "0.2.0",
@ -4876,18 +4865,6 @@
"url": "https://github.com/sponsors/ljharb" "url": "https://github.com/sponsors/ljharb"
} }
}, },
"node_modules/date-fns": {
"version": "2.29.3",
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.29.3.tgz",
"integrity": "sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA==",
"engines": {
"node": ">=0.11"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/date-fns"
}
},
"node_modules/dayjs": { "node_modules/dayjs": {
"version": "1.11.7", "version": "1.11.7",
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.7.tgz", "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.7.tgz",

View File

@ -46,7 +46,6 @@
"activedirectory2": "^2.2.0", "activedirectory2": "^2.2.0",
"better-sqlite-pool": "^0.3.2", "better-sqlite-pool": "^0.3.2",
"better-sqlite3": "^11.8.1", "better-sqlite3": "^11.8.1",
"bulma-calendar": "^6.1.19",
"camelcase": "^8.0.0", "camelcase": "^8.0.0",
"compression": "^1.8.0", "compression": "^1.8.0",
"cookie-parser": "^1.4.7", "cookie-parser": "^1.4.7",

View File

@ -68,20 +68,16 @@
<div class="message is-info is-small"> <div class="message is-info is-small">
<p class="message-body"> <p class="message-body">
Filters can be used to show or hide available fees depending on the Filters can be used to show or hide available fees depending on the
<span class="alias" data-alias="occupancy"></span> type and contract type and burial site type selected when
<span class="alias" data-alias="lot"></span> type selected when creating the contract record.
creating the <span class="alias" data-alias="lot"></span>
<span class="alias" data-alias="occupancy"></span>
record.
</p> </p>
</div> </div>
<div class="columns"> <div class="columns">
<div class="column"> <div class="column">
<div class="field"> <div class="field">
<label class="label" for="feeAdd--contractTypeId" <label class="label" for="feeAdd--contractTypeId">
><span class="alias" data-alias="Occupancy"></span> Type Contract Type Filter
Filter</label </label>
>
<div class="control"> <div class="control">
<div class="select is-fullwidth"> <div class="select is-fullwidth">
<select id="feeAdd--contractTypeId" name="contractTypeId"> <select id="feeAdd--contractTypeId" name="contractTypeId">
@ -93,9 +89,9 @@
</div> </div>
<div class="column"> <div class="column">
<div class="field"> <div class="field">
<label class="label" for="feeAdd--burialSiteTypeId" <label class="label" for="feeAdd--burialSiteTypeId">
><span class="alias" data-alias="Lot"></span> Type Filter</label Burial Site Type Filter
> </label>
<div class="control"> <div class="control">
<div class="select is-fullwidth"> <div class="select is-fullwidth">
<select id="feeAdd--burialSiteTypeId" name="burialSiteTypeId"> <select id="feeAdd--burialSiteTypeId" name="burialSiteTypeId">

View File

@ -69,11 +69,8 @@
<div class="message is-info is-small"> <div class="message is-info is-small">
<p class="message-body"> <p class="message-body">
Filters can be used to show or hide available fees depending on the Filters can be used to show or hide available fees depending on the
<span class="alias" data-alias="occupancy"></span> type and contract type and burial site type selected when
<span class="alias" data-alias="lot"></span> type selected when creating the contract record.
creating the <span class="alias" data-alias="lot"></span>
<span class="alias" data-alias="occupancy"></span>
record.
</p> </p>
</div> </div>
<div class="columns"> <div class="columns">

View File

@ -3,7 +3,7 @@
<div class="modal-card"> <div class="modal-card">
<header class="modal-card-head"> <header class="modal-card-head">
<h3 class="modal-card-title"> <h3 class="modal-card-title">
Edit <span class="alias" data-alias="Lot"></span> Status Edit Burial Site Status
</h3> </h3>
<button <button
class="delete is-close-modal-button" class="delete is-close-modal-button"
@ -12,26 +12,26 @@
></button> ></button>
</header> </header>
<section class="modal-card-body"> <section class="modal-card-body">
<form id="form--lotStatusEdit"> <form id="form--burialSiteStatusEdit">
<input id="lotStatusEdit--burialSiteId" name="burialSiteId" type="hidden" value="" /> <input id="burialSiteStatusEdit--burialSiteId" name="burialSiteId" type="hidden" value="" />
<div class="field"> <div class="field">
<label class="label" for="lotStatusEdit--burialSiteName" <label class="label" for="burialSiteStatusEdit--burialSiteName">
><span class="alias" data-alias="Lot"></span> Name</label Burial Site Name
> </label>
<div class="control"> <div class="control">
<input <input
class="input is-readonly" class="input is-readonly"
id="lotStatusEdit--burialSiteName" id="burialSiteStatusEdit--burialSiteName"
readonly readonly
/> />
</div> </div>
</div> </div>
<div class="field"> <div class="field">
<label class="label" for="lotStatusEdit--burialSiteStatusId">Status</label> <label class="label" for="burialSiteStatusEdit--burialSiteStatusId">Status</label>
<div class="control"> <div class="control">
<div class="select is-fullwidth"> <div class="select is-fullwidth">
<select id="lotStatusEdit--burialSiteStatusId" name="burialSiteStatusId"> <select id="burialSiteStatusEdit--burialSiteStatusId" name="burialSiteStatusId">
<option value="">(No Status)</option> <option value="">(No Status)</option>
</select> </select>
</div> </div>
@ -43,7 +43,7 @@
<button <button
class="button is-success" class="button is-success"
type="submit" type="submit"
form="form--lotStatusEdit" form="form--burialSiteStatusEdit"
> >
<span class="icon"><i class="fas fa-save" aria-hidden="true"></i></span> <span class="icon"><i class="fas fa-save" aria-hidden="true"></i></span>
<span>Update Status</span> <span>Update Status</span>

View File

@ -18,14 +18,14 @@
value="" value=""
/> />
<div class="field"> <div class="field">
<label class="label" for="contractCommentAdd--contractComment" <label class="label" for="contractCommentAdd--comment"
>Comment</label >Comment</label
> >
<div class="control"> <div class="control">
<textarea <textarea
class="textarea" class="textarea"
id="contractCommentAdd--contractComment" id="contractCommentAdd--comment"
name="contractComment" name="comment"
required required
></textarea> ></textarea>
</div> </div>

View File

@ -0,0 +1,203 @@
<div class="modal" role="dialog">
<div class="modal-background"></div>
<div class="modal-card">
<header class="modal-card-head">
<h3 class="modal-card-title">
Add Interment
</h3>
<button
class="delete is-close-modal-button"
aria-label="close"
type="button"
></button>
</header>
<section class="modal-card-body">
<form id="form--contractIntermentAdd">
<input
id="contractIntermentAdd--contractId"
name="contractId"
type="hidden"
value=""
/>
<div class="columns">
<div class="column">
<div class="field">
<label class="label" for="contractIntermentAdd--deceasedName"
>Name</label
>
<div class="control">
<input
class="input"
id="contractIntermentAdd--deceasedName"
name="deceasedName"
type="text"
maxlength="200"
autocomplete="off"
required
/>
</div>
</div>
</div>
</div>
<div class="field">
<label class="label" for="contractIntermentAdd--deceasedAddress1"
>Address</label
>
<div class="control">
<input
class="input"
id="contractIntermentAdd--deceasedAddress1"
name="deceasedAddress1"
type="text"
maxlength="50"
placeholder="Line 1"
autocomplete="off"
/>
</div>
</div>
<div class="field">
<div class="control">
<input
class="input"
id="contractIntermentAdd--deceasedAddress2"
name="deceasedAddress2"
type="text"
maxlength="50"
placeholder="Line 2"
aria-label="Address Line 2"
autocomplete="off"
/>
</div>
</div>
<div class="columns">
<div class="column">
<div class="field">
<label class="label" for="contractIntermentAdd--deceasedCity"
>City</label
>
<div class="control">
<input
class="input"
id="contractIntermentAdd--deceasedCity"
name="deceasedCity"
type="text"
maxlength="20"
/>
</div>
</div>
</div>
<div class="column">
<div class="field">
<label
class="label"
for="contractIntermentAdd--deceasedProvince"
>Province</label
>
<div class="control">
<input
class="input"
id="contractIntermentAdd--deceasedProvince"
name="deceasedProvince"
type="text"
maxlength="2"
/>
</div>
</div>
</div>
<div class="column">
<div class="field">
<label
class="label"
for="contractIntermentAdd--deceasedPostalCode"
>Postal Code</label
>
<div class="control">
<input
class="input"
id="contractIntermentAdd--deceasedPostalCode"
name="deceasedPostalCode"
type="text"
maxlength="7"
autocomplete="off"
/>
</div>
</div>
</div>
</div>
<div class="columns">
<div class="column">
<div class="field">
<label class="label" for="contractIntermentAdd--birthDateString">
Date of Birth
</label>
<div class="control has-icons-left">
<input class="input" id="contractIntermentAdd--birthDateString" name="birthDateString" type="date" />
<span class="icon is-left">
<i class="fas fa-calendar" aria-hidden="true"></i>
</span>
</div>
</div>
</div>
<div class="column">
<div class="field">
<label class="label" for="contractIntermentAdd--birthPlace">
Place of Birth
</label>
<div class="control">
<input class="input" id="contractIntermentAdd--birthPlace" name="birthPlace" type="text" maxlength="100" autocomplete="off" />
</div>
</div>
</div>
</div>
<div class="columns">
<div class="column">
<div class="field">
<label class="label" for="contractIntermentAdd--deathDateString">
Date of Death
</label>
<div class="control has-icons-left">
<input class="input" id="contractIntermentAdd--deathDateString" name="deathDateString" type="date" />
<span class="icon is-left">
<i class="fas fa-calendar" aria-hidden="true"></i>
</span>
</div>
</div>
</div>
<div class="column">
<div class="field">
<label class="label" for="contractIntermentAdd--deathPlace">
Place of Death
</label>
<div class="control">
<input class="input" id="contractIntermentAdd--deathPlace" name="deathPlace" type="text" maxlength="100" autocomplete="off" />
</div>
</div>
</div>
</div>
<div class="field">
<label class="label" for="contractIntermentAdd--intermentContainerTypeId">Container</label>
<div class="control">
<div class="select is-fullwidth">
<select id="contractIntermentAdd--intermentContainerTypeId" name="intermentContainerTypeId">
<option value="">(No Container)</option>
<optgroup label="Non-Cremated" data-is-cremation-type="0"></optgroup>
<optgroup label="Cremated" data-is-cremation-type="1"></optgroup>
</select>
</div>
</div>
</div>
</form>
</section>
<footer class="modal-card-foot justify-right">
<button
class="button is-success"
type="submit"
form="form--contractIntermentAdd"
>
<span class="icon"><i class="fas fa-plus" aria-hidden="true"></i></span>
<span>Add Interment</span>
</button>
<button class="button is-close-modal-button" type="button">Cancel</button>
</footer>
</div>
</div>

View File

@ -26,14 +26,14 @@
<div class="field"> <div class="field">
<label <label
class="label" class="label"
for="contractCommentEdit--contractComment" for="contractCommentEdit--comment"
>Comment</label >Comment</label
> >
<div class="control"> <div class="control">
<textarea <textarea
class="textarea" class="textarea"
id="contractCommentEdit--contractComment" id="contractCommentEdit--comment"
name="contractComment" name="comment"
required required
></textarea> ></textarea>
</div> </div>
@ -43,14 +43,14 @@
<div class="field"> <div class="field">
<label <label
class="label" class="label"
for="contractCommentEdit--contractCommentDateString" for="contractCommentEdit--commentDateString"
>Comment Date</label >Comment Date</label
> >
<div class="control has-icons-left"> <div class="control has-icons-left">
<input <input
class="input" class="input"
id="contractCommentEdit--contractCommentDateString" id="contractCommentEdit--commentDateString"
name="contractCommentDateString" name="commentDateString"
type="date" type="date"
required required
/> />
@ -64,14 +64,14 @@
<div class="field"> <div class="field">
<label <label
class="label" class="label"
for="contractCommentEdit--contractCommentTimeString" for="contractCommentEdit--commentTimeString"
>Comment Time</label >Comment Time</label
> >
<div class="control has-icons-left"> <div class="control has-icons-left">
<input <input
class="input" class="input"
id="contractCommentEdit--contractCommentTimeString" id="contractCommentEdit--commentTimeString"
name="contractCommentTimeString" name="commentTimeString"
type="time" type="time"
required required
/> />

View File

@ -3,7 +3,7 @@
<div class="modal-card"> <div class="modal-card">
<header class="modal-card-head"> <header class="modal-card-head">
<h3 class="modal-card-title"> <h3 class="modal-card-title">
Update <span class="alias" data-alias="Occupant"></span> Update Interment
</h3> </h3>
<button <button
class="delete is-close-modal-button" class="delete is-close-modal-button"
@ -12,47 +12,31 @@
></button> ></button>
</header> </header>
<section class="modal-card-body"> <section class="modal-card-body">
<form id="form--contractOccupantEdit"> <form id="form--contractIntermentEdit">
<input <input
id="contractOccupantEdit--contractId" id="contractIntermentEdit--contractId"
name="contractId" name="contractId"
type="hidden" type="hidden"
value="" value=""
/> />
<input <input
id="contractOccupantEdit--lotOccupantIndex" id="contractIntermentEdit--intermentNumber"
name="lotOccupantIndex" name="intermentNumber"
type="hidden" type="hidden"
value="" value=""
/> />
<label class="label" for="contractOccupantEdit--lotOccupantTypeId"
><span class="alias" data-alias="Occupant"></span> Type</label <div class="columns">
>
<div class="field has-addons">
<div class="control is-expanded">
<div class="select is-fullwidth">
<select
id="contractOccupantEdit--lotOccupantTypeId"
name="lotOccupantTypeId"
required
></select>
</div>
</div>
<div class="control">
<span class="button is-static" id="contractOccupantEdit--fontAwesomeIconClass"></span>
</div>
</div>
<div class="columns mt-2 mb-0">
<div class="column"> <div class="column">
<div class="field"> <div class="field">
<label class="label" for="contractOccupantEdit--occupantName" <label class="label" for="contractIntermentEdit--deceasedName"
><span class="alias" data-alias="Occupant"></span> Name</label >Name</label
> >
<div class="control"> <div class="control">
<input <input
class="input" class="input"
id="contractOccupantEdit--occupantName" id="contractIntermentEdit--deceasedName"
name="occupantName" name="deceasedName"
type="text" type="text"
maxlength="200" maxlength="200"
autocomplete="off" autocomplete="off"
@ -61,33 +45,16 @@
</div> </div>
</div> </div>
</div> </div>
<div class="column">
<div class="field">
<label class="label" for="contractOccupantEdit--occupantFamilyName"
>Family Name</label
>
<div class="control">
<input
class="input"
id="contractOccupantEdit--occupantFamilyName"
name="occupantFamilyName"
type="text"
maxlength="200"
autocomplete="off"
/>
</div>
</div>
</div>
</div> </div>
<div class="field"> <div class="field">
<label class="label" for="contractOccupantEdit--occupantAddress1" <label class="label" for="contractIntermentEdit--deceasedAddress1"
>Address</label >Address</label
> >
<div class="control"> <div class="control">
<input <input
class="input" class="input"
id="contractOccupantEdit--occupantAddress1" id="contractIntermentEdit--deceasedAddress1"
name="occupantAddress1" name="deceasedAddress1"
type="text" type="text"
maxlength="50" maxlength="50"
placeholder="Line 1" placeholder="Line 1"
@ -99,8 +66,8 @@
<div class="control"> <div class="control">
<input <input
class="input" class="input"
id="contractOccupantEdit--occupantAddress2" id="contractIntermentEdit--deceasedAddress2"
name="occupantAddress2" name="deceasedAddress2"
type="text" type="text"
maxlength="50" maxlength="50"
placeholder="Line 2" placeholder="Line 2"
@ -112,14 +79,14 @@
<div class="columns"> <div class="columns">
<div class="column"> <div class="column">
<div class="field"> <div class="field">
<label class="label" for="contractOccupantEdit--occupantCity" <label class="label" for="contractIntermentEdit--deceasedCity"
>City</label >City</label
> >
<div class="control"> <div class="control">
<input <input
class="input" class="input"
id="contractOccupantEdit--occupantCity" id="contractIntermentEdit--deceasedCity"
name="occupantCity" name="deceasedCity"
type="text" type="text"
maxlength="20" maxlength="20"
/> />
@ -130,14 +97,14 @@
<div class="field"> <div class="field">
<label <label
class="label" class="label"
for="contractOccupantEdit--occupantProvince" for="contractIntermentEdit--deceasedProvince"
>Province</label >Province</label
> >
<div class="control"> <div class="control">
<input <input
class="input" class="input"
id="contractOccupantEdit--occupantProvince" id="contractIntermentEdit--deceasedProvince"
name="occupantProvince" name="deceasedProvince"
type="text" type="text"
maxlength="2" maxlength="2"
/> />
@ -148,14 +115,14 @@
<div class="field"> <div class="field">
<label <label
class="label" class="label"
for="contractOccupantEdit--occupantPostalCode" for="contractIntermentEdit--deceasedPostalCode"
>Postal Code</label >Postal Code</label
> >
<div class="control"> <div class="control">
<input <input
class="input" class="input"
id="contractOccupantEdit--occupantPostalCode" id="contractIntermentEdit--deceasedPostalCode"
name="occupantPostalCode" name="deceasedPostalCode"
type="text" type="text"
maxlength="7" maxlength="7"
autocomplete="off" autocomplete="off"
@ -166,63 +133,64 @@
</div> </div>
<div class="columns"> <div class="columns">
<div class="column"> <div class="column">
<label
class="label"
for="contractOccupantEdit--occupantPhoneNumber"
>Phone Number</label
>
<div class="field"> <div class="field">
<label class="label" for="contractIntermentEdit--birthDateString">
Date of Birth
</label>
<div class="control has-icons-left"> <div class="control has-icons-left">
<input <input class="input" id="contractIntermentEdit--birthDateString" name="birthDateString" type="date" />
class="input" <span class="icon is-left">
id="contractOccupantEdit--occupantPhoneNumber" <i class="fas fa-calendar" aria-hidden="true"></i>
name="occupantPhoneNumber"
type="text"
maxlength="30"
autocomplete="off"
/>
<span class="icon is-small is-left">
<i class="fas fa-phone" aria-hidden="true"></i>
</span> </span>
</div> </div>
</div> </div>
</div> </div>
<div class="column"> <div class="column">
<label
class="label"
for="contractOccupantEdit--occupantEmailAddress"
>Email Address</label
>
<div class="field"> <div class="field">
<label class="label" for="contractIntermentEdit--birthPlace">
Place of Birth
</label>
<div class="control">
<input class="input" id="contractIntermentEdit--birthPlace" name="birthPlace" type="text" maxlength="100" autocomplete="off" />
</div>
</div>
</div>
</div>
<div class="columns">
<div class="column">
<div class="field">
<label class="label" for="contractIntermentEdit--deathDateString">
Date of Death
</label>
<div class="control has-icons-left"> <div class="control has-icons-left">
<input <input class="input" id="contractIntermentEdit--deathDateString" name="deathDateString" type="date" />
class="input" <span class="icon is-left">
id="contractOccupantEdit--occupantEmailAddress" <i class="fas fa-calendar" aria-hidden="true"></i>
name="occupantEmailAddress"
type="email"
maxlength="200"
autocomplete="off"
/>
<span class="icon is-small is-left">
<i class="fas fa-envelope" aria-hidden="true"></i>
</span> </span>
</div> </div>
</div> </div>
</div> </div>
<div class="column">
<div class="field">
<label class="label" for="contractIntermentEdit--deathPlace">
Place of Death
</label>
<div class="control">
<input class="input" id="contractIntermentEdit--deathPlace" name="deathPlace" type="text" maxlength="100" autocomplete="off" />
</div>
</div>
</div>
</div> </div>
<div class="field"> <div class="field">
<label <label class="label" for="contractIntermentEdit--intermentContainerTypeId">Container</label>
class="label"
id="contractOccupantEdit--occupantCommentTitle"
for="contractOccupantEdit--occupantComment"
>Comment</label
>
<div class="control"> <div class="control">
<textarea <div class="select is-fullwidth">
class="textarea" <select id="contractIntermentEdit--intermentContainerTypeId" name="intermentContainerTypeId">
id="contractOccupantEdit--occupantComment" <option value="">(No Container)</option>
name="occupantComment" <optgroup label="Non-Cremated" data-is-cremation-type="0"></optgroup>
></textarea> <optgroup label="Cremated" data-is-cremation-type="1"></optgroup>
</select>
</div>
</div> </div>
</div> </div>
</form> </form>
@ -231,10 +199,10 @@
<button <button
class="button is-success" class="button is-success"
type="submit" type="submit"
form="form--contractOccupantEdit" form="form--contractIntermentEdit"
> >
<span class="icon"><i class="fas fa-plus" aria-hidden="true"></i></span> <span class="icon"><i class="fas fa-save" aria-hidden="true"></i></span>
<span>Update <span class="alias" data-alias="Occupant"></span></span> <span>Update Interment</span>
</button> </button>
<button class="button is-close-modal-button" type="button">Cancel</button> <button class="button is-close-modal-button" type="button">Cancel</button>
</footer> </footer>

View File

@ -1,318 +0,0 @@
<div class="modal" role="dialog">
<div class="modal-background"></div>
<div class="modal-card">
<header class="modal-card-head">
<h3 class="modal-card-title">
Add <span class="alias" data-alias="Occupant"></span>
</h3>
<button
class="delete is-close-modal-button"
aria-label="close"
type="button"
></button>
</header>
<section class="modal-card-body">
<div class="tabs is-boxed">
<ul>
<li class="is-active">
<a href="#tab--contractOccupantAdd-new">
<span class="icon is-small">
<i class="fas fa-plus" aria-hidden="true"></i>
</span>
<span>Create New</span>
</a>
</li>
<li>
<a href="#tab--contractOccupantAdd-copy">
<span class="icon is-small">
<i class="fas fa-copy" aria-hidden="true"></i>
</span>
<span>Copy Previous</span>
</a>
</li>
</ul>
</div>
<div class="tab-container">
<div id="tab--contractOccupantAdd-new">
<form id="form--contractOccupantAdd">
<input
id="contractOccupantAdd--contractId"
name="contractId"
type="hidden"
value=""
/>
<label
class="label"
for="contractOccupantAdd--lotOccupantTypeId"
><span class="alias" data-alias="Occupant"></span> Type</label
>
<div class="field has-addons">
<div class="control is-expanded">
<div class="select is-fullwidth">
<select
id="contractOccupantAdd--lotOccupantTypeId"
name="lotOccupantTypeId"
required
>
<option value="" data-font-awesome-icon-class="user">(Select a Type)</option>
</select>
</div>
</div>
<div class="control">
<span class="button is-static" id="contractOccupantAdd--fontAwesomeIconClass">
<i class="fas fa-fw fa-user" aria-hidden="true"></i>
</span>
</div>
</div>
<div class="columns mt-2 mb-0">
<div class="column">
<div class="field">
<label class="label" for="contractOccupantAdd--occupantName"
><span class="alias" data-alias="Occupant"></span> Name</label
>
<div class="control">
<input
class="input"
id="contractOccupantAdd--occupantName"
name="occupantName"
type="text"
maxlength="200"
autocomplete="off"
required
/>
</div>
</div>
</div>
<div class="column">
<div class="field">
<label class="label" for="contractOccupantAdd--occupantFamilyName"
>Family Name</label
>
<div class="control">
<input
class="input"
id="contractOccupantAdd--occupantFamilyName"
name="occupantFamilyName"
type="text"
maxlength="200"
autocomplete="off"
/>
</div>
</div>
</div>
</div>
<div class="field">
<label
class="label"
for="contractOccupantAdd--occupantAddress1"
>Address</label
>
<div class="control">
<input
class="input"
id="contractOccupantAdd--occupantAddress1"
name="occupantAddress1"
type="text"
maxlength="50"
placeholder="Line 1"
autocomplete="off"
/>
</div>
</div>
<div class="field">
<div class="control">
<input
class="input"
id="contractOccupantAdd--occupantAddress2"
name="occupantAddress2"
type="text"
maxlength="50"
placeholder="Line 2"
autocomplete="off"
aria-label="Address Line 2"
/>
</div>
</div>
<div class="columns">
<div class="column">
<div class="field">
<label
class="label"
for="contractOccupantAdd--occupantCity"
>City</label
>
<div class="control">
<input
class="input"
id="contractOccupantAdd--occupantCity"
name="occupantCity"
type="text"
maxlength="20"
/>
</div>
</div>
</div>
<div class="column">
<div class="field">
<label
class="label"
for="contractOccupantAdd--occupantProvince"
>Province</label
>
<div class="control">
<input
class="input"
id="contractOccupantAdd--occupantProvince"
name="occupantProvince"
type="text"
maxlength="2"
/>
</div>
</div>
</div>
<div class="column">
<div class="field">
<label
class="label"
for="contractOccupantAdd--occupantPostalCode"
>Postal Code</label
>
<div class="control">
<input
class="input"
id="contractOccupantAdd--occupantPostalCode"
name="occupantPostalCode"
type="text"
maxlength="7"
autocomplete="off"
/>
</div>
</div>
</div>
</div>
<div class="columns">
<div class="column">
<label
class="label"
for="contractOccupantAdd--occupantPhoneNumber"
>Phone Number</label
>
<div class="field">
<div class="control has-icons-left">
<input
class="input"
id="contractOccupantAdd--occupantPhoneNumber"
name="occupantPhoneNumber"
type="text"
maxlength="30"
autocomplete="off"
/>
<span class="icon is-small is-left">
<i class="fas fa-phone" aria-hidden="true"></i>
</span>
</div>
</div>
</div>
<div class="column">
<label
class="label"
for="contractOccupantAdd--occupantEmailAddress"
>Email Address</label
>
<div class="field">
<div class="control has-icons-left">
<input
class="input"
id="contractOccupantAdd--occupantEmailAddress"
name="occupantEmailAddress"
type="email"
maxlength="200"
autocomplete="off"
/>
<span class="icon is-small is-left">
<i class="fas fa-envelope" aria-hidden="true"></i>
</span>
</div>
</div>
</div>
</div>
<div class="field">
<label
class="label"
id="contractOccupantAdd--occupantCommentTitle"
for="contractOccupantAdd--occupantComment"
>Comment</label
>
<div class="control">
<textarea
class="textarea"
id="contractOccupantAdd--occupantComment"
name="occupantComment"
></textarea>
</div>
</div>
<div class="has-text-right">
<button class="button is-success" type="submit">
<span class="icon"
><i class="fas fa-plus" aria-hidden="true"></i
></span>
<span
>Add <span class="alias" data-alias="Occupant"></span
></span>
</button>
</div>
</form>
</div>
<div class="is-hidden" id="tab--contractOccupantAdd-copy">
<div class="box">
<div class="field mb-4">
<label
class="label"
for="contractOccupantCopy--lotOccupantTypeId"
>New <span class="alias" data-alias="Occupant"></span> Type</label
>
<div class="control">
<div class="select is-fullwidth">
<select
id="contractOccupantCopy--lotOccupantTypeId"
name="lotOccupantTypeId"
required
>
<option value="">(Select a Type)</option>
</select>
</div>
</div>
</div>
<form id="form--contractOccupantCopy">
<input name="limit" type="hidden" value="50" />
<div class="field">
<label
class="label"
for="contractOccupantCopy--searchFilter"
>Find a Previously Used <span class="alias" data-alias="Occupant"></span></label
>
<div class="control has-icons-left">
<input
class="input"
id="contractOccupantCopy--searchFilter"
name="searchFilter"
type="text"
placeholder="Filter by name or address"
/>
<span class="icon is-left">
<i class="fas fa-filter" aria-hidden="true"></i>
</span>
</div>
</div>
</form>
</div>
<div id="contractOccupantCopy--searchResults"></div>
</div>
</div>
</section>
<footer class="modal-card-foot justify-right">
<button class="button is-close-modal-button" type="button">Cancel</button>
</footer>
</div>
</div>

View File

@ -3,7 +3,7 @@
<div class="modal-card has-width-900"> <div class="modal-card has-width-900">
<header class="modal-card-head"> <header class="modal-card-head">
<h3 class="modal-card-title"> <h3 class="modal-card-title">
Add Related <span class="alias" data-alias="Lot"></span> to Work Order Add Related Burial Site to Work Order
</h3> </h3>
<button <button
class="delete is-close-modal-button" class="delete is-close-modal-button"
@ -13,11 +13,11 @@
</header> </header>
<section class="modal-card-body"> <section class="modal-card-body">
<div class="box"> <div class="box">
<form id="form--lotSearch"> <form id="form--burialSiteSearch">
<input name="limit" type="hidden" value="100" /> <input name="limit" type="hidden" value="100" />
<input name="offset" type="hidden" value="0" /> <input name="offset" type="hidden" value="0" />
<input <input
id="lotSearch--notWorkOrderId" id="burialSiteSearch--notWorkOrderId"
name="notWorkOrderId" name="notWorkOrderId"
type="hidden" type="hidden"
value="" value=""
@ -26,14 +26,13 @@
<div class="columns"> <div class="columns">
<div class="column"> <div class="column">
<div class="field"> <div class="field">
<label class="label" for="lotSearch--burialSiteName"> <label class="label" for="burialSiteSearch--burialSiteName">
<span class="alias" data-alias="Lot"></span> Burial Site Name
Name
</label> </label>
<div class="control has-icons-left"> <div class="control has-icons-left">
<input <input
class="input" class="input"
id="lotSearch--burialSiteName" id="burialSiteSearch--burialSiteName"
name="burialSiteName" name="burialSiteName"
type="text" type="text"
/> />
@ -45,10 +44,10 @@
</div> </div>
<div class="column"> <div class="column">
<div class="field"> <div class="field">
<label class="label" for="lotSearch--burialSiteStatusId">Status</label> <label class="label" for="burialSiteSearch--burialSiteStatusId">Status</label>
<div class="control has-icons-left"> <div class="control has-icons-left">
<div class="select is-fullwidth"> <div class="select is-fullwidth">
<select id="lotSearch--burialSiteStatusId" name="burialSiteStatusId"> <select id="burialSiteSearch--burialSiteStatusId" name="burialSiteStatusId">
<option value="">(All Statuses)</option> <option value="">(All Statuses)</option>
</select> </select>
</div> </div>
@ -61,7 +60,7 @@
</div> </div>
</form> </form>
</div> </div>
<div id="resultsContainer--lotAdd"></div> <div id="resultsContainer--burialSiteAdd"></div>
</section> </section>
<footer class="modal-card-foot justify-right"> <footer class="modal-card-foot justify-right">
<button class="button is-close-modal-button" type="button">Close</button> <button class="button is-close-modal-button" type="button">Close</button>

View File

@ -18,14 +18,14 @@
value="" value=""
/> />
<div class="field"> <div class="field">
<label class="label" for="workOrderCommentAdd--workOrderComment" <label class="label" for="workOrderCommentAdd--comment"
>Comment</label >Comment</label
> >
<div class="control"> <div class="control">
<textarea <textarea
class="textarea" class="textarea"
id="workOrderCommentAdd--workOrderComment" id="workOrderCommentAdd--comment"
name="workOrderComment" name="comment"
required required
></textarea> ></textarea>
</div> </div>

View File

@ -3,8 +3,7 @@
<div class="modal-card has-width-900"> <div class="modal-card has-width-900">
<header class="modal-card-head"> <header class="modal-card-head">
<h3 class="modal-card-title"> <h3 class="modal-card-title">
Add Related <span class="alias" data-alias="Occupancy"></span> to Work Add Related Contract to Work Order
Order
</h3> </h3>
<button <button
class="delete is-close-modal-button" class="delete is-close-modal-button"
@ -24,23 +23,22 @@
value="" value=""
/> />
<input <input
id="contractSearch--occupancyEffectiveDateString" id="contractSearch--contractEffectiveDateString"
name="occupancyEffectiveDateString" name="contractEffectiveDateString"
type="hidden" type="hidden"
value="" value=""
/> />
<div class="columns"> <div class="columns">
<div class="column"> <div class="column">
<div class="field"> <div class="field">
<label class="label" for="contractSearch--occupantName"> <label class="label" for="contractSearch--deceasedName">
<span class="alias" data-alias="Occupant"></span> Interment Name
Name
</label> </label>
<div class="control has-icons-left"> <div class="control has-icons-left">
<input <input
class="input" class="input"
id="contractSearch--occupantName" id="contractSearch--deceasedName"
name="occupantName" name="deceasedName"
type="text" type="text"
/> />
<span class="icon is-small is-left"> <span class="icon is-small is-left">
@ -52,8 +50,7 @@
<div class="column"> <div class="column">
<div class="field"> <div class="field">
<label class="label" for="contractSearch--burialSiteName"> <label class="label" for="contractSearch--burialSiteName">
<span class="alias" data-alias="Lot"></span> Burial Site Name
Name
</label> </label>
<div class="control has-icons-left"> <div class="control has-icons-left">
<input <input

View File

@ -24,14 +24,14 @@
value="" value=""
/> />
<div class="field"> <div class="field">
<label class="label" for="workOrderCommentEdit--workOrderComment" <label class="label" for="workOrderCommentEdit--comment"
>Comment</label >Comment</label
> >
<div class="control"> <div class="control">
<textarea <textarea
class="textarea" class="textarea"
id="workOrderCommentEdit--workOrderComment" id="workOrderCommentEdit--comment"
name="workOrderComment" name="comment"
required required
></textarea> ></textarea>
</div> </div>
@ -41,14 +41,14 @@
<div class="field"> <div class="field">
<label <label
class="label" class="label"
for="workOrderCommentEdit--workOrderCommentDateString" for="workOrderCommentEdit--commentDateString"
>Comment Date</label >Comment Date</label
> >
<div class="control has-icons-left"> <div class="control has-icons-left">
<input <input
class="input" class="input"
id="workOrderCommentEdit--workOrderCommentDateString" id="workOrderCommentEdit--commentDateString"
name="workOrderCommentDateString" name="commentDateString"
type="date" type="date"
required required
/> />
@ -62,14 +62,14 @@
<div class="field"> <div class="field">
<label <label
class="label" class="label"
for="workOrderCommentEdit--workOrderCommentTimeString" for="workOrderCommentEdit--commentTimeString"
>Comment Time</label >Comment Time</label
> >
<div class="control has-icons-left"> <div class="control has-icons-left">
<input <input
class="input" class="input"
id="workOrderCommentEdit--workOrderCommentTimeString" id="workOrderCommentEdit--commentTimeString"
name="workOrderCommentTimeString" name="commentTimeString"
type="time" type="time"
required required
/> />

View File

@ -1,19 +1,21 @@
"use strict"; "use strict";
// eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair
/* eslint-disable max-lines */
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
(() => { (() => {
const los = exports.sunrise; const sunrise = exports.sunrise;
const burialSiteId = document.querySelector('#burialSite--burialSiteId').value; const burialSiteId = document.querySelector('#burialSite--burialSiteId').value;
const isCreate = burialSiteId === ''; const isCreate = burialSiteId === '';
// Main form // Main form
let refreshAfterSave = isCreate; let refreshAfterSave = isCreate;
function setUnsavedChanges() { function setUnsavedChanges() {
los.setUnsavedChanges(); sunrise.setUnsavedChanges();
document document
.querySelector("button[type='submit'][form='form--burialSite']") .querySelector("button[type='submit'][form='form--burialSite']")
?.classList.remove('is-light'); ?.classList.remove('is-light');
} }
function clearUnsavedChanges() { function clearUnsavedChanges() {
los.clearUnsavedChanges(); sunrise.clearUnsavedChanges();
document document
.querySelector("button[type='submit'][form='form--burialSite']") .querySelector("button[type='submit'][form='form--burialSite']")
?.classList.add('is-light'); ?.classList.add('is-light');
@ -21,12 +23,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
const formElement = document.querySelector('#form--burialSite'); const formElement = document.querySelector('#form--burialSite');
function updateBurialSite(formEvent) { function updateBurialSite(formEvent) {
formEvent.preventDefault(); formEvent.preventDefault();
cityssm.postJSON(`${los.urlPrefix}/burialSites/${isCreate ? 'doCreateBurialSite' : 'doUpdateBurialSite'}`, formElement, (rawResponseJSON) => { cityssm.postJSON(`${sunrise.urlPrefix}/burialSites/${isCreate ? 'doCreateBurialSite' : 'doUpdateBurialSite'}`, formElement, (rawResponseJSON) => {
const responseJSON = rawResponseJSON; const responseJSON = rawResponseJSON;
if (responseJSON.success) { if (responseJSON.success) {
clearUnsavedChanges(); clearUnsavedChanges();
if (isCreate || refreshAfterSave) { if (isCreate || refreshAfterSave) {
globalThis.location.href = los.getBurialSiteURL(responseJSON.burialSiteId, true, true); globalThis.location.href = sunrise.getBurialSiteURL(responseJSON.burialSiteId, true, true);
} }
else { else {
bulmaJS.alert({ bulmaJS.alert({
@ -49,19 +51,19 @@ Object.defineProperty(exports, "__esModule", { value: true });
for (const formInputElement of formInputElements) { for (const formInputElement of formInputElements) {
formInputElement.addEventListener('change', setUnsavedChanges); formInputElement.addEventListener('change', setUnsavedChanges);
} }
los.initializeUnlockFieldButtons(formElement); sunrise.initializeUnlockFieldButtons(formElement);
document document
.querySelector('#button--deleteBurialSite') .querySelector('#button--deleteBurialSite')
?.addEventListener('click', (clickEvent) => { ?.addEventListener('click', (clickEvent) => {
clickEvent.preventDefault(); clickEvent.preventDefault();
function doDelete() { function doDelete() {
cityssm.postJSON(`${los.urlPrefix}/burialSites/doDeleteBurialSite`, { cityssm.postJSON(`${sunrise.urlPrefix}/burialSites/doDeleteBurialSite`, {
burialSiteId burialSiteId
}, (rawResponseJSON) => { }, (rawResponseJSON) => {
const responseJSON = rawResponseJSON; const responseJSON = rawResponseJSON;
if (responseJSON.success) { if (responseJSON.success) {
clearUnsavedChanges(); clearUnsavedChanges();
globalThis.location.href = los.getBurialSiteURL(); globalThis.location.href = sunrise.getBurialSiteURL();
} }
else { else {
bulmaJS.alert({ bulmaJS.alert({
@ -93,7 +95,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
</div>`; </div>`;
return; return;
} }
cityssm.postJSON(`${los.urlPrefix}/burialSites/doGetBurialSiteTypeFields`, { cityssm.postJSON(`${sunrise.urlPrefix}/burialSites/doGetBurialSiteTypeFields`, {
burialSiteTypeId: burialSiteTypeIdElement.value burialSiteTypeId: burialSiteTypeIdElement.value
}, (rawResponseJSON) => { }, (rawResponseJSON) => {
const responseJSON = rawResponseJSON; const responseJSON = rawResponseJSON;
@ -149,7 +151,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
} }
burialSiteFieldsContainerElement.append(fieldElement); burialSiteFieldsContainerElement.append(fieldElement);
} }
burialSiteFieldsContainerElement.insertAdjacentHTML('beforeend', `<input name="burialSiteTypeFieldIds" type="hidden" burialSiteFieldsContainerElement.insertAdjacentHTML('beforeend',
// eslint-disable-next-line no-secrets/no-secrets
`<input name="burialSiteTypeFieldIds" type="hidden"
value="${cityssm.escapeHTML(burialSiteTypeFieldIds.slice(1))}" />`); value="${cityssm.escapeHTML(burialSiteTypeFieldIds.slice(1))}" />`);
}); });
}); });
@ -190,7 +194,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
let editCloseModalFunction; let editCloseModalFunction;
function editComment(submitEvent) { function editComment(submitEvent) {
submitEvent.preventDefault(); submitEvent.preventDefault();
cityssm.postJSON(`${los.urlPrefix}/burialSites/doUpdateBurialSiteComment`, editFormElement, (rawResponseJSON) => { cityssm.postJSON(`${sunrise.urlPrefix}/burialSites/doUpdateBurialSiteComment`, editFormElement, (rawResponseJSON) => {
const responseJSON = rawResponseJSON; const responseJSON = rawResponseJSON;
if (responseJSON.success) { if (responseJSON.success) {
burialSiteComments = responseJSON.burialSiteComments; burialSiteComments = responseJSON.burialSiteComments;
@ -208,7 +212,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
} }
cityssm.openHtmlModal('burialSite-editComment', { cityssm.openHtmlModal('burialSite-editComment', {
onshow(modalElement) { onshow(modalElement) {
los.populateAliases(modalElement); sunrise.populateAliases(modalElement);
modalElement.querySelector('#burialSiteCommentEdit--burialSiteId').value = burialSiteId; modalElement.querySelector('#burialSiteCommentEdit--burialSiteId').value = burialSiteId;
modalElement.querySelector('#burialSiteCommentEdit--burialSiteCommentId').value = burialSiteCommentId.toString(); modalElement.querySelector('#burialSiteCommentEdit--burialSiteCommentId').value = burialSiteCommentId.toString();
modalElement.querySelector('#burialSiteCommentEdit--comment').value = burialSiteComment.comment ?? ''; modalElement.querySelector('#burialSiteCommentEdit--comment').value = burialSiteComment.comment ?? '';
@ -224,7 +228,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
}, },
onshown(modalElement, closeModalFunction) { onshown(modalElement, closeModalFunction) {
bulmaJS.toggleHtmlClipped(); bulmaJS.toggleHtmlClipped();
los.initializeDatePickers(modalElement);
modalElement.querySelector('#burialSiteCommentEdit--comment').focus(); modalElement.querySelector('#burialSiteCommentEdit--comment').focus();
editFormElement = modalElement.querySelector('form'); editFormElement = modalElement.querySelector('form');
editFormElement.addEventListener('submit', editComment); editFormElement.addEventListener('submit', editComment);
@ -239,7 +242,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
const burialSiteCommentId = Number.parseInt(clickEvent.currentTarget.closest('tr')?.dataset const burialSiteCommentId = Number.parseInt(clickEvent.currentTarget.closest('tr')?.dataset
.burialSiteCommentId ?? '', 10); .burialSiteCommentId ?? '', 10);
function doDelete() { function doDelete() {
cityssm.postJSON(`${los.urlPrefix}/burialSites/doDeleteBurialSiteComment`, { cityssm.postJSON(`${sunrise.urlPrefix}/burialSites/doDeleteBurialSiteComment`, {
burialSiteId, burialSiteId,
burialSiteCommentId burialSiteCommentId
}, (rawResponseJSON) => { }, (rawResponseJSON) => {
@ -324,7 +327,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
let addCommentCloseModalFunction; let addCommentCloseModalFunction;
function doAddComment(formEvent) { function doAddComment(formEvent) {
formEvent.preventDefault(); formEvent.preventDefault();
cityssm.postJSON(`${los.urlPrefix}/burialSites/doAddBurialSiteComment`, formEvent.currentTarget, (rawResponseJSON) => { cityssm.postJSON(`${sunrise.urlPrefix}/burialSites/doAddBurialSiteComment`, formEvent.currentTarget, (rawResponseJSON) => {
const responseJSON = rawResponseJSON; const responseJSON = rawResponseJSON;
if (responseJSON.success) { if (responseJSON.success) {
burialSiteComments = responseJSON.burialSiteComments; burialSiteComments = responseJSON.burialSiteComments;
@ -335,7 +338,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
} }
cityssm.openHtmlModal('burialSite-addComment', { cityssm.openHtmlModal('burialSite-addComment', {
onshow(modalElement) { onshow(modalElement) {
los.populateAliases(modalElement); sunrise.populateAliases(modalElement);
modalElement.querySelector('#burialSiteCommentAdd--burialSiteId').value = burialSiteId; modalElement.querySelector('#burialSiteCommentAdd--burialSiteId').value = burialSiteId;
modalElement modalElement
.querySelector('form') .querySelector('form')

View File

@ -1,3 +1,6 @@
// eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair
/* eslint-disable max-lines */
import type { BulmaJS } from '@cityssm/bulma-js/types.js' import type { BulmaJS } from '@cityssm/bulma-js/types.js'
import type { cityssmGlobal } from '@cityssm/bulma-webapp-js/src/types.js' import type { cityssmGlobal } from '@cityssm/bulma-webapp-js/src/types.js'
@ -13,7 +16,7 @@ declare const bulmaJS: BulmaJS
declare const exports: Record<string, unknown> declare const exports: Record<string, unknown>
;(() => { ;(() => {
const los = exports.sunrise as Sunrise const sunrise = exports.sunrise as Sunrise
const burialSiteId = ( const burialSiteId = (
document.querySelector('#burialSite--burialSiteId') as HTMLInputElement document.querySelector('#burialSite--burialSiteId') as HTMLInputElement
@ -25,14 +28,14 @@ declare const exports: Record<string, unknown>
let refreshAfterSave = isCreate let refreshAfterSave = isCreate
function setUnsavedChanges(): void { function setUnsavedChanges(): void {
los.setUnsavedChanges() sunrise.setUnsavedChanges()
document document
.querySelector("button[type='submit'][form='form--burialSite']") .querySelector("button[type='submit'][form='form--burialSite']")
?.classList.remove('is-light') ?.classList.remove('is-light')
} }
function clearUnsavedChanges(): void { function clearUnsavedChanges(): void {
los.clearUnsavedChanges() sunrise.clearUnsavedChanges()
document document
.querySelector("button[type='submit'][form='form--burialSite']") .querySelector("button[type='submit'][form='form--burialSite']")
?.classList.add('is-light') ?.classList.add('is-light')
@ -46,7 +49,7 @@ declare const exports: Record<string, unknown>
formEvent.preventDefault() formEvent.preventDefault()
cityssm.postJSON( cityssm.postJSON(
`${los.urlPrefix}/burialSites/${isCreate ? 'doCreateBurialSite' : 'doUpdateBurialSite'}`, `${sunrise.urlPrefix}/burialSites/${isCreate ? 'doCreateBurialSite' : 'doUpdateBurialSite'}`,
formElement, formElement,
(rawResponseJSON) => { (rawResponseJSON) => {
const responseJSON = rawResponseJSON as { const responseJSON = rawResponseJSON as {
@ -59,7 +62,7 @@ declare const exports: Record<string, unknown>
clearUnsavedChanges() clearUnsavedChanges()
if (isCreate || refreshAfterSave) { if (isCreate || refreshAfterSave) {
globalThis.location.href = los.getBurialSiteURL( globalThis.location.href = sunrise.getBurialSiteURL(
responseJSON.burialSiteId, responseJSON.burialSiteId,
true, true,
true true
@ -89,7 +92,7 @@ declare const exports: Record<string, unknown>
formInputElement.addEventListener('change', setUnsavedChanges) formInputElement.addEventListener('change', setUnsavedChanges)
} }
los.initializeUnlockFieldButtons(formElement) sunrise.initializeUnlockFieldButtons(formElement)
document document
.querySelector('#button--deleteBurialSite') .querySelector('#button--deleteBurialSite')
@ -98,7 +101,7 @@ declare const exports: Record<string, unknown>
function doDelete(): void { function doDelete(): void {
cityssm.postJSON( cityssm.postJSON(
`${los.urlPrefix}/burialSites/doDeleteBurialSite`, `${sunrise.urlPrefix}/burialSites/doDeleteBurialSite`,
{ {
burialSiteId burialSiteId
}, },
@ -110,7 +113,7 @@ declare const exports: Record<string, unknown>
if (responseJSON.success) { if (responseJSON.success) {
clearUnsavedChanges() clearUnsavedChanges()
globalThis.location.href = los.getBurialSiteURL() globalThis.location.href = sunrise.getBurialSiteURL()
} else { } else {
bulmaJS.alert({ bulmaJS.alert({
title: `Error Deleting Burial Site`, title: `Error Deleting Burial Site`,
@ -154,7 +157,7 @@ declare const exports: Record<string, unknown>
} }
cityssm.postJSON( cityssm.postJSON(
`${los.urlPrefix}/burialSites/doGetBurialSiteTypeFields`, `${sunrise.urlPrefix}/burialSites/doGetBurialSiteTypeFields`,
{ {
burialSiteTypeId: burialSiteTypeIdElement.value burialSiteTypeId: burialSiteTypeIdElement.value
}, },
@ -245,6 +248,7 @@ declare const exports: Record<string, unknown>
burialSiteFieldsContainerElement.insertAdjacentHTML( burialSiteFieldsContainerElement.insertAdjacentHTML(
'beforeend', 'beforeend',
// eslint-disable-next-line no-secrets/no-secrets
`<input name="burialSiteTypeFieldIds" type="hidden" `<input name="burialSiteTypeFieldIds" type="hidden"
value="${cityssm.escapeHTML(burialSiteTypeFieldIds.slice(1))}" />` value="${cityssm.escapeHTML(burialSiteTypeFieldIds.slice(1))}" />`
) )
@ -302,7 +306,7 @@ declare const exports: Record<string, unknown>
submitEvent.preventDefault() submitEvent.preventDefault()
cityssm.postJSON( cityssm.postJSON(
`${los.urlPrefix}/burialSites/doUpdateBurialSiteComment`, `${sunrise.urlPrefix}/burialSites/doUpdateBurialSiteComment`,
editFormElement, editFormElement,
(rawResponseJSON) => { (rawResponseJSON) => {
const responseJSON = rawResponseJSON as { const responseJSON = rawResponseJSON as {
@ -328,7 +332,7 @@ declare const exports: Record<string, unknown>
cityssm.openHtmlModal('burialSite-editComment', { cityssm.openHtmlModal('burialSite-editComment', {
onshow(modalElement) { onshow(modalElement) {
los.populateAliases(modalElement) sunrise.populateAliases(modalElement)
;( ;(
modalElement.querySelector( modalElement.querySelector(
'#burialSiteCommentEdit--burialSiteId' '#burialSiteCommentEdit--burialSiteId'
@ -366,9 +370,6 @@ declare const exports: Record<string, unknown>
}, },
onshown(modalElement, closeModalFunction) { onshown(modalElement, closeModalFunction) {
bulmaJS.toggleHtmlClipped() bulmaJS.toggleHtmlClipped()
los.initializeDatePickers(modalElement)
// los.initializeTimePickers(modalElement);
;( ;(
modalElement.querySelector( modalElement.querySelector(
'#burialSiteCommentEdit--comment' '#burialSiteCommentEdit--comment'
@ -395,7 +396,7 @@ declare const exports: Record<string, unknown>
function doDelete(): void { function doDelete(): void {
cityssm.postJSON( cityssm.postJSON(
`${los.urlPrefix}/burialSites/doDeleteBurialSiteComment`, `${sunrise.urlPrefix}/burialSites/doDeleteBurialSiteComment`,
{ {
burialSiteId, burialSiteId,
burialSiteCommentId burialSiteCommentId
@ -505,7 +506,7 @@ declare const exports: Record<string, unknown>
formEvent.preventDefault() formEvent.preventDefault()
cityssm.postJSON( cityssm.postJSON(
`${los.urlPrefix}/burialSites/doAddBurialSiteComment`, `${sunrise.urlPrefix}/burialSites/doAddBurialSiteComment`,
formEvent.currentTarget, formEvent.currentTarget,
(rawResponseJSON) => { (rawResponseJSON) => {
const responseJSON = rawResponseJSON as { const responseJSON = rawResponseJSON as {
@ -524,7 +525,7 @@ declare const exports: Record<string, unknown>
cityssm.openHtmlModal('burialSite-addComment', { cityssm.openHtmlModal('burialSite-addComment', {
onshow(modalElement) { onshow(modalElement) {
los.populateAliases(modalElement) sunrise.populateAliases(modalElement)
;( ;(
modalElement.querySelector( modalElement.querySelector(
'#burialSiteCommentAdd--burialSiteId' '#burialSiteCommentAdd--burialSiteId'

View File

@ -1,7 +1,7 @@
"use strict"; "use strict";
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
(() => { (() => {
const los = exports.sunrise; const sunrise = exports.sunrise;
const searchFilterFormElement = document.querySelector('#form--searchFilters'); const searchFilterFormElement = document.querySelector('#form--searchFilters');
const searchResultsContainerElement = document.querySelector('#container--searchResults'); const searchResultsContainerElement = document.querySelector('#container--searchResults');
const limit = Number.parseInt(document.querySelector('#searchFilter--limit').value, 10); const limit = Number.parseInt(document.querySelector('#searchFilter--limit').value, 10);
@ -19,11 +19,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
// eslint-disable-next-line no-unsanitized/method // eslint-disable-next-line no-unsanitized/method
resultsTbodyElement.insertAdjacentHTML('beforeend', `<tr> resultsTbodyElement.insertAdjacentHTML('beforeend', `<tr>
<td> <td>
<a class="has-text-weight-bold" href="${los.getBurialSiteURL(burialSite.burialSiteId)}"> <a class="has-text-weight-bold" href="${sunrise.getBurialSiteURL(burialSite.burialSiteId)}">
${cityssm.escapeHTML(burialSite.burialSiteName ?? '')} ${cityssm.escapeHTML(burialSite.burialSiteName ?? '')}
</a> </a>
</td><td> </td><td>
<a href="${los.getCemeteryURL(burialSite.cemeteryId)}"> <a href="${sunrise.getCemeteryURL(burialSite.cemeteryId)}">
${burialSite.cemeteryName ${burialSite.cemeteryName
? cityssm.escapeHTML(burialSite.cemeteryName) ? cityssm.escapeHTML(burialSite.cemeteryName)
: '<span class="has-text-grey">(No Name)</span>'} : '<span class="has-text-grey">(No Name)</span>'}
@ -49,7 +49,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
</tr></thead> </tr></thead>
<table>`; <table>`;
// eslint-disable-next-line no-unsanitized/method // eslint-disable-next-line no-unsanitized/method
searchResultsContainerElement.insertAdjacentHTML('beforeend', los.getSearchResultsPagerHTML(limit, responseJSON.offset, responseJSON.count)); searchResultsContainerElement.insertAdjacentHTML('beforeend', sunrise.getSearchResultsPagerHTML(limit, responseJSON.offset, responseJSON.count));
searchResultsContainerElement searchResultsContainerElement
.querySelector('table') .querySelector('table')
?.append(resultsTbodyElement); ?.append(resultsTbodyElement);
@ -62,8 +62,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
} }
function getBurialSites() { function getBurialSites() {
// eslint-disable-next-line no-unsanitized/property // eslint-disable-next-line no-unsanitized/property
searchResultsContainerElement.innerHTML = los.getLoadingParagraphHTML(`Loading Burial Sites...`); searchResultsContainerElement.innerHTML = sunrise.getLoadingParagraphHTML(`Loading Burial Sites...`);
cityssm.postJSON(`${los.urlPrefix}/burialSites/doSearchBurialSites`, searchFilterFormElement, renderBurialSites); cityssm.postJSON(`${sunrise.urlPrefix}/burialSites/doSearchBurialSites`, searchFilterFormElement, renderBurialSites);
} }
function resetOffsetAndGetBurialSites() { function resetOffsetAndGetBurialSites() {
offsetElement.value = '0'; offsetElement.value = '0';

View File

@ -8,7 +8,7 @@ declare const cityssm: cityssmGlobal
declare const exports: Record<string, unknown> declare const exports: Record<string, unknown>
;(() => { ;(() => {
const los = exports.sunrise as Sunrise const sunrise = exports.sunrise as Sunrise
const searchFilterFormElement = document.querySelector( const searchFilterFormElement = document.querySelector(
'#form--searchFilters' '#form--searchFilters'
@ -49,11 +49,11 @@ declare const exports: Record<string, unknown>
'beforeend', 'beforeend',
`<tr> `<tr>
<td> <td>
<a class="has-text-weight-bold" href="${los.getBurialSiteURL(burialSite.burialSiteId)}"> <a class="has-text-weight-bold" href="${sunrise.getBurialSiteURL(burialSite.burialSiteId)}">
${cityssm.escapeHTML(burialSite.burialSiteName ?? '')} ${cityssm.escapeHTML(burialSite.burialSiteName ?? '')}
</a> </a>
</td><td> </td><td>
<a href="${los.getCemeteryURL(burialSite.cemeteryId)}"> <a href="${sunrise.getCemeteryURL(burialSite.cemeteryId)}">
${ ${
burialSite.cemeteryName burialSite.cemeteryName
? cityssm.escapeHTML(burialSite.cemeteryName) ? cityssm.escapeHTML(burialSite.cemeteryName)
@ -90,7 +90,7 @@ declare const exports: Record<string, unknown>
// eslint-disable-next-line no-unsanitized/method // eslint-disable-next-line no-unsanitized/method
searchResultsContainerElement.insertAdjacentHTML( searchResultsContainerElement.insertAdjacentHTML(
'beforeend', 'beforeend',
los.getSearchResultsPagerHTML( sunrise.getSearchResultsPagerHTML(
limit, limit,
responseJSON.offset, responseJSON.offset,
responseJSON.count responseJSON.count
@ -112,12 +112,12 @@ declare const exports: Record<string, unknown>
function getBurialSites(): void { function getBurialSites(): void {
// eslint-disable-next-line no-unsanitized/property // eslint-disable-next-line no-unsanitized/property
searchResultsContainerElement.innerHTML = los.getLoadingParagraphHTML( searchResultsContainerElement.innerHTML = sunrise.getLoadingParagraphHTML(
`Loading Burial Sites...` `Loading Burial Sites...`
) )
cityssm.postJSON( cityssm.postJSON(
`${los.urlPrefix}/burialSites/doSearchBurialSites`, `${sunrise.urlPrefix}/burialSites/doSearchBurialSites`,
searchFilterFormElement, searchFilterFormElement,
renderBurialSites renderBurialSites
) )

View File

@ -3,7 +3,7 @@
/* eslint-disable max-lines */ /* eslint-disable max-lines */
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
(() => { (() => {
const los = exports.sunrise; const sunrise = exports.sunrise;
const containerElement = document.querySelector('#container--burialSiteTypes'); const containerElement = document.querySelector('#container--burialSiteTypes');
let burialSiteTypes = exports.burialSiteTypes; let burialSiteTypes = exports.burialSiteTypes;
delete exports.burialSiteTypes; delete exports.burialSiteTypes;
@ -44,7 +44,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
function deleteBurialSiteType(clickEvent) { function deleteBurialSiteType(clickEvent) {
const burialSiteTypeId = Number.parseInt(clickEvent.currentTarget.closest('.container--burialSiteType').dataset.burialSiteTypeId ?? '', 10); const burialSiteTypeId = Number.parseInt(clickEvent.currentTarget.closest('.container--burialSiteType').dataset.burialSiteTypeId ?? '', 10);
function doDelete() { function doDelete() {
cityssm.postJSON(`${los.urlPrefix}/admin/doDeleteBurialSiteType`, { cityssm.postJSON(`${sunrise.urlPrefix}/admin/doDeleteBurialSiteType`, {
burialSiteTypeId burialSiteTypeId
}, burialSiteTypeResponseHandler); }, burialSiteTypeResponseHandler);
} }
@ -64,7 +64,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
let editCloseModalFunction; let editCloseModalFunction;
function doEdit(submitEvent) { function doEdit(submitEvent) {
submitEvent.preventDefault(); submitEvent.preventDefault();
cityssm.postJSON(`${los.urlPrefix}/admin/doUpdateBurialSiteType`, submitEvent.currentTarget, (rawResponseJSON) => { cityssm.postJSON(`${sunrise.urlPrefix}/admin/doUpdateBurialSiteType`, submitEvent.currentTarget, (rawResponseJSON) => {
const responseJSON = rawResponseJSON; const responseJSON = rawResponseJSON;
burialSiteTypeResponseHandler(responseJSON); burialSiteTypeResponseHandler(responseJSON);
if (responseJSON.success) { if (responseJSON.success) {
@ -74,7 +74,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
} }
cityssm.openHtmlModal('adminBurialSiteTypes-edit', { cityssm.openHtmlModal('adminBurialSiteTypes-edit', {
onshow(modalElement) { onshow(modalElement) {
los.populateAliases(modalElement); sunrise.populateAliases(modalElement);
modalElement.querySelector('#burialSiteTypeEdit--burialSiteTypeId').value = burialSiteTypeId.toString(); modalElement.querySelector('#burialSiteTypeEdit--burialSiteTypeId').value = burialSiteTypeId.toString();
modalElement.querySelector('#burialSiteTypeEdit--burialSiteType').value = burialSiteType.burialSiteType; modalElement.querySelector('#burialSiteTypeEdit--burialSiteType').value = burialSiteType.burialSiteType;
}, },
@ -94,7 +94,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
let addCloseModalFunction; let addCloseModalFunction;
function doAdd(submitEvent) { function doAdd(submitEvent) {
submitEvent.preventDefault(); submitEvent.preventDefault();
cityssm.postJSON(`${los.urlPrefix}/admin/doAddBurialSiteTypeField`, submitEvent.currentTarget, (rawResponseJSON) => { cityssm.postJSON(`${sunrise.urlPrefix}/admin/doAddBurialSiteTypeField`, submitEvent.currentTarget, (rawResponseJSON) => {
const responseJSON = rawResponseJSON; const responseJSON = rawResponseJSON;
expandedBurialSiteTypes.add(burialSiteTypeId); expandedBurialSiteTypes.add(burialSiteTypeId);
burialSiteTypeResponseHandler(responseJSON); burialSiteTypeResponseHandler(responseJSON);
@ -106,7 +106,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
} }
cityssm.openHtmlModal('adminBurialSiteTypes-addField', { cityssm.openHtmlModal('adminBurialSiteTypes-addField', {
onshow(modalElement) { onshow(modalElement) {
los.populateAliases(modalElement); sunrise.populateAliases(modalElement);
if (burialSiteTypeId) { if (burialSiteTypeId) {
; ;
modalElement.querySelector('#burialSiteTypeFieldAdd--burialSiteTypeId').value = burialSiteTypeId.toString(); modalElement.querySelector('#burialSiteTypeFieldAdd--burialSiteTypeId').value = burialSiteTypeId.toString();
@ -126,7 +126,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
function moveBurialSiteType(clickEvent) { function moveBurialSiteType(clickEvent) {
const buttonElement = clickEvent.currentTarget; const buttonElement = clickEvent.currentTarget;
const burialSiteTypeId = buttonElement.closest('.container--burialSiteType').dataset.burialSiteTypeId; const burialSiteTypeId = buttonElement.closest('.container--burialSiteType').dataset.burialSiteTypeId;
cityssm.postJSON(`${los.urlPrefix}/admin/${buttonElement.dataset.direction === 'up' cityssm.postJSON(`${sunrise.urlPrefix}/admin/${buttonElement.dataset.direction === 'up'
? 'doMoveBurialSiteTypeUp' ? 'doMoveBurialSiteTypeUp'
: // eslint-disable-next-line no-secrets/no-secrets : // eslint-disable-next-line no-secrets/no-secrets
'doMoveBurialSiteTypeDown'}`, { 'doMoveBurialSiteTypeDown'}`, {
@ -173,7 +173,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
} }
function doUpdate(submitEvent) { function doUpdate(submitEvent) {
submitEvent.preventDefault(); submitEvent.preventDefault();
cityssm.postJSON(`${los.urlPrefix}/admin/doUpdateBurialSiteTypeField`, submitEvent.currentTarget, (rawResponseJSON) => { cityssm.postJSON(`${sunrise.urlPrefix}/admin/doUpdateBurialSiteTypeField`, submitEvent.currentTarget, (rawResponseJSON) => {
const responseJSON = rawResponseJSON; const responseJSON = rawResponseJSON;
burialSiteTypeResponseHandler(responseJSON); burialSiteTypeResponseHandler(responseJSON);
if (responseJSON.success) { if (responseJSON.success) {
@ -182,7 +182,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
}); });
} }
function doDelete() { function doDelete() {
cityssm.postJSON(`${los.urlPrefix}/admin/doDeleteBurialSiteTypeField`, { cityssm.postJSON(`${sunrise.urlPrefix}/admin/doDeleteBurialSiteTypeField`, {
burialSiteTypeFieldId burialSiteTypeFieldId
}, (rawResponseJSON) => { }, (rawResponseJSON) => {
const responseJSON = rawResponseJSON; const responseJSON = rawResponseJSON;
@ -205,7 +205,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
} }
cityssm.openHtmlModal('adminBurialSiteTypes-editField', { cityssm.openHtmlModal('adminBurialSiteTypes-editField', {
onshow(modalElement) { onshow(modalElement) {
los.populateAliases(modalElement); sunrise.populateAliases(modalElement);
modalElement.querySelector('#burialSiteTypeFieldEdit--burialSiteTypeFieldId').value = burialSiteTypeField.burialSiteTypeFieldId.toString(); modalElement.querySelector('#burialSiteTypeFieldEdit--burialSiteTypeFieldId').value = burialSiteTypeField.burialSiteTypeFieldId.toString();
modalElement.querySelector('#burialSiteTypeFieldEdit--burialSiteTypeField').value = burialSiteTypeField.burialSiteTypeField ?? ''; modalElement.querySelector('#burialSiteTypeFieldEdit--burialSiteTypeField').value = burialSiteTypeField.burialSiteTypeField ?? '';
modalElement.querySelector('#burialSiteTypeFieldEdit--isRequired').value = burialSiteTypeField.isRequired ?? false ? '1' : '0'; modalElement.querySelector('#burialSiteTypeFieldEdit--isRequired').value = burialSiteTypeField.isRequired ?? false ? '1' : '0';
@ -251,7 +251,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
function moveBurialSiteTypeField(clickEvent) { function moveBurialSiteTypeField(clickEvent) {
const buttonElement = clickEvent.currentTarget; const buttonElement = clickEvent.currentTarget;
const burialSiteTypeFieldId = buttonElement.closest('.container--burialSiteTypeField').dataset.burialSiteTypeFieldId; const burialSiteTypeFieldId = buttonElement.closest('.container--burialSiteTypeField').dataset.burialSiteTypeFieldId;
cityssm.postJSON(`${los.urlPrefix}/admin/${buttonElement.dataset.direction === 'up' cityssm.postJSON(`${sunrise.urlPrefix}/admin/${buttonElement.dataset.direction === 'up'
? 'doMoveBurialSiteTypeFieldUp' ? 'doMoveBurialSiteTypeFieldUp'
: // eslint-disable-next-line no-secrets/no-secrets : // eslint-disable-next-line no-secrets/no-secrets
'doMoveBurialSiteTypeFieldDown'}`, { 'doMoveBurialSiteTypeFieldDown'}`, {
@ -288,7 +288,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
</div> </div>
<div class="level-right"> <div class="level-right">
<div class="level-item"> <div class="level-item">
${los.getMoveUpDownButtonFieldHTML('button--moveBurialSiteTypeFieldUp', ${sunrise.getMoveUpDownButtonFieldHTML('button--moveBurialSiteTypeFieldUp',
// eslint-disable-next-line no-secrets/no-secrets // eslint-disable-next-line no-secrets/no-secrets
'button--moveBurialSiteTypeFieldDown')} 'button--moveBurialSiteTypeFieldDown')}
</div> </div>
@ -351,7 +351,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
</button> </button>
</div> </div>
<div class="level-item"> <div class="level-item">
${los.getMoveUpDownButtonFieldHTML('button--moveBurialSiteTypeUp', 'button--moveBurialSiteTypeDown')} ${sunrise.getMoveUpDownButtonFieldHTML('button--moveBurialSiteTypeUp', 'button--moveBurialSiteTypeDown')}
</div> </div>
</div> </div>
</div> </div>
@ -380,7 +380,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
let addCloseModalFunction; let addCloseModalFunction;
function doAdd(submitEvent) { function doAdd(submitEvent) {
submitEvent.preventDefault(); submitEvent.preventDefault();
cityssm.postJSON(`${los.urlPrefix}/admin/doAddBurialSiteType`, submitEvent.currentTarget, (rawResponseJSON) => { cityssm.postJSON(`${sunrise.urlPrefix}/admin/doAddBurialSiteType`, submitEvent.currentTarget, (rawResponseJSON) => {
const responseJSON = rawResponseJSON; const responseJSON = rawResponseJSON;
if (responseJSON.success) { if (responseJSON.success) {
addCloseModalFunction(); addCloseModalFunction();
@ -398,7 +398,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
} }
cityssm.openHtmlModal('adminBurialSiteTypes-add', { cityssm.openHtmlModal('adminBurialSiteTypes-add', {
onshow(modalElement) { onshow(modalElement) {
los.populateAliases(modalElement); sunrise.populateAliases(modalElement);
}, },
onshown(modalElement, closeModalFunction) { onshown(modalElement, closeModalFunction) {
addCloseModalFunction = closeModalFunction; addCloseModalFunction = closeModalFunction;

View File

@ -27,7 +27,7 @@ type ResponseJSON =
errorMessage?: string errorMessage?: string
} }
;(() => { ;(() => {
const los = exports.sunrise as Sunrise const sunrise = exports.sunrise as Sunrise
const containerElement = document.querySelector( const containerElement = document.querySelector(
'#container--burialSiteTypes' '#container--burialSiteTypes'
@ -98,7 +98,7 @@ type ResponseJSON =
function doDelete(): void { function doDelete(): void {
cityssm.postJSON( cityssm.postJSON(
`${los.urlPrefix}/admin/doDeleteBurialSiteType`, `${sunrise.urlPrefix}/admin/doDeleteBurialSiteType`,
{ {
burialSiteTypeId burialSiteTypeId
}, },
@ -137,7 +137,7 @@ type ResponseJSON =
submitEvent.preventDefault() submitEvent.preventDefault()
cityssm.postJSON( cityssm.postJSON(
`${los.urlPrefix}/admin/doUpdateBurialSiteType`, `${sunrise.urlPrefix}/admin/doUpdateBurialSiteType`,
submitEvent.currentTarget, submitEvent.currentTarget,
(rawResponseJSON) => { (rawResponseJSON) => {
const responseJSON = rawResponseJSON as ResponseJSON const responseJSON = rawResponseJSON as ResponseJSON
@ -152,7 +152,7 @@ type ResponseJSON =
cityssm.openHtmlModal('adminBurialSiteTypes-edit', { cityssm.openHtmlModal('adminBurialSiteTypes-edit', {
onshow(modalElement) { onshow(modalElement) {
los.populateAliases(modalElement) sunrise.populateAliases(modalElement)
;( ;(
modalElement.querySelector( modalElement.querySelector(
'#burialSiteTypeEdit--burialSiteTypeId' '#burialSiteTypeEdit--burialSiteTypeId'
@ -198,7 +198,7 @@ type ResponseJSON =
submitEvent.preventDefault() submitEvent.preventDefault()
cityssm.postJSON( cityssm.postJSON(
`${los.urlPrefix}/admin/doAddBurialSiteTypeField`, `${sunrise.urlPrefix}/admin/doAddBurialSiteTypeField`,
submitEvent.currentTarget, submitEvent.currentTarget,
(rawResponseJSON) => { (rawResponseJSON) => {
const responseJSON = rawResponseJSON as ResponseJSON const responseJSON = rawResponseJSON as ResponseJSON
@ -219,7 +219,7 @@ type ResponseJSON =
cityssm.openHtmlModal('adminBurialSiteTypes-addField', { cityssm.openHtmlModal('adminBurialSiteTypes-addField', {
onshow(modalElement) { onshow(modalElement) {
los.populateAliases(modalElement) sunrise.populateAliases(modalElement)
if (burialSiteTypeId) { if (burialSiteTypeId) {
;( ;(
@ -255,7 +255,7 @@ type ResponseJSON =
).dataset.burialSiteTypeId ).dataset.burialSiteTypeId
cityssm.postJSON( cityssm.postJSON(
`${los.urlPrefix}/admin/${ `${sunrise.urlPrefix}/admin/${
buttonElement.dataset.direction === 'up' buttonElement.dataset.direction === 'up'
? 'doMoveBurialSiteTypeUp' ? 'doMoveBurialSiteTypeUp'
: // eslint-disable-next-line no-secrets/no-secrets : // eslint-disable-next-line no-secrets/no-secrets
@ -326,7 +326,7 @@ type ResponseJSON =
submitEvent.preventDefault() submitEvent.preventDefault()
cityssm.postJSON( cityssm.postJSON(
`${los.urlPrefix}/admin/doUpdateBurialSiteTypeField`, `${sunrise.urlPrefix}/admin/doUpdateBurialSiteTypeField`,
submitEvent.currentTarget, submitEvent.currentTarget,
(rawResponseJSON) => { (rawResponseJSON) => {
const responseJSON = rawResponseJSON as ResponseJSON const responseJSON = rawResponseJSON as ResponseJSON
@ -341,7 +341,7 @@ type ResponseJSON =
function doDelete(): void { function doDelete(): void {
cityssm.postJSON( cityssm.postJSON(
`${los.urlPrefix}/admin/doDeleteBurialSiteTypeField`, `${sunrise.urlPrefix}/admin/doDeleteBurialSiteTypeField`,
{ {
burialSiteTypeFieldId burialSiteTypeFieldId
}, },
@ -371,7 +371,7 @@ type ResponseJSON =
cityssm.openHtmlModal('adminBurialSiteTypes-editField', { cityssm.openHtmlModal('adminBurialSiteTypes-editField', {
onshow(modalElement) { onshow(modalElement) {
los.populateAliases(modalElement) sunrise.populateAliases(modalElement)
;( ;(
modalElement.querySelector( modalElement.querySelector(
'#burialSiteTypeFieldEdit--burialSiteTypeFieldId' '#burialSiteTypeFieldEdit--burialSiteTypeFieldId'
@ -479,7 +479,7 @@ type ResponseJSON =
).dataset.burialSiteTypeFieldId ).dataset.burialSiteTypeFieldId
cityssm.postJSON( cityssm.postJSON(
`${los.urlPrefix}/admin/${ `${sunrise.urlPrefix}/admin/${
buttonElement.dataset.direction === 'up' buttonElement.dataset.direction === 'up'
? 'doMoveBurialSiteTypeFieldUp' ? 'doMoveBurialSiteTypeFieldUp'
: // eslint-disable-next-line no-secrets/no-secrets : // eslint-disable-next-line no-secrets/no-secrets
@ -531,7 +531,7 @@ type ResponseJSON =
</div> </div>
<div class="level-right"> <div class="level-right">
<div class="level-item"> <div class="level-item">
${los.getMoveUpDownButtonFieldHTML( ${sunrise.getMoveUpDownButtonFieldHTML(
'button--moveBurialSiteTypeFieldUp', 'button--moveBurialSiteTypeFieldUp',
// eslint-disable-next-line no-secrets/no-secrets // eslint-disable-next-line no-secrets/no-secrets
'button--moveBurialSiteTypeFieldDown' 'button--moveBurialSiteTypeFieldDown'
@ -618,7 +618,7 @@ type ResponseJSON =
</button> </button>
</div> </div>
<div class="level-item"> <div class="level-item">
${los.getMoveUpDownButtonFieldHTML( ${sunrise.getMoveUpDownButtonFieldHTML(
'button--moveBurialSiteTypeUp', 'button--moveBurialSiteTypeUp',
'button--moveBurialSiteTypeDown' 'button--moveBurialSiteTypeDown'
)} )}
@ -672,7 +672,7 @@ type ResponseJSON =
submitEvent.preventDefault() submitEvent.preventDefault()
cityssm.postJSON( cityssm.postJSON(
`${los.urlPrefix}/admin/doAddBurialSiteType`, `${sunrise.urlPrefix}/admin/doAddBurialSiteType`,
submitEvent.currentTarget, submitEvent.currentTarget,
(rawResponseJSON) => { (rawResponseJSON) => {
const responseJSON = rawResponseJSON as ResponseJSON const responseJSON = rawResponseJSON as ResponseJSON
@ -694,7 +694,7 @@ type ResponseJSON =
cityssm.openHtmlModal('adminBurialSiteTypes-add', { cityssm.openHtmlModal('adminBurialSiteTypes-add', {
onshow(modalElement) { onshow(modalElement) {
los.populateAliases(modalElement) sunrise.populateAliases(modalElement)
}, },
onshown(modalElement, closeModalFunction) { onshown(modalElement, closeModalFunction) {
addCloseModalFunction = closeModalFunction addCloseModalFunction = closeModalFunction

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -0,0 +1,185 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
(() => {
const sunrise = exports.sunrise;
const contractId = document.querySelector('#contract--contractId').value;
let contractComments = exports.contractComments;
delete exports.contractComments;
function openEditContractComment(clickEvent) {
const contractCommentId = Number.parseInt(clickEvent.currentTarget.closest('tr')?.dataset
.contractCommentId ?? '', 10);
const contractComment = contractComments.find((currentComment) => currentComment.contractCommentId === contractCommentId);
let editFormElement;
let editCloseModalFunction;
function editContractComment(submitEvent) {
submitEvent.preventDefault();
cityssm.postJSON(`${sunrise.urlPrefix}/contracts/doUpdateContractComment`, editFormElement, (rawResponseJSON) => {
const responseJSON = rawResponseJSON;
if (responseJSON.success) {
contractComments = responseJSON.contractComments ?? [];
editCloseModalFunction();
renderContractComments();
}
else {
bulmaJS.alert({
title: 'Error Updating Comment',
message: responseJSON.errorMessage ?? '',
contextualColorName: 'danger'
});
}
});
}
cityssm.openHtmlModal('contract-editComment', {
onshow(modalElement) {
sunrise.populateAliases(modalElement);
modalElement.querySelector('#contractCommentEdit--contractId').value = contractId;
modalElement.querySelector('#contractCommentEdit--contractCommentId').value = contractCommentId.toString();
modalElement.querySelector('#contractCommentEdit--comment').value = contractComment.comment ?? '';
const contractCommentDateStringElement = modalElement.querySelector('#contractCommentEdit--commentDateString');
contractCommentDateStringElement.value =
contractComment.commentDateString ?? '';
const currentDateString = cityssm.dateToString(new Date());
contractCommentDateStringElement.max =
contractComment.commentDateString <= currentDateString
? currentDateString
: contractComment.commentDateString ?? '';
modalElement.querySelector('#contractCommentEdit--commentTimeString').value = contractComment.commentTimeString ?? '';
},
onshown(modalElement, closeModalFunction) {
bulmaJS.toggleHtmlClipped();
modalElement.querySelector('#contractCommentEdit--comment').focus();
editFormElement = modalElement.querySelector('form');
editFormElement.addEventListener('submit', editContractComment);
editCloseModalFunction = closeModalFunction;
},
onremoved() {
bulmaJS.toggleHtmlClipped();
}
});
}
function deleteContractComment(clickEvent) {
const contractCommentId = Number.parseInt(clickEvent.currentTarget.closest('tr')?.dataset
.contractCommentId ?? '', 10);
function doDelete() {
cityssm.postJSON(`${sunrise.urlPrefix}/contracts/doDeleteContractComment`, {
contractId,
contractCommentId
}, (rawResponseJSON) => {
const responseJSON = rawResponseJSON;
if (responseJSON.success) {
contractComments = responseJSON.contractComments;
renderContractComments();
}
else {
bulmaJS.alert({
title: 'Error Removing Comment',
message: responseJSON.errorMessage ?? '',
contextualColorName: 'danger'
});
}
});
}
bulmaJS.confirm({
title: 'Remove Comment?',
message: 'Are you sure you want to remove this comment?',
okButton: {
text: 'Yes, Remove Comment',
callbackFunction: doDelete
},
contextualColorName: 'warning'
});
}
function renderContractComments() {
const containerElement = document.querySelector('#container--contractComments');
if (contractComments.length === 0) {
containerElement.innerHTML = `<div class="message is-info">
<p class="message-body">There are no comments associated with this record.</p>
</div>`;
return;
}
const tableElement = document.createElement('table');
tableElement.className = 'table is-fullwidth is-striped is-hoverable';
tableElement.innerHTML = `<thead><tr>
<th>Author</th>
<th>Comment Date</th>
<th>Comment</th>
<th class="is-hidden-print"><span class="is-sr-only">Options</span></th>
</tr></thead>
<tbody></tbody>`;
for (const contractComment of contractComments) {
const tableRowElement = document.createElement('tr');
tableRowElement.dataset.contractCommentId =
contractComment.contractCommentId?.toString();
tableRowElement.innerHTML = `<td>${cityssm.escapeHTML(contractComment.recordCreate_userName ?? '')}</td>
<td>
${cityssm.escapeHTML(contractComment.commentDateString ?? '')}
${cityssm.escapeHTML(contractComment.commentTime === 0
? ''
: contractComment.commentTimePeriodString ?? '')}
</td>
<td>${cityssm.escapeHTML(contractComment.comment ?? '')}</td>
<td class="is-hidden-print">
<div class="buttons are-small is-justify-content-end">
<button class="button is-primary button--edit" type="button">
<span class="icon is-small"><i class="fas fa-pencil-alt" aria-hidden="true"></i></span>
<span>Edit</span>
</button>
<button class="button is-light is-danger button--delete" data-tooltip="Delete Comment" type="button" aria-label="Delete">
<i class="fas fa-trash" aria-hidden="true"></i>
</button>
</div>
</td>`;
tableRowElement
.querySelector('.button--edit')
?.addEventListener('click', openEditContractComment);
tableRowElement
.querySelector('.button--delete')
?.addEventListener('click', deleteContractComment);
tableElement.querySelector('tbody')?.append(tableRowElement);
}
containerElement.innerHTML = '';
containerElement.append(tableElement);
}
document
.querySelector('#button--addComment')
?.addEventListener('click', () => {
let addFormElement;
let addCloseModalFunction;
function addComment(submitEvent) {
submitEvent.preventDefault();
cityssm.postJSON(`${sunrise.urlPrefix}/contracts/doAddContractComment`, addFormElement, (rawResponseJSON) => {
const responseJSON = rawResponseJSON;
if (responseJSON.success) {
contractComments = responseJSON.contractComments;
addCloseModalFunction();
renderContractComments();
}
else {
bulmaJS.alert({
title: 'Error Adding Comment',
message: responseJSON.errorMessage ?? '',
contextualColorName: 'danger'
});
}
});
}
cityssm.openHtmlModal('contract-addComment', {
onshow(modalElement) {
sunrise.populateAliases(modalElement);
modalElement.querySelector('#contractCommentAdd--contractId').value = contractId;
},
onshown(modalElement, closeModalFunction) {
bulmaJS.toggleHtmlClipped();
modalElement.querySelector('#contractCommentAdd--comment').focus();
addFormElement = modalElement.querySelector('form');
addFormElement.addEventListener('submit', addComment);
addCloseModalFunction = closeModalFunction;
},
onremoved() {
bulmaJS.toggleHtmlClipped();
document.querySelector('#button--addComment').focus();
}
});
});
renderContractComments();
})();

View File

@ -0,0 +1,299 @@
import type { BulmaJS } from '@cityssm/bulma-js/types.js'
import type { cityssmGlobal } from '@cityssm/bulma-webapp-js/src/types.js'
import type { ContractComment } from '../../types/recordTypes.js'
import type { Sunrise } from './types.js'
declare const cityssm: cityssmGlobal
declare const bulmaJS: BulmaJS
declare const exports: Record<string, unknown>
;(() => {
const sunrise = exports.sunrise as Sunrise
const contractId = (
document.querySelector('#contract--contractId') as HTMLInputElement
).value
let contractComments = exports.contractComments as ContractComment[]
delete exports.contractComments
function openEditContractComment(clickEvent: Event): void {
const contractCommentId = Number.parseInt(
(clickEvent.currentTarget as HTMLElement).closest('tr')?.dataset
.contractCommentId ?? '',
10
)
const contractComment = contractComments.find(
(currentComment) => currentComment.contractCommentId === contractCommentId
) as ContractComment
let editFormElement: HTMLFormElement
let editCloseModalFunction: () => void
function editContractComment(submitEvent: SubmitEvent): void {
submitEvent.preventDefault()
cityssm.postJSON(
`${sunrise.urlPrefix}/contracts/doUpdateContractComment`,
editFormElement,
(rawResponseJSON) => {
const responseJSON = rawResponseJSON as {
success: boolean
errorMessage?: string
contractComments?: ContractComment[]
}
if (responseJSON.success) {
contractComments = responseJSON.contractComments ?? []
editCloseModalFunction()
renderContractComments()
} else {
bulmaJS.alert({
title: 'Error Updating Comment',
message: responseJSON.errorMessage ?? '',
contextualColorName: 'danger'
})
}
}
)
}
cityssm.openHtmlModal('contract-editComment', {
onshow(modalElement) {
sunrise.populateAliases(modalElement)
;(
modalElement.querySelector(
'#contractCommentEdit--contractId'
) as HTMLInputElement
).value = contractId
;(
modalElement.querySelector(
'#contractCommentEdit--contractCommentId'
) as HTMLInputElement
).value = contractCommentId.toString()
;(
modalElement.querySelector(
'#contractCommentEdit--comment'
) as HTMLInputElement
).value = contractComment.comment ?? ''
const contractCommentDateStringElement = modalElement.querySelector(
'#contractCommentEdit--commentDateString'
) as HTMLInputElement
contractCommentDateStringElement.value =
contractComment.commentDateString ?? ''
const currentDateString = cityssm.dateToString(new Date())
contractCommentDateStringElement.max =
contractComment.commentDateString! <= currentDateString
? currentDateString
: contractComment.commentDateString ?? ''
;(
modalElement.querySelector(
'#contractCommentEdit--commentTimeString'
) as HTMLInputElement
).value = contractComment.commentTimeString ?? ''
},
onshown(modalElement, closeModalFunction) {
bulmaJS.toggleHtmlClipped()
;(
modalElement.querySelector(
'#contractCommentEdit--comment'
) as HTMLTextAreaElement
).focus()
editFormElement = modalElement.querySelector('form') as HTMLFormElement
editFormElement.addEventListener('submit', editContractComment)
editCloseModalFunction = closeModalFunction
},
onremoved() {
bulmaJS.toggleHtmlClipped()
}
})
}
function deleteContractComment(clickEvent: Event): void {
const contractCommentId = Number.parseInt(
(clickEvent.currentTarget as HTMLElement).closest('tr')?.dataset
.contractCommentId ?? '',
10
)
function doDelete(): void {
cityssm.postJSON(
`${sunrise.urlPrefix}/contracts/doDeleteContractComment`,
{
contractId,
contractCommentId
},
(rawResponseJSON) => {
const responseJSON = rawResponseJSON as {
success: boolean
errorMessage?: string
contractComments: ContractComment[]
}
if (responseJSON.success) {
contractComments = responseJSON.contractComments
renderContractComments()
} else {
bulmaJS.alert({
title: 'Error Removing Comment',
message: responseJSON.errorMessage ?? '',
contextualColorName: 'danger'
})
}
}
)
}
bulmaJS.confirm({
title: 'Remove Comment?',
message: 'Are you sure you want to remove this comment?',
okButton: {
text: 'Yes, Remove Comment',
callbackFunction: doDelete
},
contextualColorName: 'warning'
})
}
function renderContractComments(): void {
const containerElement = document.querySelector(
'#container--contractComments'
) as HTMLElement
if (contractComments.length === 0) {
containerElement.innerHTML = `<div class="message is-info">
<p class="message-body">There are no comments associated with this record.</p>
</div>`
return
}
const tableElement = document.createElement('table')
tableElement.className = 'table is-fullwidth is-striped is-hoverable'
tableElement.innerHTML = `<thead><tr>
<th>Author</th>
<th>Comment Date</th>
<th>Comment</th>
<th class="is-hidden-print"><span class="is-sr-only">Options</span></th>
</tr></thead>
<tbody></tbody>`
for (const contractComment of contractComments) {
const tableRowElement = document.createElement('tr')
tableRowElement.dataset.contractCommentId =
contractComment.contractCommentId?.toString()
tableRowElement.innerHTML = `<td>${cityssm.escapeHTML(contractComment.recordCreate_userName ?? '')}</td>
<td>
${cityssm.escapeHTML(contractComment.commentDateString ?? '')}
${cityssm.escapeHTML(
contractComment.commentTime === 0
? ''
: contractComment.commentTimePeriodString ?? ''
)}
</td>
<td>${cityssm.escapeHTML(contractComment.comment ?? '')}</td>
<td class="is-hidden-print">
<div class="buttons are-small is-justify-content-end">
<button class="button is-primary button--edit" type="button">
<span class="icon is-small"><i class="fas fa-pencil-alt" aria-hidden="true"></i></span>
<span>Edit</span>
</button>
<button class="button is-light is-danger button--delete" data-tooltip="Delete Comment" type="button" aria-label="Delete">
<i class="fas fa-trash" aria-hidden="true"></i>
</button>
</div>
</td>`
tableRowElement
.querySelector('.button--edit')
?.addEventListener('click', openEditContractComment)
tableRowElement
.querySelector('.button--delete')
?.addEventListener('click', deleteContractComment)
tableElement.querySelector('tbody')?.append(tableRowElement)
}
containerElement.innerHTML = ''
containerElement.append(tableElement)
}
document
.querySelector('#button--addComment')
?.addEventListener('click', () => {
let addFormElement: HTMLFormElement
let addCloseModalFunction: () => void
function addComment(submitEvent: SubmitEvent): void {
submitEvent.preventDefault()
cityssm.postJSON(
`${sunrise.urlPrefix}/contracts/doAddContractComment`,
addFormElement,
(rawResponseJSON) => {
const responseJSON = rawResponseJSON as {
success: boolean
errorMessage?: string
contractComments: ContractComment[]
}
if (responseJSON.success) {
contractComments = responseJSON.contractComments
addCloseModalFunction()
renderContractComments()
} else {
bulmaJS.alert({
title: 'Error Adding Comment',
message: responseJSON.errorMessage ?? '',
contextualColorName: 'danger'
})
}
}
)
}
cityssm.openHtmlModal('contract-addComment', {
onshow(modalElement) {
sunrise.populateAliases(modalElement)
;(
modalElement.querySelector(
'#contractCommentAdd--contractId'
) as HTMLInputElement
).value = contractId
},
onshown(modalElement, closeModalFunction) {
bulmaJS.toggleHtmlClipped()
;(
modalElement.querySelector(
'#contractCommentAdd--comment'
) as HTMLTextAreaElement
).focus()
addFormElement = modalElement.querySelector('form') as HTMLFormElement
addFormElement.addEventListener('submit', addComment)
addCloseModalFunction = closeModalFunction
},
onremoved() {
bulmaJS.toggleHtmlClipped()
;(
document.querySelector('#button--addComment') as HTMLButtonElement
).focus()
}
})
})
renderContractComments()
})()

View File

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

View File

@ -0,0 +1,668 @@
"use strict";
// eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair
/* eslint-disable max-lines */
Object.defineProperty(exports, "__esModule", { value: true });
(() => {
const sunrise = exports.sunrise;
const contractId = document.querySelector('#contract--contractId').value;
let contractFees = exports.contractFees;
delete exports.contractFees;
const contractFeesContainerElement = document.querySelector('#container--contractFees');
function getFeeGrandTotal() {
let feeGrandTotal = 0;
for (const contractFee of contractFees) {
feeGrandTotal +=
((contractFee.feeAmount ?? 0) + (contractFee.taxAmount ?? 0)) *
(contractFee.quantity ?? 0);
}
return feeGrandTotal;
}
function editContractFeeQuantity(clickEvent) {
const feeId = Number.parseInt(clickEvent.currentTarget.closest('tr')?.dataset
.feeId ?? '', 10);
const fee = contractFees.find((possibleFee) => possibleFee.feeId === feeId);
let updateCloseModalFunction;
function doUpdateQuantity(formEvent) {
formEvent.preventDefault();
cityssm.postJSON(`${sunrise.urlPrefix}/contracts/doUpdateContractFeeQuantity`, formEvent.currentTarget, (rawResponseJSON) => {
const responseJSON = rawResponseJSON;
if (responseJSON.success) {
contractFees = responseJSON.contractFees;
renderContractFees();
updateCloseModalFunction();
}
else {
bulmaJS.alert({
title: 'Error Updating Quantity',
message: 'Please try again.',
contextualColorName: 'danger'
});
}
});
}
cityssm.openHtmlModal('contract-editFeeQuantity', {
onshow(modalElement) {
;
modalElement.querySelector('#contractFeeQuantity--contractId').value = contractId;
modalElement.querySelector('#contractFeeQuantity--feeId').value = fee.feeId.toString();
modalElement.querySelector('#contractFeeQuantity--quantity').valueAsNumber = fee.quantity ?? 0;
modalElement.querySelector('#contractFeeQuantity--quantityUnit').textContent = fee.quantityUnit ?? '';
},
onshown(modalElement, closeModalFunction) {
bulmaJS.toggleHtmlClipped();
updateCloseModalFunction = closeModalFunction;
modalElement.querySelector('#contractFeeQuantity--quantity').focus();
modalElement
.querySelector('form')
?.addEventListener('submit', doUpdateQuantity);
},
onremoved() {
bulmaJS.toggleHtmlClipped();
}
});
}
function deleteContractFee(clickEvent) {
const feeId = clickEvent.currentTarget.closest('.container--contractFee').dataset.feeId;
function doDelete() {
cityssm.postJSON(`${sunrise.urlPrefix}/contracts/doDeleteContractFee`, {
contractId,
feeId
}, (rawResponseJSON) => {
const responseJSON = rawResponseJSON;
if (responseJSON.success) {
contractFees = responseJSON.contractFees;
renderContractFees();
}
else {
bulmaJS.alert({
title: 'Error Deleting Fee',
message: responseJSON.errorMessage ?? '',
contextualColorName: 'danger'
});
}
});
}
bulmaJS.confirm({
title: 'Delete Fee',
message: 'Are you sure you want to delete this fee?',
contextualColorName: 'warning',
okButton: {
text: 'Yes, Delete Fee',
callbackFunction: doDelete
}
});
}
// eslint-disable-next-line complexity
function renderContractFees() {
if (contractFees.length === 0) {
contractFeesContainerElement.innerHTML = `<div class="message is-info">
<p class="message-body">There are no fees associated with this record.</p>
</div>`;
renderContractTransactions();
return;
}
contractFeesContainerElement.innerHTML = `<table class="table is-fullwidth is-striped is-hoverable">
<thead><tr>
<th>Fee</th>
<th><span class="is-sr-only">Unit Cost</span></th>
<th class="has-width-1"><span class="is-sr-only">&times;</span></th>
<th class="has-width-1"><span class="is-sr-only">Quantity</span></th>
<th class="has-width-1"><span class="is-sr-only">equals</span></th>
<th class="has-width-1 has-text-right">Total</th>
<th class="has-width-1 is-hidden-print"><span class="is-sr-only">Options</span></th>
</tr></thead>
<tbody></tbody>
<tfoot><tr>
<th colspan="5">Subtotal</th>
<td class="has-text-weight-bold has-text-right" id="contractFees--feeAmountTotal"></td>
<td class="is-hidden-print"></td>
</tr><tr>
<th colspan="5">Tax</th>
<td class="has-text-right" id="contractFees--taxAmountTotal"></td>
<td class="is-hidden-print"></td>
</tr><tr>
<th colspan="5">Grand Total</th>
<td class="has-text-weight-bold has-text-right" id="contractFees--grandTotal"></td>
<td class="is-hidden-print"></td>
</tr></tfoot></table>`;
let feeAmountTotal = 0;
let taxAmountTotal = 0;
for (const contractFee of contractFees) {
const tableRowElement = document.createElement('tr');
tableRowElement.className = 'container--contractFee';
tableRowElement.dataset.feeId = contractFee.feeId.toString();
tableRowElement.dataset.includeQuantity =
contractFee.includeQuantity ?? false ? '1' : '0';
// eslint-disable-next-line no-unsanitized/property
tableRowElement.innerHTML = `<td colspan="${contractFee.quantity === 1 ? '5' : '1'}">
${cityssm.escapeHTML(contractFee.feeName ?? '')}<br />
<span class="tag">${cityssm.escapeHTML(contractFee.feeCategory ?? '')}</span>
</td>
${contractFee.quantity === 1
? ''
: `<td class="has-text-right">
$${contractFee.feeAmount?.toFixed(2)}
</td>
<td>&times;</td>
<td class="has-text-right">${contractFee.quantity?.toString()}</td>
<td>=</td>`}
<td class="has-text-right">
$${((contractFee.feeAmount ?? 0) * (contractFee.quantity ?? 0)).toFixed(2)}
</td>
<td class="is-hidden-print">
<div class="buttons are-small is-flex-wrap-nowrap is-justify-content-end">
${contractFee.includeQuantity ?? false
? `<button class="button is-primary button--editQuantity">
<span class="icon is-small"><i class="fas fa-pencil-alt" aria-hidden="true"></i></span>
<span>Edit</span>
</button>`
: ''}
<button class="button is-danger is-light button--delete" data-tooltip="Delete Fee" type="button">
<i class="fas fa-trash" aria-hidden="true"></i>
</button>
</div>
</td>`;
tableRowElement
.querySelector('.button--editQuantity')
?.addEventListener('click', editContractFeeQuantity);
tableRowElement
.querySelector('.button--delete')
?.addEventListener('click', deleteContractFee);
contractFeesContainerElement
.querySelector('tbody')
?.append(tableRowElement);
feeAmountTotal +=
(contractFee.feeAmount ?? 0) * (contractFee.quantity ?? 0);
taxAmountTotal +=
(contractFee.taxAmount ?? 0) * (contractFee.quantity ?? 0);
}
;
contractFeesContainerElement.querySelector('#contractFees--feeAmountTotal').textContent = `$${feeAmountTotal.toFixed(2)}`;
contractFeesContainerElement.querySelector('#contractFees--taxAmountTotal').textContent = `$${taxAmountTotal.toFixed(2)}`;
contractFeesContainerElement.querySelector('#contractFees--grandTotal').textContent = `$${(feeAmountTotal + taxAmountTotal).toFixed(2)}`;
renderContractTransactions();
}
const addFeeButtonElement = document.querySelector('#button--addFee');
addFeeButtonElement.addEventListener('click', () => {
if (sunrise.hasUnsavedChanges()) {
bulmaJS.alert({
message: 'Please save all unsaved changes before adding fees.',
contextualColorName: 'warning'
});
return;
}
let feeCategories;
let feeFilterElement;
let feeFilterResultsElement;
function doAddFeeCategory(clickEvent) {
clickEvent.preventDefault();
const feeCategoryId = Number.parseInt(clickEvent.currentTarget.dataset.feeCategoryId ?? '', 10);
cityssm.postJSON(`${sunrise.urlPrefix}/contracts/doAddContractFeeCategory`, {
contractId,
feeCategoryId
}, (rawResponseJSON) => {
const responseJSON = rawResponseJSON;
if (responseJSON.success) {
contractFees = responseJSON.contractFees;
renderContractFees();
bulmaJS.alert({
message: 'Fee Group Added Successfully',
contextualColorName: 'success'
});
}
else {
bulmaJS.alert({
title: 'Error Adding Fee',
message: responseJSON.errorMessage ?? '',
contextualColorName: 'danger'
});
}
});
}
function doAddFee(feeId, quantity = 1) {
cityssm.postJSON(`${sunrise.urlPrefix}/contracts/doAddContractFee`, {
contractId,
feeId,
quantity
}, (rawResponseJSON) => {
const responseJSON = rawResponseJSON;
if (responseJSON.success) {
contractFees = responseJSON.contractFees;
renderContractFees();
filterFees();
}
else {
bulmaJS.alert({
title: 'Error Adding Fee',
message: responseJSON.errorMessage ?? '',
contextualColorName: 'danger'
});
}
});
}
function doSetQuantityAndAddFee(fee) {
let quantityElement;
let quantityCloseModalFunction;
function doSetQuantity(submitEvent) {
submitEvent.preventDefault();
doAddFee(fee.feeId, quantityElement.value);
quantityCloseModalFunction();
}
cityssm.openHtmlModal('contract-setFeeQuantity', {
onshow(modalElement) {
;
modalElement.querySelector('#contractFeeQuantity--quantityUnit').textContent = fee.quantityUnit ?? '';
},
onshown(modalElement, closeModalFunction) {
quantityCloseModalFunction = closeModalFunction;
quantityElement = modalElement.querySelector('#contractFeeQuantity--quantity');
modalElement
.querySelector('form')
?.addEventListener('submit', doSetQuantity);
}
});
}
function tryAddFee(clickEvent) {
clickEvent.preventDefault();
const feeId = Number.parseInt(clickEvent.currentTarget.dataset.feeId ?? '', 10);
const feeCategoryId = Number.parseInt(clickEvent.currentTarget.dataset.feeCategoryId ?? '', 10);
const feeCategory = feeCategories.find((currentFeeCategory) => currentFeeCategory.feeCategoryId === feeCategoryId);
const fee = feeCategory.fees.find((currentFee) => currentFee.feeId === feeId);
if (fee.includeQuantity ?? false) {
doSetQuantityAndAddFee(fee);
}
else {
doAddFee(feeId);
}
}
function filterFees() {
const filterStringPieces = feeFilterElement.value
.trim()
.toLowerCase()
.split(' ');
feeFilterResultsElement.innerHTML = '';
for (const feeCategory of feeCategories) {
const categoryContainerElement = document.createElement('div');
categoryContainerElement.className = 'container--feeCategory';
categoryContainerElement.dataset.feeCategoryId =
feeCategory.feeCategoryId.toString();
categoryContainerElement.innerHTML = `<div class="columns is-vcentered">
<div class="column">
<h4 class="title is-5">
${cityssm.escapeHTML(feeCategory.feeCategory ?? '')}
</h4>
</div>
</div>
<div class="panel mb-5"></div>`;
if (feeCategory.isGroupedFee) {
// eslint-disable-next-line no-unsanitized/method
categoryContainerElement
.querySelector('.columns')
?.insertAdjacentHTML('beforeend', `<div class="column is-narrow has-text-right">
<button class="button is-small is-success" type="button" data-fee-category-id="${feeCategory.feeCategoryId}">
<span class="icon is-small"><i class="fas fa-plus" aria-hidden="true"></i></span>
<span>Add Fee Group</span>
</button>
</div>`);
categoryContainerElement
.querySelector('button')
?.addEventListener('click', doAddFeeCategory);
}
let hasFees = false;
for (const fee of feeCategory.fees) {
// Don't include already applied fees that limit quantity
if (contractFeesContainerElement.querySelector(`.container--contractFee[data-fee-id='${fee.feeId}'][data-include-quantity='0']`) !== null) {
continue;
}
let includeFee = true;
const feeSearchString = `${feeCategory.feeCategory ?? ''} ${fee.feeName ?? ''} ${fee.feeDescription ?? ''}`.toLowerCase();
for (const filterStringPiece of filterStringPieces) {
if (!feeSearchString.includes(filterStringPiece)) {
includeFee = false;
break;
}
}
if (!includeFee) {
continue;
}
hasFees = true;
const panelBlockElement = document.createElement(feeCategory.isGroupedFee ? 'div' : 'a');
panelBlockElement.className = 'panel-block is-block container--fee';
panelBlockElement.dataset.feeId = fee.feeId.toString();
panelBlockElement.dataset.feeCategoryId =
feeCategory.feeCategoryId.toString();
// eslint-disable-next-line no-unsanitized/property
panelBlockElement.innerHTML = `<strong>${cityssm.escapeHTML(fee.feeName ?? '')}</strong><br />
<small>
${cityssm
.escapeHTML(fee.feeDescription ?? '')
.replaceAll('\n', '<br />')}
</small>`;
if (!feeCategory.isGroupedFee) {
;
panelBlockElement.href = '#';
panelBlockElement.addEventListener('click', tryAddFee);
}
;
categoryContainerElement.querySelector('.panel').append(panelBlockElement);
}
if (hasFees) {
feeFilterResultsElement.append(categoryContainerElement);
}
}
}
cityssm.openHtmlModal('contract-addFee', {
onshow(modalElement) {
feeFilterElement = modalElement.querySelector('#feeSelect--feeName');
feeFilterResultsElement = modalElement.querySelector('#resultsContainer--feeSelect');
cityssm.postJSON(`${sunrise.urlPrefix}/contracts/doGetFees`, {
contractId
}, (rawResponseJSON) => {
const responseJSON = rawResponseJSON;
feeCategories = responseJSON.feeCategories;
feeFilterElement.disabled = false;
feeFilterElement.addEventListener('keyup', filterFees);
feeFilterElement.focus();
filterFees();
});
},
onshown() {
bulmaJS.toggleHtmlClipped();
},
onhidden() {
renderContractFees();
},
onremoved() {
bulmaJS.toggleHtmlClipped();
addFeeButtonElement.focus();
}
});
});
let contractTransactions = exports.contractTransactions;
delete exports.contractTransactions;
const contractTransactionsContainerElement = document.querySelector('#container--contractTransactions');
function getTransactionGrandTotal() {
let transactionGrandTotal = 0;
for (const contractTransaction of contractTransactions) {
transactionGrandTotal += contractTransaction.transactionAmount;
}
return transactionGrandTotal;
}
function editContractTransaction(clickEvent) {
const transactionIndex = Number.parseInt(clickEvent.currentTarget.closest('tr')?.dataset
.transactionIndex ?? '', 10);
const transaction = contractTransactions.find((possibleTransaction) => possibleTransaction.transactionIndex === transactionIndex);
let editCloseModalFunction;
function doEdit(formEvent) {
formEvent.preventDefault();
cityssm.postJSON(`${sunrise.urlPrefix}/contracts/doUpdateContractTransaction`, formEvent.currentTarget, (rawResponseJSON) => {
const responseJSON = rawResponseJSON;
if (responseJSON.success) {
contractTransactions = responseJSON.contractTransactions;
renderContractTransactions();
editCloseModalFunction();
}
else {
bulmaJS.alert({
title: 'Error Updating Transaction',
message: 'Please try again.',
contextualColorName: 'danger'
});
}
});
}
cityssm.openHtmlModal('contract-editTransaction', {
onshow(modalElement) {
sunrise.populateAliases(modalElement);
modalElement.querySelector('#contractTransactionEdit--contractId').value = contractId;
modalElement.querySelector('#contractTransactionEdit--transactionIndex').value = transaction.transactionIndex?.toString() ?? '';
modalElement.querySelector('#contractTransactionEdit--transactionAmount').value = transaction.transactionAmount.toFixed(2);
modalElement.querySelector('#contractTransactionEdit--externalReceiptNumber').value = transaction.externalReceiptNumber ?? '';
modalElement.querySelector('#contractTransactionEdit--transactionNote').value = transaction.transactionNote ?? '';
modalElement.querySelector('#contractTransactionEdit--transactionDateString').value = transaction.transactionDateString ?? '';
modalElement.querySelector('#contractTransactionEdit--transactionTimeString').value = transaction.transactionTimeString ?? '';
},
onshown(modalElement, closeModalFunction) {
bulmaJS.toggleHtmlClipped();
modalElement.querySelector('#contractTransactionEdit--transactionAmount').focus();
modalElement.querySelector('form')?.addEventListener('submit', doEdit);
editCloseModalFunction = closeModalFunction;
},
onremoved() {
bulmaJS.toggleHtmlClipped();
}
});
}
function deleteContractTransaction(clickEvent) {
const transactionIndex = clickEvent.currentTarget.closest('.container--contractTransaction').dataset.transactionIndex;
function doDelete() {
cityssm.postJSON(`${sunrise.urlPrefix}/contracts/doDeleteContractTransaction`, {
contractId,
transactionIndex
}, (rawResponseJSON) => {
const responseJSON = rawResponseJSON;
if (responseJSON.success) {
contractTransactions = responseJSON.contractTransactions;
renderContractTransactions();
}
else {
bulmaJS.alert({
title: 'Error Deleting Transaction',
message: responseJSON.errorMessage ?? '',
contextualColorName: 'danger'
});
}
});
}
bulmaJS.confirm({
title: 'Delete Transaction',
message: 'Are you sure you want to delete this transaction?',
contextualColorName: 'warning',
okButton: {
text: 'Yes, Delete Transaction',
callbackFunction: doDelete
}
});
}
function renderContractTransactions() {
if (contractTransactions.length === 0) {
// eslint-disable-next-line no-unsanitized/property
contractTransactionsContainerElement.innerHTML = `<div class="message ${contractFees.length === 0 ? 'is-info' : 'is-warning'}">
<p class="message-body">There are no transactions associated with this record.</p>
</div>`;
return;
}
// eslint-disable-next-line no-unsanitized/property
contractTransactionsContainerElement.innerHTML = `<table class="table is-fullwidth is-striped is-hoverable">
<thead><tr>
<th class="has-width-1">Date</th>
<th>${sunrise.escapedAliases.ExternalReceiptNumber}</th>
<th class="has-text-right has-width-1">Amount</th>
<th class="has-width-1 is-hidden-print"><span class="is-sr-only">Options</span></th>
</tr></thead>
<tbody></tbody>
<tfoot><tr>
<th colspan="2">Transaction Total</th>
<td class="has-text-weight-bold has-text-right" id="contractTransactions--grandTotal"></td>
<td class="is-hidden-print"></td>
</tr></tfoot>
</table>`;
let transactionGrandTotal = 0;
for (const contractTransaction of contractTransactions) {
transactionGrandTotal += contractTransaction.transactionAmount;
const tableRowElement = document.createElement('tr');
tableRowElement.className = 'container--contractTransaction';
tableRowElement.dataset.transactionIndex =
contractTransaction.transactionIndex?.toString();
let externalReceiptNumberHTML = '';
if (contractTransaction.externalReceiptNumber !== '') {
externalReceiptNumberHTML = cityssm.escapeHTML(contractTransaction.externalReceiptNumber ?? '');
if (sunrise.dynamicsGPIntegrationIsEnabled) {
if (contractTransaction.dynamicsGPDocument === undefined) {
externalReceiptNumberHTML += ` <span data-tooltip="No Matching Document Found">
<i class="fas fa-times-circle has-text-danger" aria-label="No Matching Document Found"></i>
</span>`;
}
else if (contractTransaction.dynamicsGPDocument.documentTotal.toFixed(2) ===
contractTransaction.transactionAmount.toFixed(2)) {
externalReceiptNumberHTML += ` <span data-tooltip="Matching Document Found">
<i class="fas fa-check-circle has-text-success" aria-label="Matching Document Found"></i>
</span>`;
}
else {
externalReceiptNumberHTML += ` <span data-tooltip="Matching Document: $${contractTransaction.dynamicsGPDocument.documentTotal.toFixed(2)}">
<i class="fas fa-check-circle has-text-warning" aria-label="Matching Document: $${contractTransaction.dynamicsGPDocument.documentTotal.toFixed(2)}"></i>
</span>`;
}
}
externalReceiptNumberHTML += '<br />';
}
// eslint-disable-next-line no-unsanitized/property
tableRowElement.innerHTML = `<td>
${cityssm.escapeHTML(contractTransaction.transactionDateString ?? '')}
</td>
<td>
${externalReceiptNumberHTML}
<small>${cityssm.escapeHTML(contractTransaction.transactionNote ?? '')}</small>
</td>
<td class="has-text-right">
$${cityssm.escapeHTML(contractTransaction.transactionAmount.toFixed(2))}
</td>
<td class="is-hidden-print">
<div class="buttons are-small is-flex-wrap-nowrap is-justify-content-end">
<button class="button is-primary button--edit" type="button">
<span class="icon"><i class="fas fa-pencil-alt" aria-hidden="true"></i></span>
<span>Edit</span>
</button>
<button class="button is-danger is-light button--delete" data-tooltip="Delete Transaction" type="button">
<i class="fas fa-trash" aria-hidden="true"></i>
</button>
</div>
</td>`;
tableRowElement
.querySelector('.button--edit')
?.addEventListener('click', editContractTransaction);
tableRowElement
.querySelector('.button--delete')
?.addEventListener('click', deleteContractTransaction);
contractTransactionsContainerElement
.querySelector('tbody')
?.append(tableRowElement);
}
;
contractTransactionsContainerElement.querySelector('#contractTransactions--grandTotal').textContent = `$${transactionGrandTotal.toFixed(2)}`;
const feeGrandTotal = getFeeGrandTotal();
if (feeGrandTotal.toFixed(2) !== transactionGrandTotal.toFixed(2)) {
contractTransactionsContainerElement.insertAdjacentHTML('afterbegin', `<div class="message is-warning">
<div class="message-body">
<div class="level">
<div class="level-left">
<div class="level-item">Outstanding Balance</div>
</div>
<div class="level-right">
<div class="level-item">
$${cityssm.escapeHTML((feeGrandTotal - transactionGrandTotal).toFixed(2))}
</div>
</div>
</div>
</div></div>`);
}
}
const addTransactionButtonElement = document.querySelector('#button--addTransaction');
addTransactionButtonElement.addEventListener('click', () => {
let transactionAmountElement;
let externalReceiptNumberElement;
let addCloseModalFunction;
function doAddTransaction(submitEvent) {
submitEvent.preventDefault();
cityssm.postJSON(`${sunrise.urlPrefix}/contracts/doAddContractTransaction`, submitEvent.currentTarget, (rawResponseJSON) => {
const responseJSON = rawResponseJSON;
if (responseJSON.success) {
contractTransactions = responseJSON.contractTransactions;
addCloseModalFunction();
renderContractTransactions();
}
else {
bulmaJS.confirm({
title: 'Error Adding Transaction',
message: responseJSON.errorMessage ?? '',
contextualColorName: 'danger'
});
}
});
}
// eslint-disable-next-line @typescript-eslint/naming-convention
function dynamicsGP_refreshExternalReceiptNumberIcon() {
const externalReceiptNumber = externalReceiptNumberElement.value;
const iconElement = externalReceiptNumberElement
.closest('.control')
?.querySelector('.icon');
const helpTextElement = externalReceiptNumberElement
.closest('.field')
?.querySelector('.help');
if (externalReceiptNumber === '') {
helpTextElement.innerHTML = '&nbsp;';
iconElement.innerHTML =
'<i class="fas fa-minus" aria-hidden="true"></i>';
return;
}
cityssm.postJSON(`${sunrise.urlPrefix}/contracts/doGetDynamicsGPDocument`, {
externalReceiptNumber
}, (rawResponseJSON) => {
const responseJSON = rawResponseJSON;
if (!responseJSON.success ||
responseJSON.dynamicsGPDocument === undefined) {
helpTextElement.textContent = 'No Matching Document Found';
iconElement.innerHTML =
'<i class="fas fa-times-circle" aria-hidden="true"></i>';
}
else if (transactionAmountElement.valueAsNumber ===
responseJSON.dynamicsGPDocument.documentTotal) {
helpTextElement.textContent = 'Matching Document Found';
iconElement.innerHTML =
'<i class="fas fa-check-circle" aria-hidden="true"></i>';
}
else {
helpTextElement.textContent = `Matching Document: $${responseJSON.dynamicsGPDocument.documentTotal.toFixed(2)}`;
iconElement.innerHTML =
'<i class="fas fa-exclamation-triangle" aria-hidden="true"></i>';
}
});
}
cityssm.openHtmlModal('contract-addTransaction', {
onshow(modalElement) {
sunrise.populateAliases(modalElement);
modalElement.querySelector('#contractTransactionAdd--contractId').value = contractId.toString();
const feeGrandTotal = getFeeGrandTotal();
const transactionGrandTotal = getTransactionGrandTotal();
transactionAmountElement = modalElement.querySelector('#contractTransactionAdd--transactionAmount');
transactionAmountElement.min = (-1 * transactionGrandTotal).toFixed(2);
transactionAmountElement.max = Math.max(feeGrandTotal - transactionGrandTotal, 0).toFixed(2);
transactionAmountElement.value = Math.max(feeGrandTotal - transactionGrandTotal, 0).toFixed(2);
if (sunrise.dynamicsGPIntegrationIsEnabled) {
externalReceiptNumberElement = modalElement.querySelector('#contractTransactionAdd--externalReceiptNumber');
const externalReceiptNumberControlElement = externalReceiptNumberElement.closest('.control');
externalReceiptNumberControlElement.classList.add('has-icons-right');
externalReceiptNumberControlElement.insertAdjacentHTML('beforeend', '<span class="icon is-small is-right"></span>');
externalReceiptNumberControlElement.insertAdjacentHTML('afterend', '<p class="help has-text-right"></p>');
externalReceiptNumberElement.addEventListener('change', dynamicsGP_refreshExternalReceiptNumberIcon);
transactionAmountElement.addEventListener('change', dynamicsGP_refreshExternalReceiptNumberIcon);
dynamicsGP_refreshExternalReceiptNumberIcon();
}
},
onshown(modalElement, closeModalFunction) {
bulmaJS.toggleHtmlClipped();
transactionAmountElement.focus();
addCloseModalFunction = closeModalFunction;
modalElement
.querySelector('form')
?.addEventListener('submit', doAddTransaction);
},
onremoved() {
bulmaJS.toggleHtmlClipped();
addTransactionButtonElement.focus();
}
});
});
renderContractFees();
})();

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More