From 0ea7494b8cb6d9b6257a2c8296d8045a4ec11231 Mon Sep 17 00:00:00 2001 From: Dan Gowans Date: Fri, 21 Feb 2025 15:48:28 -0500 Subject: [PATCH] major refactoring in progress **broken** --- .codeclimate.yml | 18 - .eslintignore | 3 - .github/workflows/coverage.yml | 72 --- LICENSE.md | 4 +- README.md | 28 +- _config.yml | 2 +- app.js | 11 +- app.ts | 17 +- bin/www.js | 5 +- bin/www.ts | 5 +- bin/wwwProcess.js | 5 +- bin/wwwProcess.ts | 9 +- cypress/e2e/01-admin/feeManagement.cy.js | 2 +- cypress/e2e/01-admin/feeManagement.cy.ts | 2 +- cypress/e2e/02-update/maps.cy.js | 2 +- cypress/e2e/02-update/maps.cy.ts | 2 +- cypress/e2e/xx-other/keepAlive.cy.d.ts | 1 + cypress/e2e/xx-other/keepAlive.cy.js | 1 + data/config.base.js | 5 +- data/config.base.ts | 5 +- ...y.ontario.d.ts => config.baseOntario.d.ts} | 0 data/config.baseOntario.js | 6 + data/config.baseOntario.ts | 11 + ...nfig.cemetery.d.ts => config.baseSsm.d.ts} | 0 data/config.baseSsm.js | 17 + data/config.baseSsm.ts | 26 + data/config.cemetery.js | 19 - data/config.cemetery.ontario.js | 6 - data/config.cemetery.ontario.ts | 11 - data/config.cemetery.ssm.d.ts | 4 - data/config.cemetery.ssm.js | 65 --- data/config.cemetery.ssm.ts | 91 --- data/config.cemetery.ts | 26 - data/config.defaultValues.d.ts | 9 - data/config.defaultValues.js | 19 +- data/config.defaultValues.ts | 20 +- data/config.testing.js | 2 +- data/config.testing.ts | 2 +- data/databasePaths.d.ts | 5 - data/databasePaths.js | 15 - data/databasePaths.ts | 24 - database/{addLot.d.ts => addBurialSite.d.ts} | 0 database/{addLot.js => addBurialSite.js} | 0 database/{addLot.ts => addBurialSite.ts} | 0 database/addBurialSiteComment.d.ts | 5 + ...dLotComment.js => addBurialSiteComment.js} | 10 +- ...dLotComment.ts => addBurialSiteComment.ts} | 20 +- database/addBurialSiteContractComment.d.ts | 8 + database/addBurialSiteContractComment.js | 27 + database/addBurialSiteContractComment.ts | 66 +++ database/addBurialSiteTypeField.d.ts | 12 + database/addBurialSiteTypeField.js | 20 + ...TypeField.ts => addBurialSiteTypeField.ts} | 37 +- database/addCemetery.d.ts | 14 + database/addCemetery.js | 18 + database/addCemetery.ts | 60 ++ database/addContractTypeField.d.ts | 12 + database/addContractTypeField.js | 19 + ...cyTypeField.ts => addContractTypeField.ts} | 36 +- database/addContractTypePrint.d.ts | 6 + ...cyTypePrint.js => addContractTypePrint.js} | 16 +- ...cyTypePrint.ts => addContractTypePrint.ts} | 28 +- database/addFee.d.ts | 10 +- database/addFee.js | 4 +- database/addFee.ts | 16 +- database/addLotComment.d.ts | 5 - database/addLotOccupancyComment.d.ts | 7 - database/addLotOccupancyComment.js | 27 - database/addLotOccupancyComment.ts | 66 --- database/addLotOccupancyOccupant.d.ts | 16 - database/addLotOccupancyOccupant.js | 33 -- database/addLotOccupancyOccupant.ts | 86 --- database/addLotOccupantType.d.ts | 7 - database/addLotOccupantType.js | 16 - database/addLotOccupantType.ts | 44 -- database/addLotTypeField.d.ts | 12 - database/addLotTypeField.js | 19 - database/addMap.d.ts | 14 - database/addMap.js | 18 - database/addMap.ts | 58 -- database/addOccupancyTypeField.d.ts | 12 - database/addOccupancyTypeField.js | 19 - database/addOccupancyTypePrint.d.ts | 6 - .../addOrUpdateBurialSiteContractField.d.ts | 7 + .../addOrUpdateBurialSiteContractField.js | 28 + ... => addOrUpdateBurialSiteContractField.ts} | 36 +- database/addOrUpdateBurialSiteField.d.ts | 7 + ...Field.js => addOrUpdateBurialSiteField.js} | 18 +- ...Field.ts => addOrUpdateBurialSiteField.ts} | 36 +- database/addOrUpdateLotField.d.ts | 7 - database/addOrUpdateLotOccupancyField.d.ts | 7 - database/addOrUpdateLotOccupancyField.js | 28 - database/addRecord.d.ts | 4 +- database/addRecord.js | 8 +- database/addRecord.ts | 14 +- database/addWorkOrder.d.ts | 2 +- database/addWorkOrder.js | 8 +- database/addWorkOrder.ts | 10 +- ...erLot.d.ts => addWorkOrderBurialSite.d.ts} | 0 ...kOrderLot.js => addWorkOrderBurialSite.js} | 0 ...kOrderLot.ts => addWorkOrderBurialSite.ts} | 0 database/addWorkOrderBurialSiteContract.d.ts | 6 + ...y.js => addWorkOrderBurialSiteContract.js} | 27 +- ...y.ts => addWorkOrderBurialSiteContract.ts} | 39 +- database/addWorkOrderLotOccupancy.d.ts | 6 - database/cleanupDatabase.js | 168 +++--- database/cleanupDatabase.ts | 186 +++---- database/deleteBurialSiteContractFee.d.ts | 1 + ...yFee.js => deleteBurialSiteContractFee.js} | 8 +- ...yFee.ts => deleteBurialSiteContractFee.ts} | 10 +- database/deleteBurialSiteContractField.d.ts | 2 + database/deleteBurialSiteContractField.js | 15 + ...ld.ts => deleteBurialSiteContractField.ts} | 14 +- .../deleteBurialSiteContractInterment.d.ts | 1 + database/deleteBurialSiteContractInterment.js | 13 + database/deleteBurialSiteContractInterment.ts | 23 + .../deleteBurialSiteContractTransaction.d.ts | 1 + ...=> deleteBurialSiteContractTransaction.js} | 8 +- ...=> deleteBurialSiteContractTransaction.ts} | 10 +- database/deleteBurialSiteField.d.ts | 2 + ...teLotField.js => deleteBurialSiteField.js} | 10 +- ...teLotField.ts => deleteBurialSiteField.ts} | 14 +- database/deleteContractTypePrint.d.ts | 1 + ...ypePrint.js => deleteContractTypePrint.js} | 10 +- ...ypePrint.ts => deleteContractTypePrint.ts} | 12 +- database/deleteLotField.d.ts | 2 - database/deleteLotOccupancyFee.d.ts | 1 - database/deleteLotOccupancyField.d.ts | 2 - database/deleteLotOccupancyField.js | 15 - database/deleteLotOccupancyOccupant.d.ts | 1 - database/deleteLotOccupancyOccupant.js | 13 - database/deleteLotOccupancyOccupant.ts | 23 - database/deleteLotOccupancyTransaction.d.ts | 1 - database/deleteOccupancyTypePrint.d.ts | 1 - database/deleteRecord.d.ts | 2 +- database/deleteRecord.js | 39 +- database/deleteRecord.ts | 60 +- database/deleteWorkOrderBurialSite.d.ts | 1 + ...derLot.js => deleteWorkOrderBurialSite.js} | 8 +- ...derLot.ts => deleteWorkOrderBurialSite.ts} | 10 +- .../deleteWorkOrderBurialSiteContract.d.ts | 1 + ...s => deleteWorkOrderBurialSiteContract.js} | 8 +- ...s => deleteWorkOrderBurialSiteContract.ts} | 10 +- database/deleteWorkOrderLot.d.ts | 1 - database/deleteWorkOrderLotOccupancy.d.ts | 1 - database/{getLot.d.ts => getBurialSite.d.ts} | 2 +- database/getBurialSite.js | 48 ++ database/getBurialSite.ts | 72 +++ database/getFee.js | 8 +- database/getFee.ts | 8 +- database/getFeeCategories.d.ts | 4 +- database/getFeeCategories.js | 14 +- database/getFeeCategories.ts | 18 +- database/getFees.d.ts | 4 +- database/getFees.js | 28 +- database/getFees.ts | 32 +- database/getLot.js | 38 -- database/getLot.ts | 62 --- database/getLotOccupancies.js | 2 +- database/getLotOccupancies.ts | 2 +- database/getLotOccupancyTransactions.js | 2 +- database/getLotOccupancyTransactions.ts | 2 +- database/getLots.js | 2 +- database/getLots.ts | 2 +- database/getNextBurialSiteId.d.ts | 1 + ...getNextLotId.js => getNextBurialSiteId.js} | 14 +- ...getNextLotId.ts => getNextBurialSiteId.ts} | 23 +- database/getNextLotId.d.ts | 1 - database/getNextWorkOrderNumber.js | 2 +- database/getNextWorkOrderNumber.ts | 2 +- database/getOccupancyTypePrints.js | 2 +- database/getOccupancyTypePrints.ts | 2 +- database/getPreviousLotId.js | 2 +- database/getPreviousLotId.ts | 2 +- database/getReportData.js | 262 ++++----- database/getReportData.ts | 270 ++++----- database/getWorkOrderMilestones.js | 2 +- database/getWorkOrderMilestones.ts | 2 +- database/initializeDatabase.d.ts | 1 + database/initializeDatabase.js | 428 ++++++++++++++ database/initializeDatabase.ts | 523 ++++++++++++++++++ database/pool.js | 5 +- database/pool.ts | 5 +- debug.config.d.ts | 2 + debug.config.js | 6 + debug.config.ts | 8 + docs/README.md | 43 -- docs/adminConfigTables.md | 25 - docs/adminFees.md | 19 - docs/adminLotTypes.md | 10 - docs/adminOccupancyTypes.md | 14 - docs/cemeteryWorkflowDeceased.md | 33 -- docs/images/adminConfigTables.png | Bin 31947 -> 0 bytes docs/images/adminFees.png | Bin 50895 -> 0 bytes docs/images/adminLotTypes.png | Bin 37928 -> 0 bytes docs/images/adminOccupancyTypes.png | Bin 39413 -> 0 bytes docs/images/configTableSorting.png | Bin 2534 -> 0 bytes docs/images/lotOccupancyAddFee.png | Bin 29268 -> 0 bytes docs/images/lotOccupancyEdit-moreOptions.png | Bin 8793 -> 0 bytes docs/images/lotOccupancyEdit.png | Bin 114535 -> 0 bytes docs/images/lotOccupancySearch.png | Bin 80524 -> 0 bytes docs/images/lotOccupancyView.png | Bin 97201 -> 0 bytes docs/images/lotView.png | Bin 49446 -> 0 bytes docs/images/mapImageLotConfig.png | Bin 4725 -> 0 bytes docs/images/mapImageStructure.png | Bin 49854 -> 0 bytes docs/images/workOrderEdit.png | Bin 53180 -> 0 bytes docs/images/workOrderMilestoneEdit.png | Bin 7994 -> 0 bytes docs/lotOccupancies.md | 60 -- docs/mapImages.md | 42 -- docs/shortcuts.md | 63 --- docs/terminology.md | 26 - docs/workOrders.md | 59 -- eslint.config.d.ts | 2 +- eslint.config.js | 5 +- eslint.config.ts | 5 +- .../{lotTypes.d.ts => burialSiteTypes.d.ts} | 0 .../{lotTypes.js => burialSiteTypes.js} | 2 +- .../{lotTypes.ts => burialSiteTypes.ts} | 2 +- handlers/admin-get/ntfyStartup.js | 2 +- handlers/admin-get/ntfyStartup.ts | 2 +- handlers/admin-get/occupancyTypes.js | 2 +- handlers/admin-get/occupancyTypes.ts | 2 +- handlers/api-get/milestoneICS.js | 2 +- handlers/api-get/milestoneICS.ts | 2 +- .../edit.d.ts | 0 .../{lots-get => burialSites-get}/edit.js | 2 +- .../{lots-get => burialSites-get}/edit.ts | 2 +- .../new.d.ts | 0 handlers/{lots-get => burialSites-get}/new.js | 2 +- handlers/{lots-get => burialSites-get}/new.ts | 2 +- .../{lots-get => burialSites-get}/next.d.ts | 0 .../{lots-get => burialSites-get}/next.js | 2 +- .../{lots-get => burialSites-get}/next.ts | 2 +- .../previous.d.ts | 0 .../{lots-get => burialSites-get}/previous.js | 2 +- .../{lots-get => burialSites-get}/previous.ts | 2 +- .../search.d.ts | 0 .../{lots-get => burialSites-get}/search.js | 2 +- .../{lots-get => burialSites-get}/search.ts | 2 +- .../view.d.ts | 0 .../{lots-get => burialSites-get}/view.js | 2 +- .../{lots-get => burialSites-get}/view.ts | 2 +- .../doAddLotComment.d.ts} | 0 handlers/burialSites-post/doAddLotComment.js | 10 + .../doAddLotComment.ts | 0 .../doCreateLot.d.ts} | 0 handlers/burialSites-post/doCreateLot.js | 12 + .../doCreateLot.ts | 0 .../doDeleteLot.d.ts} | 0 handlers/burialSites-post/doDeleteLot.js | 12 + .../doDeleteLot.ts | 0 .../doDeleteLotComment.d.ts} | 0 .../burialSites-post/doDeleteLotComment.js | 10 + .../doDeleteLotComment.ts | 0 .../doGetLotTypeFields.d.ts | 0 .../doGetLotTypeFields.js | 0 .../doGetLotTypeFields.ts | 0 .../doSearchLots.d.ts | 0 .../doSearchLots.js | 0 .../doSearchLots.ts | 0 .../doUpdateLot.d.ts} | 0 .../doUpdateLot.js | 0 .../doUpdateLot.ts | 0 .../doUpdateLotComment.d.ts | 0 .../doUpdateLotComment.js | 0 .../doUpdateLotComment.ts | 0 .../{lots-get => cemeteries-get}/edit.d.ts | 0 handlers/{maps-get => cemeteries-get}/edit.js | 2 +- handlers/{maps-get => cemeteries-get}/edit.ts | 2 +- .../{maps-get => cemeteries-get}/new.d.ts | 0 handlers/{maps-get => cemeteries-get}/new.js | 2 +- handlers/{maps-get => cemeteries-get}/new.ts | 2 +- .../{maps-get => cemeteries-get}/next.d.ts | 0 handlers/{maps-get => cemeteries-get}/next.js | 2 +- handlers/{maps-get => cemeteries-get}/next.ts | 2 +- .../previous.d.ts | 0 .../{maps-get => cemeteries-get}/previous.js | 2 +- .../{maps-get => cemeteries-get}/previous.ts | 2 +- .../{maps-get => cemeteries-get}/search.d.ts | 0 .../{maps-get => cemeteries-get}/search.js | 2 +- .../{maps-get => cemeteries-get}/search.ts | 2 +- .../{lots-get => cemeteries-get}/view.d.ts | 0 handlers/{maps-get => cemeteries-get}/view.js | 2 +- handlers/{maps-get => cemeteries-get}/view.ts | 2 +- .../doCreateCemetery.d.ts} | 0 .../doCreateCemetery.js} | 0 .../doCreateCemetery.ts} | 0 .../doDeleteCemetery.d.ts} | 0 .../doDeleteCemetery.js} | 0 .../doDeleteCemetery.ts} | 0 .../doUpdateMap.d.ts | 0 .../doUpdateMap.js | 0 .../doUpdateMap.ts | 0 .../{maps-get => contracts-get}/edit.d.ts | 0 .../edit.js | 2 +- .../edit.ts | 2 +- handlers/{lots-get => contracts-get}/new.d.ts | 0 .../new.js | 2 +- .../new.ts | 2 +- .../{lots-get => contracts-get}/search.d.ts | 0 .../search.js | 2 +- .../search.ts | 2 +- .../{maps-get => contracts-get}/view.d.ts | 0 .../view.js | 2 +- .../view.ts | 2 +- .../doAddLotOccupancyComment.d.ts} | 0 .../doAddLotOccupancyComment.js | 0 .../doAddLotOccupancyComment.ts | 0 .../doAddLotOccupancyFee.d.ts} | 0 .../doAddLotOccupancyFee.js | 0 .../doAddLotOccupancyFee.ts | 0 .../doAddLotOccupancyFeeCategory.d.ts} | 0 .../doAddLotOccupancyFeeCategory.js | 0 .../doAddLotOccupancyFeeCategory.ts | 0 .../doAddLotOccupancyOccupant.d.ts} | 0 .../doAddLotOccupancyOccupant.js | 0 .../doAddLotOccupancyOccupant.ts | 0 .../doAddLotOccupancyTransaction.d.ts} | 0 .../doAddLotOccupancyTransaction.js | 0 .../doAddLotOccupancyTransaction.ts | 0 .../doCopyLotOccupancy.d.ts} | 0 .../doCopyLotOccupancy.js | 0 .../doCopyLotOccupancy.ts | 0 .../doCreateLotOccupancy.d.ts} | 0 .../doCreateLotOccupancy.js | 0 .../doCreateLotOccupancy.ts | 0 .../doDeleteLotOccupancy.d.ts} | 0 .../doDeleteLotOccupancy.js | 0 .../doDeleteLotOccupancy.ts | 0 .../doDeleteLotOccupancyComment.d.ts} | 0 .../doDeleteLotOccupancyComment.js | 0 .../doDeleteLotOccupancyComment.ts | 0 .../doDeleteLotOccupancyFee.d.ts} | 0 .../doDeleteLotOccupancyFee.js | 0 .../doDeleteLotOccupancyFee.ts | 0 .../doDeleteLotOccupancyOccupant.d.ts} | 0 .../doDeleteLotOccupancyOccupant.js | 0 .../doDeleteLotOccupancyOccupant.ts | 0 .../doDeleteLotOccupancyTransaction.d.ts} | 0 .../doDeleteLotOccupancyTransaction.js | 0 .../doDeleteLotOccupancyTransaction.ts | 0 .../doGetDynamicsGPDocument.d.ts} | 0 .../doGetDynamicsGPDocument.js | 0 .../doGetDynamicsGPDocument.ts | 0 .../doGetFees.d.ts} | 0 .../doGetFees.js | 0 .../doGetFees.ts | 0 .../doGetOccupancyTypeFields.d.ts} | 0 .../doGetOccupancyTypeFields.js | 0 .../doGetOccupancyTypeFields.ts | 0 .../doSearchLotOccupancies.d.ts} | 0 .../doSearchLotOccupancies.js | 0 .../doSearchLotOccupancies.ts | 0 .../doSearchPastOccupants.d.ts} | 0 .../doSearchPastOccupants.js | 0 .../doSearchPastOccupants.ts | 0 .../contracts-post/doUpdateLotOccupancy.d.ts | 2 + .../doUpdateLotOccupancy.js | 0 .../doUpdateLotOccupancy.ts | 0 .../doUpdateLotOccupancyComment.d.ts | 2 + .../doUpdateLotOccupancyComment.js | 0 .../doUpdateLotOccupancyComment.ts | 0 .../doUpdateLotOccupancyFeeQuantity.d.ts | 2 + .../doUpdateLotOccupancyFeeQuantity.js | 0 .../doUpdateLotOccupancyFeeQuantity.ts | 0 .../doUpdateLotOccupancyOccupant.d.ts | 2 + .../doUpdateLotOccupancyOccupant.js | 0 .../doUpdateLotOccupancyOccupant.ts | 0 .../doUpdateLotOccupancyTransaction.d.ts | 2 + .../doUpdateLotOccupancyTransaction.js | 0 .../doUpdateLotOccupancyTransaction.ts | 0 handlers/permissions.js | 2 +- handlers/permissions.ts | 2 +- handlers/print-get/pdf.js | 2 +- handlers/print-get/pdf.ts | 2 +- handlers/print-get/screen.js | 2 +- handlers/print-get/screen.ts | 2 +- handlers/workOrders-get/edit.js | 2 +- handlers/workOrders-get/edit.ts | 2 +- handlers/workOrders-get/view.js | 2 +- handlers/workOrders-get/view.ts | 2 +- helpers/burialSites.helpers.d.ts | 3 + helpers/burialSites.helpers.js | 99 ++++ helpers/burialSites.helpers.ts | 162 ++++++ helpers/cemeteries.helpers.d.ts | 1 + helpers/cemeteries.helpers.js | 15 + helpers/cemeteries.helpers.ts | 21 + ...ctions.config.d.ts => config.helpers.d.ts} | 4 + ...{functions.config.js => config.helpers.js} | 3 + ...{functions.config.ts => config.helpers.ts} | 6 +- helpers/database.helpers.d.ts | 5 + helpers/database.helpers.js | 13 + helpers/database.helpers.ts | 22 + helpers/functions.api.js | 3 +- helpers/functions.api.ts | 4 +- helpers/functions.authentication.js | 2 +- helpers/functions.authentication.ts | 2 +- helpers/functions.cache.js | 5 +- helpers/functions.cache.ts | 5 +- helpers/functions.database.js | 2 +- helpers/functions.database.ts | 4 +- helpers/functions.dynamicsGP.js | 2 +- helpers/functions.dynamicsGP.ts | 2 +- helpers/functions.lotOccupancy.d.ts | 2 +- helpers/functions.lotOccupancy.ts | 2 +- helpers/functions.lots.d.ts | 3 - helpers/functions.lots.js | 96 ---- helpers/functions.lots.ts | 141 ----- helpers/functions.map.d.ts | 1 - helpers/functions.map.js | 15 - helpers/functions.map.ts | 21 - helpers/functions.print.js | 2 +- helpers/functions.print.ts | 2 +- helpers/functions.user.js | 2 +- helpers/functions.user.ts | 2 +- helpers/initializer.database.cemetery.d.ts | 1 - helpers/initializer.database.cemetery.js | 245 -------- helpers/initializer.database.cemetery.ts | 383 ------------- helpers/initializer.database.d.ts | 1 - helpers/initializer.database.js | 127 ----- helpers/initializer.database.ts | 159 ------ package-lock.json | 9 +- package.json | 26 +- ...metery.holySepulchre-block-A-rows-1-52.svg | 0 ...etery.holySepulchre-block-A-rows-53-97.svg | 0 ...emetery.holySepulchre-block-A-rows-B-T.svg | 0 ...olySepulchre-block-A-urnRanges-52A-53A.svg | 0 ...olySepulchre-block-A-urnRanges-72A-73A.svg | 0 ...olySepulchre-block-A-urnRanges-97A-97B.svg | 0 ...metery.holySepulchre-block-B-rows-1-52.svg | 0 ...etery.holySepulchre-block-B-rows-53-97.svg | 0 ...emetery.holySepulchre-block-B-rows-B-T.svg | 0 ...metery.holySepulchre-block-C-rows-1-36.svg | 0 ...emetery.holySepulchre-block-C-rows-B-U.svg | 0 ...etery.holySepulchre-block-D-babyShrine.svg | 0 ...emetery.holySepulchre-block-D-rows-A-L.svg | 0 ...emetery.holySepulchre-block-D-rows-M-V.svg | 0 ...ry.holySepulchre-block-E-sectionCenter.svg | 0 ...tery.holySepulchre-block-E-sectionEast.svg | 0 ...tery.holySepulchre-block-E-sectionWest.svg | 0 ...metery.holySepulchre-block-F-rows-1-22.svg | 0 ...metery.holySepulchre-block-G-rows-1-32.svg | 0 ...metery.holySepulchre-block-H-rows-1-16.svg | 0 ...metery.holySepulchre-block-J-rows-1-18.svg | 0 ...metery.holySepulchre-block-K-rows-1-19.svg | 0 ...cemetery.holySepulchre-columbarium-O-P.svg | 0 ...m.cemetery.holySepulchre-columbarium-S.svg | 0 ...m.cemetery.holySepulchre-columbarium-T.svg | 0 ...m.cemetery.holySepulchre-columbarium-U.svg | 0 ...m.cemetery.holySepulchre-columbarium-V.svg | 0 ...m.cemetery.holySepulchre-columbarium-W.svg | 0 .../ssm.cemetery.holySepulchre-image.svg | 0 ....cemetery.holySepulchre-mausoleum-east.svg | 0 ...cemetery.holySepulchre-mausoleum-image.svg | 0 ...tery.holySepulchre-mausoleum-niche-J-E.svg | 0 ...tery.holySepulchre-mausoleum-niche-J-W.svg | 0 ...tery.holySepulchre-mausoleum-niche-L-E.svg | 0 ...tery.holySepulchre-mausoleum-niche-L-W.svg | 0 ...metery.holySepulchre-mausoleum-niche-L.svg | 0 ...tery.holySepulchre-mausoleum-niche-M-E.svg | 0 ...tery.holySepulchre-mausoleum-niche-M-W.svg | 0 ...metery.holySepulchre-mausoleum-niche-M.svg | 0 ...tery.holySepulchre-mausoleum-section-T.svg | 0 ...tery.holySepulchre-mausoleum-section-U.svg | 0 ....cemetery.holySepulchre-mausoleum-west.svg | 0 .../ssm.cemetery.holySepulchre-overview.svg | 0 ...sm.cemetery.newGreenwood-columbarium-A.svg | 0 ...sm.cemetery.newGreenwood-columbarium-B.svg | 0 ...sm.cemetery.newGreenwood-columbarium-C.svg | 0 ...sm.cemetery.newGreenwood-columbarium-D.svg | 0 ...sm.cemetery.newGreenwood-columbarium-E.svg | 0 ...sm.cemetery.newGreenwood-columbarium-F.svg | 0 ...sm.cemetery.newGreenwood-columbarium-G.svg | 0 ...sm.cemetery.newGreenwood-columbarium-H.svg | 0 ...sm.cemetery.newGreenwood-columbarium-I.svg | 0 ...sm.cemetery.newGreenwood-columbarium-J.svg | 0 ...sm.cemetery.newGreenwood-columbarium-K.svg | 0 ...sm.cemetery.newGreenwood-columbarium-L.svg | 0 ...sm.cemetery.newGreenwood-columbarium-M.svg | 0 ...sm.cemetery.newGreenwood-columbarium-N.svg | 0 .../ssm.cemetery.newGreenwood-image.svg | 0 ...m.cemetery.newGreenwood-infantsSection.svg | 0 ...m.cemetery.newGreenwood-nicheWall-1-40.svg | 0 ....cemetery.newGreenwood-nicheWall-41-80.svg | 0 ...cemetery.newGreenwood-nicheWall-81-106.svg | 0 .../ssm.cemetery.newGreenwood-overview.svg | 0 ...etery.newGreenwood-rows-1-31-lots 3-21.svg | 0 ...tery.newGreenwood-rows-1-31-lots-22-46.svg | 0 ...ery.newGreenwood-rows-25-61-lots-47-59.svg | 0 ...ery.newGreenwood-rows-33-60-lots-4-21A.svg | 0 ...ery.newGreenwood-rows-33-61-lots-22-46.svg | 0 ...ery.newGreenwood-rows-63-94-lots-24-40.svg | 0 ...ery.newGreenwood-rows-63-94-lots-47-59.svg | 0 ...ery.newGreenwood-rows-66-95-lots-12-24.svg | 0 .../ssm.cemetery.newGreenwood-urnGarden.svg | 0 ....cemetery.newGreenwood-veteransSection.svg | 0 .../ssm.cemetery.oldGreenwood-babySection.svg | 0 ...reenwood-eastNorth-rows-1-18-lots-1-11.svg | 0 ...eenwood-eastNorth-rows-1-18-lots-12-17.svg | 0 ...eenwood-eastNorth-rows-19-38-lots-1-11.svg | 0 ...enwood-eastNorth-rows-19-38-lots-12-17.svg | 0 ...enwood-eastSouthA-rows-1-18-lots 23-31.svg | 0 ...eenwood-eastSouthA-rows-1-18-lots-1-22.svg | 0 ...enwood-eastSouthA-rows-19-32-lots-1-22.svg | 0 ...nwood-eastSouthA-rows-19-32-lots-23-31.svg | 0 ...enwood-eastSouthB-lots-33-45-rows-1-22.svg | 0 ...nwood-eastSouthB-rows-33-57-lots 23-31.svg | 0 ...nwood-eastSouthB-rows-46-57-lots-11-24.svg | 0 .../ssm.cemetery.oldGreenwood-image.svg | 0 .../ssm.cemetery.oldGreenwood-overview.svg | 0 ...emetery.oldGreenwood-westSection-image.svg | 0 .../ssm.cemetery.oldGreenwood-westSection.svg | 0 .../ssm.cemetery.pineGrove-overview.svg | 0 .../ssm.cemetery.westKorah-eastSection.svg | 0 .../ssm.cemetery.westKorah-northSection.svg | 0 .../ssm.cemetery.westKorah-overview.svg | 0 .../ssm.cemetery.westKorah-westSection.svg | 0 routes/admin.js | 4 +- routes/admin.ts | 4 +- .../{lotOccupancies.d.ts => burialSites.d.ts} | 0 routes/{lots.js => burialSites.js} | 0 routes/{lots.ts => burialSites.ts} | 0 routes/{lots.d.ts => cemeteries.d.ts} | 0 routes/cemeteries.js | 22 + routes/cemeteries.ts | 46 ++ routes/{maps.d.ts => contracts.d.ts} | 0 routes/{lotOccupancies.js => contracts.js} | 2 +- routes/{lotOccupancies.ts => contracts.ts} | 2 +- routes/login.js | 7 +- routes/login.ts | 7 +- routes/maps.js | 22 - routes/maps.ts | 46 -- temp/legacy.importFromCSV.js | 72 +-- temp/legacy.importFromCSV.ts | 65 +-- temp/legacy.importFromCsv.ids.d.ts | 6 +- temp/legacy.importFromCsv.ids.js | 2 +- temp/legacy.importFromCsv.ids.ts | 2 +- test/1_serverCypress.js | 2 +- test/1_serverCypress.ts | 2 +- test/functions.js | 8 - test/functions.ts | 12 - tsconfig.json | 6 +- types/applicationTypes.d.ts | 14 +- types/applicationTypes.ts | 14 +- types/configTypes.d.ts | 29 +- types/configTypes.ts | 29 +- types/recordTypes.d.ts | 114 ++-- types/recordTypes.ts | 116 ++-- version.d.ts | 2 +- version.js | 2 +- version.ts | 2 +- views/_header.ejs | 2 +- views/_menu-workOrders.ejs | 11 - views/dashboard.ejs | 30 +- views/login.ejs | 6 +- views/lot-edit.ejs | 24 +- windowsService.js | 4 +- windowsService.ts | 4 +- 558 files changed, 3147 insertions(+), 4188 deletions(-) delete mode 100644 .codeclimate.yml delete mode 100644 .eslintignore delete mode 100644 .github/workflows/coverage.yml rename data/{config.cemetery.ontario.d.ts => config.baseOntario.d.ts} (100%) create mode 100644 data/config.baseOntario.js create mode 100644 data/config.baseOntario.ts rename data/{config.cemetery.d.ts => config.baseSsm.d.ts} (100%) create mode 100644 data/config.baseSsm.js create mode 100644 data/config.baseSsm.ts delete mode 100644 data/config.cemetery.js delete mode 100644 data/config.cemetery.ontario.js delete mode 100644 data/config.cemetery.ontario.ts delete mode 100644 data/config.cemetery.ssm.d.ts delete mode 100644 data/config.cemetery.ssm.js delete mode 100644 data/config.cemetery.ssm.ts delete mode 100644 data/config.cemetery.ts delete mode 100644 data/databasePaths.d.ts delete mode 100644 data/databasePaths.js delete mode 100644 data/databasePaths.ts rename database/{addLot.d.ts => addBurialSite.d.ts} (100%) rename database/{addLot.js => addBurialSite.js} (100%) rename database/{addLot.ts => addBurialSite.ts} (100%) create mode 100644 database/addBurialSiteComment.d.ts rename database/{addLotComment.js => addBurialSiteComment.js} (54%) rename database/{addLotComment.ts => addBurialSiteComment.ts} (66%) create mode 100644 database/addBurialSiteContractComment.d.ts create mode 100644 database/addBurialSiteContractComment.js create mode 100644 database/addBurialSiteContractComment.ts create mode 100644 database/addBurialSiteTypeField.d.ts create mode 100644 database/addBurialSiteTypeField.js rename database/{addLotTypeField.ts => addBurialSiteTypeField.ts} (54%) create mode 100644 database/addCemetery.d.ts create mode 100644 database/addCemetery.js create mode 100644 database/addCemetery.ts create mode 100644 database/addContractTypeField.d.ts create mode 100644 database/addContractTypeField.js rename database/{addOccupancyTypeField.ts => addContractTypeField.ts} (50%) create mode 100644 database/addContractTypePrint.d.ts rename database/{addOccupancyTypePrint.js => addContractTypePrint.js} (52%) rename database/{addOccupancyTypePrint.ts => addContractTypePrint.ts} (61%) delete mode 100644 database/addLotComment.d.ts delete mode 100644 database/addLotOccupancyComment.d.ts delete mode 100644 database/addLotOccupancyComment.js delete mode 100644 database/addLotOccupancyComment.ts delete mode 100644 database/addLotOccupancyOccupant.d.ts delete mode 100644 database/addLotOccupancyOccupant.js delete mode 100644 database/addLotOccupancyOccupant.ts delete mode 100644 database/addLotOccupantType.d.ts delete mode 100644 database/addLotOccupantType.js delete mode 100644 database/addLotOccupantType.ts delete mode 100644 database/addLotTypeField.d.ts delete mode 100644 database/addLotTypeField.js delete mode 100644 database/addMap.d.ts delete mode 100644 database/addMap.js delete mode 100644 database/addMap.ts delete mode 100644 database/addOccupancyTypeField.d.ts delete mode 100644 database/addOccupancyTypeField.js delete mode 100644 database/addOccupancyTypePrint.d.ts create mode 100644 database/addOrUpdateBurialSiteContractField.d.ts create mode 100644 database/addOrUpdateBurialSiteContractField.js rename database/{addOrUpdateLotOccupancyField.ts => addOrUpdateBurialSiteContractField.ts} (54%) create mode 100644 database/addOrUpdateBurialSiteField.d.ts rename database/{addOrUpdateLotField.js => addOrUpdateBurialSiteField.js} (51%) rename database/{addOrUpdateLotField.ts => addOrUpdateBurialSiteField.ts} (60%) delete mode 100644 database/addOrUpdateLotField.d.ts delete mode 100644 database/addOrUpdateLotOccupancyField.d.ts delete mode 100644 database/addOrUpdateLotOccupancyField.js rename database/{addWorkOrderLot.d.ts => addWorkOrderBurialSite.d.ts} (100%) rename database/{addWorkOrderLot.js => addWorkOrderBurialSite.js} (100%) rename database/{addWorkOrderLot.ts => addWorkOrderBurialSite.ts} (100%) create mode 100644 database/addWorkOrderBurialSiteContract.d.ts rename database/{addWorkOrderLotOccupancy.js => addWorkOrderBurialSiteContract.js} (51%) rename database/{addWorkOrderLotOccupancy.ts => addWorkOrderBurialSiteContract.ts} (61%) delete mode 100644 database/addWorkOrderLotOccupancy.d.ts create mode 100644 database/deleteBurialSiteContractFee.d.ts rename database/{deleteLotOccupancyFee.js => deleteBurialSiteContractFee.js} (52%) rename database/{deleteLotOccupancyFee.ts => deleteBurialSiteContractFee.ts} (59%) create mode 100644 database/deleteBurialSiteContractField.d.ts create mode 100644 database/deleteBurialSiteContractField.js rename database/{deleteLotOccupancyField.ts => deleteBurialSiteContractField.ts} (58%) create mode 100644 database/deleteBurialSiteContractInterment.d.ts create mode 100644 database/deleteBurialSiteContractInterment.js create mode 100644 database/deleteBurialSiteContractInterment.ts create mode 100644 database/deleteBurialSiteContractTransaction.d.ts rename database/{deleteLotOccupancyTransaction.js => deleteBurialSiteContractTransaction.js} (50%) rename database/{deleteLotOccupancyTransaction.ts => deleteBurialSiteContractTransaction.ts} (58%) create mode 100644 database/deleteBurialSiteField.d.ts rename database/{deleteLotField.js => deleteBurialSiteField.js} (51%) rename database/{deleteLotField.ts => deleteBurialSiteField.ts} (60%) create mode 100644 database/deleteContractTypePrint.d.ts rename database/{deleteOccupancyTypePrint.js => deleteContractTypePrint.js} (55%) rename database/{deleteOccupancyTypePrint.ts => deleteContractTypePrint.ts} (60%) delete mode 100644 database/deleteLotField.d.ts delete mode 100644 database/deleteLotOccupancyFee.d.ts delete mode 100644 database/deleteLotOccupancyField.d.ts delete mode 100644 database/deleteLotOccupancyField.js delete mode 100644 database/deleteLotOccupancyOccupant.d.ts delete mode 100644 database/deleteLotOccupancyOccupant.js delete mode 100644 database/deleteLotOccupancyOccupant.ts delete mode 100644 database/deleteLotOccupancyTransaction.d.ts delete mode 100644 database/deleteOccupancyTypePrint.d.ts create mode 100644 database/deleteWorkOrderBurialSite.d.ts rename database/{deleteWorkOrderLot.js => deleteWorkOrderBurialSite.js} (54%) rename database/{deleteWorkOrderLot.ts => deleteWorkOrderBurialSite.ts} (62%) create mode 100644 database/deleteWorkOrderBurialSiteContract.d.ts rename database/{deleteWorkOrderLotOccupancy.js => deleteWorkOrderBurialSiteContract.js} (50%) rename database/{deleteWorkOrderLotOccupancy.ts => deleteWorkOrderBurialSiteContract.ts} (58%) delete mode 100644 database/deleteWorkOrderLot.d.ts delete mode 100644 database/deleteWorkOrderLotOccupancy.d.ts rename database/{getLot.d.ts => getBurialSite.d.ts} (60%) create mode 100644 database/getBurialSite.js create mode 100644 database/getBurialSite.ts delete mode 100644 database/getLot.js delete mode 100644 database/getLot.ts create mode 100644 database/getNextBurialSiteId.d.ts rename database/{getNextLotId.js => getNextBurialSiteId.js} (57%) rename database/{getNextLotId.ts => getNextBurialSiteId.ts} (57%) delete mode 100644 database/getNextLotId.d.ts create mode 100644 database/initializeDatabase.d.ts create mode 100644 database/initializeDatabase.js create mode 100644 database/initializeDatabase.ts create mode 100644 debug.config.d.ts create mode 100644 debug.config.js create mode 100644 debug.config.ts delete mode 100644 docs/README.md delete mode 100644 docs/adminConfigTables.md delete mode 100644 docs/adminFees.md delete mode 100644 docs/adminLotTypes.md delete mode 100644 docs/adminOccupancyTypes.md delete mode 100644 docs/cemeteryWorkflowDeceased.md delete mode 100644 docs/images/adminConfigTables.png delete mode 100644 docs/images/adminFees.png delete mode 100644 docs/images/adminLotTypes.png delete mode 100644 docs/images/adminOccupancyTypes.png delete mode 100644 docs/images/configTableSorting.png delete mode 100644 docs/images/lotOccupancyAddFee.png delete mode 100644 docs/images/lotOccupancyEdit-moreOptions.png delete mode 100644 docs/images/lotOccupancyEdit.png delete mode 100644 docs/images/lotOccupancySearch.png delete mode 100644 docs/images/lotOccupancyView.png delete mode 100644 docs/images/lotView.png delete mode 100644 docs/images/mapImageLotConfig.png delete mode 100644 docs/images/mapImageStructure.png delete mode 100644 docs/images/workOrderEdit.png delete mode 100644 docs/images/workOrderMilestoneEdit.png delete mode 100644 docs/lotOccupancies.md delete mode 100644 docs/mapImages.md delete mode 100644 docs/shortcuts.md delete mode 100644 docs/terminology.md delete mode 100644 docs/workOrders.md rename handlers/admin-get/{lotTypes.d.ts => burialSiteTypes.d.ts} (100%) rename handlers/admin-get/{lotTypes.js => burialSiteTypes.js} (81%) rename handlers/admin-get/{lotTypes.ts => burialSiteTypes.ts} (84%) rename handlers/{lotOccupancies-get => burialSites-get}/edit.d.ts (100%) rename handlers/{lots-get => burialSites-get}/edit.js (91%) rename handlers/{lots-get => burialSites-get}/edit.ts (91%) rename handlers/{lotOccupancies-get => burialSites-get}/new.d.ts (100%) rename handlers/{lots-get => burialSites-get}/new.js (92%) rename handlers/{lots-get => burialSites-get}/new.ts (93%) rename handlers/{lots-get => burialSites-get}/next.d.ts (100%) rename handlers/{lots-get => burialSites-get}/next.js (87%) rename handlers/{lots-get => burialSites-get}/next.ts (89%) rename handlers/{lots-get => burialSites-get}/previous.d.ts (100%) rename handlers/{lots-get => burialSites-get}/previous.js (88%) rename handlers/{lots-get => burialSites-get}/previous.ts (90%) rename handlers/{lotOccupancies-get => burialSites-get}/search.d.ts (100%) rename handlers/{lots-get => burialSites-get}/search.js (89%) rename handlers/{lots-get => burialSites-get}/search.ts (90%) rename handlers/{lotOccupancies-get => burialSites-get}/view.d.ts (100%) rename handlers/{lots-get => burialSites-get}/view.js (89%) rename handlers/{lots-get => burialSites-get}/view.ts (90%) rename handlers/{lotOccupancies-post/doAddLotOccupancyComment.d.ts => burialSites-post/doAddLotComment.d.ts} (100%) create mode 100644 handlers/burialSites-post/doAddLotComment.js rename handlers/{lots-post => burialSites-post}/doAddLotComment.ts (100%) rename handlers/{lotOccupancies-post/doAddLotOccupancyFee.d.ts => burialSites-post/doCreateLot.d.ts} (100%) create mode 100644 handlers/burialSites-post/doCreateLot.js rename handlers/{lots-post => burialSites-post}/doCreateLot.ts (100%) rename handlers/{lotOccupancies-post/doAddLotOccupancyFeeCategory.d.ts => burialSites-post/doDeleteLot.d.ts} (100%) create mode 100644 handlers/burialSites-post/doDeleteLot.js rename handlers/{lots-post => burialSites-post}/doDeleteLot.ts (100%) rename handlers/{lotOccupancies-post/doAddLotOccupancyOccupant.d.ts => burialSites-post/doDeleteLotComment.d.ts} (100%) create mode 100644 handlers/burialSites-post/doDeleteLotComment.js rename handlers/{lots-post => burialSites-post}/doDeleteLotComment.ts (100%) rename handlers/{lots-post => burialSites-post}/doGetLotTypeFields.d.ts (100%) rename handlers/{lots-post => burialSites-post}/doGetLotTypeFields.js (100%) rename handlers/{lots-post => burialSites-post}/doGetLotTypeFields.ts (100%) rename handlers/{lots-post => burialSites-post}/doSearchLots.d.ts (100%) rename handlers/{lots-post => burialSites-post}/doSearchLots.js (100%) rename handlers/{lots-post => burialSites-post}/doSearchLots.ts (100%) rename handlers/{lotOccupancies-post/doAddLotOccupancyTransaction.d.ts => burialSites-post/doUpdateLot.d.ts} (100%) rename handlers/{lots-post => burialSites-post}/doUpdateLot.js (100%) rename handlers/{lots-post => burialSites-post}/doUpdateLot.ts (100%) rename handlers/{lots-post => burialSites-post}/doUpdateLotComment.d.ts (100%) rename handlers/{lots-post => burialSites-post}/doUpdateLotComment.js (100%) rename handlers/{lots-post => burialSites-post}/doUpdateLotComment.ts (100%) rename handlers/{lots-get => cemeteries-get}/edit.d.ts (100%) rename handlers/{maps-get => cemeteries-get}/edit.js (92%) rename handlers/{maps-get => cemeteries-get}/edit.ts (93%) rename handlers/{maps-get => cemeteries-get}/new.d.ts (100%) rename handlers/{maps-get => cemeteries-get}/new.js (87%) rename handlers/{maps-get => cemeteries-get}/new.ts (89%) rename handlers/{maps-get => cemeteries-get}/next.d.ts (100%) rename handlers/{maps-get => cemeteries-get}/next.js (87%) rename handlers/{maps-get => cemeteries-get}/next.ts (89%) rename handlers/{maps-get => cemeteries-get}/previous.d.ts (100%) rename handlers/{maps-get => cemeteries-get}/previous.js (88%) rename handlers/{maps-get => cemeteries-get}/previous.ts (90%) rename handlers/{maps-get => cemeteries-get}/search.d.ts (100%) rename handlers/{maps-get => cemeteries-get}/search.js (78%) rename handlers/{maps-get => cemeteries-get}/search.ts (83%) rename handlers/{lots-get => cemeteries-get}/view.d.ts (100%) rename handlers/{maps-get => cemeteries-get}/view.js (91%) rename handlers/{maps-get => cemeteries-get}/view.ts (92%) rename handlers/{lotOccupancies-post/doCopyLotOccupancy.d.ts => cemeteries-post/doCreateCemetery.d.ts} (100%) rename handlers/{maps-post/doCreateMap.js => cemeteries-post/doCreateCemetery.js} (100%) rename handlers/{maps-post/doCreateMap.ts => cemeteries-post/doCreateCemetery.ts} (100%) rename handlers/{lotOccupancies-post/doCreateLotOccupancy.d.ts => cemeteries-post/doDeleteCemetery.d.ts} (100%) rename handlers/{maps-post/doDeleteMap.js => cemeteries-post/doDeleteCemetery.js} (100%) rename handlers/{maps-post/doDeleteMap.ts => cemeteries-post/doDeleteCemetery.ts} (100%) rename handlers/{maps-post => cemeteries-post}/doUpdateMap.d.ts (100%) rename handlers/{maps-post => cemeteries-post}/doUpdateMap.js (100%) rename handlers/{maps-post => cemeteries-post}/doUpdateMap.ts (100%) rename handlers/{maps-get => contracts-get}/edit.d.ts (100%) rename handlers/{lotOccupancies-get => contracts-get}/edit.js (94%) rename handlers/{lotOccupancies-get => contracts-get}/edit.ts (95%) rename handlers/{lots-get => contracts-get}/new.d.ts (100%) rename handlers/{lotOccupancies-get => contracts-get}/new.js (95%) rename handlers/{lotOccupancies-get => contracts-get}/new.ts (95%) rename handlers/{lots-get => contracts-get}/search.d.ts (100%) rename handlers/{lotOccupancies-get => contracts-get}/search.js (88%) rename handlers/{lotOccupancies-get => contracts-get}/search.ts (89%) rename handlers/{maps-get => contracts-get}/view.d.ts (100%) rename handlers/{lotOccupancies-get => contracts-get}/view.js (91%) rename handlers/{lotOccupancies-get => contracts-get}/view.ts (92%) rename handlers/{lotOccupancies-post/doDeleteLotOccupancy.d.ts => contracts-post/doAddLotOccupancyComment.d.ts} (100%) rename handlers/{lotOccupancies-post => contracts-post}/doAddLotOccupancyComment.js (100%) rename handlers/{lotOccupancies-post => contracts-post}/doAddLotOccupancyComment.ts (100%) rename handlers/{lotOccupancies-post/doDeleteLotOccupancyComment.d.ts => contracts-post/doAddLotOccupancyFee.d.ts} (100%) rename handlers/{lotOccupancies-post => contracts-post}/doAddLotOccupancyFee.js (100%) rename handlers/{lotOccupancies-post => contracts-post}/doAddLotOccupancyFee.ts (100%) rename handlers/{lotOccupancies-post/doDeleteLotOccupancyFee.d.ts => contracts-post/doAddLotOccupancyFeeCategory.d.ts} (100%) rename handlers/{lotOccupancies-post => contracts-post}/doAddLotOccupancyFeeCategory.js (100%) rename handlers/{lotOccupancies-post => contracts-post}/doAddLotOccupancyFeeCategory.ts (100%) rename handlers/{lotOccupancies-post/doDeleteLotOccupancyOccupant.d.ts => contracts-post/doAddLotOccupancyOccupant.d.ts} (100%) rename handlers/{lotOccupancies-post => contracts-post}/doAddLotOccupancyOccupant.js (100%) rename handlers/{lotOccupancies-post => contracts-post}/doAddLotOccupancyOccupant.ts (100%) rename handlers/{lotOccupancies-post/doDeleteLotOccupancyTransaction.d.ts => contracts-post/doAddLotOccupancyTransaction.d.ts} (100%) rename handlers/{lotOccupancies-post => contracts-post}/doAddLotOccupancyTransaction.js (100%) rename handlers/{lotOccupancies-post => contracts-post}/doAddLotOccupancyTransaction.ts (100%) rename handlers/{lotOccupancies-post/doGetDynamicsGPDocument.d.ts => contracts-post/doCopyLotOccupancy.d.ts} (100%) rename handlers/{lotOccupancies-post => contracts-post}/doCopyLotOccupancy.js (100%) rename handlers/{lotOccupancies-post => contracts-post}/doCopyLotOccupancy.ts (100%) rename handlers/{lotOccupancies-post/doGetFees.d.ts => contracts-post/doCreateLotOccupancy.d.ts} (100%) rename handlers/{lotOccupancies-post => contracts-post}/doCreateLotOccupancy.js (100%) rename handlers/{lotOccupancies-post => contracts-post}/doCreateLotOccupancy.ts (100%) rename handlers/{lotOccupancies-post/doGetOccupancyTypeFields.d.ts => contracts-post/doDeleteLotOccupancy.d.ts} (100%) rename handlers/{lotOccupancies-post => contracts-post}/doDeleteLotOccupancy.js (100%) rename handlers/{lotOccupancies-post => contracts-post}/doDeleteLotOccupancy.ts (100%) rename handlers/{lotOccupancies-post/doSearchLotOccupancies.d.ts => contracts-post/doDeleteLotOccupancyComment.d.ts} (100%) rename handlers/{lotOccupancies-post => contracts-post}/doDeleteLotOccupancyComment.js (100%) rename handlers/{lotOccupancies-post => contracts-post}/doDeleteLotOccupancyComment.ts (100%) rename handlers/{lotOccupancies-post/doSearchPastOccupants.d.ts => contracts-post/doDeleteLotOccupancyFee.d.ts} (100%) rename handlers/{lotOccupancies-post => contracts-post}/doDeleteLotOccupancyFee.js (100%) rename handlers/{lotOccupancies-post => contracts-post}/doDeleteLotOccupancyFee.ts (100%) rename handlers/{lotOccupancies-post/doUpdateLotOccupancy.d.ts => contracts-post/doDeleteLotOccupancyOccupant.d.ts} (100%) rename handlers/{lotOccupancies-post => contracts-post}/doDeleteLotOccupancyOccupant.js (100%) rename handlers/{lotOccupancies-post => contracts-post}/doDeleteLotOccupancyOccupant.ts (100%) rename handlers/{lotOccupancies-post/doUpdateLotOccupancyComment.d.ts => contracts-post/doDeleteLotOccupancyTransaction.d.ts} (100%) rename handlers/{lotOccupancies-post => contracts-post}/doDeleteLotOccupancyTransaction.js (100%) rename handlers/{lotOccupancies-post => contracts-post}/doDeleteLotOccupancyTransaction.ts (100%) rename handlers/{lotOccupancies-post/doUpdateLotOccupancyFeeQuantity.d.ts => contracts-post/doGetDynamicsGPDocument.d.ts} (100%) rename handlers/{lotOccupancies-post => contracts-post}/doGetDynamicsGPDocument.js (100%) rename handlers/{lotOccupancies-post => contracts-post}/doGetDynamicsGPDocument.ts (100%) rename handlers/{lotOccupancies-post/doUpdateLotOccupancyOccupant.d.ts => contracts-post/doGetFees.d.ts} (100%) rename handlers/{lotOccupancies-post => contracts-post}/doGetFees.js (100%) rename handlers/{lotOccupancies-post => contracts-post}/doGetFees.ts (100%) rename handlers/{lotOccupancies-post/doUpdateLotOccupancyTransaction.d.ts => contracts-post/doGetOccupancyTypeFields.d.ts} (100%) rename handlers/{lotOccupancies-post => contracts-post}/doGetOccupancyTypeFields.js (100%) rename handlers/{lotOccupancies-post => contracts-post}/doGetOccupancyTypeFields.ts (100%) rename handlers/{maps-post/doCreateMap.d.ts => contracts-post/doSearchLotOccupancies.d.ts} (100%) rename handlers/{lotOccupancies-post => contracts-post}/doSearchLotOccupancies.js (100%) rename handlers/{lotOccupancies-post => contracts-post}/doSearchLotOccupancies.ts (100%) rename handlers/{maps-post/doDeleteMap.d.ts => contracts-post/doSearchPastOccupants.d.ts} (100%) rename handlers/{lotOccupancies-post => contracts-post}/doSearchPastOccupants.js (100%) rename handlers/{lotOccupancies-post => contracts-post}/doSearchPastOccupants.ts (100%) create mode 100644 handlers/contracts-post/doUpdateLotOccupancy.d.ts rename handlers/{lotOccupancies-post => contracts-post}/doUpdateLotOccupancy.js (100%) rename handlers/{lotOccupancies-post => contracts-post}/doUpdateLotOccupancy.ts (100%) create mode 100644 handlers/contracts-post/doUpdateLotOccupancyComment.d.ts rename handlers/{lotOccupancies-post => contracts-post}/doUpdateLotOccupancyComment.js (100%) rename handlers/{lotOccupancies-post => contracts-post}/doUpdateLotOccupancyComment.ts (100%) create mode 100644 handlers/contracts-post/doUpdateLotOccupancyFeeQuantity.d.ts rename handlers/{lotOccupancies-post => contracts-post}/doUpdateLotOccupancyFeeQuantity.js (100%) rename handlers/{lotOccupancies-post => contracts-post}/doUpdateLotOccupancyFeeQuantity.ts (100%) create mode 100644 handlers/contracts-post/doUpdateLotOccupancyOccupant.d.ts rename handlers/{lotOccupancies-post => contracts-post}/doUpdateLotOccupancyOccupant.js (100%) rename handlers/{lotOccupancies-post => contracts-post}/doUpdateLotOccupancyOccupant.ts (100%) create mode 100644 handlers/contracts-post/doUpdateLotOccupancyTransaction.d.ts rename handlers/{lotOccupancies-post => contracts-post}/doUpdateLotOccupancyTransaction.js (100%) rename handlers/{lotOccupancies-post => contracts-post}/doUpdateLotOccupancyTransaction.ts (100%) create mode 100644 helpers/burialSites.helpers.d.ts create mode 100644 helpers/burialSites.helpers.js create mode 100644 helpers/burialSites.helpers.ts create mode 100644 helpers/cemeteries.helpers.d.ts create mode 100644 helpers/cemeteries.helpers.js create mode 100644 helpers/cemeteries.helpers.ts rename helpers/{functions.config.d.ts => config.helpers.d.ts} (74%) rename helpers/{functions.config.js => config.helpers.js} (93%) rename helpers/{functions.config.ts => config.helpers.ts} (94%) create mode 100644 helpers/database.helpers.d.ts create mode 100644 helpers/database.helpers.js create mode 100644 helpers/database.helpers.ts delete mode 100644 helpers/functions.lots.d.ts delete mode 100644 helpers/functions.lots.js delete mode 100644 helpers/functions.lots.ts delete mode 100644 helpers/functions.map.d.ts delete mode 100644 helpers/functions.map.js delete mode 100644 helpers/functions.map.ts delete mode 100644 helpers/initializer.database.cemetery.d.ts delete mode 100644 helpers/initializer.database.cemetery.js delete mode 100644 helpers/initializer.database.cemetery.ts delete mode 100644 helpers/initializer.database.d.ts delete mode 100644 helpers/initializer.database.js delete mode 100644 helpers/initializer.database.ts rename public/images/{maps => cemeteries}/ssm.cemetery.holySepulchre-block-A-rows-1-52.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.holySepulchre-block-A-rows-53-97.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.holySepulchre-block-A-rows-B-T.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.holySepulchre-block-A-urnRanges-52A-53A.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.holySepulchre-block-A-urnRanges-72A-73A.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.holySepulchre-block-A-urnRanges-97A-97B.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.holySepulchre-block-B-rows-1-52.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.holySepulchre-block-B-rows-53-97.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.holySepulchre-block-B-rows-B-T.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.holySepulchre-block-C-rows-1-36.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.holySepulchre-block-C-rows-B-U.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.holySepulchre-block-D-babyShrine.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.holySepulchre-block-D-rows-A-L.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.holySepulchre-block-D-rows-M-V.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.holySepulchre-block-E-sectionCenter.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.holySepulchre-block-E-sectionEast.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.holySepulchre-block-E-sectionWest.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.holySepulchre-block-F-rows-1-22.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.holySepulchre-block-G-rows-1-32.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.holySepulchre-block-H-rows-1-16.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.holySepulchre-block-J-rows-1-18.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.holySepulchre-block-K-rows-1-19.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.holySepulchre-columbarium-O-P.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.holySepulchre-columbarium-S.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.holySepulchre-columbarium-T.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.holySepulchre-columbarium-U.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.holySepulchre-columbarium-V.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.holySepulchre-columbarium-W.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.holySepulchre-image.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.holySepulchre-mausoleum-east.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.holySepulchre-mausoleum-image.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.holySepulchre-mausoleum-niche-J-E.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.holySepulchre-mausoleum-niche-J-W.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.holySepulchre-mausoleum-niche-L-E.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.holySepulchre-mausoleum-niche-L-W.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.holySepulchre-mausoleum-niche-L.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.holySepulchre-mausoleum-niche-M-E.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.holySepulchre-mausoleum-niche-M-W.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.holySepulchre-mausoleum-niche-M.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.holySepulchre-mausoleum-section-T.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.holySepulchre-mausoleum-section-U.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.holySepulchre-mausoleum-west.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.holySepulchre-overview.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.newGreenwood-columbarium-A.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.newGreenwood-columbarium-B.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.newGreenwood-columbarium-C.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.newGreenwood-columbarium-D.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.newGreenwood-columbarium-E.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.newGreenwood-columbarium-F.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.newGreenwood-columbarium-G.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.newGreenwood-columbarium-H.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.newGreenwood-columbarium-I.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.newGreenwood-columbarium-J.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.newGreenwood-columbarium-K.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.newGreenwood-columbarium-L.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.newGreenwood-columbarium-M.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.newGreenwood-columbarium-N.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.newGreenwood-image.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.newGreenwood-infantsSection.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.newGreenwood-nicheWall-1-40.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.newGreenwood-nicheWall-41-80.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.newGreenwood-nicheWall-81-106.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.newGreenwood-overview.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.newGreenwood-rows-1-31-lots 3-21.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.newGreenwood-rows-1-31-lots-22-46.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.newGreenwood-rows-25-61-lots-47-59.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.newGreenwood-rows-33-60-lots-4-21A.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.newGreenwood-rows-33-61-lots-22-46.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.newGreenwood-rows-63-94-lots-24-40.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.newGreenwood-rows-63-94-lots-47-59.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.newGreenwood-rows-66-95-lots-12-24.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.newGreenwood-urnGarden.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.newGreenwood-veteransSection.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.oldGreenwood-babySection.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.oldGreenwood-eastNorth-rows-1-18-lots-1-11.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.oldGreenwood-eastNorth-rows-1-18-lots-12-17.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.oldGreenwood-eastNorth-rows-19-38-lots-1-11.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.oldGreenwood-eastNorth-rows-19-38-lots-12-17.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.oldGreenwood-eastSouthA-rows-1-18-lots 23-31.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.oldGreenwood-eastSouthA-rows-1-18-lots-1-22.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.oldGreenwood-eastSouthA-rows-19-32-lots-1-22.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.oldGreenwood-eastSouthA-rows-19-32-lots-23-31.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.oldGreenwood-eastSouthB-lots-33-45-rows-1-22.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.oldGreenwood-eastSouthB-rows-33-57-lots 23-31.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.oldGreenwood-eastSouthB-rows-46-57-lots-11-24.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.oldGreenwood-image.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.oldGreenwood-overview.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.oldGreenwood-westSection-image.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.oldGreenwood-westSection.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.pineGrove-overview.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.westKorah-eastSection.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.westKorah-northSection.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.westKorah-overview.svg (100%) rename public/images/{maps => cemeteries}/ssm.cemetery.westKorah-westSection.svg (100%) rename routes/{lotOccupancies.d.ts => burialSites.d.ts} (100%) rename routes/{lots.js => burialSites.js} (100%) rename routes/{lots.ts => burialSites.ts} (100%) rename routes/{lots.d.ts => cemeteries.d.ts} (100%) create mode 100644 routes/cemeteries.js create mode 100644 routes/cemeteries.ts rename routes/{maps.d.ts => contracts.d.ts} (100%) rename routes/{lotOccupancies.js => contracts.js} (98%) rename routes/{lotOccupancies.ts => contracts.ts} (98%) delete mode 100644 routes/maps.js delete mode 100644 routes/maps.ts diff --git a/.codeclimate.yml b/.codeclimate.yml deleted file mode 100644 index b838579f..00000000 --- a/.codeclimate.yml +++ /dev/null @@ -1,18 +0,0 @@ -version: "2" -checks: - file-lines: - config: - threshold: 1500 - method-complexity: - config: - threshold: 20 - method-lines: - config: - threshold: 500 -exclude_patterns: -- "cypress/" -- "**/node_modules/" -- "temp/" -- "test/" -- "**/*.d.ts" -- "**/*.js" \ No newline at end of file diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index d1b9d32e..00000000 --- a/.eslintignore +++ /dev/null @@ -1,3 +0,0 @@ -**/*.d.ts -**/*.ejs -**/*.js diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml deleted file mode 100644 index 50fdedfe..00000000 --- a/.github/workflows/coverage.yml +++ /dev/null @@ -1,72 +0,0 @@ -name: Coverage Testing - -on: [workflow_dispatch, push, pull_request] - -permissions: read-all - -jobs: - Coverage: - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - node: [ 18, 20, 21 ] - env: - CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }} - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} - CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }} - DEEPSOURCE_DSN: ${{ secrets.DEEPSOURCE_DSN }} - name: Node ${{ matrix.node }} - steps: - - uses: actions/checkout@v4 - - name: Setup Node - uses: actions/setup-node@v4 - with: - node-version: ${{ matrix.node }} - - - name: Install Application - run: | - npm ci - npm install -g mocha c8 cypress@13 - - - name: Copy Test Config - run: cp ./data/config.testing.js ./data/config.js - - - name: Test Application Startup - run: npm run test:startup - - - name: Code Climate (Before) - if: ${{ github.event_name != 'pull_request' && env.CC_TEST_REPORTER_ID != '' && matrix.node == 20 }} - run: | - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./codeclimate-test-reporter - chmod +x codeclimate-test-reporter - ./codeclimate-test-reporter before-build - - - name: Verify Cypress - run: cypress verify - env: - CYPRESS_VERIFY_TIMEOUT: 600000 - - - name: Run Coverage Testing - run: c8 --reporter=lcov --reporter=text --reporter=text-summary mocha --timeout 10000 --exit - - - name: Code Climate (After) - if: ${{ github.event_name != 'pull_request' && env.CC_TEST_REPORTER_ID != '' && matrix.node == 20 }} - run: | - ./codeclimate-test-reporter after-build -t lcov --exit-code $? - - - name: Codecov - if: ${{ github.event_name != 'pull_request' && env.CODECOV_TOKEN != '' && matrix.node == 20 }} - run: | - curl -Os https://uploader.codecov.io/latest/linux/codecov - chmod +x codecov - ./codecov -t ${CODECOV_TOKEN} - - - name: DeepSource - if: ${{ github.event_name != 'pull_request' && env.DEEPSOURCE_DSN != '' && matrix.node == 20 }} - run: | - # Install deepsource CLI - curl https://deepsource.io/cli | sh - - # From the root directory, run the report coverage command - ./bin/deepsource report --analyzer test-coverage --key javascript --value-file ./coverage/lcov.info \ No newline at end of file diff --git a/LICENSE.md b/LICENSE.md index a9435528..e10515e9 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,6 +1,6 @@ -MIT License +# MIT License -Copyright (c) 2023 The City of Sault Ste. Marie +Copyright (c) 2025 The City of Sault Ste. Marie Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index fc393b30..953b3d4e 100644 --- a/README.md +++ b/README.md @@ -1,27 +1,13 @@ -# Lot Occupancy System +# Sunrise Cemetery Management System (CMS) -[![DeepSource](https://app.deepsource.com/gh/cityssm/lot-occupancy-system.svg/?label=active+issues&show_trend=true&token=8rYoZ1g7FoZHstfQmOzvlBn7)](https://app.deepsource.com/gh/cityssm/lot-occupancy-system/) -[![Maintainability](https://api.codeclimate.com/v1/badges/11a8975b332f66e6eec7/maintainability)](https://codeclimate.com/github/cityssm/lot-occupancy-system/maintainability) -[![codecov](https://codecov.io/gh/cityssm/lot-occupancy-system/branch/main/graph/badge.svg?token=1M38ZVCLKE)](https://codecov.io/gh/cityssm/lot-occupancy-system) -[![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/cityssm/lot-occupancy-system/coverage.yml?branch=main)](https://github.com/cityssm/lot-occupancy-system/actions/workflows/coverage.yml) -[![lot-occupancy-system](https://img.shields.io/endpoint?url=https://cloud.cypress.io/badge/simple/xya1fn&style=flat&logo=cypress)](https://cloud.cypress.io/projects/xya1fn/runs) +🚧 **In development** 🚧 -**In development** +**A web-based application that allows cemetery managers to manage their cemetery records** -![Lot View](docs/images/lotView.png) - -A system for managing the occupancy of lots. - -Built with **cemetery management** in mind, but flexible enough to handle marinas and campgrounds as well. - -[**User Documentation**](docs/) (In The Works) - -## Key Features - -**Maps are optional!**
-Many systems of this type start with a map, and drill down into the data from it. -This can result in a huge amount of effort to get started. -This system can run "out-of-the-box" without maps, with the option to add them when it makes sense. +This is a major refactoring of the +[Lot Occupancy System](https://github.com/cityssm/lot-occupancy-system), +originally built with multiple focuses. This fork reworks the project to focus exculsively +on cemetery management. ## About this Project diff --git a/_config.yml b/_config.yml index a6192c77..36ec6895 100644 --- a/_config.yml +++ b/_config.yml @@ -1,2 +1,2 @@ theme: jekyll-theme-cayman -title: Lot Occupancy System \ No newline at end of file +title: Sunrise Cemetery Management System \ No newline at end of file diff --git a/app.js b/app.js index 43ba3d3f..3e8d577c 100644 --- a/app.js +++ b/app.js @@ -10,11 +10,12 @@ import session from 'express-session'; import createError from 'http-errors'; import FileStore from 'session-file-store'; import { useTestDatabases } from './data/databasePaths.js'; +import { DEBUG_NAMESPACE } from './debug.config.js'; import * as permissionHandlers from './handlers/permissions.js'; import { getSafeRedirectURL } from './helpers/functions.authentication.js'; -import * as configFunctions from './helpers/functions.config.js'; +import * as configFunctions from './helpers/config.helpers.js'; import * as printFunctions from './helpers/functions.print.js'; -import { initializeDatabase } from './helpers/initializer.database.js'; +import { initializeDatabase } from './helpers/helpers.database.js'; import routerAdmin from './routes/admin.js'; import routerApi from './routes/api.js'; import routerDashboard from './routes/dashboard.js'; @@ -26,11 +27,11 @@ import routerPrint from './routes/print.js'; import routerReports from './routes/reports.js'; import routerWorkOrders from './routes/workOrders.js'; import { version } from './version.js'; -const debug = Debug(`lot-occupancy-system:app:${process.pid}`); +const debug = Debug(`${DEBUG_NAMESPACE}:app:${process.pid}`); /* * INITIALIZE THE DATABASE */ -initializeDatabase(); +await initializeDatabase(); /* * INITIALIZE APP */ @@ -88,7 +89,7 @@ const FileStoreSession = FileStore(session); app.use(session({ store: new FileStoreSession({ path: './data/sessions', - logFn: Debug(`lot-occupancy-system:session:${process.pid}`), + logFn: Debug(`${DEBUG_NAMESPACE}:session:${process.pid}`), retries: 20 }), name: sessionCookieName, diff --git a/app.ts b/app.ts index c0a0b704..91831643 100644 --- a/app.ts +++ b/app.ts @@ -12,11 +12,12 @@ import createError from 'http-errors' import FileStore from 'session-file-store' import { useTestDatabases } from './data/databasePaths.js' +import { DEBUG_NAMESPACE } from './debug.config.js' import * as permissionHandlers from './handlers/permissions.js' import { getSafeRedirectURL } from './helpers/functions.authentication.js' -import * as configFunctions from './helpers/functions.config.js' +import * as configFunctions from './helpers/config.helpers.js' import * as printFunctions from './helpers/functions.print.js' -import { initializeDatabase } from './helpers/initializer.database.js' +import { initializeDatabase } from './helpers/helpers.database.js' import routerAdmin from './routes/admin.js' import routerApi from './routes/api.js' import routerDashboard from './routes/dashboard.js' @@ -29,13 +30,13 @@ import routerReports from './routes/reports.js' import routerWorkOrders from './routes/workOrders.js' import { version } from './version.js' -const debug = Debug(`lot-occupancy-system:app:${process.pid}`) +const debug = Debug(`${DEBUG_NAMESPACE}:app:${process.pid}`) /* * INITIALIZE THE DATABASE */ -initializeDatabase() +await initializeDatabase() /* * INITIALIZE APP @@ -150,7 +151,7 @@ app.use( session({ store: new FileStoreSession({ path: './data/sessions', - logFn: Debug(`lot-occupancy-system:session:${process.pid}`), + logFn: Debug(`${DEBUG_NAMESPACE}:session:${process.pid}`), retries: 20 }), name: sessionCookieName, @@ -227,11 +228,7 @@ app.get(`${urlPrefix}/`, sessionChecker, (_request, response) => { app.use(`${urlPrefix}/dashboard`, sessionChecker, routerDashboard) -app.use( - `${urlPrefix}/api/:apiKey`, - permissionHandlers.apiGetHandler, - routerApi -) +app.use(`${urlPrefix}/api/:apiKey`, permissionHandlers.apiGetHandler, routerApi) app.use(`${urlPrefix}/print`, sessionChecker, routerPrint) app.use(`${urlPrefix}/maps`, sessionChecker, routerMaps) diff --git a/bin/www.js b/bin/www.js index f2714086..7b84d712 100644 --- a/bin/www.js +++ b/bin/www.js @@ -6,8 +6,9 @@ import ntfyPublish from '@cityssm/ntfy-publish'; import { secondsToMillis } from '@cityssm/to-millis'; import Debug from 'debug'; import exitHook from 'exit-hook'; -import { getConfigProperty } from '../helpers/functions.config.js'; -const debug = Debug(`lot-occupancy-system:www:${process.pid}`); +import { DEBUG_NAMESPACE } from '../debug.config.js'; +import { getConfigProperty } from '../helpers/config.helpers.js'; +const debug = Debug(`${DEBUG_NAMESPACE}:www:${process.pid}`); const directoryName = path.dirname(fileURLToPath(import.meta.url)); const processCount = Math.min(getConfigProperty('application.maximumProcesses'), os.cpus().length); process.title = `${getConfigProperty('application.applicationName')} (Primary)`; diff --git a/bin/www.ts b/bin/www.ts index ea8752ee..ade1101f 100644 --- a/bin/www.ts +++ b/bin/www.ts @@ -8,10 +8,11 @@ import { secondsToMillis } from '@cityssm/to-millis' import Debug from 'debug' import exitHook from 'exit-hook' -import { getConfigProperty } from '../helpers/functions.config.js' +import { DEBUG_NAMESPACE } from '../debug.config.js' +import { getConfigProperty } from '../helpers/config.helpers.js' import type { WorkerMessage } from '../types/applicationTypes.js' -const debug = Debug(`lot-occupancy-system:www:${process.pid}`) +const debug = Debug(`${DEBUG_NAMESPACE}:www:${process.pid}`) const directoryName = path.dirname(fileURLToPath(import.meta.url)) diff --git a/bin/wwwProcess.js b/bin/wwwProcess.js index 51dd0c23..70fc4b88 100644 --- a/bin/wwwProcess.js +++ b/bin/wwwProcess.js @@ -4,8 +4,9 @@ import http from 'node:http'; import Debug from 'debug'; import exitHook from 'exit-hook'; import { app } from '../app.js'; -import { getConfigProperty } from '../helpers/functions.config.js'; -const debug = Debug(`lot-occupancy-system:wwwProcess:${process.pid}`); +import { DEBUG_NAMESPACE } from '../debug.config.js'; +import { getConfigProperty } from '../helpers/config.helpers.js'; +const debug = Debug(`${DEBUG_NAMESPACE}:wwwProcess:${process.pid}`); function onError(error) { if (error.syscall !== 'listen') { throw error; diff --git a/bin/wwwProcess.ts b/bin/wwwProcess.ts index 395f56a5..9bbb9111 100644 --- a/bin/wwwProcess.ts +++ b/bin/wwwProcess.ts @@ -7,9 +7,10 @@ import Debug from 'debug' import exitHook from 'exit-hook' import { app } from '../app.js' -import { getConfigProperty } from '../helpers/functions.config.js' +import { DEBUG_NAMESPACE } from '../debug.config.js' +import { getConfigProperty } from '../helpers/config.helpers.js' -const debug = Debug(`lot-occupancy-system:wwwProcess:${process.pid}`) +const debug = Debug(`${DEBUG_NAMESPACE}:wwwProcess:${process.pid}`) interface ServerError extends Error { syscall: string @@ -57,9 +58,7 @@ function onListening(server: http.Server): void { * Initialize HTTP */ -process.title = `${getConfigProperty( - 'application.applicationName' -)} (Worker)` +process.title = `${getConfigProperty('application.applicationName')} (Worker)` const httpPort = getConfigProperty('application.httpPort') diff --git a/cypress/e2e/01-admin/feeManagement.cy.js b/cypress/e2e/01-admin/feeManagement.cy.js index f3f0c111..1e16b986 100644 --- a/cypress/e2e/01-admin/feeManagement.cy.js +++ b/cypress/e2e/01-admin/feeManagement.cy.js @@ -1,4 +1,4 @@ -import { getConfigProperty } from '../../../helpers/functions.config.js'; +import { getConfigProperty } from '../../../helpers/config.helpers.js'; import { testAdmin } from '../../../test/_globals.js'; import { ajaxDelayMillis, login, logout } from '../../support/index.js'; describe('Admin - Fee Management', () => { diff --git a/cypress/e2e/01-admin/feeManagement.cy.ts b/cypress/e2e/01-admin/feeManagement.cy.ts index 21a193e8..b2ada34d 100644 --- a/cypress/e2e/01-admin/feeManagement.cy.ts +++ b/cypress/e2e/01-admin/feeManagement.cy.ts @@ -1,4 +1,4 @@ -import { getConfigProperty } from '../../../helpers/functions.config.js' +import { getConfigProperty } from '../../../helpers/config.helpers.js' import { testAdmin } from '../../../test/_globals.js' import type { Fee } from '../../../types/recordTypes.js' import { ajaxDelayMillis, login, logout } from '../../support/index.js' diff --git a/cypress/e2e/02-update/maps.cy.js b/cypress/e2e/02-update/maps.cy.js index ce90d3c8..f8c424d9 100644 --- a/cypress/e2e/02-update/maps.cy.js +++ b/cypress/e2e/02-update/maps.cy.js @@ -1,4 +1,4 @@ -import { getConfigProperty } from '../../../helpers/functions.config.js'; +import { getConfigProperty } from '../../../helpers/config.helpers.js'; import { testUpdate } from '../../../test/_globals.js'; import { login, logout } from '../../support/index.js'; describe('Update - Maps', () => { diff --git a/cypress/e2e/02-update/maps.cy.ts b/cypress/e2e/02-update/maps.cy.ts index c2c70129..903b1a35 100644 --- a/cypress/e2e/02-update/maps.cy.ts +++ b/cypress/e2e/02-update/maps.cy.ts @@ -1,4 +1,4 @@ -import { getConfigProperty } from '../../../helpers/functions.config.js' +import { getConfigProperty } from '../../../helpers/config.helpers.js' import { testUpdate } from '../../../test/_globals.js' import type { MapRecord } from '../../../types/recordTypes.js' import { login, logout } from '../../support/index.js' diff --git a/cypress/e2e/xx-other/keepAlive.cy.d.ts b/cypress/e2e/xx-other/keepAlive.cy.d.ts index e69de29b..cb0ff5c3 100644 --- a/cypress/e2e/xx-other/keepAlive.cy.d.ts +++ b/cypress/e2e/xx-other/keepAlive.cy.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/cypress/e2e/xx-other/keepAlive.cy.js b/cypress/e2e/xx-other/keepAlive.cy.js index 0741cb75..1ea89760 100644 --- a/cypress/e2e/xx-other/keepAlive.cy.js +++ b/cypress/e2e/xx-other/keepAlive.cy.js @@ -5,3 +5,4 @@ describe('Keep Alive', () => { }); }); }); +export {}; diff --git a/data/config.base.js b/data/config.base.js index c6098c58..ca7dc17c 100644 --- a/data/config.base.js +++ b/data/config.base.js @@ -6,9 +6,8 @@ export const config = { aliases: {}, settings: { fees: {}, - map: {}, - lot: {}, - lotOccupancy: {}, + cemeteries: {}, + contracts: {}, workOrders: {}, adminCleanup: {}, printPdf: {}, diff --git a/data/config.base.ts b/data/config.base.ts index f122f4c7..cc0a2f13 100644 --- a/data/config.base.ts +++ b/data/config.base.ts @@ -8,9 +8,8 @@ export const config: Config = { aliases: {}, settings: { fees: {}, - map: {}, - lot: {}, - lotOccupancy: {}, + cemeteries: {}, + contracts: {}, workOrders: {}, adminCleanup: {}, printPdf: {}, diff --git a/data/config.cemetery.ontario.d.ts b/data/config.baseOntario.d.ts similarity index 100% rename from data/config.cemetery.ontario.d.ts rename to data/config.baseOntario.d.ts diff --git a/data/config.baseOntario.js b/data/config.baseOntario.js new file mode 100644 index 00000000..a8498898 --- /dev/null +++ b/data/config.baseOntario.js @@ -0,0 +1,6 @@ +import { config as baseConfig } from './config.base.js'; +export const config = Object.assign({}, baseConfig); +config.settings.contracts.provinceDefault = 'ON'; +config.settings.cemeteries.provinceDefault = 'ON'; +config.settings.fees.taxPercentageDefault = 13; +export default config; diff --git a/data/config.baseOntario.ts b/data/config.baseOntario.ts new file mode 100644 index 00000000..ee30a862 --- /dev/null +++ b/data/config.baseOntario.ts @@ -0,0 +1,11 @@ +import { config as baseConfig } from './config.base.js' + +export const config = Object.assign({}, baseConfig) + +config.settings.contracts.provinceDefault = 'ON' + +config.settings.cemeteries.provinceDefault = 'ON' + +config.settings.fees.taxPercentageDefault = 13 + +export default config diff --git a/data/config.cemetery.d.ts b/data/config.baseSsm.d.ts similarity index 100% rename from data/config.cemetery.d.ts rename to data/config.baseSsm.d.ts diff --git a/data/config.baseSsm.js b/data/config.baseSsm.js new file mode 100644 index 00000000..f3350dd6 --- /dev/null +++ b/data/config.baseSsm.js @@ -0,0 +1,17 @@ +import { config as cemeteryConfig } from './config.baseOntario.js'; +export const config = { ...cemeteryConfig }; +config.aliases.externalReceiptNumber = 'GP Receipt Number'; +config.settings.contracts.cityDefault = 'Sault Ste. Marie'; +config.settings.contracts.prints = [ + 'pdf/ssm.cemetery.burialPermit', + 'pdf/ssm.cemetery.contract' +]; +config.settings.cemeteries.cityDefault = 'Sault Ste. Marie'; +config.settings.workOrders.workOrderNumberLength = 6; +config.settings.workOrders.workOrderMilestoneDateRecentBeforeDays = 7; +config.settings.workOrders.workOrderMilestoneDateRecentAfterDays = 30; +config.settings.dynamicsGP = { + integrationIsEnabled: true, + lookupOrder: ['diamond/cashReceipt', 'diamond/extendedInvoice'] +}; +export default config; diff --git a/data/config.baseSsm.ts b/data/config.baseSsm.ts new file mode 100644 index 00000000..4f269582 --- /dev/null +++ b/data/config.baseSsm.ts @@ -0,0 +1,26 @@ +import type { Config } from '../types/configTypes.js' + +import { config as cemeteryConfig } from './config.baseOntario.js' + +export const config: Config = { ...cemeteryConfig } + +config.aliases.externalReceiptNumber = 'GP Receipt Number' + +config.settings.contracts.cityDefault = 'Sault Ste. Marie' +config.settings.contracts.prints = [ + 'pdf/ssm.cemetery.burialPermit', + 'pdf/ssm.cemetery.contract' +] + +config.settings.cemeteries.cityDefault = 'Sault Ste. Marie' + +config.settings.workOrders.workOrderNumberLength = 6 +config.settings.workOrders.workOrderMilestoneDateRecentBeforeDays = 7 +config.settings.workOrders.workOrderMilestoneDateRecentAfterDays = 30 + +config.settings.dynamicsGP = { + integrationIsEnabled: true, + lookupOrder: ['diamond/cashReceipt', 'diamond/extendedInvoice'] +} + +export default config diff --git a/data/config.cemetery.js b/data/config.cemetery.js deleted file mode 100644 index 4111fbe6..00000000 --- a/data/config.cemetery.js +++ /dev/null @@ -1,19 +0,0 @@ -import { config as baseConfig } from './config.base.js'; -export const config = { ...baseConfig }; -config.application = { - applicationName: 'Cemetery Management System', - backgroundURL: '/images/cemetery-background.jpg', - logoURL: '/images/cemetery-logo.svg' -}; -config.aliases.lot = 'Burial Site'; -config.aliases.lots = 'Burial Sites'; -config.aliases.map = 'Cemetery'; -config.aliases.maps = 'Cemeteries'; -config.aliases.occupancy = 'Contract'; -config.aliases.occupancies = 'Contracts'; -config.aliases.occupant = 'Customer'; -config.aliases.occupants = 'Customers'; -config.aliases.workOrderOpenDate = 'Order Date'; -config.aliases.workOrderCloseDate = 'Completion Date'; -config.settings.lotOccupancy.occupancyEndDateIsRequired = false; -export default config; diff --git a/data/config.cemetery.ontario.js b/data/config.cemetery.ontario.js deleted file mode 100644 index b788099e..00000000 --- a/data/config.cemetery.ontario.js +++ /dev/null @@ -1,6 +0,0 @@ -import { config as cemeteryConfig } from './config.cemetery.js'; -export const config = Object.assign({}, cemeteryConfig); -config.settings.lotOccupancy.occupantProvinceDefault = 'ON'; -config.settings.map.mapProvinceDefault = 'ON'; -config.settings.fees.taxPercentageDefault = 13; -export default config; diff --git a/data/config.cemetery.ontario.ts b/data/config.cemetery.ontario.ts deleted file mode 100644 index 59d36276..00000000 --- a/data/config.cemetery.ontario.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { config as cemeteryConfig } from './config.cemetery.js' - -export const config = Object.assign({}, cemeteryConfig) - -config.settings.lotOccupancy.occupantProvinceDefault = 'ON' - -config.settings.map.mapProvinceDefault = 'ON' - -config.settings.fees.taxPercentageDefault = 13 - -export default config diff --git a/data/config.cemetery.ssm.d.ts b/data/config.cemetery.ssm.d.ts deleted file mode 100644 index f4b7dd5f..00000000 --- a/data/config.cemetery.ssm.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -import type { Config } from '../types/configTypes.js'; -export declare const config: Config; -export declare function lotNameSortNameFunction(lotName: string): string; -export default config; diff --git a/data/config.cemetery.ssm.js b/data/config.cemetery.ssm.js deleted file mode 100644 index e0fa7845..00000000 --- a/data/config.cemetery.ssm.js +++ /dev/null @@ -1,65 +0,0 @@ -import NodeCache from 'node-cache'; -import { config as cemeteryConfig } from './config.cemetery.ontario.js'; -export const config = { ...cemeteryConfig }; -config.aliases.occupancyStartDate = 'Purchase Date'; -config.aliases.externalReceiptNumber = 'GP Receipt Number'; -config.settings.lot.lotNamePattern = - /^[\dA-Z]{2}-(B[\dA-Z]+-)?(R[\dA-Z]+-)?(L[\dA-Z]+-)?G[\dA-Z]+(, Interment \d+)?$/; -config.settings.lot.lotNameHelpText = `Two digit cemetery-Block-Range-Lot-Grave, Interment number\n - ex. XX-BA-R41-L15-G3A, Interment 1`; -const numericPadding = '00000'; -const lotNameSortNameCache = new NodeCache({ - stdTTL: 5 * 60, - useClones: false -}); -export function lotNameSortNameFunction(lotName) { - let sortName = lotNameSortNameCache.get(lotName) ?? ''; - if (sortName === '') { - try { - const lotNameSplit = lotName.toUpperCase().split('-'); - const cleanLotNamePieces = []; - for (let lotNamePiece of lotNameSplit) { - if (cleanLotNamePieces.length === 0) { - cleanLotNamePieces.push(lotNamePiece); - continue; - } - let numericPiece = numericPadding; - let letterPiece = ''; - const firstLetter = lotNamePiece.charAt(0); - lotNamePiece = lotNamePiece.slice(1); - for (const letter of lotNamePiece) { - if (letterPiece === '' && '0123456789'.includes(letter)) { - numericPiece += letter; - } - else { - letterPiece += letter; - } - } - cleanLotNamePieces.push(firstLetter + - numericPiece.slice(-1 * numericPadding.length) + - letterPiece); - } - sortName = cleanLotNamePieces.join('-'); - } - catch { - sortName = lotName; - } - lotNameSortNameCache.set(lotName, sortName); - } - return sortName; -} -config.settings.lot.lotNameSortNameFunction = lotNameSortNameFunction; -config.settings.lotOccupancy.occupantCityDefault = 'Sault Ste. Marie'; -config.settings.lotOccupancy.prints = [ - 'pdf/ssm.cemetery.burialPermit', - 'pdf/ssm.cemetery.contract' -]; -config.settings.map.mapCityDefault = 'Sault Ste. Marie'; -config.settings.workOrders.workOrderNumberLength = 6; -config.settings.workOrders.workOrderMilestoneDateRecentBeforeDays = 7; -config.settings.workOrders.workOrderMilestoneDateRecentAfterDays = 30; -config.settings.dynamicsGP = { - integrationIsEnabled: true, - lookupOrder: ['diamond/cashReceipt', 'diamond/extendedInvoice'] -}; -export default config; diff --git a/data/config.cemetery.ssm.ts b/data/config.cemetery.ssm.ts deleted file mode 100644 index 63ef6cf4..00000000 --- a/data/config.cemetery.ssm.ts +++ /dev/null @@ -1,91 +0,0 @@ -import NodeCache from 'node-cache' - -import type { Config } from '../types/configTypes.js' - -import { config as cemeteryConfig } from './config.cemetery.ontario.js' - -export const config: Config = { ...cemeteryConfig} - -config.aliases.occupancyStartDate = 'Purchase Date' -config.aliases.externalReceiptNumber = 'GP Receipt Number' - -config.settings.lot.lotNamePattern = - /^[\dA-Z]{2}-(B[\dA-Z]+-)?(R[\dA-Z]+-)?(L[\dA-Z]+-)?G[\dA-Z]+(, Interment \d+)?$/ - -config.settings.lot.lotNameHelpText = `Two digit cemetery-Block-Range-Lot-Grave, Interment number\n - ex. XX-BA-R41-L15-G3A, Interment 1` - -const numericPadding = '00000' - -const lotNameSortNameCache = new NodeCache({ - stdTTL: 5 * 60, - useClones: false -}) - -export function lotNameSortNameFunction(lotName: string): string { - let sortName: string = lotNameSortNameCache.get(lotName) ?? '' - - if (sortName === '') { - try { - const lotNameSplit = lotName.toUpperCase().split('-') - - const cleanLotNamePieces: string[] = [] - - for (let lotNamePiece of lotNameSplit) { - if (cleanLotNamePieces.length === 0) { - cleanLotNamePieces.push(lotNamePiece) - continue - } - - let numericPiece = numericPadding - let letterPiece = '' - - const firstLetter = lotNamePiece.charAt(0) - lotNamePiece = lotNamePiece.slice(1) - - for (const letter of lotNamePiece) { - if (letterPiece === '' && '0123456789'.includes(letter)) { - numericPiece += letter - } else { - letterPiece += letter - } - } - - cleanLotNamePieces.push( - firstLetter + - numericPiece.slice(-1 * numericPadding.length) + - letterPiece - ) - } - - sortName = cleanLotNamePieces.join('-') - } catch { - sortName = lotName - } - - lotNameSortNameCache.set(lotName, sortName) - } - - return sortName -} - -config.settings.lot.lotNameSortNameFunction = lotNameSortNameFunction - -config.settings.lotOccupancy.occupantCityDefault = 'Sault Ste. Marie' -config.settings.lotOccupancy.prints = [ - 'pdf/ssm.cemetery.burialPermit', - 'pdf/ssm.cemetery.contract' -] - -config.settings.map.mapCityDefault = 'Sault Ste. Marie' - -config.settings.workOrders.workOrderNumberLength = 6 -config.settings.workOrders.workOrderMilestoneDateRecentBeforeDays = 7 -config.settings.workOrders.workOrderMilestoneDateRecentAfterDays = 30 - -config.settings.dynamicsGP = { - integrationIsEnabled: true, - lookupOrder: ['diamond/cashReceipt', 'diamond/extendedInvoice'] -} - -export default config diff --git a/data/config.cemetery.ts b/data/config.cemetery.ts deleted file mode 100644 index 024baaff..00000000 --- a/data/config.cemetery.ts +++ /dev/null @@ -1,26 +0,0 @@ -import type { Config } from '../types/configTypes.js' - -import { config as baseConfig } from './config.base.js' - -export const config: Config = { ...baseConfig } - -config.application = { - applicationName: 'Cemetery Management System', - backgroundURL: '/images/cemetery-background.jpg', - logoURL: '/images/cemetery-logo.svg' -} - -config.aliases.lot = 'Burial Site' -config.aliases.lots = 'Burial Sites' -config.aliases.map = 'Cemetery' -config.aliases.maps = 'Cemeteries' -config.aliases.occupancy = 'Contract' -config.aliases.occupancies = 'Contracts' -config.aliases.occupant = 'Customer' -config.aliases.occupants = 'Customers' -config.aliases.workOrderOpenDate = 'Order Date' -config.aliases.workOrderCloseDate = 'Completion Date' - -config.settings.lotOccupancy.occupancyEndDateIsRequired = false - -export default config diff --git a/data/config.defaultValues.d.ts b/data/config.defaultValues.d.ts index 03982e18..df329499 100644 --- a/data/config.defaultValues.d.ts +++ b/data/config.defaultValues.d.ts @@ -21,15 +21,6 @@ export declare const configDefaultValues: { 'users.canLogin': string[]; 'users.canUpdate': string[]; 'users.isAdmin': string[]; - 'aliases.lot': string; - 'aliases.lots': string; - 'aliases.map': string; - 'aliases.maps': string; - 'aliases.occupancy': string; - 'aliases.occupancies': string; - 'aliases.occupancyStartDate': string; - 'aliases.occupant': string; - 'aliases.occupants': string; 'aliases.externalReceiptNumber': string; 'aliases.workOrderOpenDate': string; 'aliases.workOrderCloseDate': string; diff --git a/data/config.defaultValues.js b/data/config.defaultValues.js index 889a9599..1ab54e3d 100644 --- a/data/config.defaultValues.js +++ b/data/config.defaultValues.js @@ -1,7 +1,7 @@ import { hoursToMillis } from '@cityssm/to-millis'; export const configDefaultValues = { activeDirectory: undefined, - 'application.applicationName': 'Lot Occupancy System', + 'application.applicationName': 'Sunrise CMS', 'application.backgroundURL': '/images/cemetery-background.jpg', 'application.logoURL': '/images/cemetery-logo.png', 'application.httpPort': 7000, @@ -12,26 +12,17 @@ export const configDefaultValues = { 'reverseProxy.disableCompression': false, 'reverseProxy.disableEtag': false, 'reverseProxy.urlPrefix': '', - 'session.cookieName': 'lot-occupancy-system-user-sid', - 'session.secret': 'cityssm/lot-occupancy-system', + 'session.cookieName': 'sunrise-user-sid', + 'session.secret': 'cityssm/sunrise', 'session.maxAgeMillis': hoursToMillis(1), 'session.doKeepAlive': false, 'users.testing': [], 'users.canLogin': ['administrator'], 'users.canUpdate': [], 'users.isAdmin': ['administrator'], - 'aliases.lot': 'Lot', - 'aliases.lots': 'Lots', - 'aliases.map': 'Map', - 'aliases.maps': 'Maps', - 'aliases.occupancy': 'Occupancy', - 'aliases.occupancies': 'Occupancies', - 'aliases.occupancyStartDate': 'Start Date', - 'aliases.occupant': 'Occupant', - 'aliases.occupants': 'Occupants', 'aliases.externalReceiptNumber': 'External Receipt Number', - 'aliases.workOrderOpenDate': 'Open Date', - 'aliases.workOrderCloseDate': 'Close Date', + 'aliases.workOrderOpenDate': 'Order Date', + 'aliases.workOrderCloseDate': 'Completion Date', 'settings.map.mapCityDefault': '', 'settings.map.mapProvinceDefault': '', 'settings.lot.lotNamePattern': undefined, diff --git a/data/config.defaultValues.ts b/data/config.defaultValues.ts index 8b34ff96..ebeb330d 100644 --- a/data/config.defaultValues.ts +++ b/data/config.defaultValues.ts @@ -10,7 +10,7 @@ import type { export const configDefaultValues = { activeDirectory: undefined as unknown as ConfigActiveDirectory, - 'application.applicationName': 'Lot Occupancy System', + 'application.applicationName': 'Sunrise CMS', 'application.backgroundURL': '/images/cemetery-background.jpg', 'application.logoURL': '/images/cemetery-logo.png', 'application.httpPort': 7000, @@ -24,8 +24,8 @@ export const configDefaultValues = { 'reverseProxy.disableEtag': false, 'reverseProxy.urlPrefix': '', - 'session.cookieName': 'lot-occupancy-system-user-sid', - 'session.secret': 'cityssm/lot-occupancy-system', + 'session.cookieName': 'sunrise-user-sid', + 'session.secret': 'cityssm/sunrise', 'session.maxAgeMillis': hoursToMillis(1), 'session.doKeepAlive': false, @@ -34,19 +34,9 @@ export const configDefaultValues = { 'users.canUpdate': [] as string[], 'users.isAdmin': ['administrator'], - 'aliases.lot': 'Lot', - 'aliases.lots': 'Lots', - 'aliases.map': 'Map', - 'aliases.maps': 'Maps', - 'aliases.occupancy': 'Occupancy', - 'aliases.occupancies': 'Occupancies', - 'aliases.occupancyStartDate': 'Start Date', - 'aliases.occupant': 'Occupant', - 'aliases.occupants': 'Occupants', - 'aliases.externalReceiptNumber': 'External Receipt Number', - 'aliases.workOrderOpenDate': 'Open Date', - 'aliases.workOrderCloseDate': 'Close Date', + 'aliases.workOrderOpenDate': 'Order Date', + 'aliases.workOrderCloseDate': 'Completion Date', 'settings.map.mapCityDefault': '', 'settings.map.mapProvinceDefault': '', diff --git a/data/config.testing.js b/data/config.testing.js index d7923bd7..58ea5d30 100644 --- a/data/config.testing.js +++ b/data/config.testing.js @@ -1,4 +1,4 @@ -import { config as cemeteryConfig } from './config.cemetery.ssm.js'; +import { config as cemeteryConfig } from './config.baseSsm.js'; export const config = { ...cemeteryConfig }; config.application.useTestDatabases = true; config.session.doKeepAlive = true; diff --git a/data/config.testing.ts b/data/config.testing.ts index 7e908edd..330e0a03 100644 --- a/data/config.testing.ts +++ b/data/config.testing.ts @@ -1,6 +1,6 @@ import type { Config } from '../types/configTypes.js' -import { config as cemeteryConfig } from './config.cemetery.ssm.js' +import { config as cemeteryConfig } from './config.baseSsm.js' export const config: Config = { ...cemeteryConfig } diff --git a/data/databasePaths.d.ts b/data/databasePaths.d.ts deleted file mode 100644 index 2b563041..00000000 --- a/data/databasePaths.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -export declare const useTestDatabases: boolean; -export declare const lotOccupancyDBLive = "data/lotOccupancy.db"; -export declare const lotOccupancyDBTesting = "data/lotOccupancy-testing.db"; -export declare const lotOccupancyDB: string; -export declare const backupFolder = "data/backups"; diff --git a/data/databasePaths.js b/data/databasePaths.js deleted file mode 100644 index c3ef2a1c..00000000 --- a/data/databasePaths.js +++ /dev/null @@ -1,15 +0,0 @@ -import Debug from 'debug'; -import { getConfigProperty } from '../helpers/functions.config.js'; -const debug = Debug('lot-occupancy-system:databasePaths'); -// Determine if test databases should be used -export const useTestDatabases = getConfigProperty('application.useTestDatabases') || - process.env.TEST_DATABASES === 'true'; -if (useTestDatabases) { - debug('Using "-testing" databases.'); -} -export const lotOccupancyDBLive = 'data/lotOccupancy.db'; -export const lotOccupancyDBTesting = 'data/lotOccupancy-testing.db'; -export const lotOccupancyDB = useTestDatabases - ? lotOccupancyDBTesting - : lotOccupancyDBLive; -export const backupFolder = 'data/backups'; diff --git a/data/databasePaths.ts b/data/databasePaths.ts deleted file mode 100644 index 093de9a8..00000000 --- a/data/databasePaths.ts +++ /dev/null @@ -1,24 +0,0 @@ -import Debug from 'debug' - -import { getConfigProperty } from '../helpers/functions.config.js' - -const debug = Debug('lot-occupancy-system:databasePaths') - -// Determine if test databases should be used - -export const useTestDatabases = - getConfigProperty('application.useTestDatabases') || - process.env.TEST_DATABASES === 'true' - -if (useTestDatabases) { - debug('Using "-testing" databases.') -} - -export const lotOccupancyDBLive = 'data/lotOccupancy.db' -export const lotOccupancyDBTesting = 'data/lotOccupancy-testing.db' - -export const lotOccupancyDB = useTestDatabases - ? lotOccupancyDBTesting - : lotOccupancyDBLive - -export const backupFolder = 'data/backups' diff --git a/database/addLot.d.ts b/database/addBurialSite.d.ts similarity index 100% rename from database/addLot.d.ts rename to database/addBurialSite.d.ts diff --git a/database/addLot.js b/database/addBurialSite.js similarity index 100% rename from database/addLot.js rename to database/addBurialSite.js diff --git a/database/addLot.ts b/database/addBurialSite.ts similarity index 100% rename from database/addLot.ts rename to database/addBurialSite.ts diff --git a/database/addBurialSiteComment.d.ts b/database/addBurialSiteComment.d.ts new file mode 100644 index 00000000..0324c67e --- /dev/null +++ b/database/addBurialSiteComment.d.ts @@ -0,0 +1,5 @@ +export interface AddBurialSiteCommentForm { + burialSiteId: string; + comment: string; +} +export default function addBurialSiteComment(commentForm: AddBurialSiteCommentForm, user: User): Promise; diff --git a/database/addLotComment.js b/database/addBurialSiteComment.js similarity index 54% rename from database/addLotComment.js rename to database/addBurialSiteComment.js index 078d8849..808d0a5a 100644 --- a/database/addLotComment.js +++ b/database/addBurialSiteComment.js @@ -1,16 +1,16 @@ import { dateToInteger, dateToTimeInteger } from '@cityssm/utils-datetime'; import { acquireConnection } from './pool.js'; -export default async function addLotComment(lotCommentForm, user) { +export default async function addBurialSiteComment(commentForm, user) { const database = await acquireConnection(); const rightNow = new Date(); const result = database - .prepare(`insert into LotComments ( - lotId, - lotCommentDate, lotCommentTime, lotComment, + .prepare(`insert into BurialSiteComments ( + burialSiteId, + commentDate, commentTime, comment, recordCreate_userName, recordCreate_timeMillis, recordUpdate_userName, recordUpdate_timeMillis) values (?, ?, ?, ?, ?, ?, ?, ?)`) - .run(lotCommentForm.lotId, dateToInteger(rightNow), dateToTimeInteger(rightNow), lotCommentForm.lotComment, user.userName, rightNow.getTime(), user.userName, rightNow.getTime()); + .run(commentForm.burialSiteId, dateToInteger(rightNow), dateToTimeInteger(rightNow), commentForm.comment, user.userName, rightNow.getTime(), user.userName, rightNow.getTime()); database.release(); return result.lastInsertRowid; } diff --git a/database/addLotComment.ts b/database/addBurialSiteComment.ts similarity index 66% rename from database/addLotComment.ts rename to database/addBurialSiteComment.ts index b55ceb11..aa54cc35 100644 --- a/database/addLotComment.ts +++ b/database/addBurialSiteComment.ts @@ -2,13 +2,13 @@ import { dateToInteger, dateToTimeInteger } from '@cityssm/utils-datetime' import { acquireConnection } from './pool.js' -export interface AddLotCommentForm { - lotId: string - lotComment: string +export interface AddBurialSiteCommentForm { + burialSiteId: string + comment: string } -export default async function addLotComment( - lotCommentForm: AddLotCommentForm, +export default async function addBurialSiteComment( + commentForm: AddBurialSiteCommentForm, user: User ): Promise { const database = await acquireConnection() @@ -17,18 +17,18 @@ export default async function addLotComment( const result = database .prepare( - `insert into LotComments ( - lotId, - lotCommentDate, lotCommentTime, lotComment, + `insert into BurialSiteComments ( + burialSiteId, + commentDate, commentTime, comment, recordCreate_userName, recordCreate_timeMillis, recordUpdate_userName, recordUpdate_timeMillis) values (?, ?, ?, ?, ?, ?, ?, ?)` ) .run( - lotCommentForm.lotId, + commentForm.burialSiteId, dateToInteger(rightNow), dateToTimeInteger(rightNow), - lotCommentForm.lotComment, + commentForm.comment, user.userName, rightNow.getTime(), user.userName, diff --git a/database/addBurialSiteContractComment.d.ts b/database/addBurialSiteContractComment.d.ts new file mode 100644 index 00000000..b48ab570 --- /dev/null +++ b/database/addBurialSiteContractComment.d.ts @@ -0,0 +1,8 @@ +import { type DateString, type TimeString } from '@cityssm/utils-datetime'; +export interface AddBurialSiteContractCommentForm { + burialSiteContractId: string | number; + commentDateString?: DateString; + commentTimeString?: TimeString; + comment: string; +} +export default function addLotOccupancyComment(commentForm: AddBurialSiteContractCommentForm, user: User): Promise; diff --git a/database/addBurialSiteContractComment.js b/database/addBurialSiteContractComment.js new file mode 100644 index 00000000..2a0a133a --- /dev/null +++ b/database/addBurialSiteContractComment.js @@ -0,0 +1,27 @@ +import { dateStringToInteger, dateToInteger, dateToTimeInteger, timeStringToInteger } from '@cityssm/utils-datetime'; +import { acquireConnection } from './pool.js'; +export default async function addLotOccupancyComment(commentForm, user) { + const rightNow = new Date(); + let commentDate = 0; + let commentTime = 0; + if (commentForm.commentDateString === undefined) { + commentDate = dateToInteger(rightNow); + commentTime = dateToTimeInteger(rightNow); + } + else { + commentDate = dateStringToInteger(commentForm.commentDateString); + commentTime = timeStringToInteger(commentForm.commentTimeString); + } + const database = await acquireConnection(); + const result = database + .prepare(`insert into BurialSiteContactComments ( + burialSiteContractId, + commentDate, commentTime, + comment, + recordCreate_userName, recordCreate_timeMillis, + recordUpdate_userName, recordUpdate_timeMillis) + values (?, ?, ?, ?, ?, ?, ?, ?)`) + .run(commentForm.burialSiteContractId, commentDate, commentTime ?? 0, commentForm.comment, user.userName, rightNow.getTime(), user.userName, rightNow.getTime()); + database.release(); + return result.lastInsertRowid; +} diff --git a/database/addBurialSiteContractComment.ts b/database/addBurialSiteContractComment.ts new file mode 100644 index 00000000..19ede41c --- /dev/null +++ b/database/addBurialSiteContractComment.ts @@ -0,0 +1,66 @@ +import { + type DateString, + type TimeString, + dateStringToInteger, + dateToInteger, + dateToTimeInteger, + timeStringToInteger +} from '@cityssm/utils-datetime' + +import { acquireConnection } from './pool.js' + +export interface AddBurialSiteContractCommentForm { + burialSiteContractId: string | number + commentDateString?: DateString + commentTimeString?: TimeString + comment: string +} + +export default async function addLotOccupancyComment( + commentForm: AddBurialSiteContractCommentForm, + user: User +): Promise { + const rightNow = new Date() + + let commentDate = 0 + let commentTime: number | undefined = 0 + + if (commentForm.commentDateString === undefined) { + commentDate = dateToInteger(rightNow) + commentTime = dateToTimeInteger(rightNow) + } else { + commentDate = dateStringToInteger( + commentForm.commentDateString as DateString + ) + commentTime = timeStringToInteger( + commentForm.commentTimeString as TimeString + ) + } + + const database = await acquireConnection() + + const result = database + .prepare( + `insert into BurialSiteContactComments ( + burialSiteContractId, + commentDate, commentTime, + comment, + recordCreate_userName, recordCreate_timeMillis, + recordUpdate_userName, recordUpdate_timeMillis) + values (?, ?, ?, ?, ?, ?, ?, ?)` + ) + .run( + commentForm.burialSiteContractId, + commentDate, + commentTime ?? 0, + commentForm.comment, + user.userName, + rightNow.getTime(), + user.userName, + rightNow.getTime() + ) + + database.release() + + return result.lastInsertRowid as number +} diff --git a/database/addBurialSiteTypeField.d.ts b/database/addBurialSiteTypeField.d.ts new file mode 100644 index 00000000..682b1531 --- /dev/null +++ b/database/addBurialSiteTypeField.d.ts @@ -0,0 +1,12 @@ +export interface AddBurialSiteTypeFieldForm { + burialSiteTypeId: string | number; + burialSiteTypeField: string; + fieldType?: string; + fieldValues?: string; + isRequired?: string; + pattern?: string; + minimumLength?: string | number; + maximumLength?: string | number; + orderNumber?: number; +} +export default function addBurialSiteTypeField(addForm: AddBurialSiteTypeFieldForm, user: User): Promise; diff --git a/database/addBurialSiteTypeField.js b/database/addBurialSiteTypeField.js new file mode 100644 index 00000000..66b3f6cb --- /dev/null +++ b/database/addBurialSiteTypeField.js @@ -0,0 +1,20 @@ +import { clearCacheByTableName } from '../helpers/functions.cache.js'; +import { acquireConnection } from './pool.js'; +export default async function addBurialSiteTypeField(addForm, user) { + const database = await acquireConnection(); + const rightNowMillis = Date.now(); + const result = database + .prepare(`insert into BurialSiteTypeFields ( + burialSiteTypeId, burialSiteTypeField, + fieldType, fieldValues, + isRequired, pattern, + minimumLength, maximumLength, + orderNumber, + recordCreate_userName, recordCreate_timeMillis, + recordUpdate_userName, recordUpdate_timeMillis) + values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`) + .run(addForm.burialSiteTypeId, addForm.burialSiteTypeField, addForm.fieldType ?? 'text', addForm.fieldValues ?? '', addForm.isRequired === '' ? 0 : 1, addForm.pattern ?? '', addForm.minimumLength ?? 0, addForm.maximumLength ?? 100, addForm.orderNumber ?? -1, user.userName, rightNowMillis, user.userName, rightNowMillis); + database.release(); + clearCacheByTableName('BurialSiteTypeFields'); + return result.lastInsertRowid; +} diff --git a/database/addLotTypeField.ts b/database/addBurialSiteTypeField.ts similarity index 54% rename from database/addLotTypeField.ts rename to database/addBurialSiteTypeField.ts index d6926c9f..730ebfd0 100644 --- a/database/addLotTypeField.ts +++ b/database/addBurialSiteTypeField.ts @@ -2,11 +2,11 @@ import { clearCacheByTableName } from '../helpers/functions.cache.js' import { acquireConnection } from './pool.js' -export interface AddLotTypeFieldForm { - lotTypeId: string | number - lotTypeField: string +export interface AddBurialSiteTypeFieldForm { + burialSiteTypeId: string | number + burialSiteTypeField: string fieldType?: string - lotTypeFieldValues?: string + fieldValues?: string isRequired?: string pattern?: string minimumLength?: string | number @@ -14,8 +14,8 @@ export interface AddLotTypeFieldForm { orderNumber?: number } -export default async function addLotTypeField( - lotTypeFieldForm: AddLotTypeFieldForm, +export default async function addBurialSiteTypeField( + addForm: AddBurialSiteTypeFieldForm, user: User ): Promise { const database = await acquireConnection() @@ -24,8 +24,9 @@ export default async function addLotTypeField( const result = database .prepare( - `insert into LotTypeFields ( - lotTypeId, lotTypeField, fieldType, lotTypeFieldValues, + `insert into BurialSiteTypeFields ( + burialSiteTypeId, burialSiteTypeField, + fieldType, fieldValues, isRequired, pattern, minimumLength, maximumLength, orderNumber, @@ -34,15 +35,15 @@ export default async function addLotTypeField( values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)` ) .run( - lotTypeFieldForm.lotTypeId, - lotTypeFieldForm.lotTypeField, - lotTypeFieldForm.fieldType ?? 'text', - lotTypeFieldForm.lotTypeFieldValues ?? '', - lotTypeFieldForm.isRequired === '' ? 0 : 1, - lotTypeFieldForm.pattern ?? '', - lotTypeFieldForm.minimumLength ?? 0, - lotTypeFieldForm.maximumLength ?? 100, - lotTypeFieldForm.orderNumber ?? -1, + addForm.burialSiteTypeId, + addForm.burialSiteTypeField, + addForm.fieldType ?? 'text', + addForm.fieldValues ?? '', + addForm.isRequired === '' ? 0 : 1, + addForm.pattern ?? '', + addForm.minimumLength ?? 0, + addForm.maximumLength ?? 100, + addForm.orderNumber ?? -1, user.userName, rightNowMillis, user.userName, @@ -51,7 +52,7 @@ export default async function addLotTypeField( database.release() - clearCacheByTableName('LotTypeFields') + clearCacheByTableName('BurialSiteTypeFields') return result.lastInsertRowid as number } diff --git a/database/addCemetery.d.ts b/database/addCemetery.d.ts new file mode 100644 index 00000000..50178e6c --- /dev/null +++ b/database/addCemetery.d.ts @@ -0,0 +1,14 @@ +export interface AddCemeteryForm { + cemeteryName: string; + cemeteryDescription: string; + cemeterySvg: string; + cemeteryLatitude: string; + cemeteryLongitude: string; + cemeteryAddress1: string; + cemeteryAddress2: string; + cemeteryCity: string; + cemeteryProvince: string; + cemeteryPostalCode: string; + cemeteryPhoneNumber: string; +} +export default function addCemetery(addForm: AddCemeteryForm, user: User): Promise; diff --git a/database/addCemetery.js b/database/addCemetery.js new file mode 100644 index 00000000..93ab4baa --- /dev/null +++ b/database/addCemetery.js @@ -0,0 +1,18 @@ +import { acquireConnection } from './pool.js'; +export default async function addCemetery(addForm, user) { + const database = await acquireConnection(); + const rightNowMillis = Date.now(); + const result = database + .prepare(`insert into Cemeteries ( + cemeteryName, cemeteryDescription, + cemeterySvg, cemeteryLatitude, cemeteryLongitude, + cemeteryAddress1, cemeteryAddress2, + cemeteryCity, cemeteryProvince, cemeteryPostalCode, + cemeteryPhoneNumber, + recordCreate_userName, recordCreate_timeMillis, + recordUpdate_userName, recordUpdate_timeMillis) + values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`) + .run(addForm.cemeteryName, addForm.cemeteryDescription, addForm.cemeterySvg, addForm.cemeteryLatitude === '' ? undefined : addForm.cemeteryLatitude, addForm.cemeteryLongitude === '' ? undefined : addForm.cemeteryLongitude, addForm.cemeteryAddress1, addForm.cemeteryAddress2, addForm.cemeteryCity, addForm.cemeteryProvince, addForm.cemeteryPostalCode, addForm.cemeteryPhoneNumber, user.userName, rightNowMillis, user.userName, rightNowMillis); + database.release(); + return result.lastInsertRowid; +} diff --git a/database/addCemetery.ts b/database/addCemetery.ts new file mode 100644 index 00000000..8d17271a --- /dev/null +++ b/database/addCemetery.ts @@ -0,0 +1,60 @@ +import { acquireConnection } from './pool.js' + +export interface AddCemeteryForm { + cemeteryName: string + cemeteryDescription: string + + cemeterySvg: string + cemeteryLatitude: string + cemeteryLongitude: string + + cemeteryAddress1: string + cemeteryAddress2: string + cemeteryCity: string + cemeteryProvince: string + cemeteryPostalCode: string + cemeteryPhoneNumber: string +} + +export default async function addCemetery( + addForm: AddCemeteryForm, + user: User +): Promise { + const database = await acquireConnection() + + const rightNowMillis = Date.now() + + const result = database + .prepare( + `insert into Cemeteries ( + cemeteryName, cemeteryDescription, + cemeterySvg, cemeteryLatitude, cemeteryLongitude, + cemeteryAddress1, cemeteryAddress2, + cemeteryCity, cemeteryProvince, cemeteryPostalCode, + cemeteryPhoneNumber, + recordCreate_userName, recordCreate_timeMillis, + recordUpdate_userName, recordUpdate_timeMillis) + values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)` + ) + .run( + addForm.cemeteryName, + addForm.cemeteryDescription, + addForm.cemeterySvg, + addForm.cemeteryLatitude === '' ? undefined : addForm.cemeteryLatitude, + addForm.cemeteryLongitude === '' ? undefined : addForm.cemeteryLongitude, + addForm.cemeteryAddress1, + addForm.cemeteryAddress2, + addForm.cemeteryCity, + addForm.cemeteryProvince, + addForm.cemeteryPostalCode, + addForm.cemeteryPhoneNumber, + user.userName, + rightNowMillis, + user.userName, + rightNowMillis + ) + + database.release() + + return result.lastInsertRowid as number +} diff --git a/database/addContractTypeField.d.ts b/database/addContractTypeField.d.ts new file mode 100644 index 00000000..1597c31c --- /dev/null +++ b/database/addContractTypeField.d.ts @@ -0,0 +1,12 @@ +export interface AddContractTypeFieldForm { + contractTypeId?: string | number; + contractTypeField: string; + fieldValues?: string; + fieldType?: string; + isRequired?: string; + pattern?: string; + minimumLength?: string | number; + maximumLength?: string | number; + orderNumber?: number; +} +export default function addContractTypeField(addForm: AddContractTypeFieldForm, user: User): Promise; diff --git a/database/addContractTypeField.js b/database/addContractTypeField.js new file mode 100644 index 00000000..525fd210 --- /dev/null +++ b/database/addContractTypeField.js @@ -0,0 +1,19 @@ +import { clearCacheByTableName } from '../helpers/functions.cache.js'; +import { acquireConnection } from './pool.js'; +export default async function addContractTypeField(addForm, user) { + const database = await acquireConnection(); + const rightNowMillis = Date.now(); + const result = database + .prepare(`insert into ContractTypeFields ( + contractTypeId, contractTypeField, fieldType, + fieldValues, isRequired, pattern, + minimumLength, maximumLength, + orderNumber, + recordCreate_userName, recordCreate_timeMillis, + recordUpdate_userName, recordUpdate_timeMillis) + values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`) + .run(addForm.contractTypeId ?? undefined, addForm.contractTypeField, addForm.fieldType ?? 'text', addForm.fieldValues ?? '', addForm.isRequired === '' ? 0 : 1, addForm.pattern ?? '', addForm.minimumLength ?? 0, addForm.maximumLength ?? 100, addForm.orderNumber ?? -1, user.userName, rightNowMillis, user.userName, rightNowMillis); + database.release(); + clearCacheByTableName('OccupancyTypeFields'); + return result.lastInsertRowid; +} diff --git a/database/addOccupancyTypeField.ts b/database/addContractTypeField.ts similarity index 50% rename from database/addOccupancyTypeField.ts rename to database/addContractTypeField.ts index c46e009c..eefc7a94 100644 --- a/database/addOccupancyTypeField.ts +++ b/database/addContractTypeField.ts @@ -2,10 +2,10 @@ import { clearCacheByTableName } from '../helpers/functions.cache.js' import { acquireConnection } from './pool.js' -export interface AddOccupancyTypeFieldForm { - occupancyTypeId?: string | number - occupancyTypeField: string - occupancyTypeFieldValues?: string +export interface AddContractTypeFieldForm { + contractTypeId?: string | number + contractTypeField: string + fieldValues?: string fieldType?: string isRequired?: string pattern?: string @@ -14,8 +14,8 @@ export interface AddOccupancyTypeFieldForm { orderNumber?: number } -export default async function addOccupancyTypeField( - occupancyTypeFieldForm: AddOccupancyTypeFieldForm, +export default async function addContractTypeField( + addForm: AddContractTypeFieldForm, user: User ): Promise { const database = await acquireConnection() @@ -24,9 +24,9 @@ export default async function addOccupancyTypeField( const result = database .prepare( - `insert into OccupancyTypeFields ( - occupancyTypeId, occupancyTypeField, fieldType, - occupancyTypeFieldValues, isRequired, pattern, + `insert into ContractTypeFields ( + contractTypeId, contractTypeField, fieldType, + fieldValues, isRequired, pattern, minimumLength, maximumLength, orderNumber, recordCreate_userName, recordCreate_timeMillis, @@ -34,15 +34,15 @@ export default async function addOccupancyTypeField( values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)` ) .run( - occupancyTypeFieldForm.occupancyTypeId ?? undefined, - occupancyTypeFieldForm.occupancyTypeField, - occupancyTypeFieldForm.fieldType ?? 'text', - occupancyTypeFieldForm.occupancyTypeFieldValues ?? '', - occupancyTypeFieldForm.isRequired === '' ? 0 : 1, - occupancyTypeFieldForm.pattern ?? '', - occupancyTypeFieldForm.minimumLength ?? 0, - occupancyTypeFieldForm.maximumLength ?? 100, - occupancyTypeFieldForm.orderNumber ?? -1, + addForm.contractTypeId ?? undefined, + addForm.contractTypeField, + addForm.fieldType ?? 'text', + addForm.fieldValues ?? '', + addForm.isRequired === '' ? 0 : 1, + addForm.pattern ?? '', + addForm.minimumLength ?? 0, + addForm.maximumLength ?? 100, + addForm.orderNumber ?? -1, user.userName, rightNowMillis, user.userName, diff --git a/database/addContractTypePrint.d.ts b/database/addContractTypePrint.d.ts new file mode 100644 index 00000000..e399846b --- /dev/null +++ b/database/addContractTypePrint.d.ts @@ -0,0 +1,6 @@ +export interface AddContractTypePrintForm { + contractTypeId: string | number; + printEJS: string; + orderNumber?: number; +} +export default function addContractTypePrint(addForm: AddContractTypePrintForm, user: User): Promise; diff --git a/database/addOccupancyTypePrint.js b/database/addContractTypePrint.js similarity index 52% rename from database/addOccupancyTypePrint.js rename to database/addContractTypePrint.js index 21acd5cf..cb2314d4 100644 --- a/database/addOccupancyTypePrint.js +++ b/database/addContractTypePrint.js @@ -1,27 +1,27 @@ import { clearCacheByTableName } from '../helpers/functions.cache.js'; import { acquireConnection } from './pool.js'; -export default async function addOccupancyTypePrint(occupancyTypePrintForm, user) { +export default async function addContractTypePrint(addForm, user) { const database = await acquireConnection(); const rightNowMillis = Date.now(); let result = database - .prepare(`update OccupancyTypePrints + .prepare(`update ContractTypePrints set recordUpdate_userName = ?, recordUpdate_timeMillis = ?, recordDelete_userName = null, recordDelete_timeMillis = null - where occupancyTypeId = ? + where contractTypeId = ? and printEJS = ?`) - .run(user.userName, rightNowMillis, occupancyTypePrintForm.occupancyTypeId, occupancyTypePrintForm.printEJS); + .run(user.userName, rightNowMillis, addForm.contractTypeId, addForm.printEJS); if (result.changes === 0) { result = database - .prepare(`insert into OccupancyTypePrints ( - occupancyTypeId, printEJS, orderNumber, + .prepare(`insert into ContractTypePrints ( + contractTypeId, printEJS, orderNumber, recordCreate_userName, recordCreate_timeMillis, recordUpdate_userName, recordUpdate_timeMillis) values (?, ?, ?, ?, ?, ?, ?)`) - .run(occupancyTypePrintForm.occupancyTypeId, occupancyTypePrintForm.printEJS, occupancyTypePrintForm.orderNumber ?? -1, user.userName, rightNowMillis, user.userName, rightNowMillis); + .run(addForm.contractTypeId, addForm.printEJS, addForm.orderNumber ?? -1, user.userName, rightNowMillis, user.userName, rightNowMillis); } database.release(); - clearCacheByTableName('OccupancyTypePrints'); + clearCacheByTableName('ContractTypePrints'); return result.changes > 0; } diff --git a/database/addOccupancyTypePrint.ts b/database/addContractTypePrint.ts similarity index 61% rename from database/addOccupancyTypePrint.ts rename to database/addContractTypePrint.ts index 72a72ef1..d978c529 100644 --- a/database/addOccupancyTypePrint.ts +++ b/database/addContractTypePrint.ts @@ -2,14 +2,14 @@ import { clearCacheByTableName } from '../helpers/functions.cache.js' import { acquireConnection } from './pool.js' -export interface AddOccupancyTypePrintForm { - occupancyTypeId: string | number +export interface AddContractTypePrintForm { + contractTypeId: string | number printEJS: string orderNumber?: number } -export default async function addOccupancyTypePrint( - occupancyTypePrintForm: AddOccupancyTypePrintForm, +export default async function addContractTypePrint( + addForm: AddContractTypePrintForm, user: User ): Promise { const database = await acquireConnection() @@ -18,34 +18,34 @@ export default async function addOccupancyTypePrint( let result = database .prepare( - `update OccupancyTypePrints + `update ContractTypePrints set recordUpdate_userName = ?, recordUpdate_timeMillis = ?, recordDelete_userName = null, recordDelete_timeMillis = null - where occupancyTypeId = ? + where contractTypeId = ? and printEJS = ?` ) .run( user.userName, rightNowMillis, - occupancyTypePrintForm.occupancyTypeId, - occupancyTypePrintForm.printEJS + addForm.contractTypeId, + addForm.printEJS ) if (result.changes === 0) { result = database .prepare( - `insert into OccupancyTypePrints ( - occupancyTypeId, printEJS, orderNumber, + `insert into ContractTypePrints ( + contractTypeId, printEJS, orderNumber, recordCreate_userName, recordCreate_timeMillis, recordUpdate_userName, recordUpdate_timeMillis) values (?, ?, ?, ?, ?, ?, ?)` ) .run( - occupancyTypePrintForm.occupancyTypeId, - occupancyTypePrintForm.printEJS, - occupancyTypePrintForm.orderNumber ?? -1, + addForm.contractTypeId, + addForm.printEJS, + addForm.orderNumber ?? -1, user.userName, rightNowMillis, user.userName, @@ -55,7 +55,7 @@ export default async function addOccupancyTypePrint( database.release() - clearCacheByTableName('OccupancyTypePrints') + clearCacheByTableName('ContractTypePrints') return result.changes > 0 } diff --git a/database/addFee.d.ts b/database/addFee.d.ts index 8d48739a..eee8c6b3 100644 --- a/database/addFee.d.ts +++ b/database/addFee.d.ts @@ -3,15 +3,15 @@ export interface AddFeeForm { feeName: string; feeDescription: string; feeAccount: string; - occupancyTypeId: string; - lotTypeId: string; + contractTypeId: string; + burialSiteTypeId: string; feeAmount?: string; - feeFunction: string; + feeFunction?: string; taxAmount?: string; taxPercentage?: string; - includeQuantity: '' | '1'; + includeQuantity?: '' | '1'; quantityUnit?: string; - isRequired: '' | '1'; + isRequired?: '' | '1'; orderNumber?: number; } export default function addFee(feeForm: AddFeeForm, user: User): Promise; diff --git a/database/addFee.js b/database/addFee.js index c20ba0b8..ebdba8fd 100644 --- a/database/addFee.js +++ b/database/addFee.js @@ -6,7 +6,7 @@ export default async function addFee(feeForm, user) { .prepare(`insert into Fees ( feeCategoryId, feeName, feeDescription, feeAccount, - occupancyTypeId, lotTypeId, + contractTypeId, burialSiteTypeId, feeAmount, feeFunction, taxAmount, taxPercentage, includeQuantity, quantityUnit, @@ -14,7 +14,7 @@ export default async function addFee(feeForm, user) { recordCreate_userName, recordCreate_timeMillis, recordUpdate_userName, recordUpdate_timeMillis) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`) - .run(feeForm.feeCategoryId, feeForm.feeName, feeForm.feeDescription, feeForm.feeAccount, feeForm.occupancyTypeId === '' ? undefined : feeForm.occupancyTypeId, feeForm.lotTypeId === '' ? undefined : feeForm.lotTypeId, feeForm.feeAmount ?? undefined, feeForm.feeFunction ?? undefined, feeForm.taxAmount ?? undefined, feeForm.taxPercentage ?? undefined, (feeForm.includeQuantity ?? '') === '' ? 0 : 1, feeForm.quantityUnit, (feeForm.isRequired ?? '') === '' ? 0 : 1, feeForm.orderNumber ?? -1, user.userName, rightNowMillis, user.userName, rightNowMillis); + .run(feeForm.feeCategoryId, feeForm.feeName, feeForm.feeDescription, feeForm.feeAccount, feeForm.contractTypeId === '' ? undefined : feeForm.contractTypeId, feeForm.burialSiteTypeId === '' ? undefined : feeForm.burialSiteTypeId, feeForm.feeAmount ?? undefined, feeForm.feeFunction ?? undefined, feeForm.taxAmount ?? undefined, feeForm.taxPercentage ?? undefined, (feeForm.includeQuantity ?? '') === '' ? 0 : 1, feeForm.quantityUnit, (feeForm.isRequired ?? '') === '' ? 0 : 1, feeForm.orderNumber ?? -1, user.userName, rightNowMillis, user.userName, rightNowMillis); database.release(); return result.lastInsertRowid; } diff --git a/database/addFee.ts b/database/addFee.ts index 5c26065b..954adb43 100644 --- a/database/addFee.ts +++ b/database/addFee.ts @@ -5,15 +5,15 @@ export interface AddFeeForm { feeName: string feeDescription: string feeAccount: string - occupancyTypeId: string - lotTypeId: string + contractTypeId: string + burialSiteTypeId: string feeAmount?: string - feeFunction: string + feeFunction?: string taxAmount?: string taxPercentage?: string - includeQuantity: '' | '1' + includeQuantity?: '' | '1' quantityUnit?: string - isRequired: '' | '1' + isRequired?: '' | '1' orderNumber?: number } @@ -30,7 +30,7 @@ export default async function addFee( `insert into Fees ( feeCategoryId, feeName, feeDescription, feeAccount, - occupancyTypeId, lotTypeId, + contractTypeId, burialSiteTypeId, feeAmount, feeFunction, taxAmount, taxPercentage, includeQuantity, quantityUnit, @@ -44,8 +44,8 @@ export default async function addFee( feeForm.feeName, feeForm.feeDescription, feeForm.feeAccount, - feeForm.occupancyTypeId === '' ? undefined : feeForm.occupancyTypeId, - feeForm.lotTypeId === '' ? undefined : feeForm.lotTypeId, + feeForm.contractTypeId === '' ? undefined : feeForm.contractTypeId, + feeForm.burialSiteTypeId === '' ? undefined : feeForm.burialSiteTypeId, feeForm.feeAmount ?? undefined, feeForm.feeFunction ?? undefined, feeForm.taxAmount ?? undefined, diff --git a/database/addLotComment.d.ts b/database/addLotComment.d.ts deleted file mode 100644 index 933a7bfe..00000000 --- a/database/addLotComment.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -export interface AddLotCommentForm { - lotId: string; - lotComment: string; -} -export default function addLotComment(lotCommentForm: AddLotCommentForm, user: User): Promise; diff --git a/database/addLotOccupancyComment.d.ts b/database/addLotOccupancyComment.d.ts deleted file mode 100644 index 07bbd7b2..00000000 --- a/database/addLotOccupancyComment.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -export interface AddLotOccupancyCommentForm { - lotOccupancyId: string | number; - lotOccupancyCommentDateString?: string; - lotOccupancyCommentTimeString?: string; - lotOccupancyComment: string; -} -export default function addLotOccupancyComment(commentForm: AddLotOccupancyCommentForm, user: User): Promise; diff --git a/database/addLotOccupancyComment.js b/database/addLotOccupancyComment.js deleted file mode 100644 index 7e46d9ce..00000000 --- a/database/addLotOccupancyComment.js +++ /dev/null @@ -1,27 +0,0 @@ -import { dateStringToInteger, dateToInteger, dateToTimeInteger, timeStringToInteger } from '@cityssm/utils-datetime'; -import { acquireConnection } from './pool.js'; -export default async function addLotOccupancyComment(commentForm, user) { - const rightNow = new Date(); - let lotOccupancyCommentDate; - let lotOccupancyCommentTime; - if (commentForm.lotOccupancyCommentDateString) { - lotOccupancyCommentDate = dateStringToInteger(commentForm.lotOccupancyCommentDateString); - lotOccupancyCommentTime = timeStringToInteger(commentForm.lotOccupancyCommentTimeString ?? ''); - } - else { - lotOccupancyCommentDate = dateToInteger(rightNow); - lotOccupancyCommentTime = dateToTimeInteger(rightNow); - } - const database = await acquireConnection(); - const result = database - .prepare(`insert into LotOccupancyComments ( - lotOccupancyId, - lotOccupancyCommentDate, lotOccupancyCommentTime, - lotOccupancyComment, - recordCreate_userName, recordCreate_timeMillis, - recordUpdate_userName, recordUpdate_timeMillis) - values (?, ?, ?, ?, ?, ?, ?, ?)`) - .run(commentForm.lotOccupancyId, lotOccupancyCommentDate, lotOccupancyCommentTime ?? 0, commentForm.lotOccupancyComment, user.userName, rightNow.getTime(), user.userName, rightNow.getTime()); - database.release(); - return result.lastInsertRowid; -} diff --git a/database/addLotOccupancyComment.ts b/database/addLotOccupancyComment.ts deleted file mode 100644 index 8503fd33..00000000 --- a/database/addLotOccupancyComment.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { - type DateString, - type TimeString, - dateStringToInteger, - dateToInteger, - dateToTimeInteger, - timeStringToInteger -} from '@cityssm/utils-datetime' - -import { acquireConnection } from './pool.js' - -export interface AddLotOccupancyCommentForm { - lotOccupancyId: string | number - lotOccupancyCommentDateString?: string - lotOccupancyCommentTimeString?: string - lotOccupancyComment: string -} - -export default async function addLotOccupancyComment( - commentForm: AddLotOccupancyCommentForm, - user: User -): Promise { - const rightNow = new Date() - - let lotOccupancyCommentDate: number - let lotOccupancyCommentTime: number | undefined - - if (commentForm.lotOccupancyCommentDateString) { - lotOccupancyCommentDate = dateStringToInteger( - commentForm.lotOccupancyCommentDateString as DateString - ) - lotOccupancyCommentTime = timeStringToInteger( - (commentForm.lotOccupancyCommentTimeString as TimeString) ?? '' - ) - } else { - lotOccupancyCommentDate = dateToInteger(rightNow) - lotOccupancyCommentTime = dateToTimeInteger(rightNow) - } - - const database = await acquireConnection() - - const result = database - .prepare( - `insert into LotOccupancyComments ( - lotOccupancyId, - lotOccupancyCommentDate, lotOccupancyCommentTime, - lotOccupancyComment, - recordCreate_userName, recordCreate_timeMillis, - recordUpdate_userName, recordUpdate_timeMillis) - values (?, ?, ?, ?, ?, ?, ?, ?)` - ) - .run( - commentForm.lotOccupancyId, - lotOccupancyCommentDate, - lotOccupancyCommentTime ?? 0, - commentForm.lotOccupancyComment, - user.userName, - rightNow.getTime(), - user.userName, - rightNow.getTime() - ) - - database.release() - - return result.lastInsertRowid as number -} diff --git a/database/addLotOccupancyOccupant.d.ts b/database/addLotOccupancyOccupant.d.ts deleted file mode 100644 index 199b2ae8..00000000 --- a/database/addLotOccupancyOccupant.d.ts +++ /dev/null @@ -1,16 +0,0 @@ -import type { PoolConnection } from 'better-sqlite-pool'; -export interface AddLotOccupancyOccupantForm { - lotOccupancyId: 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 addLotOccupancyOccupant(lotOccupancyOccupantForm: AddLotOccupancyOccupantForm, user: User, connectedDatabase?: PoolConnection): Promise; diff --git a/database/addLotOccupancyOccupant.js b/database/addLotOccupancyOccupant.js deleted file mode 100644 index e60cfe6b..00000000 --- a/database/addLotOccupancyOccupant.js +++ /dev/null @@ -1,33 +0,0 @@ -import { acquireConnection } from './pool.js'; -export default async function addLotOccupancyOccupant(lotOccupancyOccupantForm, user, connectedDatabase) { - const database = connectedDatabase ?? (await acquireConnection()); - let lotOccupantIndex = 0; - const maxIndexResult = database - .prepare(`select lotOccupantIndex - from LotOccupancyOccupants - where lotOccupancyId = ? - order by lotOccupantIndex desc - limit 1`) - .get(lotOccupancyOccupantForm.lotOccupancyId); - if (maxIndexResult !== undefined) { - lotOccupantIndex = maxIndexResult.lotOccupantIndex + 1; - } - const rightNowMillis = Date.now(); - database - .prepare(`insert into LotOccupancyOccupants ( - lotOccupancyId, lotOccupantIndex, - occupantName, occupantFamilyName, - occupantAddress1, occupantAddress2, - occupantCity, occupantProvince, occupantPostalCode, - occupantPhoneNumber, occupantEmailAddress, - occupantComment, - lotOccupantTypeId, - recordCreate_userName, recordCreate_timeMillis, - recordUpdate_userName, recordUpdate_timeMillis) - values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`) - .run(lotOccupancyOccupantForm.lotOccupancyId, lotOccupantIndex, lotOccupancyOccupantForm.occupantName, lotOccupancyOccupantForm.occupantFamilyName, lotOccupancyOccupantForm.occupantAddress1, lotOccupancyOccupantForm.occupantAddress2, lotOccupancyOccupantForm.occupantCity, lotOccupancyOccupantForm.occupantProvince, lotOccupancyOccupantForm.occupantPostalCode, lotOccupancyOccupantForm.occupantPhoneNumber, lotOccupancyOccupantForm.occupantEmailAddress, lotOccupancyOccupantForm.occupantComment ?? '', lotOccupancyOccupantForm.lotOccupantTypeId, user.userName, rightNowMillis, user.userName, rightNowMillis); - if (connectedDatabase === undefined) { - database.release(); - } - return lotOccupantIndex; -} diff --git a/database/addLotOccupancyOccupant.ts b/database/addLotOccupancyOccupant.ts deleted file mode 100644 index 53fc749b..00000000 --- a/database/addLotOccupancyOccupant.ts +++ /dev/null @@ -1,86 +0,0 @@ -import type { PoolConnection } from 'better-sqlite-pool' - -import { acquireConnection } from './pool.js' - -export interface AddLotOccupancyOccupantForm { - lotOccupancyId: 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 addLotOccupancyOccupant( - lotOccupancyOccupantForm: AddLotOccupancyOccupantForm, - user: User, - connectedDatabase?: PoolConnection -): Promise { - const database = connectedDatabase ?? (await acquireConnection()) - - let lotOccupantIndex = 0 - - const maxIndexResult = database - .prepare( - `select lotOccupantIndex - from LotOccupancyOccupants - where lotOccupancyId = ? - order by lotOccupantIndex desc - limit 1` - ) - .get(lotOccupancyOccupantForm.lotOccupancyId) as - | { lotOccupantIndex: number } - | undefined - - if (maxIndexResult !== undefined) { - lotOccupantIndex = maxIndexResult.lotOccupantIndex + 1 - } - - const rightNowMillis = Date.now() - - database - .prepare( - `insert into LotOccupancyOccupants ( - lotOccupancyId, lotOccupantIndex, - occupantName, occupantFamilyName, - occupantAddress1, occupantAddress2, - occupantCity, occupantProvince, occupantPostalCode, - occupantPhoneNumber, occupantEmailAddress, - occupantComment, - lotOccupantTypeId, - recordCreate_userName, recordCreate_timeMillis, - recordUpdate_userName, recordUpdate_timeMillis) - values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)` - ) - .run( - lotOccupancyOccupantForm.lotOccupancyId, - lotOccupantIndex, - lotOccupancyOccupantForm.occupantName, - lotOccupancyOccupantForm.occupantFamilyName, - lotOccupancyOccupantForm.occupantAddress1, - lotOccupancyOccupantForm.occupantAddress2, - lotOccupancyOccupantForm.occupantCity, - lotOccupancyOccupantForm.occupantProvince, - lotOccupancyOccupantForm.occupantPostalCode, - lotOccupancyOccupantForm.occupantPhoneNumber, - lotOccupancyOccupantForm.occupantEmailAddress, - lotOccupancyOccupantForm.occupantComment ?? '', - lotOccupancyOccupantForm.lotOccupantTypeId, - user.userName, - rightNowMillis, - user.userName, - rightNowMillis - ) - - if (connectedDatabase === undefined) { - database.release() - } - - return lotOccupantIndex -} diff --git a/database/addLotOccupantType.d.ts b/database/addLotOccupantType.d.ts deleted file mode 100644 index 3ab9a367..00000000 --- a/database/addLotOccupantType.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -export interface AddLotOccupantTypeForm { - lotOccupantType: string; - fontAwesomeIconClass?: string; - occupantCommentTitle?: string; - orderNumber?: number; -} -export default function addLotOccupantType(lotOccupantTypeForm: AddLotOccupantTypeForm, user: User): Promise; diff --git a/database/addLotOccupantType.js b/database/addLotOccupantType.js deleted file mode 100644 index 8f3d68b6..00000000 --- a/database/addLotOccupantType.js +++ /dev/null @@ -1,16 +0,0 @@ -import { clearCacheByTableName } from '../helpers/functions.cache.js'; -import { acquireConnection } from './pool.js'; -export default async function addLotOccupantType(lotOccupantTypeForm, user) { - const database = await acquireConnection(); - const rightNowMillis = Date.now(); - const result = database - .prepare(`insert into LotOccupantTypes ( - lotOccupantType, fontAwesomeIconClass, occupantCommentTitle, orderNumber, - recordCreate_userName, recordCreate_timeMillis, - recordUpdate_userName, recordUpdate_timeMillis) - values (?, ?, ?, ?, ?, ?, ?, ?)`) - .run(lotOccupantTypeForm.lotOccupantType, lotOccupantTypeForm.fontAwesomeIconClass ?? '', lotOccupantTypeForm.occupantCommentTitle ?? '', lotOccupantTypeForm.orderNumber ?? -1, user.userName, rightNowMillis, user.userName, rightNowMillis); - database.release(); - clearCacheByTableName('LotOccupantTypes'); - return result.lastInsertRowid; -} diff --git a/database/addLotOccupantType.ts b/database/addLotOccupantType.ts deleted file mode 100644 index 1e0b6ed5..00000000 --- a/database/addLotOccupantType.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { clearCacheByTableName } from '../helpers/functions.cache.js' - -import { acquireConnection } from './pool.js' - -export interface AddLotOccupantTypeForm { - lotOccupantType: string - fontAwesomeIconClass?: string - occupantCommentTitle?: string - orderNumber?: number -} - -export default async function addLotOccupantType( - lotOccupantTypeForm: AddLotOccupantTypeForm, - user: User -): Promise { - const database = await acquireConnection() - - const rightNowMillis = Date.now() - - const result = database - .prepare( - `insert into LotOccupantTypes ( - lotOccupantType, fontAwesomeIconClass, occupantCommentTitle, orderNumber, - recordCreate_userName, recordCreate_timeMillis, - recordUpdate_userName, recordUpdate_timeMillis) - values (?, ?, ?, ?, ?, ?, ?, ?)` - ) - .run( - lotOccupantTypeForm.lotOccupantType, - lotOccupantTypeForm.fontAwesomeIconClass ?? '', - lotOccupantTypeForm.occupantCommentTitle ?? '', - lotOccupantTypeForm.orderNumber ?? -1, - user.userName, - rightNowMillis, - user.userName, - rightNowMillis - ) - - database.release() - - clearCacheByTableName('LotOccupantTypes') - - return result.lastInsertRowid as number -} diff --git a/database/addLotTypeField.d.ts b/database/addLotTypeField.d.ts deleted file mode 100644 index a596b9dd..00000000 --- a/database/addLotTypeField.d.ts +++ /dev/null @@ -1,12 +0,0 @@ -export interface AddLotTypeFieldForm { - lotTypeId: string | number; - lotTypeField: string; - fieldType?: string; - lotTypeFieldValues?: string; - isRequired?: string; - pattern?: string; - minimumLength?: string | number; - maximumLength?: string | number; - orderNumber?: number; -} -export default function addLotTypeField(lotTypeFieldForm: AddLotTypeFieldForm, user: User): Promise; diff --git a/database/addLotTypeField.js b/database/addLotTypeField.js deleted file mode 100644 index 3d2cc17f..00000000 --- a/database/addLotTypeField.js +++ /dev/null @@ -1,19 +0,0 @@ -import { clearCacheByTableName } from '../helpers/functions.cache.js'; -import { acquireConnection } from './pool.js'; -export default async function addLotTypeField(lotTypeFieldForm, user) { - const database = await acquireConnection(); - const rightNowMillis = Date.now(); - const result = database - .prepare(`insert into LotTypeFields ( - lotTypeId, lotTypeField, fieldType, lotTypeFieldValues, - isRequired, pattern, - minimumLength, maximumLength, - orderNumber, - recordCreate_userName, recordCreate_timeMillis, - recordUpdate_userName, recordUpdate_timeMillis) - values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`) - .run(lotTypeFieldForm.lotTypeId, lotTypeFieldForm.lotTypeField, lotTypeFieldForm.fieldType ?? 'text', lotTypeFieldForm.lotTypeFieldValues ?? '', lotTypeFieldForm.isRequired === '' ? 0 : 1, lotTypeFieldForm.pattern ?? '', lotTypeFieldForm.minimumLength ?? 0, lotTypeFieldForm.maximumLength ?? 100, lotTypeFieldForm.orderNumber ?? -1, user.userName, rightNowMillis, user.userName, rightNowMillis); - database.release(); - clearCacheByTableName('LotTypeFields'); - return result.lastInsertRowid; -} diff --git a/database/addMap.d.ts b/database/addMap.d.ts deleted file mode 100644 index 6f6e2509..00000000 --- a/database/addMap.d.ts +++ /dev/null @@ -1,14 +0,0 @@ -export interface AddMapForm { - mapName: string; - mapDescription: string; - mapSVG: string; - mapLatitude: string; - mapLongitude: string; - mapAddress1: string; - mapAddress2: string; - mapCity: string; - mapProvince: string; - mapPostalCode: string; - mapPhoneNumber: string; -} -export default function addMap(mapForm: AddMapForm, user: User): Promise; diff --git a/database/addMap.js b/database/addMap.js deleted file mode 100644 index 9e13a904..00000000 --- a/database/addMap.js +++ /dev/null @@ -1,18 +0,0 @@ -import { acquireConnection } from './pool.js'; -export default async function addMap(mapForm, user) { - const database = await acquireConnection(); - const rightNowMillis = Date.now(); - const result = database - .prepare(`insert into Maps ( - mapName, mapDescription, - mapSVG, mapLatitude, mapLongitude, - mapAddress1, mapAddress2, - mapCity, mapProvince, mapPostalCode, - mapPhoneNumber, - recordCreate_userName, recordCreate_timeMillis, - recordUpdate_userName, recordUpdate_timeMillis) - values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`) - .run(mapForm.mapName, mapForm.mapDescription, mapForm.mapSVG, mapForm.mapLatitude === '' ? undefined : mapForm.mapLatitude, mapForm.mapLongitude === '' ? undefined : mapForm.mapLongitude, mapForm.mapAddress1, mapForm.mapAddress2, mapForm.mapCity, mapForm.mapProvince, mapForm.mapPostalCode, mapForm.mapPhoneNumber, user.userName, rightNowMillis, user.userName, rightNowMillis); - database.release(); - return result.lastInsertRowid; -} diff --git a/database/addMap.ts b/database/addMap.ts deleted file mode 100644 index e5c8f0f1..00000000 --- a/database/addMap.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { acquireConnection } from './pool.js' - -export interface AddMapForm { - mapName: string - mapDescription: string - mapSVG: string - mapLatitude: string - mapLongitude: string - mapAddress1: string - mapAddress2: string - mapCity: string - mapProvince: string - mapPostalCode: string - mapPhoneNumber: string -} - -export default async function addMap( - mapForm: AddMapForm, - user: User -): Promise { - const database = await acquireConnection() - - const rightNowMillis = Date.now() - - const result = database - .prepare( - `insert into Maps ( - mapName, mapDescription, - mapSVG, mapLatitude, mapLongitude, - mapAddress1, mapAddress2, - mapCity, mapProvince, mapPostalCode, - mapPhoneNumber, - recordCreate_userName, recordCreate_timeMillis, - recordUpdate_userName, recordUpdate_timeMillis) - values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)` - ) - .run( - mapForm.mapName, - mapForm.mapDescription, - mapForm.mapSVG, - mapForm.mapLatitude === '' ? undefined : mapForm.mapLatitude, - mapForm.mapLongitude === '' ? undefined : mapForm.mapLongitude, - mapForm.mapAddress1, - mapForm.mapAddress2, - mapForm.mapCity, - mapForm.mapProvince, - mapForm.mapPostalCode, - mapForm.mapPhoneNumber, - user.userName, - rightNowMillis, - user.userName, - rightNowMillis - ) - - database.release() - - return result.lastInsertRowid as number -} diff --git a/database/addOccupancyTypeField.d.ts b/database/addOccupancyTypeField.d.ts deleted file mode 100644 index e619da02..00000000 --- a/database/addOccupancyTypeField.d.ts +++ /dev/null @@ -1,12 +0,0 @@ -export interface AddOccupancyTypeFieldForm { - occupancyTypeId?: string | number; - occupancyTypeField: string; - occupancyTypeFieldValues?: string; - fieldType?: string; - isRequired?: string; - pattern?: string; - minimumLength?: string | number; - maximumLength?: string | number; - orderNumber?: number; -} -export default function addOccupancyTypeField(occupancyTypeFieldForm: AddOccupancyTypeFieldForm, user: User): Promise; diff --git a/database/addOccupancyTypeField.js b/database/addOccupancyTypeField.js deleted file mode 100644 index 93fd2718..00000000 --- a/database/addOccupancyTypeField.js +++ /dev/null @@ -1,19 +0,0 @@ -import { clearCacheByTableName } from '../helpers/functions.cache.js'; -import { acquireConnection } from './pool.js'; -export default async function addOccupancyTypeField(occupancyTypeFieldForm, user) { - const database = await acquireConnection(); - const rightNowMillis = Date.now(); - const result = database - .prepare(`insert into OccupancyTypeFields ( - occupancyTypeId, occupancyTypeField, fieldType, - occupancyTypeFieldValues, isRequired, pattern, - minimumLength, maximumLength, - orderNumber, - recordCreate_userName, recordCreate_timeMillis, - recordUpdate_userName, recordUpdate_timeMillis) - values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`) - .run(occupancyTypeFieldForm.occupancyTypeId ?? undefined, occupancyTypeFieldForm.occupancyTypeField, occupancyTypeFieldForm.fieldType ?? 'text', occupancyTypeFieldForm.occupancyTypeFieldValues ?? '', occupancyTypeFieldForm.isRequired === '' ? 0 : 1, occupancyTypeFieldForm.pattern ?? '', occupancyTypeFieldForm.minimumLength ?? 0, occupancyTypeFieldForm.maximumLength ?? 100, occupancyTypeFieldForm.orderNumber ?? -1, user.userName, rightNowMillis, user.userName, rightNowMillis); - database.release(); - clearCacheByTableName('OccupancyTypeFields'); - return result.lastInsertRowid; -} diff --git a/database/addOccupancyTypePrint.d.ts b/database/addOccupancyTypePrint.d.ts deleted file mode 100644 index 283e86aa..00000000 --- a/database/addOccupancyTypePrint.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -export interface AddOccupancyTypePrintForm { - occupancyTypeId: string | number; - printEJS: string; - orderNumber?: number; -} -export default function addOccupancyTypePrint(occupancyTypePrintForm: AddOccupancyTypePrintForm, user: User): Promise; diff --git a/database/addOrUpdateBurialSiteContractField.d.ts b/database/addOrUpdateBurialSiteContractField.d.ts new file mode 100644 index 00000000..f47a7d00 --- /dev/null +++ b/database/addOrUpdateBurialSiteContractField.d.ts @@ -0,0 +1,7 @@ +import type { PoolConnection } from 'better-sqlite-pool'; +export interface BurialSiteContractFieldForm { + burialSiteContractId: string | number; + contractTypeFieldId: string | number; + fieldValue: string; +} +export default function addOrUpdateBurialSiteContractField(fieldForm: BurialSiteContractFieldForm, user: User, connectedDatabase?: PoolConnection): Promise; diff --git a/database/addOrUpdateBurialSiteContractField.js b/database/addOrUpdateBurialSiteContractField.js new file mode 100644 index 00000000..67f38213 --- /dev/null +++ b/database/addOrUpdateBurialSiteContractField.js @@ -0,0 +1,28 @@ +import { acquireConnection } from './pool.js'; +export default async function addOrUpdateBurialSiteContractField(fieldForm, user, connectedDatabase) { + const database = connectedDatabase ?? (await acquireConnection()); + const rightNowMillis = Date.now(); + let result = database + .prepare(`update BurialSiteContractFields + set fieldValue = ?, + recordUpdate_userName = ?, + recordUpdate_timeMillis = ?, + recordDelete_userName = null, + recordDelete_timeMillis = null + where burialSiteContractId = ? + and contractTypeFieldId = ?`) + .run(fieldForm.fieldValue, user.userName, rightNowMillis, fieldForm.burialSiteContractId, fieldForm.contractTypeFieldId); + if (result.changes === 0) { + result = database + .prepare(`insert into BurialSiteContractFields ( + burialSiteContractId, contractTypeFieldId, fieldValue, + recordCreate_userName, recordCreate_timeMillis, + recordUpdate_userName, recordUpdate_timeMillis) + values (?, ?, ?, ?, ?, ?, ?)`) + .run(fieldForm.burialSiteContractId, fieldForm.contractTypeFieldId, fieldForm.fieldValue, user.userName, rightNowMillis, user.userName, rightNowMillis); + } + if (connectedDatabase === undefined) { + database.release(); + } + return result.changes > 0; +} diff --git a/database/addOrUpdateLotOccupancyField.ts b/database/addOrUpdateBurialSiteContractField.ts similarity index 54% rename from database/addOrUpdateLotOccupancyField.ts rename to database/addOrUpdateBurialSiteContractField.ts index 7e70d4d8..2fbb6567 100644 --- a/database/addOrUpdateLotOccupancyField.ts +++ b/database/addOrUpdateBurialSiteContractField.ts @@ -2,14 +2,14 @@ import type { PoolConnection } from 'better-sqlite-pool' import { acquireConnection } from './pool.js' -export interface LotOccupancyFieldForm { - lotOccupancyId: string | number - occupancyTypeFieldId: string | number - lotOccupancyFieldValue: string +export interface BurialSiteContractFieldForm { + burialSiteContractId: string | number + contractTypeFieldId: string | number + fieldValue: string } -export default async function addOrUpdateLotOccupancyField( - lotOccupancyFieldForm: LotOccupancyFieldForm, +export default async function addOrUpdateBurialSiteContractField( + fieldForm: BurialSiteContractFieldForm, user: User, connectedDatabase?: PoolConnection ): Promise { @@ -19,36 +19,36 @@ export default async function addOrUpdateLotOccupancyField( let result = database .prepare( - `update LotOccupancyFields - set lotOccupancyFieldValue = ?, + `update BurialSiteContractFields + set fieldValue = ?, recordUpdate_userName = ?, recordUpdate_timeMillis = ?, recordDelete_userName = null, recordDelete_timeMillis = null - where lotOccupancyId = ? - and occupancyTypeFieldId = ?` + where burialSiteContractId = ? + and contractTypeFieldId = ?` ) .run( - lotOccupancyFieldForm.lotOccupancyFieldValue, + fieldForm.fieldValue, user.userName, rightNowMillis, - lotOccupancyFieldForm.lotOccupancyId, - lotOccupancyFieldForm.occupancyTypeFieldId + fieldForm.burialSiteContractId, + fieldForm.contractTypeFieldId ) if (result.changes === 0) { result = database .prepare( - `insert into LotOccupancyFields ( - lotOccupancyId, occupancyTypeFieldId, lotOccupancyFieldValue, + `insert into BurialSiteContractFields ( + burialSiteContractId, contractTypeFieldId, fieldValue, recordCreate_userName, recordCreate_timeMillis, recordUpdate_userName, recordUpdate_timeMillis) values (?, ?, ?, ?, ?, ?, ?)` ) .run( - lotOccupancyFieldForm.lotOccupancyId, - lotOccupancyFieldForm.occupancyTypeFieldId, - lotOccupancyFieldForm.lotOccupancyFieldValue, + fieldForm.burialSiteContractId, + fieldForm.contractTypeFieldId, + fieldForm.fieldValue, user.userName, rightNowMillis, user.userName, diff --git a/database/addOrUpdateBurialSiteField.d.ts b/database/addOrUpdateBurialSiteField.d.ts new file mode 100644 index 00000000..321f71a9 --- /dev/null +++ b/database/addOrUpdateBurialSiteField.d.ts @@ -0,0 +1,7 @@ +import type { PoolConnection } from 'better-sqlite-pool'; +export interface BurialSiteFieldForm { + burialSiteId: string | number; + burialSiteTypeFieldId: string | number; + fieldValue: string; +} +export default function addOrUpdateBurialSiteField(fieldForm: BurialSiteFieldForm, user: User, connectedDatabase?: PoolConnection): Promise; diff --git a/database/addOrUpdateLotField.js b/database/addOrUpdateBurialSiteField.js similarity index 51% rename from database/addOrUpdateLotField.js rename to database/addOrUpdateBurialSiteField.js index 81466e88..de3296cc 100644 --- a/database/addOrUpdateLotField.js +++ b/database/addOrUpdateBurialSiteField.js @@ -1,25 +1,25 @@ import { acquireConnection } from './pool.js'; -export default async function addOrUpdateLotField(lotFieldForm, user, connectedDatabase) { +export default async function addOrUpdateBurialSiteField(fieldForm, user, connectedDatabase) { const database = connectedDatabase ?? (await acquireConnection()); const rightNowMillis = Date.now(); let result = database - .prepare(`update LotFields - set lotFieldValue = ?, + .prepare(`update BurialSiteFields + set fieldValue = ?, recordUpdate_userName = ?, recordUpdate_timeMillis = ?, recordDelete_userName = null, recordDelete_timeMillis = null - where lotId = ? - and lotTypeFieldId = ?`) - .run(lotFieldForm.lotFieldValue, user.userName, rightNowMillis, lotFieldForm.lotId, lotFieldForm.lotTypeFieldId); + where burialSiteId = ? + and burialSiteTypeFieldId = ?`) + .run(fieldForm.fieldValue, user.userName, rightNowMillis, fieldForm.burialSiteId, fieldForm.burialSiteTypeFieldId); if (result.changes === 0) { result = database - .prepare(`insert into LotFields ( - lotId, lotTypeFieldId, lotFieldValue, + .prepare(`insert into BurialSiteFields ( + burialSiteId, burialSiteTypeFieldId, fieldValue, recordCreate_userName, recordCreate_timeMillis, recordUpdate_userName, recordUpdate_timeMillis) values (?, ?, ?, ?, ?, ?, ?)`) - .run(lotFieldForm.lotId, lotFieldForm.lotTypeFieldId, lotFieldForm.lotFieldValue, user.userName, rightNowMillis, user.userName, rightNowMillis); + .run(fieldForm.burialSiteId, fieldForm.burialSiteTypeFieldId, fieldForm.fieldValue, user.userName, rightNowMillis, user.userName, rightNowMillis); } if (connectedDatabase === undefined) { database.release(); diff --git a/database/addOrUpdateLotField.ts b/database/addOrUpdateBurialSiteField.ts similarity index 60% rename from database/addOrUpdateLotField.ts rename to database/addOrUpdateBurialSiteField.ts index fa55122d..3307740b 100644 --- a/database/addOrUpdateLotField.ts +++ b/database/addOrUpdateBurialSiteField.ts @@ -2,14 +2,14 @@ import type { PoolConnection } from 'better-sqlite-pool' import { acquireConnection } from './pool.js' -export interface LotFieldForm { - lotId: string | number - lotTypeFieldId: string | number - lotFieldValue: string +export interface BurialSiteFieldForm { + burialSiteId: string | number + burialSiteTypeFieldId: string | number + fieldValue: string } -export default async function addOrUpdateLotField( - lotFieldForm: LotFieldForm, +export default async function addOrUpdateBurialSiteField( + fieldForm: BurialSiteFieldForm, user: User, connectedDatabase?: PoolConnection ): Promise { @@ -19,36 +19,36 @@ export default async function addOrUpdateLotField( let result = database .prepare( - `update LotFields - set lotFieldValue = ?, + `update BurialSiteFields + set fieldValue = ?, recordUpdate_userName = ?, recordUpdate_timeMillis = ?, recordDelete_userName = null, recordDelete_timeMillis = null - where lotId = ? - and lotTypeFieldId = ?` + where burialSiteId = ? + and burialSiteTypeFieldId = ?` ) .run( - lotFieldForm.lotFieldValue, + fieldForm.fieldValue, user.userName, rightNowMillis, - lotFieldForm.lotId, - lotFieldForm.lotTypeFieldId + fieldForm.burialSiteId, + fieldForm.burialSiteTypeFieldId ) if (result.changes === 0) { result = database .prepare( - `insert into LotFields ( - lotId, lotTypeFieldId, lotFieldValue, + `insert into BurialSiteFields ( + burialSiteId, burialSiteTypeFieldId, fieldValue, recordCreate_userName, recordCreate_timeMillis, recordUpdate_userName, recordUpdate_timeMillis) values (?, ?, ?, ?, ?, ?, ?)` ) .run( - lotFieldForm.lotId, - lotFieldForm.lotTypeFieldId, - lotFieldForm.lotFieldValue, + fieldForm.burialSiteId, + fieldForm.burialSiteTypeFieldId, + fieldForm.fieldValue, user.userName, rightNowMillis, user.userName, diff --git a/database/addOrUpdateLotField.d.ts b/database/addOrUpdateLotField.d.ts deleted file mode 100644 index 08bbcce8..00000000 --- a/database/addOrUpdateLotField.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -import type { PoolConnection } from 'better-sqlite-pool'; -export interface LotFieldForm { - lotId: string | number; - lotTypeFieldId: string | number; - lotFieldValue: string; -} -export default function addOrUpdateLotField(lotFieldForm: LotFieldForm, user: User, connectedDatabase?: PoolConnection): Promise; diff --git a/database/addOrUpdateLotOccupancyField.d.ts b/database/addOrUpdateLotOccupancyField.d.ts deleted file mode 100644 index 624ec917..00000000 --- a/database/addOrUpdateLotOccupancyField.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -import type { PoolConnection } from 'better-sqlite-pool'; -export interface LotOccupancyFieldForm { - lotOccupancyId: string | number; - occupancyTypeFieldId: string | number; - lotOccupancyFieldValue: string; -} -export default function addOrUpdateLotOccupancyField(lotOccupancyFieldForm: LotOccupancyFieldForm, user: User, connectedDatabase?: PoolConnection): Promise; diff --git a/database/addOrUpdateLotOccupancyField.js b/database/addOrUpdateLotOccupancyField.js deleted file mode 100644 index 09511cdb..00000000 --- a/database/addOrUpdateLotOccupancyField.js +++ /dev/null @@ -1,28 +0,0 @@ -import { acquireConnection } from './pool.js'; -export default async function addOrUpdateLotOccupancyField(lotOccupancyFieldForm, user, connectedDatabase) { - const database = connectedDatabase ?? (await acquireConnection()); - const rightNowMillis = Date.now(); - let result = database - .prepare(`update LotOccupancyFields - set lotOccupancyFieldValue = ?, - recordUpdate_userName = ?, - recordUpdate_timeMillis = ?, - recordDelete_userName = null, - recordDelete_timeMillis = null - where lotOccupancyId = ? - and occupancyTypeFieldId = ?`) - .run(lotOccupancyFieldForm.lotOccupancyFieldValue, user.userName, rightNowMillis, lotOccupancyFieldForm.lotOccupancyId, lotOccupancyFieldForm.occupancyTypeFieldId); - if (result.changes === 0) { - result = database - .prepare(`insert into LotOccupancyFields ( - lotOccupancyId, occupancyTypeFieldId, lotOccupancyFieldValue, - recordCreate_userName, recordCreate_timeMillis, - recordUpdate_userName, recordUpdate_timeMillis) - values (?, ?, ?, ?, ?, ?, ?)`) - .run(lotOccupancyFieldForm.lotOccupancyId, lotOccupancyFieldForm.occupancyTypeFieldId, lotOccupancyFieldForm.lotOccupancyFieldValue, user.userName, rightNowMillis, user.userName, rightNowMillis); - } - if (connectedDatabase === undefined) { - database.release(); - } - return result.changes > 0; -} diff --git a/database/addRecord.d.ts b/database/addRecord.d.ts index 988739f0..d1527b6e 100644 --- a/database/addRecord.d.ts +++ b/database/addRecord.d.ts @@ -1,3 +1,3 @@ -type RecordTable = 'LotStatuses' | 'LotTypes' | 'OccupancyTypes' | 'WorkOrderMilestoneTypes' | 'WorkOrderTypes'; -export declare function addRecord(recordTable: RecordTable, recordName: string, orderNumber: number | string, user: User): Promise; +type RecordTable = 'BurialSiteStatuses' | 'BurialSiteTypes' | 'ContractTypes' | 'WorkOrderMilestoneTypes' | 'WorkOrderTypes'; +export default function addRecord(recordTable: RecordTable, recordName: string, orderNumber: number | string, user: User): Promise; export {}; diff --git a/database/addRecord.js b/database/addRecord.js index 819fdec2..97387734 100644 --- a/database/addRecord.js +++ b/database/addRecord.js @@ -1,12 +1,12 @@ import { clearCacheByTableName } from '../helpers/functions.cache.js'; import { acquireConnection } from './pool.js'; const recordNameColumns = new Map(); -recordNameColumns.set('LotStatuses', 'lotStatus'); -recordNameColumns.set('LotTypes', 'lotType'); -recordNameColumns.set('OccupancyTypes', 'occupancyType'); +recordNameColumns.set('BurialSiteStatuses', 'burialSiteStatus'); +recordNameColumns.set('BurialSiteTypes', 'burialSiteType'); +recordNameColumns.set('ContractTypes', 'contractType'); recordNameColumns.set('WorkOrderMilestoneTypes', 'workOrderMilestoneType'); recordNameColumns.set('WorkOrderTypes', 'workOrderType'); -export async function addRecord(recordTable, recordName, orderNumber, user) { +export default async function addRecord(recordTable, recordName, orderNumber, user) { const database = await acquireConnection(); const rightNowMillis = Date.now(); const result = database diff --git a/database/addRecord.ts b/database/addRecord.ts index ace4111e..ff050ed5 100644 --- a/database/addRecord.ts +++ b/database/addRecord.ts @@ -3,20 +3,20 @@ import { clearCacheByTableName } from '../helpers/functions.cache.js' import { acquireConnection } from './pool.js' type RecordTable = - | 'LotStatuses' - | 'LotTypes' - | 'OccupancyTypes' + | 'BurialSiteStatuses' + | 'BurialSiteTypes' + | 'ContractTypes' | 'WorkOrderMilestoneTypes' | 'WorkOrderTypes' const recordNameColumns = new Map() -recordNameColumns.set('LotStatuses', 'lotStatus') -recordNameColumns.set('LotTypes', 'lotType') -recordNameColumns.set('OccupancyTypes', 'occupancyType') +recordNameColumns.set('BurialSiteStatuses', 'burialSiteStatus') +recordNameColumns.set('BurialSiteTypes', 'burialSiteType') +recordNameColumns.set('ContractTypes', 'contractType') recordNameColumns.set('WorkOrderMilestoneTypes', 'workOrderMilestoneType') recordNameColumns.set('WorkOrderTypes', 'workOrderType') -export async function addRecord( +export default async function addRecord( recordTable: RecordTable, recordName: string, orderNumber: number | string, diff --git a/database/addWorkOrder.d.ts b/database/addWorkOrder.d.ts index ce7d4171..4c96d69b 100644 --- a/database/addWorkOrder.d.ts +++ b/database/addWorkOrder.d.ts @@ -4,6 +4,6 @@ export interface AddWorkOrderForm { workOrderDescription: string; workOrderOpenDateString?: string; workOrderCloseDateString?: string; - lotOccupancyId?: string; + burialSiteContractId?: string; } export default function addWorkOrder(workOrderForm: AddWorkOrderForm, user: User): Promise; diff --git a/database/addWorkOrder.js b/database/addWorkOrder.js index 73d2d5c4..9a91b40e 100644 --- a/database/addWorkOrder.js +++ b/database/addWorkOrder.js @@ -1,5 +1,5 @@ import { dateStringToInteger, dateToInteger } from '@cityssm/utils-datetime'; -import addWorkOrderLotOccupancy from './addWorkOrderLotOccupancy.js'; +import addWorkOrderBurialSiteContract from './addWorkOrderBurialSiteContract.js'; import getNextWorkOrderNumber from './getNextWorkOrderNumber.js'; import { acquireConnection } from './pool.js'; export default async function addWorkOrder(workOrderForm, user) { @@ -22,10 +22,10 @@ export default async function addWorkOrder(workOrderForm, user) { ? undefined : dateStringToInteger(workOrderForm.workOrderCloseDateString), user.userName, rightNow.getTime(), user.userName, rightNow.getTime()); const workOrderId = result.lastInsertRowid; - if ((workOrderForm.lotOccupancyId ?? '') !== '') { - await addWorkOrderLotOccupancy({ + if ((workOrderForm.burialSiteContractId ?? '') !== '') { + await addWorkOrderBurialSiteContract({ workOrderId, - lotOccupancyId: workOrderForm.lotOccupancyId + burialSiteContractId: workOrderForm.burialSiteContractId }, user, database); } database.release(); diff --git a/database/addWorkOrder.ts b/database/addWorkOrder.ts index 983375e4..5255045a 100644 --- a/database/addWorkOrder.ts +++ b/database/addWorkOrder.ts @@ -4,7 +4,7 @@ import { dateToInteger } from '@cityssm/utils-datetime' -import addWorkOrderLotOccupancy from './addWorkOrderLotOccupancy.js' +import addWorkOrderBurialSiteContract from './addWorkOrderBurialSiteContract.js' import getNextWorkOrderNumber from './getNextWorkOrderNumber.js' import { acquireConnection } from './pool.js' @@ -14,7 +14,7 @@ export interface AddWorkOrderForm { workOrderDescription: string workOrderOpenDateString?: string workOrderCloseDateString?: string - lotOccupancyId?: string + burialSiteContractId?: string } export default async function addWorkOrder( @@ -62,11 +62,11 @@ export default async function addWorkOrder( const workOrderId = result.lastInsertRowid as number - if ((workOrderForm.lotOccupancyId ?? '') !== '') { - await addWorkOrderLotOccupancy( + if ((workOrderForm.burialSiteContractId ?? '') !== '') { + await addWorkOrderBurialSiteContract( { workOrderId, - lotOccupancyId: workOrderForm.lotOccupancyId! + burialSiteContractId: workOrderForm.burialSiteContractId as string }, user, database diff --git a/database/addWorkOrderLot.d.ts b/database/addWorkOrderBurialSite.d.ts similarity index 100% rename from database/addWorkOrderLot.d.ts rename to database/addWorkOrderBurialSite.d.ts diff --git a/database/addWorkOrderLot.js b/database/addWorkOrderBurialSite.js similarity index 100% rename from database/addWorkOrderLot.js rename to database/addWorkOrderBurialSite.js diff --git a/database/addWorkOrderLot.ts b/database/addWorkOrderBurialSite.ts similarity index 100% rename from database/addWorkOrderLot.ts rename to database/addWorkOrderBurialSite.ts diff --git a/database/addWorkOrderBurialSiteContract.d.ts b/database/addWorkOrderBurialSiteContract.d.ts new file mode 100644 index 00000000..4c6da837 --- /dev/null +++ b/database/addWorkOrderBurialSiteContract.d.ts @@ -0,0 +1,6 @@ +import type { PoolConnection } from 'better-sqlite-pool'; +export interface AddWorkOrderBurialSiteContractOccupancyForm { + workOrderId: number | string; + burialSiteContractId: number | string; +} +export default function addWorkOrderLotOccupancy(addForm: AddWorkOrderBurialSiteContractOccupancyForm, user: User, connectedDatabase?: PoolConnection): Promise; diff --git a/database/addWorkOrderLotOccupancy.js b/database/addWorkOrderBurialSiteContract.js similarity index 51% rename from database/addWorkOrderLotOccupancy.js rename to database/addWorkOrderBurialSiteContract.js index 63b5dd19..92f8f262 100644 --- a/database/addWorkOrderLotOccupancy.js +++ b/database/addWorkOrderBurialSiteContract.js @@ -1,26 +1,27 @@ import { acquireConnection } from './pool.js'; -export default async function addWorkOrderLotOccupancy(workOrderLotOccupancyForm, user, connectedDatabase) { +export default async function addWorkOrderLotOccupancy(addForm, user, connectedDatabase) { const database = connectedDatabase ?? (await acquireConnection()); const rightNowMillis = Date.now(); - const row = database + const recordDeleteTimeMillis = database .prepare(`select recordDelete_timeMillis - from WorkOrderLotOccupancies + from WorkOrderBurialSiteContracts where workOrderId = ? - and lotOccupancyId = ?`) - .get(workOrderLotOccupancyForm.workOrderId, workOrderLotOccupancyForm.lotOccupancyId); - if (row === undefined) { + and burialSiteContractId = ?`) + .pluck() + .get(addForm.workOrderId, addForm.burialSiteContractId); + if (recordDeleteTimeMillis === undefined) { database - .prepare(`insert into WorkOrderLotOccupancies ( - workOrderId, lotOccupancyId, + .prepare(`insert into WorkOrderBurialSiteContracts ( + workOrderId, burialSiteContractId, recordCreate_userName, recordCreate_timeMillis, recordUpdate_userName, recordUpdate_timeMillis) values (?, ?, ?, ?, ?, ?)`) - .run(workOrderLotOccupancyForm.workOrderId, workOrderLotOccupancyForm.lotOccupancyId, user.userName, rightNowMillis, user.userName, rightNowMillis); + .run(addForm.workOrderId, addForm.burialSiteContractId, user.userName, rightNowMillis, user.userName, rightNowMillis); } else { - if (row.recordDelete_timeMillis !== null) { + if (recordDeleteTimeMillis !== null) { database - .prepare(`update WorkOrderLotOccupancies + .prepare(`update WorkOrderBurialSiteContracts set recordCreate_userName = ?, recordCreate_timeMillis = ?, recordUpdate_userName = ?, @@ -28,8 +29,8 @@ export default async function addWorkOrderLotOccupancy(workOrderLotOccupancyForm recordDelete_userName = null, recordDelete_timeMillis = null where workOrderId = ? - and lotOccupancyId = ?`) - .run(user.userName, rightNowMillis, user.userName, rightNowMillis, workOrderLotOccupancyForm.workOrderId, workOrderLotOccupancyForm.lotOccupancyId); + and burialSiteContractId = ?`) + .run(user.userName, rightNowMillis, user.userName, rightNowMillis, addForm.workOrderId, addForm.burialSiteContractId); } } if (connectedDatabase === undefined) { diff --git a/database/addWorkOrderLotOccupancy.ts b/database/addWorkOrderBurialSiteContract.ts similarity index 61% rename from database/addWorkOrderLotOccupancy.ts rename to database/addWorkOrderBurialSiteContract.ts index 9435174c..da96fdb7 100644 --- a/database/addWorkOrderLotOccupancy.ts +++ b/database/addWorkOrderBurialSiteContract.ts @@ -2,13 +2,13 @@ import type { PoolConnection } from 'better-sqlite-pool' import { acquireConnection } from './pool.js' -export interface AddWorkOrderLotOccupancyForm { +export interface AddWorkOrderBurialSiteContractOccupancyForm { workOrderId: number | string - lotOccupancyId: number | string + burialSiteContractId: number | string } export default async function addWorkOrderLotOccupancy( - workOrderLotOccupancyForm: AddWorkOrderLotOccupancyForm, + addForm: AddWorkOrderBurialSiteContractOccupancyForm, user: User, connectedDatabase?: PoolConnection ): Promise { @@ -16,40 +16,41 @@ export default async function addWorkOrderLotOccupancy( const rightNowMillis = Date.now() - const row = database + const recordDeleteTimeMillis: number | null | undefined = database .prepare( `select recordDelete_timeMillis - from WorkOrderLotOccupancies + from WorkOrderBurialSiteContracts where workOrderId = ? - and lotOccupancyId = ?` + and burialSiteContractId = ?` ) + .pluck() .get( - workOrderLotOccupancyForm.workOrderId, - workOrderLotOccupancyForm.lotOccupancyId - ) as { recordDelete_timeMillis?: number } + addForm.workOrderId, + addForm.burialSiteContractId + ) as number | null | undefined - if (row === undefined) { + if (recordDeleteTimeMillis === undefined) { database .prepare( - `insert into WorkOrderLotOccupancies ( - workOrderId, lotOccupancyId, + `insert into WorkOrderBurialSiteContracts ( + workOrderId, burialSiteContractId, recordCreate_userName, recordCreate_timeMillis, recordUpdate_userName, recordUpdate_timeMillis) values (?, ?, ?, ?, ?, ?)` ) .run( - workOrderLotOccupancyForm.workOrderId, - workOrderLotOccupancyForm.lotOccupancyId, + addForm.workOrderId, + addForm.burialSiteContractId, user.userName, rightNowMillis, user.userName, rightNowMillis ) } else { - if (row.recordDelete_timeMillis !== null) { + if (recordDeleteTimeMillis !== null) { database .prepare( - `update WorkOrderLotOccupancies + `update WorkOrderBurialSiteContracts set recordCreate_userName = ?, recordCreate_timeMillis = ?, recordUpdate_userName = ?, @@ -57,15 +58,15 @@ export default async function addWorkOrderLotOccupancy( recordDelete_userName = null, recordDelete_timeMillis = null where workOrderId = ? - and lotOccupancyId = ?` + and burialSiteContractId = ?` ) .run( user.userName, rightNowMillis, user.userName, rightNowMillis, - workOrderLotOccupancyForm.workOrderId, - workOrderLotOccupancyForm.lotOccupancyId + addForm.workOrderId, + addForm.burialSiteContractId ) } } diff --git a/database/addWorkOrderLotOccupancy.d.ts b/database/addWorkOrderLotOccupancy.d.ts deleted file mode 100644 index 6c97ae94..00000000 --- a/database/addWorkOrderLotOccupancy.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -import type { PoolConnection } from 'better-sqlite-pool'; -export interface AddWorkOrderLotOccupancyForm { - workOrderId: number | string; - lotOccupancyId: number | string; -} -export default function addWorkOrderLotOccupancy(workOrderLotOccupancyForm: AddWorkOrderLotOccupancyForm, user: User, connectedDatabase?: PoolConnection): Promise; diff --git a/database/cleanupDatabase.js b/database/cleanupDatabase.js index 1e80a4cf..9e813098 100644 --- a/database/cleanupDatabase.js +++ b/database/cleanupDatabase.js @@ -1,12 +1,11 @@ -import { getConfigProperty } from '../helpers/functions.config.js'; +import { daysToMillis } from '@cityssm/to-millis'; +import { getConfigProperty } from '../helpers/config.helpers.js'; import { acquireConnection } from './pool.js'; export default async function cleanupDatabase(user) { const database = await acquireConnection(); const rightNowMillis = Date.now(); const recordDeleteTimeMillisMin = rightNowMillis - - getConfigProperty('settings.adminCleanup.recordDeleteAgeDays') * - 86_400 * - 1000; + daysToMillis(getConfigProperty('settings.adminCleanup.recordDeleteAgeDays')); let inactivatedRecordCount = 0; let purgedRecordCount = 0; /* @@ -24,10 +23,10 @@ export default async function cleanupDatabase(user) { .prepare('delete from WorkOrderComments where recordDelete_timeMillis <= ?') .run(recordDeleteTimeMillisMin).changes; /* - * Work Order Lot Occupancies + * Work Order Burial Site Contracts */ inactivatedRecordCount += database - .prepare(`update WorkOrderLotOccupancies + .prepare(`update WorkOrderBurialSiteContracts set recordDelete_userName = ?, recordDelete_timeMillis = ? where recordDelete_timeMillis is null @@ -35,13 +34,13 @@ export default async function cleanupDatabase(user) { select workOrderId from WorkOrders where recordDelete_timeMillis is not null)`) .run(user.userName, rightNowMillis).changes; purgedRecordCount += database - .prepare('delete from WorkOrderLotOccupancies where recordDelete_timeMillis <= ?') + .prepare('delete from WorkOrderBurialSiteContracts where recordDelete_timeMillis <= ?') .run(recordDeleteTimeMillisMin).changes; /* - * Work Order Lots + * Work Order Burial Sites */ inactivatedRecordCount += database - .prepare(`update WorkOrderLots + .prepare(`update WorkOrderBurialSites set recordDelete_userName = ?, recordDelete_timeMillis = ? where recordDelete_timeMillis is null @@ -49,7 +48,7 @@ export default async function cleanupDatabase(user) { select workOrderId from WorkOrders where recordDelete_timeMillis is not null)`) .run(user.userName, rightNowMillis).changes; purgedRecordCount += database - .prepare('delete from WorkOrderLots where recordDelete_timeMillis <= ?') + .prepare('delete from WorkOrderBurialSites where recordDelete_timeMillis <= ?') .run(recordDeleteTimeMillisMin).changes; /* * Work Order Milestones @@ -72,8 +71,8 @@ export default async function cleanupDatabase(user) { .prepare(`delete from WorkOrders where recordDelete_timeMillis <= ? and workOrderId not in (select workOrderId from WorkOrderComments) - and workOrderId not in (select workOrderId from WorkOrderLotOccupancies) - and workOrderId not in (select workOrderId from WorkOrderLots) + and workOrderId not in (select workOrderId from WorkOrderBurialSiteContracts) + and workOrderId not in (select workOrderId from WorkOrderBurialSites) and workOrderId not in (select workOrderId from WorkOrderMilestones)`) .run(recordDeleteTimeMillisMin).changes; /* @@ -94,67 +93,54 @@ export default async function cleanupDatabase(user) { and workOrderTypeId not in (select workOrderTypeId from WorkOrders)`) .run(recordDeleteTimeMillisMin).changes; /* - * Lot Occupancy Comments + * Burial Site Contract Comments */ inactivatedRecordCount += database - .prepare(`update LotOccupancyComments + .prepare(`update BurialSiteContractComments set recordDelete_userName = ?, recordDelete_timeMillis = ? where recordDelete_timeMillis is null - and lotOccupancyId in ( - select lotOccupancyId from LotOccupancies where recordDelete_timeMillis is not null)`) + and burialSiteContractId in ( + select burialSiteContractId from BurialSiteContracts where recordDelete_timeMillis is not null)`) .run(user.userName, rightNowMillis).changes; purgedRecordCount += database - .prepare('delete from LotOccupancyComments where recordDelete_timeMillis <= ?') + .prepare('delete from BurialSiteContractComments where recordDelete_timeMillis <= ?') .run(recordDeleteTimeMillisMin).changes; /* - * Lot Occupancy Fields + * Burial Site Contract Fields */ inactivatedRecordCount += database - .prepare(`update LotOccupancyFields + .prepare(`update BurialSiteContractFields set recordDelete_userName = ?, recordDelete_timeMillis = ? where recordDelete_timeMillis is null - and lotOccupancyId in (select lotOccupancyId from LotOccupancies where recordDelete_timeMillis is not null)`) + and burialSiteContractId in (select burialSiteContractId from BurialSiteContracts where recordDelete_timeMillis is not null)`) .run(user.userName, rightNowMillis).changes; purgedRecordCount += database - .prepare('delete from LotOccupancyFields where recordDelete_timeMillis <= ?') + .prepare('delete from BurialSiteContractFields where recordDelete_timeMillis <= ?') .run(recordDeleteTimeMillisMin).changes; /* - * Lot Occupancy Occupants - */ - inactivatedRecordCount += database - .prepare(`update LotOccupancyOccupants - set recordDelete_userName = ?, - recordDelete_timeMillis = ? - where recordDelete_timeMillis is null - and lotOccupancyId in (select lotOccupancyId from LotOccupancies where recordDelete_timeMillis is not null)`) - .run(user.userName, rightNowMillis).changes; - purgedRecordCount += database - .prepare('delete from LotOccupancyOccupants where recordDelete_timeMillis <= ?') - .run(recordDeleteTimeMillisMin).changes; - /* - * Lot Occupancy Fees/Transactions + * Burial Site Contract Fees/Transactions * - Maintain financials, do not delete related. */ purgedRecordCount += database - .prepare('delete from LotOccupancyFees where recordDelete_timeMillis <= ?') + .prepare('delete from BurialSiteContractFees where recordDelete_timeMillis <= ?') .run(recordDeleteTimeMillisMin).changes; purgedRecordCount += database - .prepare('delete from LotOccupancyTransactions where recordDelete_timeMillis <= ?') + .prepare('delete from BurialSiteContractTransactions where recordDelete_timeMillis <= ?') .run(recordDeleteTimeMillisMin).changes; /* - * Lot Occupancies + * Burial Site Contracts */ purgedRecordCount += database - .prepare(`delete from LotOccupancies + .prepare(`delete from BurialSiteContracts where recordDelete_timeMillis <= ? - and lotOccupancyId not in (select lotOccupancyId from LotOccupancyComments) - and lotOccupancyId not in (select lotOccupancyId from LotOccupancyFees) - and lotOccupancyId not in (select lotOccupancyId from LotOccupancyFields) - and lotOccupancyId not in (select lotOccupancyId from LotOccupancyOccupants) - and lotOccupancyId not in (select lotOccupancyId from LotOccupancyTransactions) - and lotOccupancyId not in (select lotOccupancyId from WorkOrderLotOccupancies)`) + and burialSiteContractId not in (select burialSiteContractId from BurialSiteContractComments) + and burialSiteContractId not in (select burialSiteContractId from BurialSiteContractFees) + and burialSiteContractId not in (select burialSiteContractId from BurialSiteContractFields) + and burialSiteContractId not in (select burialSiteContractId from BurialSiteContractInterments) + and burialSiteContractId not in (select burialSiteContractId from BurialSiteContractTransactions) + and burialSiteContractId not in (select burialSiteContractId from WorkOrderBurialSiteContracts)`) .run(recordDeleteTimeMillisMin).changes; /* * Fees @@ -169,7 +155,7 @@ export default async function cleanupDatabase(user) { purgedRecordCount += database .prepare(`delete from Fees where recordDelete_timeMillis <= ? - and feeId not in (select feeId from LotOccupancyFees)`) + and feeId not in (select feeId from BurialSiteContractFees)`) .run(recordDeleteTimeMillisMin).changes; /* * Fee Categories @@ -180,126 +166,118 @@ export default async function cleanupDatabase(user) { and feeCategoryId not in (select feeCategoryId from Fees)`) .run(recordDeleteTimeMillisMin).changes; /* - * Occupancy Type Fields + * Contract Type Fields */ inactivatedRecordCount += database - .prepare(`update OccupancyTypeFields + .prepare(`update ContractTypeFields set recordDelete_userName = ?, recordDelete_timeMillis = ? where recordDelete_timeMillis is null - and occupancyTypeId in (select occupancyTypeId from OccupancyTypes where recordDelete_timeMillis is not null)`) + and contractTypeId in (select contractTypeId from ContractTypes where recordDelete_timeMillis is not null)`) .run(user.userName, rightNowMillis).changes; purgedRecordCount += database - .prepare(`delete from OccupancyTypeFields + .prepare(`delete from ContractTypeFields where recordDelete_timeMillis <= ? - and occupancyTypeFieldId not in (select occupancyTypeFieldId from LotOccupancyFields)`) + and contractTypeFieldId not in (select contractTypeFieldId from BurialSiteContractFields)`) .run(recordDeleteTimeMillisMin).changes; /* * Occupancy Type Prints */ inactivatedRecordCount += database - .prepare(`update OccupancyTypePrints + .prepare(`update ContractTypePrints set recordDelete_userName = ?, recordDelete_timeMillis = ? where recordDelete_timeMillis is null - and occupancyTypeId in (select occupancyTypeId from OccupancyTypes where recordDelete_timeMillis is not null)`) + and contractTypeId in (select contractTypeId from ContractTypes where recordDelete_timeMillis is not null)`) .run(user.userName, rightNowMillis).changes; purgedRecordCount += database - .prepare('delete from OccupancyTypePrints where recordDelete_timeMillis <= ?') + .prepare('delete from ContractTypePrints where recordDelete_timeMillis <= ?') .run(recordDeleteTimeMillisMin).changes; /* - * Occupancy Types + * Contract Types */ purgedRecordCount += database - .prepare(`delete from OccupancyTypes + .prepare(`delete from ContractTypes where recordDelete_timeMillis <= ? - and occupancyTypeId not in (select occupancyTypeId from OccupancyTypeFields) - and occupancyTypeId not in (select occupancyTypeId from OccupancyTypePrints) - and occupancyTypeId not in (select occupancyTypeId from LotOccupancies) - and occupancyTypeId not in (select occupancyTypeId from Fees)`) + and contractTypeId not in (select contractTypeId from ContractTypeFields) + and contractTypeId not in (select contractTypeId from ContractTypePrints) + and contractTypeId not in (select contractTypeId from BurialSiteContracts) + and contractTypeId not in (select contractTypeId from Fees)`) .run(recordDeleteTimeMillisMin).changes; /* - * Lot Occupant Types - */ - purgedRecordCount += database - .prepare(`delete from LotOccupantTypes - where recordDelete_timeMillis <= ? - and lotOccupantTypeId not in (select lotOccupantTypeId from LotOccupancyOccupants)`) - .run(recordDeleteTimeMillisMin).changes; - /* - * Lot Comments + * Burial Site Comments */ inactivatedRecordCount += database - .prepare(`update LotComments + .prepare(`update BurialSiteComments set recordDelete_userName = ?, recordDelete_timeMillis = ? where recordDelete_timeMillis is null - and lotId in (select lotId from Lots where recordDelete_timeMillis is not null)`) + and burialSiteId in (select burialSiteId from BurialSites where recordDelete_timeMillis is not null)`) .run(user.userName, rightNowMillis).changes; purgedRecordCount += database - .prepare('delete from LotComments where recordDelete_timeMillis <= ?') + .prepare('delete from BurialSiteComments where recordDelete_timeMillis <= ?') .run(recordDeleteTimeMillisMin).changes; /* - * Lot Fields + * Burial Site Fields */ inactivatedRecordCount += database - .prepare(`update LotFields + .prepare(`update BurialSiteFields set recordDelete_userName = ?, recordDelete_timeMillis = ? where recordDelete_timeMillis is null - and lotId in (select lotId from Lots where recordDelete_timeMillis is not null)`) + and burialSiteId in (select burialSiteId from BurialSites where recordDelete_timeMillis is not null)`) .run(user.userName, rightNowMillis).changes; purgedRecordCount += database - .prepare('delete from LotFields where recordDelete_timeMillis <= ?') + .prepare('delete from BurialSiteFields where recordDelete_timeMillis <= ?') .run(recordDeleteTimeMillisMin).changes; /* - * Lots + * Burial Sites */ inactivatedRecordCount += database - .prepare(`update Lots + .prepare(`update BurialSites set recordDelete_userName = ?, recordDelete_timeMillis = ? where recordDelete_timeMillis is null - and mapId in (select mapId from Maps where recordDelete_timeMillis is not null)`) + and cemeteryId in (select cemeteryId from Cemeteries where recordDelete_timeMillis is not null)`) .run(user.userName, rightNowMillis).changes; purgedRecordCount += database - .prepare(`delete from Lots + .prepare(`delete from BurialSites where recordDelete_timeMillis <= ? - and lotId not in (select lotId from LotComments) - and lotId not in (select lotId from LotFields) - and lotId not in (select lotId from LotOccupancies) - and lotId not in (select lotId from WorkOrderLots)`) + and burialSiteId not in (select burialSiteId from BurialSiteComments) + and burialSiteId not in (select burialSiteId from BurialSiteFields) + and burialSiteId not in (select burialSiteId from BurialSiteContracts) + and burialSiteId not in (select burialSiteId from WorkOrderLots)`) .run(recordDeleteTimeMillisMin).changes; /* - * Lot Statuses + * Burial Site Statuses */ purgedRecordCount += database - .prepare(`delete from LotStatuses + .prepare(`delete from BurialSiteStatuses where recordDelete_timeMillis <= ? - and lotStatusId not in (select lotStatusId from Lots)`) + and burialSiteStatusId not in (select burialSiteStatusId from BurialSites)`) .run(recordDeleteTimeMillisMin).changes; /* - * Lot Type Fields + * Burial Site Type Fields */ inactivatedRecordCount += database - .prepare(`update LotTypeFields + .prepare(`update BurialSiteTypeFields set recordDelete_userName = ?, recordDelete_timeMillis = ? where recordDelete_timeMillis is null - and lotTypeId in (select lotTypeId from LotTypes where recordDelete_timeMillis is not null)`) + and burialSiteTypeId in (select burialSiteTypeId from BurialSiteTypes where recordDelete_timeMillis is not null)`) .run(user.userName, rightNowMillis).changes; purgedRecordCount += database - .prepare(`delete from LotTypeFields + .prepare(`delete from BurialSiteTypeFields where recordDelete_timeMillis <= ? - and lotTypeFieldId not in (select lotTypeFieldId from LotFields)`) + and burialSiteTypeFieldId not in (select burialSiteTypeFieldId from BurialSiteFields)`) .run(recordDeleteTimeMillisMin).changes; /* - * Lot Types + * Burial Site Types */ purgedRecordCount += database - .prepare(`delete from LotTypes + .prepare(`delete from BurialSiteTypes where recordDelete_timeMillis <= ? - and lotTypeId not in (select lotTypeId from Lots)`) + and burialSiteTypeId not in (select burialSiteTypeId from BurialSites)`) .run(recordDeleteTimeMillisMin).changes; database.release(); return { diff --git a/database/cleanupDatabase.ts b/database/cleanupDatabase.ts index 8e851401..f16fbc25 100644 --- a/database/cleanupDatabase.ts +++ b/database/cleanupDatabase.ts @@ -1,4 +1,6 @@ -import { getConfigProperty } from '../helpers/functions.config.js' +import { daysToMillis } from '@cityssm/to-millis' + +import { getConfigProperty } from '../helpers/config.helpers.js' import { acquireConnection } from './pool.js' @@ -10,9 +12,7 @@ export default async function cleanupDatabase( const rightNowMillis = Date.now() const recordDeleteTimeMillisMin = rightNowMillis - - getConfigProperty('settings.adminCleanup.recordDeleteAgeDays') * - 86_400 * - 1000 + daysToMillis(getConfigProperty('settings.adminCleanup.recordDeleteAgeDays')) let inactivatedRecordCount = 0 let purgedRecordCount = 0 @@ -37,12 +37,12 @@ export default async function cleanupDatabase( .run(recordDeleteTimeMillisMin).changes /* - * Work Order Lot Occupancies + * Work Order Burial Site Contracts */ inactivatedRecordCount += database .prepare( - `update WorkOrderLotOccupancies + `update WorkOrderBurialSiteContracts set recordDelete_userName = ?, recordDelete_timeMillis = ? where recordDelete_timeMillis is null @@ -53,17 +53,17 @@ export default async function cleanupDatabase( purgedRecordCount += database .prepare( - 'delete from WorkOrderLotOccupancies where recordDelete_timeMillis <= ?' + 'delete from WorkOrderBurialSiteContracts where recordDelete_timeMillis <= ?' ) .run(recordDeleteTimeMillisMin).changes /* - * Work Order Lots + * Work Order Burial Sites */ inactivatedRecordCount += database .prepare( - `update WorkOrderLots + `update WorkOrderBurialSites set recordDelete_userName = ?, recordDelete_timeMillis = ? where recordDelete_timeMillis is null @@ -73,7 +73,9 @@ export default async function cleanupDatabase( .run(user.userName, rightNowMillis).changes purgedRecordCount += database - .prepare('delete from WorkOrderLots where recordDelete_timeMillis <= ?') + .prepare( + 'delete from WorkOrderBurialSites where recordDelete_timeMillis <= ?' + ) .run(recordDeleteTimeMillisMin).changes /* @@ -106,8 +108,8 @@ export default async function cleanupDatabase( `delete from WorkOrders where recordDelete_timeMillis <= ? and workOrderId not in (select workOrderId from WorkOrderComments) - and workOrderId not in (select workOrderId from WorkOrderLotOccupancies) - and workOrderId not in (select workOrderId from WorkOrderLots) + and workOrderId not in (select workOrderId from WorkOrderBurialSiteContracts) + and workOrderId not in (select workOrderId from WorkOrderBurialSites) and workOrderId not in (select workOrderId from WorkOrderMilestones)` ) .run(recordDeleteTimeMillisMin).changes @@ -138,95 +140,77 @@ export default async function cleanupDatabase( .run(recordDeleteTimeMillisMin).changes /* - * Lot Occupancy Comments + * Burial Site Contract Comments */ inactivatedRecordCount += database .prepare( - `update LotOccupancyComments + `update BurialSiteContractComments set recordDelete_userName = ?, recordDelete_timeMillis = ? where recordDelete_timeMillis is null - and lotOccupancyId in ( - select lotOccupancyId from LotOccupancies where recordDelete_timeMillis is not null)` + and burialSiteContractId in ( + select burialSiteContractId from BurialSiteContracts where recordDelete_timeMillis is not null)` ) .run(user.userName, rightNowMillis).changes purgedRecordCount += database .prepare( - 'delete from LotOccupancyComments where recordDelete_timeMillis <= ?' + 'delete from BurialSiteContractComments where recordDelete_timeMillis <= ?' ) .run(recordDeleteTimeMillisMin).changes /* - * Lot Occupancy Fields + * Burial Site Contract Fields */ inactivatedRecordCount += database .prepare( - `update LotOccupancyFields + `update BurialSiteContractFields set recordDelete_userName = ?, recordDelete_timeMillis = ? where recordDelete_timeMillis is null - and lotOccupancyId in (select lotOccupancyId from LotOccupancies where recordDelete_timeMillis is not null)` + and burialSiteContractId in (select burialSiteContractId from BurialSiteContracts where recordDelete_timeMillis is not null)` ) .run(user.userName, rightNowMillis).changes purgedRecordCount += database .prepare( - 'delete from LotOccupancyFields where recordDelete_timeMillis <= ?' + 'delete from BurialSiteContractFields where recordDelete_timeMillis <= ?' ) .run(recordDeleteTimeMillisMin).changes /* - * Lot Occupancy Occupants - */ - - inactivatedRecordCount += database - .prepare( - `update LotOccupancyOccupants - set recordDelete_userName = ?, - recordDelete_timeMillis = ? - where recordDelete_timeMillis is null - and lotOccupancyId in (select lotOccupancyId from LotOccupancies where recordDelete_timeMillis is not null)` - ) - .run(user.userName, rightNowMillis).changes - - purgedRecordCount += database - .prepare( - 'delete from LotOccupancyOccupants where recordDelete_timeMillis <= ?' - ) - .run(recordDeleteTimeMillisMin).changes - - /* - * Lot Occupancy Fees/Transactions + * Burial Site Contract Fees/Transactions * - Maintain financials, do not delete related. */ purgedRecordCount += database - .prepare('delete from LotOccupancyFees where recordDelete_timeMillis <= ?') + .prepare( + 'delete from BurialSiteContractFees where recordDelete_timeMillis <= ?' + ) .run(recordDeleteTimeMillisMin).changes purgedRecordCount += database .prepare( - 'delete from LotOccupancyTransactions where recordDelete_timeMillis <= ?' + 'delete from BurialSiteContractTransactions where recordDelete_timeMillis <= ?' ) .run(recordDeleteTimeMillisMin).changes /* - * Lot Occupancies + * Burial Site Contracts */ purgedRecordCount += database .prepare( - `delete from LotOccupancies + `delete from BurialSiteContracts where recordDelete_timeMillis <= ? - and lotOccupancyId not in (select lotOccupancyId from LotOccupancyComments) - and lotOccupancyId not in (select lotOccupancyId from LotOccupancyFees) - and lotOccupancyId not in (select lotOccupancyId from LotOccupancyFields) - and lotOccupancyId not in (select lotOccupancyId from LotOccupancyOccupants) - and lotOccupancyId not in (select lotOccupancyId from LotOccupancyTransactions) - and lotOccupancyId not in (select lotOccupancyId from WorkOrderLotOccupancies)` + and burialSiteContractId not in (select burialSiteContractId from BurialSiteContractComments) + and burialSiteContractId not in (select burialSiteContractId from BurialSiteContractFees) + and burialSiteContractId not in (select burialSiteContractId from BurialSiteContractFields) + and burialSiteContractId not in (select burialSiteContractId from BurialSiteContractInterments) + and burialSiteContractId not in (select burialSiteContractId from BurialSiteContractTransactions) + and burialSiteContractId not in (select burialSiteContractId from WorkOrderBurialSiteContracts)` ) .run(recordDeleteTimeMillisMin).changes @@ -248,7 +232,7 @@ export default async function cleanupDatabase( .prepare( `delete from Fees where recordDelete_timeMillis <= ? - and feeId not in (select feeId from LotOccupancyFees)` + and feeId not in (select feeId from BurialSiteContractFees)` ) .run(recordDeleteTimeMillisMin).changes @@ -265,24 +249,24 @@ export default async function cleanupDatabase( .run(recordDeleteTimeMillisMin).changes /* - * Occupancy Type Fields + * Contract Type Fields */ inactivatedRecordCount += database .prepare( - `update OccupancyTypeFields + `update ContractTypeFields set recordDelete_userName = ?, recordDelete_timeMillis = ? where recordDelete_timeMillis is null - and occupancyTypeId in (select occupancyTypeId from OccupancyTypes where recordDelete_timeMillis is not null)` + and contractTypeId in (select contractTypeId from ContractTypes where recordDelete_timeMillis is not null)` ) .run(user.userName, rightNowMillis).changes purgedRecordCount += database .prepare( - `delete from OccupancyTypeFields + `delete from ContractTypeFields where recordDelete_timeMillis <= ? - and occupancyTypeFieldId not in (select occupancyTypeFieldId from LotOccupancyFields)` + and contractTypeFieldId not in (select contractTypeFieldId from BurialSiteContractFields)` ) .run(recordDeleteTimeMillisMin).changes @@ -292,151 +276,141 @@ export default async function cleanupDatabase( inactivatedRecordCount += database .prepare( - `update OccupancyTypePrints + `update ContractTypePrints set recordDelete_userName = ?, recordDelete_timeMillis = ? where recordDelete_timeMillis is null - and occupancyTypeId in (select occupancyTypeId from OccupancyTypes where recordDelete_timeMillis is not null)` + and contractTypeId in (select contractTypeId from ContractTypes where recordDelete_timeMillis is not null)` ) .run(user.userName, rightNowMillis).changes purgedRecordCount += database .prepare( - 'delete from OccupancyTypePrints where recordDelete_timeMillis <= ?' + 'delete from ContractTypePrints where recordDelete_timeMillis <= ?' ) .run(recordDeleteTimeMillisMin).changes /* - * Occupancy Types + * Contract Types */ purgedRecordCount += database .prepare( - `delete from OccupancyTypes + `delete from ContractTypes where recordDelete_timeMillis <= ? - and occupancyTypeId not in (select occupancyTypeId from OccupancyTypeFields) - and occupancyTypeId not in (select occupancyTypeId from OccupancyTypePrints) - and occupancyTypeId not in (select occupancyTypeId from LotOccupancies) - and occupancyTypeId not in (select occupancyTypeId from Fees)` + and contractTypeId not in (select contractTypeId from ContractTypeFields) + and contractTypeId not in (select contractTypeId from ContractTypePrints) + and contractTypeId not in (select contractTypeId from BurialSiteContracts) + and contractTypeId not in (select contractTypeId from Fees)` ) .run(recordDeleteTimeMillisMin).changes /* - * Lot Occupant Types - */ - - purgedRecordCount += database - .prepare( - `delete from LotOccupantTypes - where recordDelete_timeMillis <= ? - and lotOccupantTypeId not in (select lotOccupantTypeId from LotOccupancyOccupants)` - ) - .run(recordDeleteTimeMillisMin).changes - - /* - * Lot Comments + * Burial Site Comments */ inactivatedRecordCount += database .prepare( - `update LotComments + `update BurialSiteComments set recordDelete_userName = ?, recordDelete_timeMillis = ? where recordDelete_timeMillis is null - and lotId in (select lotId from Lots where recordDelete_timeMillis is not null)` + and burialSiteId in (select burialSiteId from BurialSites where recordDelete_timeMillis is not null)` ) .run(user.userName, rightNowMillis).changes purgedRecordCount += database - .prepare('delete from LotComments where recordDelete_timeMillis <= ?') + .prepare( + 'delete from BurialSiteComments where recordDelete_timeMillis <= ?' + ) .run(recordDeleteTimeMillisMin).changes /* - * Lot Fields + * Burial Site Fields */ inactivatedRecordCount += database .prepare( - `update LotFields + `update BurialSiteFields set recordDelete_userName = ?, recordDelete_timeMillis = ? where recordDelete_timeMillis is null - and lotId in (select lotId from Lots where recordDelete_timeMillis is not null)` + and burialSiteId in (select burialSiteId from BurialSites where recordDelete_timeMillis is not null)` ) .run(user.userName, rightNowMillis).changes purgedRecordCount += database - .prepare('delete from LotFields where recordDelete_timeMillis <= ?') + .prepare('delete from BurialSiteFields where recordDelete_timeMillis <= ?') .run(recordDeleteTimeMillisMin).changes /* - * Lots + * Burial Sites */ inactivatedRecordCount += database .prepare( - `update Lots + `update BurialSites set recordDelete_userName = ?, recordDelete_timeMillis = ? where recordDelete_timeMillis is null - and mapId in (select mapId from Maps where recordDelete_timeMillis is not null)` + and cemeteryId in (select cemeteryId from Cemeteries where recordDelete_timeMillis is not null)` ) .run(user.userName, rightNowMillis).changes purgedRecordCount += database .prepare( - `delete from Lots + `delete from BurialSites where recordDelete_timeMillis <= ? - and lotId not in (select lotId from LotComments) - and lotId not in (select lotId from LotFields) - and lotId not in (select lotId from LotOccupancies) - and lotId not in (select lotId from WorkOrderLots)` + and burialSiteId not in (select burialSiteId from BurialSiteComments) + and burialSiteId not in (select burialSiteId from BurialSiteFields) + and burialSiteId not in (select burialSiteId from BurialSiteContracts) + and burialSiteId not in (select burialSiteId from WorkOrderLots)` ) .run(recordDeleteTimeMillisMin).changes /* - * Lot Statuses + * Burial Site Statuses */ purgedRecordCount += database .prepare( - `delete from LotStatuses + `delete from BurialSiteStatuses where recordDelete_timeMillis <= ? - and lotStatusId not in (select lotStatusId from Lots)` + and burialSiteStatusId not in (select burialSiteStatusId from BurialSites)` ) .run(recordDeleteTimeMillisMin).changes /* - * Lot Type Fields + * Burial Site Type Fields */ inactivatedRecordCount += database .prepare( - `update LotTypeFields + `update BurialSiteTypeFields set recordDelete_userName = ?, recordDelete_timeMillis = ? where recordDelete_timeMillis is null - and lotTypeId in (select lotTypeId from LotTypes where recordDelete_timeMillis is not null)` + and burialSiteTypeId in (select burialSiteTypeId from BurialSiteTypes where recordDelete_timeMillis is not null)` ) .run(user.userName, rightNowMillis).changes purgedRecordCount += database .prepare( - `delete from LotTypeFields + `delete from BurialSiteTypeFields where recordDelete_timeMillis <= ? - and lotTypeFieldId not in (select lotTypeFieldId from LotFields)` + and burialSiteTypeFieldId not in (select burialSiteTypeFieldId from BurialSiteFields)` ) .run(recordDeleteTimeMillisMin).changes /* - * Lot Types + * Burial Site Types */ purgedRecordCount += database .prepare( - `delete from LotTypes + `delete from BurialSiteTypes where recordDelete_timeMillis <= ? - and lotTypeId not in (select lotTypeId from Lots)` + and burialSiteTypeId not in (select burialSiteTypeId from BurialSites)` ) .run(recordDeleteTimeMillisMin).changes diff --git a/database/deleteBurialSiteContractFee.d.ts b/database/deleteBurialSiteContractFee.d.ts new file mode 100644 index 00000000..9ad5a7fc --- /dev/null +++ b/database/deleteBurialSiteContractFee.d.ts @@ -0,0 +1 @@ +export default function deleteBurialSiteContractFee(burialSiteContractId: number | string, feeId: number | string, user: User): Promise; diff --git a/database/deleteLotOccupancyFee.js b/database/deleteBurialSiteContractFee.js similarity index 52% rename from database/deleteLotOccupancyFee.js rename to database/deleteBurialSiteContractFee.js index 40e60737..85c3a41d 100644 --- a/database/deleteLotOccupancyFee.js +++ b/database/deleteBurialSiteContractFee.js @@ -1,13 +1,13 @@ import { acquireConnection } from './pool.js'; -export default async function deleteLotOccupancyFee(lotOccupancyId, feeId, user) { +export default async function deleteBurialSiteContractFee(burialSiteContractId, feeId, user) { const database = await acquireConnection(); const result = database - .prepare(`update LotOccupancyFees + .prepare(`update BurialSteContractFees set recordDelete_userName = ?, recordDelete_timeMillis = ? - where lotOccupancyId = ? + where burialSiteContractId = ? and feeId = ?`) - .run(user.userName, Date.now(), lotOccupancyId, feeId); + .run(user.userName, Date.now(), burialSiteContractId, feeId); database.release(); return result.changes > 0; } diff --git a/database/deleteLotOccupancyFee.ts b/database/deleteBurialSiteContractFee.ts similarity index 59% rename from database/deleteLotOccupancyFee.ts rename to database/deleteBurialSiteContractFee.ts index 67293547..c3c52a9a 100644 --- a/database/deleteLotOccupancyFee.ts +++ b/database/deleteBurialSiteContractFee.ts @@ -1,7 +1,7 @@ import { acquireConnection } from './pool.js' -export default async function deleteLotOccupancyFee( - lotOccupancyId: number | string, +export default async function deleteBurialSiteContractFee( + burialSiteContractId: number | string, feeId: number | string, user: User ): Promise { @@ -9,13 +9,13 @@ export default async function deleteLotOccupancyFee( const result = database .prepare( - `update LotOccupancyFees + `update BurialSteContractFees set recordDelete_userName = ?, recordDelete_timeMillis = ? - where lotOccupancyId = ? + where burialSiteContractId = ? and feeId = ?` ) - .run(user.userName, Date.now(), lotOccupancyId, feeId) + .run(user.userName, Date.now(), burialSiteContractId, feeId) database.release() diff --git a/database/deleteBurialSiteContractField.d.ts b/database/deleteBurialSiteContractField.d.ts new file mode 100644 index 00000000..6a71c485 --- /dev/null +++ b/database/deleteBurialSiteContractField.d.ts @@ -0,0 +1,2 @@ +import type { PoolConnection } from 'better-sqlite-pool'; +export default function deleteBurialSiteContractField(burialSiteContractId: number | string, contractTypeFieldId: number | string, user: User, connectedDatabase?: PoolConnection): Promise; diff --git a/database/deleteBurialSiteContractField.js b/database/deleteBurialSiteContractField.js new file mode 100644 index 00000000..388e9e94 --- /dev/null +++ b/database/deleteBurialSiteContractField.js @@ -0,0 +1,15 @@ +import { acquireConnection } from './pool.js'; +export default async function deleteBurialSiteContractField(burialSiteContractId, contractTypeFieldId, user, connectedDatabase) { + const database = connectedDatabase ?? (await acquireConnection()); + const result = database + .prepare(`update BurialSiteContractFields + set recordDelete_userName = ?, + recordDelete_timeMillis = ? + where burialSiteContractId = ? + and contractTypeFieldId = ?`) + .run(user.userName, Date.now(), burialSiteContractId, contractTypeFieldId); + if (connectedDatabase === undefined) { + database.release(); + } + return result.changes > 0; +} diff --git a/database/deleteLotOccupancyField.ts b/database/deleteBurialSiteContractField.ts similarity index 58% rename from database/deleteLotOccupancyField.ts rename to database/deleteBurialSiteContractField.ts index f7332d46..d9067bc8 100644 --- a/database/deleteLotOccupancyField.ts +++ b/database/deleteBurialSiteContractField.ts @@ -2,9 +2,9 @@ import type { PoolConnection } from 'better-sqlite-pool' import { acquireConnection } from './pool.js' -export default async function deleteLotOccupancyField( - lotOccupancyId: number | string, - occupancyTypeFieldId: number | string, +export default async function deleteBurialSiteContractField( + burialSiteContractId: number | string, + contractTypeFieldId: number | string, user: User, connectedDatabase?: PoolConnection ): Promise { @@ -12,13 +12,13 @@ export default async function deleteLotOccupancyField( const result = database .prepare( - `update LotOccupancyFields + `update BurialSiteContractFields set recordDelete_userName = ?, recordDelete_timeMillis = ? - where lotOccupancyId = ? - and occupancyTypeFieldId = ?` + where burialSiteContractId = ? + and contractTypeFieldId = ?` ) - .run(user.userName, Date.now(), lotOccupancyId, occupancyTypeFieldId) + .run(user.userName, Date.now(), burialSiteContractId, contractTypeFieldId) if (connectedDatabase === undefined) { database.release() diff --git a/database/deleteBurialSiteContractInterment.d.ts b/database/deleteBurialSiteContractInterment.d.ts new file mode 100644 index 00000000..7961bfa4 --- /dev/null +++ b/database/deleteBurialSiteContractInterment.d.ts @@ -0,0 +1 @@ +export default function deleteBurialSiteContractInterment(burialSiteContractId: number | string, intermentNumber: number | string, user: User): Promise; diff --git a/database/deleteBurialSiteContractInterment.js b/database/deleteBurialSiteContractInterment.js new file mode 100644 index 00000000..31e5afb4 --- /dev/null +++ b/database/deleteBurialSiteContractInterment.js @@ -0,0 +1,13 @@ +import { acquireConnection } from './pool.js'; +export default async function deleteBurialSiteContractInterment(burialSiteContractId, intermentNumber, user) { + const database = await acquireConnection(); + const result = database + .prepare(`update BurialSiteContractInterments + set recordDelete_userName = ?, + recordDelete_timeMillis = ? + where burialSiteContractId = ? + and intermentNumber = ?`) + .run(user.userName, Date.now(), burialSiteContractId, intermentNumber); + database.release(); + return result.changes > 0; +} diff --git a/database/deleteBurialSiteContractInterment.ts b/database/deleteBurialSiteContractInterment.ts new file mode 100644 index 00000000..d59e92a0 --- /dev/null +++ b/database/deleteBurialSiteContractInterment.ts @@ -0,0 +1,23 @@ +import { acquireConnection } from './pool.js' + +export default async function deleteBurialSiteContractInterment( + burialSiteContractId: number | string, + intermentNumber: number | string, + user: User +): Promise { + const database = await acquireConnection() + + const result = database + .prepare( + `update BurialSiteContractInterments + set recordDelete_userName = ?, + recordDelete_timeMillis = ? + where burialSiteContractId = ? + and intermentNumber = ?` + ) + .run(user.userName, Date.now(), burialSiteContractId, intermentNumber) + + database.release() + + return result.changes > 0 +} diff --git a/database/deleteBurialSiteContractTransaction.d.ts b/database/deleteBurialSiteContractTransaction.d.ts new file mode 100644 index 00000000..12a0577c --- /dev/null +++ b/database/deleteBurialSiteContractTransaction.d.ts @@ -0,0 +1 @@ +export default function deleteBurialSiteContractTransaction(burialSiteContractId: number | string, transactionIndex: number | string, user: User): Promise; diff --git a/database/deleteLotOccupancyTransaction.js b/database/deleteBurialSiteContractTransaction.js similarity index 50% rename from database/deleteLotOccupancyTransaction.js rename to database/deleteBurialSiteContractTransaction.js index 0a7bb9e4..c7f72852 100644 --- a/database/deleteLotOccupancyTransaction.js +++ b/database/deleteBurialSiteContractTransaction.js @@ -1,13 +1,13 @@ import { acquireConnection } from './pool.js'; -export default async function deleteLotOccupancyTransaction(lotOccupancyId, transactionIndex, user) { +export default async function deleteBurialSiteContractTransaction(burialSiteContractId, transactionIndex, user) { const database = await acquireConnection(); const result = database - .prepare(`update LotOccupancyTransactions + .prepare(`update BurialSiteContractTransactions set recordDelete_userName = ?, recordDelete_timeMillis = ? - where lotOccupancyId = ? + where burialSiteContractId = ? and transactionIndex = ?`) - .run(user.userName, Date.now(), lotOccupancyId, transactionIndex); + .run(user.userName, Date.now(), burialSiteContractId, transactionIndex); database.release(); return result.changes > 0; } diff --git a/database/deleteLotOccupancyTransaction.ts b/database/deleteBurialSiteContractTransaction.ts similarity index 58% rename from database/deleteLotOccupancyTransaction.ts rename to database/deleteBurialSiteContractTransaction.ts index 6301265c..b4c991cf 100644 --- a/database/deleteLotOccupancyTransaction.ts +++ b/database/deleteBurialSiteContractTransaction.ts @@ -1,7 +1,7 @@ import { acquireConnection } from './pool.js' -export default async function deleteLotOccupancyTransaction( - lotOccupancyId: number | string, +export default async function deleteBurialSiteContractTransaction( + burialSiteContractId: number | string, transactionIndex: number | string, user: User ): Promise { @@ -9,13 +9,13 @@ export default async function deleteLotOccupancyTransaction( const result = database .prepare( - `update LotOccupancyTransactions + `update BurialSiteContractTransactions set recordDelete_userName = ?, recordDelete_timeMillis = ? - where lotOccupancyId = ? + where burialSiteContractId = ? and transactionIndex = ?` ) - .run(user.userName, Date.now(), lotOccupancyId, transactionIndex) + .run(user.userName, Date.now(), burialSiteContractId, transactionIndex) database.release() diff --git a/database/deleteBurialSiteField.d.ts b/database/deleteBurialSiteField.d.ts new file mode 100644 index 00000000..5385343b --- /dev/null +++ b/database/deleteBurialSiteField.d.ts @@ -0,0 +1,2 @@ +import type { PoolConnection } from 'better-sqlite-pool'; +export default function deleteBurialSiteField(burialSiteId: number | string, burialSiteTypeFieldId: number | string, user: User, connectedDatabase?: PoolConnection): Promise; diff --git a/database/deleteLotField.js b/database/deleteBurialSiteField.js similarity index 51% rename from database/deleteLotField.js rename to database/deleteBurialSiteField.js index c52d59c3..56fa109a 100644 --- a/database/deleteLotField.js +++ b/database/deleteBurialSiteField.js @@ -1,13 +1,13 @@ import { acquireConnection } from './pool.js'; -export default async function deleteLotField(lotId, lotTypeFieldId, user, connectedDatabase) { +export default async function deleteBurialSiteField(burialSiteId, burialSiteTypeFieldId, user, connectedDatabase) { const database = connectedDatabase ?? (await acquireConnection()); const result = database - .prepare(`update LotFields + .prepare(`update BurialSiteFields set recordDelete_userName = ?, recordDelete_timeMillis = ? - where lotId = ? - and lotTypeFieldId = ?`) - .run(user.userName, Date.now(), lotId, lotTypeFieldId); + where burialSiteId = ? + and burialSiteTypeFieldId = ?`) + .run(user.userName, Date.now(), burialSiteId, burialSiteTypeFieldId); if (connectedDatabase === undefined) { database.release(); } diff --git a/database/deleteLotField.ts b/database/deleteBurialSiteField.ts similarity index 60% rename from database/deleteLotField.ts rename to database/deleteBurialSiteField.ts index 3ac93c9d..41b49629 100644 --- a/database/deleteLotField.ts +++ b/database/deleteBurialSiteField.ts @@ -2,9 +2,9 @@ import type { PoolConnection } from 'better-sqlite-pool' import { acquireConnection } from './pool.js' -export default async function deleteLotField( - lotId: number | string, - lotTypeFieldId: number | string, +export default async function deleteBurialSiteField( + burialSiteId: number | string, + burialSiteTypeFieldId: number | string, user: User, connectedDatabase?: PoolConnection ): Promise { @@ -12,13 +12,13 @@ export default async function deleteLotField( const result = database .prepare( - `update LotFields + `update BurialSiteFields set recordDelete_userName = ?, recordDelete_timeMillis = ? - where lotId = ? - and lotTypeFieldId = ?` + where burialSiteId = ? + and burialSiteTypeFieldId = ?` ) - .run(user.userName, Date.now(), lotId, lotTypeFieldId) + .run(user.userName, Date.now(), burialSiteId, burialSiteTypeFieldId) if (connectedDatabase === undefined) { database.release() diff --git a/database/deleteContractTypePrint.d.ts b/database/deleteContractTypePrint.d.ts new file mode 100644 index 00000000..58058ccd --- /dev/null +++ b/database/deleteContractTypePrint.d.ts @@ -0,0 +1 @@ +export default function deleteContractTypePrint(contractTypeId: number | string, printEJS: string, user: User): Promise; diff --git a/database/deleteOccupancyTypePrint.js b/database/deleteContractTypePrint.js similarity index 55% rename from database/deleteOccupancyTypePrint.js rename to database/deleteContractTypePrint.js index dc436560..776edb6f 100644 --- a/database/deleteOccupancyTypePrint.js +++ b/database/deleteContractTypePrint.js @@ -1,15 +1,15 @@ import { clearCacheByTableName } from '../helpers/functions.cache.js'; import { acquireConnection } from './pool.js'; -export default async function deleteOccupancyTypePrint(occupancyTypeId, printEJS, user) { +export default async function deleteContractTypePrint(contractTypeId, printEJS, user) { const database = await acquireConnection(); const result = database - .prepare(`update OccupancyTypePrints + .prepare(`update ContractTypePrints set recordDelete_userName = ?, recordDelete_timeMillis = ? - where occupancyTypeId = ? + where contractTypeId = ? and printEJS = ?`) - .run(user.userName, Date.now(), occupancyTypeId, printEJS); + .run(user.userName, Date.now(), contractTypeId, printEJS); database.release(); - clearCacheByTableName('OccupancyTypePrints'); + clearCacheByTableName('ContractTypePrints'); return result.changes > 0; } diff --git a/database/deleteOccupancyTypePrint.ts b/database/deleteContractTypePrint.ts similarity index 60% rename from database/deleteOccupancyTypePrint.ts rename to database/deleteContractTypePrint.ts index 087a9e11..840ed211 100644 --- a/database/deleteOccupancyTypePrint.ts +++ b/database/deleteContractTypePrint.ts @@ -2,8 +2,8 @@ import { clearCacheByTableName } from '../helpers/functions.cache.js' import { acquireConnection } from './pool.js' -export default async function deleteOccupancyTypePrint( - occupancyTypeId: number | string, +export default async function deleteContractTypePrint( + contractTypeId: number | string, printEJS: string, user: User ): Promise { @@ -11,17 +11,17 @@ export default async function deleteOccupancyTypePrint( const result = database .prepare( - `update OccupancyTypePrints + `update ContractTypePrints set recordDelete_userName = ?, recordDelete_timeMillis = ? - where occupancyTypeId = ? + where contractTypeId = ? and printEJS = ?` ) - .run(user.userName, Date.now(), occupancyTypeId, printEJS) + .run(user.userName, Date.now(), contractTypeId, printEJS) database.release() - clearCacheByTableName('OccupancyTypePrints') + clearCacheByTableName('ContractTypePrints') return result.changes > 0 } diff --git a/database/deleteLotField.d.ts b/database/deleteLotField.d.ts deleted file mode 100644 index 1d3d7a93..00000000 --- a/database/deleteLotField.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -import type { PoolConnection } from 'better-sqlite-pool'; -export default function deleteLotField(lotId: number | string, lotTypeFieldId: number | string, user: User, connectedDatabase?: PoolConnection): Promise; diff --git a/database/deleteLotOccupancyFee.d.ts b/database/deleteLotOccupancyFee.d.ts deleted file mode 100644 index 83d67eed..00000000 --- a/database/deleteLotOccupancyFee.d.ts +++ /dev/null @@ -1 +0,0 @@ -export default function deleteLotOccupancyFee(lotOccupancyId: number | string, feeId: number | string, user: User): Promise; diff --git a/database/deleteLotOccupancyField.d.ts b/database/deleteLotOccupancyField.d.ts deleted file mode 100644 index e7228f85..00000000 --- a/database/deleteLotOccupancyField.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -import type { PoolConnection } from 'better-sqlite-pool'; -export default function deleteLotOccupancyField(lotOccupancyId: number | string, occupancyTypeFieldId: number | string, user: User, connectedDatabase?: PoolConnection): Promise; diff --git a/database/deleteLotOccupancyField.js b/database/deleteLotOccupancyField.js deleted file mode 100644 index 04f0130c..00000000 --- a/database/deleteLotOccupancyField.js +++ /dev/null @@ -1,15 +0,0 @@ -import { acquireConnection } from './pool.js'; -export default async function deleteLotOccupancyField(lotOccupancyId, occupancyTypeFieldId, user, connectedDatabase) { - const database = connectedDatabase ?? (await acquireConnection()); - const result = database - .prepare(`update LotOccupancyFields - set recordDelete_userName = ?, - recordDelete_timeMillis = ? - where lotOccupancyId = ? - and occupancyTypeFieldId = ?`) - .run(user.userName, Date.now(), lotOccupancyId, occupancyTypeFieldId); - if (connectedDatabase === undefined) { - database.release(); - } - return result.changes > 0; -} diff --git a/database/deleteLotOccupancyOccupant.d.ts b/database/deleteLotOccupancyOccupant.d.ts deleted file mode 100644 index 8f7d456e..00000000 --- a/database/deleteLotOccupancyOccupant.d.ts +++ /dev/null @@ -1 +0,0 @@ -export default function deleteLotOccupancyOccupant(lotOccupancyId: number | string, lotOccupantIndex: number | string, user: User): Promise; diff --git a/database/deleteLotOccupancyOccupant.js b/database/deleteLotOccupancyOccupant.js deleted file mode 100644 index 59965934..00000000 --- a/database/deleteLotOccupancyOccupant.js +++ /dev/null @@ -1,13 +0,0 @@ -import { acquireConnection } from './pool.js'; -export default async function deleteLotOccupancyOccupant(lotOccupancyId, lotOccupantIndex, user) { - const database = await acquireConnection(); - const result = database - .prepare(`update LotOccupancyOccupants - set recordDelete_userName = ?, - recordDelete_timeMillis = ? - where lotOccupancyId = ? - and lotOccupantIndex = ?`) - .run(user.userName, Date.now(), lotOccupancyId, lotOccupantIndex); - database.release(); - return result.changes > 0; -} diff --git a/database/deleteLotOccupancyOccupant.ts b/database/deleteLotOccupancyOccupant.ts deleted file mode 100644 index 1e37eaf6..00000000 --- a/database/deleteLotOccupancyOccupant.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { acquireConnection } from './pool.js' - -export default async function deleteLotOccupancyOccupant( - lotOccupancyId: number | string, - lotOccupantIndex: number | string, - user: User -): Promise { - const database = await acquireConnection() - - const result = database - .prepare( - `update LotOccupancyOccupants - set recordDelete_userName = ?, - recordDelete_timeMillis = ? - where lotOccupancyId = ? - and lotOccupantIndex = ?` - ) - .run(user.userName, Date.now(), lotOccupancyId, lotOccupantIndex) - - database.release() - - return result.changes > 0 -} diff --git a/database/deleteLotOccupancyTransaction.d.ts b/database/deleteLotOccupancyTransaction.d.ts deleted file mode 100644 index 38324ddc..00000000 --- a/database/deleteLotOccupancyTransaction.d.ts +++ /dev/null @@ -1 +0,0 @@ -export default function deleteLotOccupancyTransaction(lotOccupancyId: number | string, transactionIndex: number | string, user: User): Promise; diff --git a/database/deleteOccupancyTypePrint.d.ts b/database/deleteOccupancyTypePrint.d.ts deleted file mode 100644 index 64ce0a3b..00000000 --- a/database/deleteOccupancyTypePrint.d.ts +++ /dev/null @@ -1 +0,0 @@ -export default function deleteOccupancyTypePrint(occupancyTypeId: number | string, printEJS: string, user: User): Promise; diff --git a/database/deleteRecord.d.ts b/database/deleteRecord.d.ts index 434506f3..5bb92ae1 100644 --- a/database/deleteRecord.d.ts +++ b/database/deleteRecord.d.ts @@ -1,3 +1,3 @@ -type RecordTable = 'FeeCategories' | 'Fees' | 'Lots' | 'LotComments' | 'LotOccupancies' | 'LotOccupancyComments' | 'LotOccupantTypes' | 'LotStatuses' | 'LotTypes' | 'LotTypeFields' | 'Maps' | 'OccupancyTypes' | 'OccupancyTypeFields' | 'WorkOrders' | 'WorkOrderComments' | 'WorkOrderMilestones' | 'WorkOrderMilestoneTypes' | 'WorkOrderTypes'; +type RecordTable = 'FeeCategories' | 'Fees' | 'BurialSites' | 'BurialSiteComments' | 'BurialSiteContracts' | 'BurialSiteContractComments' | 'BurialSiteStatuses' | 'BurialSiteTypes' | 'BurialSiteTypeFields' | 'Cemeteries' | 'ContractTypes' | 'ContractTypeFields' | 'WorkOrders' | 'WorkOrderComments' | 'WorkOrderMilestones' | 'WorkOrderMilestoneTypes' | 'WorkOrderTypes'; export declare function deleteRecord(recordTable: RecordTable, recordId: number | string, user: User): Promise; export {}; diff --git a/database/deleteRecord.js b/database/deleteRecord.js index 5102341a..5356517f 100644 --- a/database/deleteRecord.js +++ b/database/deleteRecord.js @@ -3,17 +3,16 @@ import { acquireConnection } from './pool.js'; const recordIdColumns = new Map(); recordIdColumns.set('FeeCategories', 'feeCategoryId'); recordIdColumns.set('Fees', 'feeId'); -recordIdColumns.set('Lots', 'lotId'); -recordIdColumns.set('LotComments', 'lotCommentId'); -recordIdColumns.set('LotOccupancies', 'lotOccupancyId'); -recordIdColumns.set('LotOccupancyComments', 'lotOccupancyCommentId'); -recordIdColumns.set('LotOccupantTypes', 'lotOccupantTypeId'); -recordIdColumns.set('LotStatuses', 'lotStatusId'); -recordIdColumns.set('LotTypes', 'lotTypeId'); -recordIdColumns.set('LotTypeFields', 'lotTypeId'); -recordIdColumns.set('Maps', 'mapId'); -recordIdColumns.set('OccupancyTypes', 'occupancyTypeId'); -recordIdColumns.set('OccupancyTypeFields', 'occupancyTypeFieldId'); +recordIdColumns.set('BurialSites', 'burialSiteId'); +recordIdColumns.set('BurialSiteComments', 'burialSiteCommentId'); +recordIdColumns.set('BurialSiteContracts', 'burialSiteContractId'); +recordIdColumns.set('BurialSiteContractComments', 'burialSiteContractCommentId'); +recordIdColumns.set('BurialSiteStatuses', 'burialSiteStatusId'); +recordIdColumns.set('BurialSiteTypes', 'burialSiteTypeId'); +recordIdColumns.set('BurialSiteTypeFields', 'burialSiteFieldTypeId'); +recordIdColumns.set('Cemeteries', 'cemeteryId'); +recordIdColumns.set('ContractTypes', 'contractTypeId'); +recordIdColumns.set('ContractTypeFields', 'contractTypeFieldId'); recordIdColumns.set('WorkOrders', 'workOrderId'); recordIdColumns.set('WorkOrderComments', 'workOrderCommentId'); recordIdColumns.set('WorkOrderMilestones', 'workOrderMilestoneId'); @@ -21,18 +20,14 @@ recordIdColumns.set('WorkOrderMilestoneTypes', 'workOrderMilestoneTypeId'); recordIdColumns.set('WorkOrderTypes', 'workOrderTypeId'); const relatedTables = new Map(); relatedTables.set('FeeCategories', ['Fees']); -relatedTables.set('Lots', ['LotFields', 'LotComments']); -relatedTables.set('LotOccupancies', [ - 'LotOccupancyOccupants', - 'LotOccupancyFields', - 'LotOccupancyComments' -]); -relatedTables.set('LotTypes', ['LotTypeFields']); -relatedTables.set('Maps', ['Lots']); -relatedTables.set('OccupancyTypes', [ - 'OccupancyTypePrints', - 'OccupancyTypeFields' +relatedTables.set('BurialSites', ['BurialSiteFields', 'BurialSiteComments']); +relatedTables.set('BurialSiteContracts', [ + 'BurialSiteContractFields', + 'BurialSiteContractComments' ]); +relatedTables.set('BurialSiteTypes', ['BurialSiteTypeFields']); +relatedTables.set('Cemeteries', ['BurialSites']); +relatedTables.set('ContractTypes', ['ContractTypePrints', 'ContractTypeFields']); relatedTables.set('WorkOrders', [ 'WorkOrderMilestones', 'WorkOrderLots', diff --git a/database/deleteRecord.ts b/database/deleteRecord.ts index f8d02017..7e3d364e 100644 --- a/database/deleteRecord.ts +++ b/database/deleteRecord.ts @@ -5,17 +5,16 @@ import { acquireConnection } from './pool.js' type RecordTable = | 'FeeCategories' | 'Fees' - | 'Lots' - | 'LotComments' - | 'LotOccupancies' - | 'LotOccupancyComments' - | 'LotOccupantTypes' - | 'LotStatuses' - | 'LotTypes' - | 'LotTypeFields' - | 'Maps' - | 'OccupancyTypes' - | 'OccupancyTypeFields' + | 'BurialSites' + | 'BurialSiteComments' + | 'BurialSiteContracts' + | 'BurialSiteContractComments' + | 'BurialSiteStatuses' + | 'BurialSiteTypes' + | 'BurialSiteTypeFields' + | 'Cemeteries' + | 'ContractTypes' + | 'ContractTypeFields' | 'WorkOrders' | 'WorkOrderComments' | 'WorkOrderMilestones' @@ -25,17 +24,16 @@ type RecordTable = const recordIdColumns = new Map() recordIdColumns.set('FeeCategories', 'feeCategoryId') recordIdColumns.set('Fees', 'feeId') -recordIdColumns.set('Lots', 'lotId') -recordIdColumns.set('LotComments', 'lotCommentId') -recordIdColumns.set('LotOccupancies', 'lotOccupancyId') -recordIdColumns.set('LotOccupancyComments', 'lotOccupancyCommentId') -recordIdColumns.set('LotOccupantTypes', 'lotOccupantTypeId') -recordIdColumns.set('LotStatuses', 'lotStatusId') -recordIdColumns.set('LotTypes', 'lotTypeId') -recordIdColumns.set('LotTypeFields', 'lotTypeId') -recordIdColumns.set('Maps', 'mapId') -recordIdColumns.set('OccupancyTypes', 'occupancyTypeId') -recordIdColumns.set('OccupancyTypeFields', 'occupancyTypeFieldId') +recordIdColumns.set('BurialSites', 'burialSiteId') +recordIdColumns.set('BurialSiteComments', 'burialSiteCommentId') +recordIdColumns.set('BurialSiteContracts', 'burialSiteContractId') +recordIdColumns.set('BurialSiteContractComments', 'burialSiteContractCommentId') +recordIdColumns.set('BurialSiteStatuses', 'burialSiteStatusId') +recordIdColumns.set('BurialSiteTypes', 'burialSiteTypeId') +recordIdColumns.set('BurialSiteTypeFields', 'burialSiteFieldTypeId') +recordIdColumns.set('Cemeteries', 'cemeteryId') +recordIdColumns.set('ContractTypes', 'contractTypeId') +recordIdColumns.set('ContractTypeFields', 'contractTypeFieldId') recordIdColumns.set('WorkOrders', 'workOrderId') recordIdColumns.set('WorkOrderComments', 'workOrderCommentId') recordIdColumns.set('WorkOrderMilestones', 'workOrderMilestoneId') @@ -44,18 +42,14 @@ recordIdColumns.set('WorkOrderTypes', 'workOrderTypeId') const relatedTables = new Map() relatedTables.set('FeeCategories', ['Fees']) -relatedTables.set('Lots', ['LotFields', 'LotComments']) -relatedTables.set('LotOccupancies', [ - 'LotOccupancyOccupants', - 'LotOccupancyFields', - 'LotOccupancyComments' -]) -relatedTables.set('LotTypes', ['LotTypeFields']) -relatedTables.set('Maps', ['Lots']) -relatedTables.set('OccupancyTypes', [ - 'OccupancyTypePrints', - 'OccupancyTypeFields' +relatedTables.set('BurialSites', ['BurialSiteFields', 'BurialSiteComments']) +relatedTables.set('BurialSiteContracts', [ + 'BurialSiteContractFields', + 'BurialSiteContractComments' ]) +relatedTables.set('BurialSiteTypes', ['BurialSiteTypeFields']) +relatedTables.set('Cemeteries', ['BurialSites']) +relatedTables.set('ContractTypes', ['ContractTypePrints', 'ContractTypeFields']) relatedTables.set('WorkOrders', [ 'WorkOrderMilestones', 'WorkOrderLots', diff --git a/database/deleteWorkOrderBurialSite.d.ts b/database/deleteWorkOrderBurialSite.d.ts new file mode 100644 index 00000000..d4ba162c --- /dev/null +++ b/database/deleteWorkOrderBurialSite.d.ts @@ -0,0 +1 @@ +export default function deleteWorkOrderBurialSite(workOrderId: number | string, burialSiteId: number | string, user: User): Promise; diff --git a/database/deleteWorkOrderLot.js b/database/deleteWorkOrderBurialSite.js similarity index 54% rename from database/deleteWorkOrderLot.js rename to database/deleteWorkOrderBurialSite.js index 9f8b16cf..5fcd6b58 100644 --- a/database/deleteWorkOrderLot.js +++ b/database/deleteWorkOrderBurialSite.js @@ -1,13 +1,13 @@ import { acquireConnection } from './pool.js'; -export default async function deleteWorkOrderLot(workOrderId, lotId, user) { +export default async function deleteWorkOrderBurialSite(workOrderId, burialSiteId, user) { const database = await acquireConnection(); const result = database - .prepare(`update WorkOrderLots + .prepare(`update WorkOrderBurialSites set recordDelete_userName = ?, recordDelete_timeMillis = ? where workOrderId = ? - and lotId = ?`) - .run(user.userName, Date.now(), workOrderId, lotId); + and burialSiteId = ?`) + .run(user.userName, Date.now(), workOrderId, burialSiteId); database.release(); return result.changes > 0; } diff --git a/database/deleteWorkOrderLot.ts b/database/deleteWorkOrderBurialSite.ts similarity index 62% rename from database/deleteWorkOrderLot.ts rename to database/deleteWorkOrderBurialSite.ts index 827f7162..df99f5ac 100644 --- a/database/deleteWorkOrderLot.ts +++ b/database/deleteWorkOrderBurialSite.ts @@ -1,21 +1,21 @@ import { acquireConnection } from './pool.js' -export default async function deleteWorkOrderLot( +export default async function deleteWorkOrderBurialSite( workOrderId: number | string, - lotId: number | string, + burialSiteId: number | string, user: User ): Promise { const database = await acquireConnection() const result = database .prepare( - `update WorkOrderLots + `update WorkOrderBurialSites set recordDelete_userName = ?, recordDelete_timeMillis = ? where workOrderId = ? - and lotId = ?` + and burialSiteId = ?` ) - .run(user.userName, Date.now(), workOrderId, lotId) + .run(user.userName, Date.now(), workOrderId, burialSiteId) database.release() diff --git a/database/deleteWorkOrderBurialSiteContract.d.ts b/database/deleteWorkOrderBurialSiteContract.d.ts new file mode 100644 index 00000000..8a834a14 --- /dev/null +++ b/database/deleteWorkOrderBurialSiteContract.d.ts @@ -0,0 +1 @@ +export default function deleteWorkOrderBurialSiteContract(workOrderId: number | string, burialSiteContractId: number | string, user: User): Promise; diff --git a/database/deleteWorkOrderLotOccupancy.js b/database/deleteWorkOrderBurialSiteContract.js similarity index 50% rename from database/deleteWorkOrderLotOccupancy.js rename to database/deleteWorkOrderBurialSiteContract.js index c877c2c3..b403f460 100644 --- a/database/deleteWorkOrderLotOccupancy.js +++ b/database/deleteWorkOrderBurialSiteContract.js @@ -1,13 +1,13 @@ import { acquireConnection } from './pool.js'; -export default async function deleteWorkOrderLotOccupancy(workOrderId, lotOccupancyId, user) { +export default async function deleteWorkOrderBurialSiteContract(workOrderId, burialSiteContractId, user) { const database = await acquireConnection(); const result = database - .prepare(`update WorkOrderLotOccupancies + .prepare(`update WorkOrderBurialSiteContracts set recordDelete_userName = ?, recordDelete_timeMillis = ? where workOrderId = ? - and lotOccupancyId = ?`) - .run(user.userName, Date.now(), workOrderId, lotOccupancyId); + and burialSiteContractId = ?`) + .run(user.userName, Date.now(), workOrderId, burialSiteContractId); database.release(); return result.changes > 0; } diff --git a/database/deleteWorkOrderLotOccupancy.ts b/database/deleteWorkOrderBurialSiteContract.ts similarity index 58% rename from database/deleteWorkOrderLotOccupancy.ts rename to database/deleteWorkOrderBurialSiteContract.ts index 82be9e0f..3ec5fa82 100644 --- a/database/deleteWorkOrderLotOccupancy.ts +++ b/database/deleteWorkOrderBurialSiteContract.ts @@ -1,21 +1,21 @@ import { acquireConnection } from './pool.js' -export default async function deleteWorkOrderLotOccupancy( +export default async function deleteWorkOrderBurialSiteContract( workOrderId: number | string, - lotOccupancyId: number | string, + burialSiteContractId: number | string, user: User ): Promise { const database = await acquireConnection() const result = database .prepare( - `update WorkOrderLotOccupancies + `update WorkOrderBurialSiteContracts set recordDelete_userName = ?, recordDelete_timeMillis = ? where workOrderId = ? - and lotOccupancyId = ?` + and burialSiteContractId = ?` ) - .run(user.userName, Date.now(), workOrderId, lotOccupancyId) + .run(user.userName, Date.now(), workOrderId, burialSiteContractId) database.release() diff --git a/database/deleteWorkOrderLot.d.ts b/database/deleteWorkOrderLot.d.ts deleted file mode 100644 index 7da5b373..00000000 --- a/database/deleteWorkOrderLot.d.ts +++ /dev/null @@ -1 +0,0 @@ -export default function deleteWorkOrderLot(workOrderId: number | string, lotId: number | string, user: User): Promise; diff --git a/database/deleteWorkOrderLotOccupancy.d.ts b/database/deleteWorkOrderLotOccupancy.d.ts deleted file mode 100644 index c253668d..00000000 --- a/database/deleteWorkOrderLotOccupancy.d.ts +++ /dev/null @@ -1 +0,0 @@ -export default function deleteWorkOrderLotOccupancy(workOrderId: number | string, lotOccupancyId: number | string, user: User): Promise; diff --git a/database/getLot.d.ts b/database/getBurialSite.d.ts similarity index 60% rename from database/getLot.d.ts rename to database/getBurialSite.d.ts index 5ef6a0fb..d5f2d2fd 100644 --- a/database/getLot.d.ts +++ b/database/getBurialSite.d.ts @@ -1,3 +1,3 @@ import type { Lot } from '../types/recordTypes.js'; export declare function getLotByLotName(lotName: string): Promise; -export default function getLot(lotId: number | string): Promise; +export default function getLot(burialSiteId: number | string): Promise; diff --git a/database/getBurialSite.js b/database/getBurialSite.js new file mode 100644 index 00000000..25c12557 --- /dev/null +++ b/database/getBurialSite.js @@ -0,0 +1,48 @@ +import getLotComments from './getLotComments.js'; +import getLotFields from './getLotFields.js'; +import getBurialSiteInterments from './getLotOccupancies.js'; +import { acquireConnection } from './pool.js'; +const baseSQL = `select l.burialSiteId, + l.burialSiteTypeId, t.burialSiteType, + l.burialSiteNameSegment1, + l.burialSiteNameSegment2, + l.burialSiteNameSegment3, + l.burialSiteNameSegment4, + l.burialSiteNameSegment5, + l.burialSiteStatusId, s.burialSiteStatus, + l.cemeteryId, m.cemeteryName, + m.cemeterySvg, l.cemeterySvgId, + l.burialSiteLatitude, l.burialSiteLongitude, + + from BurialSites l + left join BurialSiteTypes t on l.burialSiteTypeId = t.burialSiteTypeId + left join BurialSiteStatuses s on l.burialSiteStatusId = s.burialSiteStatusId + left join Cemeteries m on l.cemeteryId = m.cemeteryId + where l.recordDelete_timeMillis is null`; +async function _getBurialSite(sql, burialSiteIdOrLotName) { + const database = await acquireConnection(); + const burialSite = database.prepare(sql).get(burialSiteIdOrLotName); + if (burialSite !== undefined) { + const lotOccupancies = await getBurialSiteInterments({ + lotId: burialSite.lotId + }, { + includeOccupants: true, + includeFees: false, + includeTransactions: false, + limit: -1, + offset: 0 + }, database); + burialSite.lotOccupancies = lotOccupancies.lotOccupancies; + burialSite.lotFields = await getLotFields(burialSite.lotId, database); + burialSite.lotComments = await getLotComments(burialSite.lotId, database); + } + database.release(); + return burialSite; +} +// TODO +export async function getLotByLotName(lotName) { + return await _getBurialSite(`${baseSQL} and l.lotName = ?`, lotName); +} +export default async function getLot(burialSiteId) { + return await _getBurialSite(`${baseSQL} and l.burialSiteId = ?`, burialSiteId); +} diff --git a/database/getBurialSite.ts b/database/getBurialSite.ts new file mode 100644 index 00000000..dd8affa9 --- /dev/null +++ b/database/getBurialSite.ts @@ -0,0 +1,72 @@ +import type { Lot } from '../types/recordTypes.js' + +import getLotComments from './getLotComments.js' +import getLotFields from './getLotFields.js' +import getBurialSiteInterments from './getLotOccupancies.js' +import { acquireConnection } from './pool.js' + +const baseSQL = `select l.burialSiteId, + l.burialSiteTypeId, t.burialSiteType, + l.burialSiteNameSegment1, + l.burialSiteNameSegment2, + l.burialSiteNameSegment3, + l.burialSiteNameSegment4, + l.burialSiteNameSegment5, + l.burialSiteStatusId, s.burialSiteStatus, + l.cemeteryId, m.cemeteryName, + m.cemeterySvg, l.cemeterySvgId, + l.burialSiteLatitude, l.burialSiteLongitude, + + from BurialSites l + left join BurialSiteTypes t on l.burialSiteTypeId = t.burialSiteTypeId + left join BurialSiteStatuses s on l.burialSiteStatusId = s.burialSiteStatusId + left join Cemeteries m on l.cemeteryId = m.cemeteryId + where l.recordDelete_timeMillis is null` + +async function _getBurialSite( + sql: string, + burialSiteIdOrLotName: number | string +): Promise { + const database = await acquireConnection() + + const burialSite = database.prepare(sql).get(burialSiteIdOrLotName) as Lot | undefined + + if (burialSite !== undefined) { + const lotOccupancies = await getBurialSiteInterments( + { + lotId: burialSite.lotId + }, + { + includeOccupants: true, + includeFees: false, + includeTransactions: false, + limit: -1, + offset: 0 + }, + database + ) + + burialSite.lotOccupancies = lotOccupancies.lotOccupancies + + burialSite.lotFields = await getLotFields(burialSite.lotId, database) + + burialSite.lotComments = await getLotComments(burialSite.lotId, database) + } + + database.release() + + return burialSite +} + +// TODO +export async function getLotByLotName( + lotName: string +): Promise { + return await _getBurialSite(`${baseSQL} and l.lotName = ?`, lotName) +} + +export default async function getLot( + burialSiteId: number | string +): Promise { + return await _getBurialSite(`${baseSQL} and l.burialSiteId = ?`, burialSiteId) +} diff --git a/database/getFee.js b/database/getFee.js index bbde8a5d..a1ab35bc 100644 --- a/database/getFee.js +++ b/database/getFee.js @@ -5,16 +5,16 @@ export default async function getFee(feeId, connectedDatabase) { .prepare(`select f.feeId, f.feeCategoryId, c.feeCategory, f.feeName, f.feeDescription, f.feeAccount, - f.occupancyTypeId, o.occupancyType, - f.lotTypeId, l.lotType, + f.contractTypeId, o.contractType, + f.burialSiteTypeId, l.burialSiteType, ifnull(f.feeAmount, 0) as feeAmount, f.feeFunction, f.taxAmount, f.taxPercentage, f.includeQuantity, f.quantityUnit, f.isRequired, f.orderNumber from Fees f left join FeeCategories c on f.feeCategoryId = c.feeCategoryId - left join OccupancyTypes o on f.occupancyTypeId = o.occupancyTypeId - left join LotTypes l on f.lotTypeId = l.lotTypeId + left join ContractTypes o on f.contractTypeId = o.contractTypeId + left join BurialSiteTypes l on f.burialSiteTypeId = l.burialSiteTypeId where f.recordDelete_timeMillis is null and f.feeId = ?`) .get(feeId); diff --git a/database/getFee.ts b/database/getFee.ts index 596f4c1b..73c24953 100644 --- a/database/getFee.ts +++ b/database/getFee.ts @@ -15,16 +15,16 @@ export default async function getFee( `select f.feeId, f.feeCategoryId, c.feeCategory, f.feeName, f.feeDescription, f.feeAccount, - f.occupancyTypeId, o.occupancyType, - f.lotTypeId, l.lotType, + f.contractTypeId, o.contractType, + f.burialSiteTypeId, l.burialSiteType, ifnull(f.feeAmount, 0) as feeAmount, f.feeFunction, f.taxAmount, f.taxPercentage, f.includeQuantity, f.quantityUnit, f.isRequired, f.orderNumber from Fees f left join FeeCategories c on f.feeCategoryId = c.feeCategoryId - left join OccupancyTypes o on f.occupancyTypeId = o.occupancyTypeId - left join LotTypes l on f.lotTypeId = l.lotTypeId + left join ContractTypes o on f.contractTypeId = o.contractTypeId + left join BurialSiteTypes l on f.burialSiteTypeId = l.burialSiteTypeId where f.recordDelete_timeMillis is null and f.feeId = ?` ) diff --git a/database/getFeeCategories.d.ts b/database/getFeeCategories.d.ts index bf967192..60845f88 100644 --- a/database/getFeeCategories.d.ts +++ b/database/getFeeCategories.d.ts @@ -1,8 +1,8 @@ import type { PoolConnection } from 'better-sqlite-pool'; import type { FeeCategory } from '../types/recordTypes.js'; interface GetFeeCategoriesFilters { - occupancyTypeId?: number | string; - lotTypeId?: number | string; + contractTypeId?: number | string; + burialSiteTypeId?: number | string; feeCategoryId?: number | string; } interface GetFeeCategoriesOptions { diff --git a/database/getFeeCategories.js b/database/getFeeCategories.js index 88cb9421..c9bf8ee1 100644 --- a/database/getFeeCategories.js +++ b/database/getFeeCategories.js @@ -2,19 +2,19 @@ import getFees from './getFees.js'; import { acquireConnection } from './pool.js'; import { updateRecordOrderNumber } from './updateRecordOrderNumber.js'; export default async function getFeeCategories(filters, options, connectedDatabase) { - const updateOrderNumbers = !(filters.lotTypeId || filters.occupancyTypeId) && options.includeFees; + const updateOrderNumbers = !(filters.burialSiteTypeId || filters.contractTypeId) && options.includeFees; const database = await acquireConnection(); let sqlWhereClause = ' where recordDelete_timeMillis is null'; const sqlParameters = []; - if ((filters.occupancyTypeId ?? '') !== '') { + if ((filters.contractTypeId ?? '') !== '') { sqlWhereClause += ` and feeCategoryId in ( - select feeCategoryId from Fees where recordDelete_timeMillis is null and (occupancyTypeId is null or occupancyTypeId = ?))`; - sqlParameters.push(filters.occupancyTypeId); + select feeCategoryId from Fees where recordDelete_timeMillis is null and (contractTypeId is null or contractTypeId = ?))`; + sqlParameters.push(filters.contractTypeId); } - if ((filters.lotTypeId ?? '') !== '') { + if ((filters.burialSiteTypeId ?? '') !== '') { sqlWhereClause += ` and feeCategoryId in ( - select feeCategoryId from Fees where recordDelete_timeMillis is null and (lotTypeId is null or lotTypeId = ?))`; - sqlParameters.push(filters.lotTypeId); + select feeCategoryId from Fees where recordDelete_timeMillis is null and (burialSiteTypeId is null or burialSiteTypeId = ?))`; + sqlParameters.push(filters.burialSiteTypeId); } const feeCategories = database .prepare(`select feeCategoryId, feeCategory, isGroupedFee, orderNumber diff --git a/database/getFeeCategories.ts b/database/getFeeCategories.ts index 30f16593..6a931f11 100644 --- a/database/getFeeCategories.ts +++ b/database/getFeeCategories.ts @@ -7,8 +7,8 @@ import { acquireConnection } from './pool.js' import { updateRecordOrderNumber } from './updateRecordOrderNumber.js' interface GetFeeCategoriesFilters { - occupancyTypeId?: number | string - lotTypeId?: number | string + contractTypeId?: number | string + burialSiteTypeId?: number | string feeCategoryId?: number | string } @@ -22,7 +22,7 @@ export default async function getFeeCategories( connectedDatabase?: PoolConnection ): Promise { const updateOrderNumbers = - !(filters.lotTypeId || filters.occupancyTypeId) && options.includeFees + !(filters.burialSiteTypeId || filters.contractTypeId) && options.includeFees const database = await acquireConnection() @@ -30,18 +30,18 @@ export default async function getFeeCategories( const sqlParameters: unknown[] = [] - if ((filters.occupancyTypeId ?? '') !== '') { + if ((filters.contractTypeId ?? '') !== '') { sqlWhereClause += ` and feeCategoryId in ( - select feeCategoryId from Fees where recordDelete_timeMillis is null and (occupancyTypeId is null or occupancyTypeId = ?))` + select feeCategoryId from Fees where recordDelete_timeMillis is null and (contractTypeId is null or contractTypeId = ?))` - sqlParameters.push(filters.occupancyTypeId) + sqlParameters.push(filters.contractTypeId) } - if ((filters.lotTypeId ?? '') !== '') { + if ((filters.burialSiteTypeId ?? '') !== '') { sqlWhereClause += ` and feeCategoryId in ( - select feeCategoryId from Fees where recordDelete_timeMillis is null and (lotTypeId is null or lotTypeId = ?))` + select feeCategoryId from Fees where recordDelete_timeMillis is null and (burialSiteTypeId is null or burialSiteTypeId = ?))` - sqlParameters.push(filters.lotTypeId) + sqlParameters.push(filters.burialSiteTypeId) } const feeCategories = database diff --git a/database/getFees.d.ts b/database/getFees.d.ts index 41e3583f..97dace36 100644 --- a/database/getFees.d.ts +++ b/database/getFees.d.ts @@ -1,8 +1,8 @@ import type { PoolConnection } from 'better-sqlite-pool'; import type { Fee } from '../types/recordTypes.js'; interface GetFeesFilters { - occupancyTypeId?: number | string; - lotTypeId?: number | string; + contractTypeId?: number | string; + burialSiteTypeId?: number | string; } export default function getFees(feeCategoryId: number, additionalFilters: GetFeesFilters, connectedDatabase?: PoolConnection): Promise; export {}; diff --git a/database/getFees.js b/database/getFees.js index aeb784a5..270dd077 100644 --- a/database/getFees.js +++ b/database/getFees.js @@ -1,39 +1,39 @@ import { acquireConnection } from './pool.js'; import { updateRecordOrderNumber } from './updateRecordOrderNumber.js'; export default async function getFees(feeCategoryId, additionalFilters, connectedDatabase) { - const updateOrderNumbers = !(additionalFilters.lotTypeId || additionalFilters.occupancyTypeId); + const updateOrderNumbers = !(additionalFilters.burialSiteTypeId || additionalFilters.contractTypeId); const database = connectedDatabase ?? (await acquireConnection()); let sqlWhereClause = ' where f.recordDelete_timeMillis is null and f.feeCategoryId = ?'; const sqlParameters = [feeCategoryId]; - if (additionalFilters.occupancyTypeId) { + if (additionalFilters.contractTypeId) { sqlWhereClause += - ' and (f.occupancyTypeId is null or f.occupancyTypeId = ?)'; - sqlParameters.push(additionalFilters.occupancyTypeId); + ' and (f.contractTypeId is null or f.contractTypeId = ?)'; + sqlParameters.push(additionalFilters.contractTypeId); } - if (additionalFilters.lotTypeId) { - sqlWhereClause += ' and (f.lotTypeId is null or f.lotTypeId = ?)'; - sqlParameters.push(additionalFilters.lotTypeId); + if (additionalFilters.burialSiteTypeId) { + sqlWhereClause += ' and (f.burialSiteTypeId is null or f.burialSiteTypeId = ?)'; + sqlParameters.push(additionalFilters.burialSiteTypeId); } const fees = database .prepare(`select f.feeId, f.feeCategoryId, f.feeName, f.feeDescription, f.feeAccount, - f.occupancyTypeId, o.occupancyType, - f.lotTypeId, l.lotType, + f.contractTypeId, o.contractType, + f.burialSiteTypeId, l.burialSiteType, ifnull(f.feeAmount, 0) as feeAmount, f.feeFunction, f.taxAmount, f.taxPercentage, f.includeQuantity, f.quantityUnit, f.isRequired, f.orderNumber, - ifnull(lo.lotOccupancyFeeCount, 0) as lotOccupancyFeeCount + ifnull(lo.burialSiteContractFeeCount, 0) as burialSiteContractFeeCount from Fees f left join ( - select feeId, count(lotOccupancyId) as lotOccupancyFeeCount - from LotOccupancyFees + select feeId, count(burialSiteContractId) as burialSiteContractFeeCount + from BurialSiteContractFees where recordDelete_timeMillis is null group by feeId ) lo on f.feeId = lo.feeId - left join OccupancyTypes o on f.occupancyTypeId = o.occupancyTypeId - left join LotTypes l on f.lotTypeId = l.lotTypeId + left join ContractTypes o on f.contractTypeId = o.contractTypeId + left join BurialSiteTypes l on f.burialSiteTypeId = l.burialSiteTypeId ${sqlWhereClause} order by f.orderNumber, f.feeName`) .all(sqlParameters); diff --git a/database/getFees.ts b/database/getFees.ts index 1f204eed..311faf20 100644 --- a/database/getFees.ts +++ b/database/getFees.ts @@ -6,8 +6,8 @@ import { acquireConnection } from './pool.js' import { updateRecordOrderNumber } from './updateRecordOrderNumber.js' interface GetFeesFilters { - occupancyTypeId?: number | string - lotTypeId?: number | string + contractTypeId?: number | string + burialSiteTypeId?: number | string } export default async function getFees( @@ -16,7 +16,7 @@ export default async function getFees( connectedDatabase?: PoolConnection ): Promise { const updateOrderNumbers = !( - additionalFilters.lotTypeId || additionalFilters.occupancyTypeId + additionalFilters.burialSiteTypeId || additionalFilters.contractTypeId ) const database = connectedDatabase ?? (await acquireConnection()) @@ -26,40 +26,40 @@ export default async function getFees( const sqlParameters: unknown[] = [feeCategoryId] - if (additionalFilters.occupancyTypeId) { + if (additionalFilters.contractTypeId) { sqlWhereClause += - ' and (f.occupancyTypeId is null or f.occupancyTypeId = ?)' + ' and (f.contractTypeId is null or f.contractTypeId = ?)' - sqlParameters.push(additionalFilters.occupancyTypeId) + sqlParameters.push(additionalFilters.contractTypeId) } - if (additionalFilters.lotTypeId) { - sqlWhereClause += ' and (f.lotTypeId is null or f.lotTypeId = ?)' + if (additionalFilters.burialSiteTypeId) { + sqlWhereClause += ' and (f.burialSiteTypeId is null or f.burialSiteTypeId = ?)' - sqlParameters.push(additionalFilters.lotTypeId) + sqlParameters.push(additionalFilters.burialSiteTypeId) } const fees = database .prepare( `select f.feeId, f.feeCategoryId, f.feeName, f.feeDescription, f.feeAccount, - f.occupancyTypeId, o.occupancyType, - f.lotTypeId, l.lotType, + f.contractTypeId, o.contractType, + f.burialSiteTypeId, l.burialSiteType, ifnull(f.feeAmount, 0) as feeAmount, f.feeFunction, f.taxAmount, f.taxPercentage, f.includeQuantity, f.quantityUnit, f.isRequired, f.orderNumber, - ifnull(lo.lotOccupancyFeeCount, 0) as lotOccupancyFeeCount + ifnull(lo.burialSiteContractFeeCount, 0) as burialSiteContractFeeCount from Fees f left join ( - select feeId, count(lotOccupancyId) as lotOccupancyFeeCount - from LotOccupancyFees + select feeId, count(burialSiteContractId) as burialSiteContractFeeCount + from BurialSiteContractFees where recordDelete_timeMillis is null group by feeId ) lo on f.feeId = lo.feeId - left join OccupancyTypes o on f.occupancyTypeId = o.occupancyTypeId - left join LotTypes l on f.lotTypeId = l.lotTypeId + left join ContractTypes o on f.contractTypeId = o.contractTypeId + left join BurialSiteTypes l on f.burialSiteTypeId = l.burialSiteTypeId ${sqlWhereClause} order by f.orderNumber, f.feeName` ) diff --git a/database/getLot.js b/database/getLot.js deleted file mode 100644 index 868208fb..00000000 --- a/database/getLot.js +++ /dev/null @@ -1,38 +0,0 @@ -import getLotComments from './getLotComments.js'; -import getLotFields from './getLotFields.js'; -import getLotOccupancies from './getLotOccupancies.js'; -import { acquireConnection } from './pool.js'; -const baseSQL = `select l.lotId, l.lotTypeId, t.lotType, l.lotName, l.lotStatusId, s.lotStatus, - l.mapId, m.mapName, m.mapSVG, l.mapKey, - l.lotLatitude, l.lotLongitude - from Lots l - left join LotTypes t on l.lotTypeId = t.lotTypeId - left join LotStatuses s on l.lotStatusId = s.lotStatusId - left join Maps m on l.mapId = m.mapId - where l.recordDelete_timeMillis is null`; -async function _getLot(sql, lotIdOrLotName) { - const database = await acquireConnection(); - const lot = database.prepare(sql).get(lotIdOrLotName); - if (lot !== undefined) { - const lotOccupancies = await getLotOccupancies({ - lotId: lot.lotId - }, { - includeOccupants: true, - includeFees: false, - includeTransactions: false, - limit: -1, - offset: 0 - }, database); - lot.lotOccupancies = lotOccupancies.lotOccupancies; - lot.lotFields = await getLotFields(lot.lotId, database); - lot.lotComments = await getLotComments(lot.lotId, database); - } - database.release(); - return lot; -} -export async function getLotByLotName(lotName) { - return await _getLot(`${baseSQL} and l.lotName = ?`, lotName); -} -export default async function getLot(lotId) { - return await _getLot(`${baseSQL} and l.lotId = ?`, lotId); -} diff --git a/database/getLot.ts b/database/getLot.ts deleted file mode 100644 index 9ff9c53b..00000000 --- a/database/getLot.ts +++ /dev/null @@ -1,62 +0,0 @@ -import type { Lot } from '../types/recordTypes.js' - -import getLotComments from './getLotComments.js' -import getLotFields from './getLotFields.js' -import getLotOccupancies from './getLotOccupancies.js' -import { acquireConnection } from './pool.js' - -const baseSQL = `select l.lotId, l.lotTypeId, t.lotType, l.lotName, l.lotStatusId, s.lotStatus, - l.mapId, m.mapName, m.mapSVG, l.mapKey, - l.lotLatitude, l.lotLongitude - from Lots l - left join LotTypes t on l.lotTypeId = t.lotTypeId - left join LotStatuses s on l.lotStatusId = s.lotStatusId - left join Maps m on l.mapId = m.mapId - where l.recordDelete_timeMillis is null` - -async function _getLot( - sql: string, - lotIdOrLotName: number | string -): Promise { - const database = await acquireConnection() - - const lot = database.prepare(sql).get(lotIdOrLotName) as Lot | undefined - - if (lot !== undefined) { - const lotOccupancies = await getLotOccupancies( - { - lotId: lot.lotId - }, - { - includeOccupants: true, - includeFees: false, - includeTransactions: false, - limit: -1, - offset: 0 - }, - database - ) - - lot.lotOccupancies = lotOccupancies.lotOccupancies - - lot.lotFields = await getLotFields(lot.lotId, database) - - lot.lotComments = await getLotComments(lot.lotId, database) - } - - database.release() - - return lot -} - -export async function getLotByLotName( - lotName: string -): Promise { - return await _getLot(`${baseSQL} and l.lotName = ?`, lotName) -} - -export default async function getLot( - lotId: number | string -): Promise { - return await _getLot(`${baseSQL} and l.lotId = ?`, lotId) -} diff --git a/database/getLotOccupancies.js b/database/getLotOccupancies.js index 8ac3257e..04556fe0 100644 --- a/database/getLotOccupancies.js +++ b/database/getLotOccupancies.js @@ -1,6 +1,6 @@ import { dateIntegerToString, dateStringToInteger } from '@cityssm/utils-datetime'; import { getOccupancyTypeById } from '../helpers/functions.cache.js'; -import { getConfigProperty } from '../helpers/functions.config.js'; +import { getConfigProperty } from '../helpers/config.helpers.js'; import { getLotNameWhereClause, getOccupancyTimeWhereClause, getOccupantNameWhereClause } from '../helpers/functions.sqlFilters.js'; import getLotOccupancyFees from './getLotOccupancyFees.js'; import getLotOccupancyOccupants from './getLotOccupancyOccupants.js'; diff --git a/database/getLotOccupancies.ts b/database/getLotOccupancies.ts index 18f769a0..41df0061 100644 --- a/database/getLotOccupancies.ts +++ b/database/getLotOccupancies.ts @@ -6,7 +6,7 @@ import { import type { PoolConnection } from 'better-sqlite-pool' import { getOccupancyTypeById } from '../helpers/functions.cache.js' -import { getConfigProperty } from '../helpers/functions.config.js' +import { getConfigProperty } from '../helpers/config.helpers.js' import { getLotNameWhereClause, getOccupancyTimeWhereClause, diff --git a/database/getLotOccupancyTransactions.js b/database/getLotOccupancyTransactions.js index 51907597..4ba45b62 100644 --- a/database/getLotOccupancyTransactions.js +++ b/database/getLotOccupancyTransactions.js @@ -1,5 +1,5 @@ import { dateIntegerToString, timeIntegerToString } from '@cityssm/utils-datetime'; -import { getConfigProperty } from '../helpers/functions.config.js'; +import { getConfigProperty } from '../helpers/config.helpers.js'; import { getDynamicsGPDocument } from '../helpers/functions.dynamicsGP.js'; import { acquireConnection } from './pool.js'; export default async function getLotOccupancyTransactions(lotOccupancyId, options, connectedDatabase) { diff --git a/database/getLotOccupancyTransactions.ts b/database/getLotOccupancyTransactions.ts index 00a619bc..66ed93f3 100644 --- a/database/getLotOccupancyTransactions.ts +++ b/database/getLotOccupancyTransactions.ts @@ -4,7 +4,7 @@ import { } from '@cityssm/utils-datetime' import type { PoolConnection } from 'better-sqlite-pool' -import { getConfigProperty } from '../helpers/functions.config.js' +import { getConfigProperty } from '../helpers/config.helpers.js' import { getDynamicsGPDocument } from '../helpers/functions.dynamicsGP.js' import type { LotOccupancyTransaction } from '../types/recordTypes.js' diff --git a/database/getLots.js b/database/getLots.js index 2c82df05..5b8c22c2 100644 --- a/database/getLots.js +++ b/database/getLots.js @@ -1,5 +1,5 @@ import { dateToInteger } from '@cityssm/utils-datetime'; -import { getConfigProperty } from '../helpers/functions.config.js'; +import { getConfigProperty } from '../helpers/config.helpers.js'; import { getLotNameWhereClause } from '../helpers/functions.sqlFilters.js'; import { acquireConnection } from './pool.js'; function buildWhereClause(filters) { diff --git a/database/getLots.ts b/database/getLots.ts index b750f614..74b53ed3 100644 --- a/database/getLots.ts +++ b/database/getLots.ts @@ -1,7 +1,7 @@ import { dateToInteger } from '@cityssm/utils-datetime' import type { PoolConnection } from 'better-sqlite-pool' -import { getConfigProperty } from '../helpers/functions.config.js' +import { getConfigProperty } from '../helpers/config.helpers.js' import { getLotNameWhereClause } from '../helpers/functions.sqlFilters.js' import type { Lot } from '../types/recordTypes.js' diff --git a/database/getNextBurialSiteId.d.ts b/database/getNextBurialSiteId.d.ts new file mode 100644 index 00000000..806f1a31 --- /dev/null +++ b/database/getNextBurialSiteId.d.ts @@ -0,0 +1 @@ +export default function getNextBurialSiteId(burialSiteId: number | string): Promise; diff --git a/database/getNextLotId.js b/database/getNextBurialSiteId.js similarity index 57% rename from database/getNextLotId.js rename to database/getNextBurialSiteId.js index 4a89c761..ef586f07 100644 --- a/database/getNextLotId.js +++ b/database/getNextBurialSiteId.js @@ -1,19 +1,19 @@ -import { getConfigProperty } from '../helpers/functions.config.js'; import { acquireConnection } from './pool.js'; -export default async function getNextLotId(lotId) { +// TODO +export default async function getNextBurialSiteId(burialSiteId) { const database = await acquireConnection(); - database.function('userFn_lotNameSortName', getConfigProperty('settings.lot.lotNameSortNameFunction')); const result = database - .prepare(`select lotId - from Lots + .prepare(`select burialSiteId + from BurialSites where recordDelete_timeMillis is null and userFn_lotNameSortName(lotName) > (select userFn_lotNameSortName(lotName) from Lots where lotId = ?) order by userFn_lotNameSortName(lotName) limit 1`) - .get(lotId); + .pluck() + .get(burialSiteId); database.release(); if (result === undefined) { return undefined; } - return result.lotId; + return result; } diff --git a/database/getNextLotId.ts b/database/getNextBurialSiteId.ts similarity index 57% rename from database/getNextLotId.ts rename to database/getNextBurialSiteId.ts index a1df8ff4..2f9a8966 100644 --- a/database/getNextLotId.ts +++ b/database/getNextBurialSiteId.ts @@ -1,29 +1,22 @@ -import { getConfigProperty } from '../helpers/functions.config.js' - import { acquireConnection } from './pool.js' -export default async function getNextLotId( - lotId: number | string +// TODO +export default async function getNextBurialSiteId( + burialSiteId: number | string ): Promise { const database = await acquireConnection() - database.function( - 'userFn_lotNameSortName', - getConfigProperty('settings.lot.lotNameSortNameFunction') - ) - const result = database .prepare( - `select lotId - from Lots + `select burialSiteId + from BurialSites where recordDelete_timeMillis is null and userFn_lotNameSortName(lotName) > (select userFn_lotNameSortName(lotName) from Lots where lotId = ?) order by userFn_lotNameSortName(lotName) limit 1` ) - .get(lotId) as { - lotId: number - } + .pluck() + .get(burialSiteId) as number | undefined database.release() @@ -31,5 +24,5 @@ export default async function getNextLotId( return undefined } - return result.lotId + return result } diff --git a/database/getNextLotId.d.ts b/database/getNextLotId.d.ts deleted file mode 100644 index e5f1aca9..00000000 --- a/database/getNextLotId.d.ts +++ /dev/null @@ -1 +0,0 @@ -export default function getNextLotId(lotId: number | string): Promise; diff --git a/database/getNextWorkOrderNumber.js b/database/getNextWorkOrderNumber.js index ab9420ab..40af1a1b 100644 --- a/database/getNextWorkOrderNumber.js +++ b/database/getNextWorkOrderNumber.js @@ -1,4 +1,4 @@ -import { getConfigProperty } from '../helpers/functions.config.js'; +import { getConfigProperty } from '../helpers/config.helpers.js'; import { acquireConnection } from './pool.js'; export default async function getNextWorkOrderNumber(connectedDatabase) { const database = connectedDatabase ?? (await acquireConnection()); diff --git a/database/getNextWorkOrderNumber.ts b/database/getNextWorkOrderNumber.ts index 3944aa9d..2ae7f1dc 100644 --- a/database/getNextWorkOrderNumber.ts +++ b/database/getNextWorkOrderNumber.ts @@ -1,6 +1,6 @@ import type { PoolConnection } from 'better-sqlite-pool' -import { getConfigProperty } from '../helpers/functions.config.js' +import { getConfigProperty } from '../helpers/config.helpers.js' import { acquireConnection } from './pool.js' diff --git a/database/getOccupancyTypePrints.js b/database/getOccupancyTypePrints.js index 2d1602ba..6eb16583 100644 --- a/database/getOccupancyTypePrints.js +++ b/database/getOccupancyTypePrints.js @@ -1,4 +1,4 @@ -import { getConfigProperty } from '../helpers/functions.config.js'; +import { getConfigProperty } from '../helpers/config.helpers.js'; import { acquireConnection } from './pool.js'; const availablePrints = getConfigProperty('settings.lotOccupancy.prints'); // eslint-disable-next-line @typescript-eslint/naming-convention diff --git a/database/getOccupancyTypePrints.ts b/database/getOccupancyTypePrints.ts index 36f4aa27..38ec2dc3 100644 --- a/database/getOccupancyTypePrints.ts +++ b/database/getOccupancyTypePrints.ts @@ -1,6 +1,6 @@ import type { PoolConnection } from 'better-sqlite-pool' -import { getConfigProperty } from '../helpers/functions.config.js' +import { getConfigProperty } from '../helpers/config.helpers.js' import { acquireConnection } from './pool.js' diff --git a/database/getPreviousLotId.js b/database/getPreviousLotId.js index 25a5243b..796edaa7 100644 --- a/database/getPreviousLotId.js +++ b/database/getPreviousLotId.js @@ -1,4 +1,4 @@ -import { getConfigProperty } from '../helpers/functions.config.js'; +import { getConfigProperty } from '../helpers/config.helpers.js'; import { acquireConnection } from './pool.js'; export default async function getPreviousLotId(lotId) { const database = await acquireConnection(); diff --git a/database/getPreviousLotId.ts b/database/getPreviousLotId.ts index 7fdefabd..48b6172e 100644 --- a/database/getPreviousLotId.ts +++ b/database/getPreviousLotId.ts @@ -1,4 +1,4 @@ -import { getConfigProperty } from '../helpers/functions.config.js' +import { getConfigProperty } from '../helpers/config.helpers.js' import { acquireConnection } from './pool.js' diff --git a/database/getReportData.js b/database/getReportData.js index 51a0b580..9e88ffe9 100644 --- a/database/getReportData.js +++ b/database/getReportData.js @@ -1,188 +1,142 @@ import { dateIntegerToString, dateStringToInteger, dateToInteger, timeIntegerToString } from '@cityssm/utils-datetime'; -import camelCase from 'camelcase'; -import { getConfigProperty } from '../helpers/functions.config.js'; import { acquireConnection } from './pool.js'; -const mapCamelCase = camelCase(getConfigProperty('aliases.map')); -const mapNameAlias = `${mapCamelCase}Name`; -const mapDescriptionAlias = `${mapCamelCase}Description`; -const mapAddress1Alias = `${mapCamelCase}Address1`; -const mapAddress2Alias = `${mapCamelCase}Address2`; -const mapCityAlias = `${mapCamelCase}City`; -const mapProvinceAlias = `${mapCamelCase}Province`; -const mapPostalCodeAlias = `${mapCamelCase}PostalCode`; -const mapPhoneNumberAlias = `${mapCamelCase}PhoneNumber`; -const lotCamelCase = camelCase(getConfigProperty('aliases.lot')); -const lotIdAlias = `${lotCamelCase}Id`; -const lotNameAlias = `${lotCamelCase}Name`; -const lotTypeAlias = `${lotCamelCase}Type`; -const lotStatusAlias = `${lotCamelCase}Status`; -const occupancyCamelCase = camelCase(getConfigProperty('aliases.occupancy')); -const lotOccupancyIdAlias = `${occupancyCamelCase}Id`; -const occupancyTypeAlias = `${occupancyCamelCase}Type`; -const occupancyStartDateAlias = `${occupancyCamelCase}StartDate`; -const occupancyEndDateAlias = `${occupancyCamelCase}EndDate`; -const occupantCamelCase = camelCase(getConfigProperty('aliases.occupant')); -const lotOccupantIndexAlias = `${occupantCamelCase}Index`; -const lotOccupantTypeAlias = `${occupantCamelCase}Type`; -const occupantNameAlias = `${occupantCamelCase}Name`; -const occupantFamilyNameAlias = `${occupantCamelCase}FamilyName`; -const occupantAddress1Alias = `${occupantCamelCase}Address1`; -const occupantAddress2Alias = `${occupantCamelCase}Address2`; -const occupantCityAlias = `${occupantCamelCase}City`; -const occupantProvinceAlias = `${occupantCamelCase}Province`; -const occupantPostalCodeAlias = `${occupantCamelCase}PostalCode`; -const occupantPhoneNumberAlias = `${occupantCamelCase}PhoneNumber`; -const occupantEmailAddressAlias = `${occupantCamelCase}EmailAddress`; -const occupantCommentTitleAlias = `${occupantCamelCase}CommentTitle`; -const occupantCommentAlias = `${occupantCamelCase}Comment`; +// eslint-disable-next-line complexity export default async function getReportData(reportName, reportParameters = {}) { let sql = ''; const sqlParameters = []; - // eslint-disable-next-line sonarjs/max-switch-cases switch (reportName) { - case 'maps-all': { + case 'cemeteries-all': { sql = 'select * from Maps'; break; } - case 'maps-formatted': { - sql = `select mapName as ${mapNameAlias}, - mapDescription as ${mapDescriptionAlias}, - mapAddress1 as ${mapAddress1Alias}, - mapAddress2 as ${mapAddress2Alias}, - mapCity as ${mapCityAlias}, - mapProvince as ${mapProvinceAlias}, - mapPostalCode as ${mapPostalCodeAlias}, - mapPhoneNumber as ${mapPhoneNumberAlias} - from Maps + case 'cemeteries-formatted': { + sql = `select cemeteryName, + cemeteryDescription, + cemeteryAddress1, cemeteryAddress2, + cemeteryCity, cemeteryProvince, + cemeteryPostalCode, + cemeteryPhoneNumber + from Cemeteries where recordDelete_timeMillis is null - order by mapName`; + order by cemeteryName`; break; } - case 'lots-all': { - sql = 'select * from Lots'; + case 'burialSites-all': { + sql = 'select * from BurialSites'; break; } - case 'lots-byLotTypeId': { - sql = `select l.lotId as ${lotIdAlias}, - m.mapName as ${mapNameAlias}, - l.lotName as ${lotNameAlias}, - t.lotType as ${lotTypeAlias}, - s.lotStatus as ${lotStatusAlias} - from Lots l - left join LotTypes t on l.lotTypeId = t.lotTypeId - left join LotStatuses s on l.lotStatusId = s.lotStatusId - left join Maps m on l.mapId = m.mapId + case 'burialSites-byBurialSiteTypeId': { + sql = `select l.burialSiteId, + m.cemeteryName, + l.burialSiteNameSegment1, + l.burialSiteNameSegment2, + l.burialSiteNameSegment3, + l.burialSiteNameSegment4, + l.burialSiteNameSegment5, + t.burialSiteType, + s.burialSiteStatus + from BurialSites l + left join BurialSiteTypes t on l.burialSiteTypeId = t.burialSiteTypeId + left join BurialSiteStatuses s on l.burialSiteStatusId = s.burialSiteStatusId + left join Cemeteries m on l.cemeteryId = m.cemeteryId where l.recordDelete_timeMillis is null - and l.lotTypeId = ?`; - sqlParameters.push(reportParameters.lotTypeId); + and l.burialSiteTypeId = ?`; + sqlParameters.push(reportParameters.burialSiteTypeId); break; } - case 'lots-byLotStatusId': { - sql = `select l.lotId as ${lotIdAlias}, - m.mapName as ${mapNameAlias}, - l.lotName as ${lotNameAlias}, - t.lotType as ${lotTypeAlias}, - s.lotStatus as ${lotStatusAlias} - from Lots l - left join LotTypes t on l.lotTypeId = t.lotTypeId - left join LotStatuses s on l.lotStatusId = s.lotStatusId - left join Maps m on l.mapId = m.mapId + case 'burialSites-byBurialSiteStatusId': { + sql = `select l.burialSiteId, + m.cemeteryName, + l.burialSiteNameSegment1, + l.burialSiteNameSegment2, + l.burialSiteNameSegment3, + l.burialSiteNameSegment4, + l.burialSiteNameSegment5, + t.burialSiteType, + s.burialSiteStatus + from BurialSites l + left join BurialSiteTypes t on l.burialSiteTypeId = t.burialSiteTypeId + left join BurialSiteStatuses s on l.burialSiteStatusId = s.burialSiteStatusId + left join Cemeteries m on l.cemeteryId = m.cemeteryId where l.recordDelete_timeMillis is null - and l.lotStatusId = ?`; - sqlParameters.push(reportParameters.lotStatusId); + and l.burialSiteStatusId = ?`; + sqlParameters.push(reportParameters.burialSiteStatusId); break; } - case 'lots-byMapId': { - sql = `select l.lotId as ${lotIdAlias}, - m.mapName as ${mapNameAlias}, - l.lotName as ${lotNameAlias}, - t.lotType as ${lotTypeAlias}, - s.lotStatus as ${lotStatusAlias} - from Lots l - left join LotTypes t on l.lotTypeId = t.lotTypeId - left join LotStatuses s on l.lotStatusId = s.lotStatusId - left join Maps m on l.mapId = m.mapId + case 'burialSites-byCemeteryId': { + sql = `select l.burialSiteId, + m.cemeteryName, + l.burialSiteNameSegment1, + l.burialSiteNameSegment2, + l.burialSiteNameSegment3, + l.burialSiteNameSegment4, + l.burialSiteNameSegment5, + t.burialSiteType, + s.burialSiteStatus + from BurialSites l + left join BurialSiteTypes t on l.burialSiteTypeId = t.burialSiteTypeId + left join BurialSiteStatuses s on l.burialSiteStatusId = s.burialSiteStatusId + left join Cemeteries m on l.cemeteryId = m.cemeteryId where l.recordDelete_timeMillis is null - and l.mapId = ?`; - sqlParameters.push(reportParameters.mapId); + and l.cemeteryId = ?`; + sqlParameters.push(reportParameters.cemeteryId); break; } - case 'lotComments-all': { - sql = 'select * from LotComments'; + case 'burialSiteComments-all': { + sql = 'select * from BurialSiteComments'; break; } - case 'lotFields-all': { - sql = 'select * from LotFields'; + case 'burialSiteFields-all': { + sql = 'select * from BurialSiteFields'; break; } - case 'lotOccupancies-all': { - sql = 'select * from LotOccupancies'; + case 'burialSiteContracts-all': { + sql = 'select * from BurialSiteContracts'; break; } - case 'lotOccupancies-current-byMapId': { - sql = `select o.lotOccupancyId as ${lotOccupancyIdAlias}, - l.lotName as ${lotNameAlias}, - m.mapName as ${mapNameAlias}, - ot.occupancyType as ${occupancyTypeAlias}, - o.occupancyStartDate as ${occupancyStartDateAlias}, - o.occupancyEndDate as ${occupancyEndDateAlias} - from LotOccupancies o - left join OccupancyTypes ot on o.occupancyTypeId = ot.occupancyTypeId - left join Lots l on o.lotId = l.lotId - left join Maps m on l.mapId = m.mapId + case 'burialSiteContracts-current-byCemeteryId': { + sql = `select o.burialSiteContractId, + l.burialSiteNameSegment1, + l.burialSiteNameSegment2, + l.burialSiteNameSegment3, + l.burialSiteNameSegment4, + l.burialSiteNameSegment5, + m.cemeteryName, + ot.contractType, + o.contractStartDate, + o.contractEndDate + from BurialSiteContracts o + left join ContractTypes ot on o.contractTypeId = ot.contractTypeId + left join BurialSites l on o.burialSiteId = l.burialSiteId + left join Cemeteries m on l.cemeteryId = m.cemeteryId where o.recordDelete_timeMillis is null - and (o.occupancyEndDate is null or o.occupancyEndDate >= ?) - and l.mapId = ?`; - sqlParameters.push(dateToInteger(new Date()), reportParameters.mapId); + and (o.contractEndDate is null or o.contractEndDate >= ?) + and l.cemeteryId = ?`; + sqlParameters.push(dateToInteger(new Date()), reportParameters.cemeteryId); break; } - case 'lotOccupancyComments-all': { - sql = 'select * from LotOccupancyComments'; + case 'burialSiteContractComments-all': { + sql = 'select * from BurialSiteContractComments'; break; } - case 'lotOccupancyFees-all': { - sql = 'select * from LotOccupancyFees'; + case 'burialSiteContractFees-all': { + sql = 'select * from BurialSiteContractFees'; break; } - case 'lotOccupancyFields-all': { - sql = 'select * from LotOccupancyFields'; + case 'burialSiteContractFields-all': { + sql = 'select * from BurialSiteContractFields'; break; } - case 'lotOccupancyOccupants-all': { - sql = 'select * from LotOccupancyOccupants'; + case 'burialSiteContractTransactions-all': { + sql = 'select * from BurialSiteContractTransactions'; break; } - case 'lotOccupancyOccupants-byLotOccupancyId': { - sql = `select o.lotOccupantIndex as ${lotOccupantIndexAlias}, - t.lotOccupantType as ${lotOccupantTypeAlias}, - o.occupantName as ${occupantNameAlias}, - o.occupantFamilyName as ${occupantFamilyNameAlias}, - o.occupantAddress1 as ${occupantAddress1Alias}, - o.occupantAddress2 as ${occupantAddress2Alias}, - o.occupantCity as ${occupantCityAlias}, - o.occupantProvince as ${occupantProvinceAlias}, - o.occupantPostalCode as ${occupantPostalCodeAlias}, - o.occupantPhoneNumber as ${occupantPhoneNumberAlias}, - o.occupantEmailAddress as ${occupantEmailAddressAlias}, - t.occupantCommentTitle as ${occupantCommentTitleAlias}, - o.occupantComment as ${occupantCommentAlias} - from LotOccupancyOccupants o - left join LotOccupantTypes t on o.lotOccupantTypeId = t.lotOccupantTypeId - where o.recordDelete_timeMillis is null - and o.lotOccupancyId = ?`; - sqlParameters.push(reportParameters.lotOccupancyId); - break; - } - case 'lotOccupancyTransactions-all': { - sql = 'select * from LotOccupancyTransactions'; - break; - } - case 'lotOccupancyTransactions-byTransactionDateString': { - sql = `select t.lotOccupancyId, t.transactionIndex, + case 'burialSiteContractTransactions-byTransactionDateString': { + sql = `select t.burialSiteContractId, t.transactionIndex, t.transactionDate, t.transactionTime, t.transactionAmount, t.externalReceiptNumber, t.transactionNote - from LotOccupancyTransactions t + from BurialSiteContractTransactions t where t.recordDelete_timeMillis is null and t.transactionDate = ?`; sqlParameters.push(dateStringToInteger(reportParameters.transactionDateString)); @@ -245,28 +199,24 @@ export default async function getReportData(reportName, reportParameters = {}) { sql = 'select * from FeeCategories'; break; } - case 'lotTypes-all': { - sql = 'select * from LotTypes'; + case 'burialSiteTypes-all': { + sql = 'select * from BurialSiteTypes'; break; } - case 'lotTypeFields-all': { - sql = 'select * from LotTypeFields'; + case 'burialSiteTypeFields-all': { + sql = 'select * from BurialSiteTypeFields'; break; } - case 'lotStatuses-all': { - sql = 'select * from LotStatuses'; + case 'burialSiteStatuses-all': { + sql = 'select * from BurialSiteStatuses'; break; } - case 'occupancyTypes-all': { - sql = 'select * from OccupancyTypes'; + case 'contractTypes-all': { + sql = 'select * from ContractTypes'; break; } - case 'occupancyTypeFields-all': { - sql = 'select * from OccupancyTypeFields'; - break; - } - case 'lotOccupantTypes-all': { - sql = 'select * from LotOccupantTypes'; + case 'contractTypeFields-all': { + sql = 'select * from ContractTypeFields'; break; } case 'workOrderTypes-all': { diff --git a/database/getReportData.ts b/database/getReportData.ts index 61f5767b..f175b69c 100644 --- a/database/getReportData.ts +++ b/database/getReportData.ts @@ -5,51 +5,12 @@ import { dateToInteger, timeIntegerToString } from '@cityssm/utils-datetime' -import camelCase from 'camelcase' - -import { getConfigProperty } from '../helpers/functions.config.js' import { acquireConnection } from './pool.js' export type ReportParameters = Record -const mapCamelCase = camelCase(getConfigProperty('aliases.map')) -const mapNameAlias = `${mapCamelCase}Name` -const mapDescriptionAlias = `${mapCamelCase}Description` -const mapAddress1Alias = `${mapCamelCase}Address1` -const mapAddress2Alias = `${mapCamelCase}Address2` -const mapCityAlias = `${mapCamelCase}City` -const mapProvinceAlias = `${mapCamelCase}Province` -const mapPostalCodeAlias = `${mapCamelCase}PostalCode` -const mapPhoneNumberAlias = `${mapCamelCase}PhoneNumber` - -const lotCamelCase = camelCase(getConfigProperty('aliases.lot')) -const lotIdAlias = `${lotCamelCase}Id` -const lotNameAlias = `${lotCamelCase}Name` -const lotTypeAlias = `${lotCamelCase}Type` -const lotStatusAlias = `${lotCamelCase}Status` - -const occupancyCamelCase = camelCase(getConfigProperty('aliases.occupancy')) -const lotOccupancyIdAlias = `${occupancyCamelCase}Id` -const occupancyTypeAlias = `${occupancyCamelCase}Type` -const occupancyStartDateAlias = `${occupancyCamelCase}StartDate` -const occupancyEndDateAlias = `${occupancyCamelCase}EndDate` - -const occupantCamelCase = camelCase(getConfigProperty('aliases.occupant')) -const lotOccupantIndexAlias = `${occupantCamelCase}Index` -const lotOccupantTypeAlias = `${occupantCamelCase}Type` -const occupantNameAlias = `${occupantCamelCase}Name` -const occupantFamilyNameAlias = `${occupantCamelCase}FamilyName` -const occupantAddress1Alias = `${occupantCamelCase}Address1` -const occupantAddress2Alias = `${occupantCamelCase}Address2` -const occupantCityAlias = `${occupantCamelCase}City` -const occupantProvinceAlias = `${occupantCamelCase}Province` -const occupantPostalCodeAlias = `${occupantCamelCase}PostalCode` -const occupantPhoneNumberAlias = `${occupantCamelCase}PhoneNumber` -const occupantEmailAddressAlias = `${occupantCamelCase}EmailAddress` -const occupantCommentTitleAlias = `${occupantCamelCase}CommentTitle` -const occupantCommentAlias = `${occupantCamelCase}Comment` - +// eslint-disable-next-line complexity export default async function getReportData( reportName: string, reportParameters: ReportParameters = {} @@ -57,176 +18,162 @@ export default async function getReportData( let sql = '' const sqlParameters: unknown[] = [] - // eslint-disable-next-line sonarjs/max-switch-cases switch (reportName) { - case 'maps-all': { + case 'cemeteries-all': { sql = 'select * from Maps' break } - case 'maps-formatted': { - sql = `select mapName as ${mapNameAlias}, - mapDescription as ${mapDescriptionAlias}, - mapAddress1 as ${mapAddress1Alias}, - mapAddress2 as ${mapAddress2Alias}, - mapCity as ${mapCityAlias}, - mapProvince as ${mapProvinceAlias}, - mapPostalCode as ${mapPostalCodeAlias}, - mapPhoneNumber as ${mapPhoneNumberAlias} - from Maps + case 'cemeteries-formatted': { + sql = `select cemeteryName, + cemeteryDescription, + cemeteryAddress1, cemeteryAddress2, + cemeteryCity, cemeteryProvince, + cemeteryPostalCode, + cemeteryPhoneNumber + from Cemeteries where recordDelete_timeMillis is null - order by mapName` + order by cemeteryName` break } - case 'lots-all': { - sql = 'select * from Lots' + case 'burialSites-all': { + sql = 'select * from BurialSites' break } - case 'lots-byLotTypeId': { - sql = `select l.lotId as ${lotIdAlias}, - m.mapName as ${mapNameAlias}, - l.lotName as ${lotNameAlias}, - t.lotType as ${lotTypeAlias}, - s.lotStatus as ${lotStatusAlias} - from Lots l - left join LotTypes t on l.lotTypeId = t.lotTypeId - left join LotStatuses s on l.lotStatusId = s.lotStatusId - left join Maps m on l.mapId = m.mapId + case 'burialSites-byBurialSiteTypeId': { + sql = `select l.burialSiteId, + m.cemeteryName, + l.burialSiteNameSegment1, + l.burialSiteNameSegment2, + l.burialSiteNameSegment3, + l.burialSiteNameSegment4, + l.burialSiteNameSegment5, + t.burialSiteType, + s.burialSiteStatus + from BurialSites l + left join BurialSiteTypes t on l.burialSiteTypeId = t.burialSiteTypeId + left join BurialSiteStatuses s on l.burialSiteStatusId = s.burialSiteStatusId + left join Cemeteries m on l.cemeteryId = m.cemeteryId where l.recordDelete_timeMillis is null - and l.lotTypeId = ?` + and l.burialSiteTypeId = ?` - sqlParameters.push(reportParameters.lotTypeId) + sqlParameters.push(reportParameters.burialSiteTypeId) break } - case 'lots-byLotStatusId': { - sql = `select l.lotId as ${lotIdAlias}, - m.mapName as ${mapNameAlias}, - l.lotName as ${lotNameAlias}, - t.lotType as ${lotTypeAlias}, - s.lotStatus as ${lotStatusAlias} - from Lots l - left join LotTypes t on l.lotTypeId = t.lotTypeId - left join LotStatuses s on l.lotStatusId = s.lotStatusId - left join Maps m on l.mapId = m.mapId + case 'burialSites-byBurialSiteStatusId': { + sql = `select l.burialSiteId, + m.cemeteryName, + l.burialSiteNameSegment1, + l.burialSiteNameSegment2, + l.burialSiteNameSegment3, + l.burialSiteNameSegment4, + l.burialSiteNameSegment5, + t.burialSiteType, + s.burialSiteStatus + from BurialSites l + left join BurialSiteTypes t on l.burialSiteTypeId = t.burialSiteTypeId + left join BurialSiteStatuses s on l.burialSiteStatusId = s.burialSiteStatusId + left join Cemeteries m on l.cemeteryId = m.cemeteryId where l.recordDelete_timeMillis is null - and l.lotStatusId = ?` + and l.burialSiteStatusId = ?` - sqlParameters.push(reportParameters.lotStatusId) + sqlParameters.push(reportParameters.burialSiteStatusId) break } - case 'lots-byMapId': { - sql = `select l.lotId as ${lotIdAlias}, - m.mapName as ${mapNameAlias}, - l.lotName as ${lotNameAlias}, - t.lotType as ${lotTypeAlias}, - s.lotStatus as ${lotStatusAlias} - from Lots l - left join LotTypes t on l.lotTypeId = t.lotTypeId - left join LotStatuses s on l.lotStatusId = s.lotStatusId - left join Maps m on l.mapId = m.mapId + case 'burialSites-byCemeteryId': { + sql = `select l.burialSiteId, + m.cemeteryName, + l.burialSiteNameSegment1, + l.burialSiteNameSegment2, + l.burialSiteNameSegment3, + l.burialSiteNameSegment4, + l.burialSiteNameSegment5, + t.burialSiteType, + s.burialSiteStatus + from BurialSites l + left join BurialSiteTypes t on l.burialSiteTypeId = t.burialSiteTypeId + left join BurialSiteStatuses s on l.burialSiteStatusId = s.burialSiteStatusId + left join Cemeteries m on l.cemeteryId = m.cemeteryId where l.recordDelete_timeMillis is null - and l.mapId = ?` + and l.cemeteryId = ?` - sqlParameters.push(reportParameters.mapId) + sqlParameters.push(reportParameters.cemeteryId) break } - case 'lotComments-all': { - sql = 'select * from LotComments' + case 'burialSiteComments-all': { + sql = 'select * from BurialSiteComments' break } - case 'lotFields-all': { - sql = 'select * from LotFields' + case 'burialSiteFields-all': { + sql = 'select * from BurialSiteFields' break } - case 'lotOccupancies-all': { - sql = 'select * from LotOccupancies' + case 'burialSiteContracts-all': { + sql = 'select * from BurialSiteContracts' break } - case 'lotOccupancies-current-byMapId': { - sql = `select o.lotOccupancyId as ${lotOccupancyIdAlias}, - l.lotName as ${lotNameAlias}, - m.mapName as ${mapNameAlias}, - ot.occupancyType as ${occupancyTypeAlias}, - o.occupancyStartDate as ${occupancyStartDateAlias}, - o.occupancyEndDate as ${occupancyEndDateAlias} - from LotOccupancies o - left join OccupancyTypes ot on o.occupancyTypeId = ot.occupancyTypeId - left join Lots l on o.lotId = l.lotId - left join Maps m on l.mapId = m.mapId + case 'burialSiteContracts-current-byCemeteryId': { + sql = `select o.burialSiteContractId, + l.burialSiteNameSegment1, + l.burialSiteNameSegment2, + l.burialSiteNameSegment3, + l.burialSiteNameSegment4, + l.burialSiteNameSegment5, + m.cemeteryName, + ot.contractType, + o.contractStartDate, + o.contractEndDate + from BurialSiteContracts o + left join ContractTypes ot on o.contractTypeId = ot.contractTypeId + left join BurialSites l on o.burialSiteId = l.burialSiteId + left join Cemeteries m on l.cemeteryId = m.cemeteryId where o.recordDelete_timeMillis is null - and (o.occupancyEndDate is null or o.occupancyEndDate >= ?) - and l.mapId = ?` + and (o.contractEndDate is null or o.contractEndDate >= ?) + and l.cemeteryId = ?` - sqlParameters.push(dateToInteger(new Date()), reportParameters.mapId) + sqlParameters.push(dateToInteger(new Date()), reportParameters.cemeteryId) break } - case 'lotOccupancyComments-all': { - sql = 'select * from LotOccupancyComments' + case 'burialSiteContractComments-all': { + sql = 'select * from BurialSiteContractComments' break } - case 'lotOccupancyFees-all': { - sql = 'select * from LotOccupancyFees' + case 'burialSiteContractFees-all': { + sql = 'select * from BurialSiteContractFees' break } - case 'lotOccupancyFields-all': { - sql = 'select * from LotOccupancyFields' + case 'burialSiteContractFields-all': { + sql = 'select * from BurialSiteContractFields' break } - case 'lotOccupancyOccupants-all': { - sql = 'select * from LotOccupancyOccupants' + case 'burialSiteContractTransactions-all': { + sql = 'select * from BurialSiteContractTransactions' break } - case 'lotOccupancyOccupants-byLotOccupancyId': { - sql = `select o.lotOccupantIndex as ${lotOccupantIndexAlias}, - t.lotOccupantType as ${lotOccupantTypeAlias}, - o.occupantName as ${occupantNameAlias}, - o.occupantFamilyName as ${occupantFamilyNameAlias}, - o.occupantAddress1 as ${occupantAddress1Alias}, - o.occupantAddress2 as ${occupantAddress2Alias}, - o.occupantCity as ${occupantCityAlias}, - o.occupantProvince as ${occupantProvinceAlias}, - o.occupantPostalCode as ${occupantPostalCodeAlias}, - o.occupantPhoneNumber as ${occupantPhoneNumberAlias}, - o.occupantEmailAddress as ${occupantEmailAddressAlias}, - t.occupantCommentTitle as ${occupantCommentTitleAlias}, - o.occupantComment as ${occupantCommentAlias} - from LotOccupancyOccupants o - left join LotOccupantTypes t on o.lotOccupantTypeId = t.lotOccupantTypeId - where o.recordDelete_timeMillis is null - and o.lotOccupancyId = ?` - sqlParameters.push(reportParameters.lotOccupancyId) - break - } - - case 'lotOccupancyTransactions-all': { - sql = 'select * from LotOccupancyTransactions' - break - } - - case 'lotOccupancyTransactions-byTransactionDateString': { - sql = `select t.lotOccupancyId, t.transactionIndex, + case 'burialSiteContractTransactions-byTransactionDateString': { + sql = `select t.burialSiteContractId, t.transactionIndex, t.transactionDate, t.transactionTime, t.transactionAmount, t.externalReceiptNumber, t.transactionNote - from LotOccupancyTransactions t + from BurialSiteContractTransactions t where t.recordDelete_timeMillis is null and t.transactionDate = ?` @@ -303,33 +250,28 @@ export default async function getReportData( break } - case 'lotTypes-all': { - sql = 'select * from LotTypes' + case 'burialSiteTypes-all': { + sql = 'select * from BurialSiteTypes' break } - case 'lotTypeFields-all': { - sql = 'select * from LotTypeFields' + case 'burialSiteTypeFields-all': { + sql = 'select * from BurialSiteTypeFields' break } - case 'lotStatuses-all': { - sql = 'select * from LotStatuses' + case 'burialSiteStatuses-all': { + sql = 'select * from BurialSiteStatuses' break } - case 'occupancyTypes-all': { - sql = 'select * from OccupancyTypes' + case 'contractTypes-all': { + sql = 'select * from ContractTypes' break } - case 'occupancyTypeFields-all': { - sql = 'select * from OccupancyTypeFields' - break - } - - case 'lotOccupantTypes-all': { - sql = 'select * from LotOccupantTypes' + case 'contractTypeFields-all': { + sql = 'select * from ContractTypeFields' break } diff --git a/database/getWorkOrderMilestones.js b/database/getWorkOrderMilestones.js index 382513b2..4dabecda 100644 --- a/database/getWorkOrderMilestones.js +++ b/database/getWorkOrderMilestones.js @@ -1,5 +1,5 @@ import { dateIntegerToString, dateStringToInteger, dateToInteger, timeIntegerToPeriodString, timeIntegerToString } from '@cityssm/utils-datetime'; -import { getConfigProperty } from '../helpers/functions.config.js'; +import { getConfigProperty } from '../helpers/config.helpers.js'; import getLotOccupancies from './getLotOccupancies.js'; import getLots from './getLots.js'; import { acquireConnection } from './pool.js'; diff --git a/database/getWorkOrderMilestones.ts b/database/getWorkOrderMilestones.ts index 82938e83..f7189a48 100644 --- a/database/getWorkOrderMilestones.ts +++ b/database/getWorkOrderMilestones.ts @@ -8,7 +8,7 @@ import { } from '@cityssm/utils-datetime' import type { PoolConnection } from 'better-sqlite-pool' -import { getConfigProperty } from '../helpers/functions.config.js' +import { getConfigProperty } from '../helpers/config.helpers.js' import type { WorkOrderMilestone } from '../types/recordTypes.js' import getLotOccupancies from './getLotOccupancies.js' diff --git a/database/initializeDatabase.d.ts b/database/initializeDatabase.d.ts new file mode 100644 index 00000000..8f5f5727 --- /dev/null +++ b/database/initializeDatabase.d.ts @@ -0,0 +1 @@ +export declare function initializeDatabase(): Promise; diff --git a/database/initializeDatabase.js b/database/initializeDatabase.js new file mode 100644 index 00000000..06358054 --- /dev/null +++ b/database/initializeDatabase.js @@ -0,0 +1,428 @@ +// eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair +/* eslint-disable no-secrets/no-secrets */ +import sqlite from 'better-sqlite3'; +import Debug from 'debug'; +import { DEBUG_NAMESPACE } from '../debug.config.js'; +import { sunriseDB as databasePath } from '../helpers/database.helpers.js'; +import addFeeCategory from './addFeeCategory.js'; +import addRecord from './addRecord.js'; +const debug = Debug(`${DEBUG_NAMESPACE}:database/initializeDatabase`); +const recordColumns = `recordCreate_userName varchar(30) not null, + recordCreate_timeMillis integer not null, + recordUpdate_userName varchar(30) not null, + recordUpdate_timeMillis integer not null, + recordDelete_userName varchar(30), + recordDelete_timeMillis integer`; +const createStatements = [ + /* + * Burial Site Types + */ + `create table if not exists BurialSiteTypes ( + burialSiteTypeId integer not null primary key autoincrement, + burialSiteType varchar(100) not null, + orderNumber smallint not null default 0, + ${recordColumns})`, + `create index if not exists idx_BurialSiteTypes_orderNumber + on LotTypes (orderNumber, burialSiteType)`, + `create table if not exists BurialSiteTypeFields ( + burialSiteTypeFieldId integer not null primary key autoincrement, + burialSiteTypeId integer not null, + burialSiteTypeField varchar(100) not null, + fieldType varchar(15) not null default 'text', + fieldValues text, + isRequired bit not null default 0, + pattern varchar(100), + minimumLength smallint not null default 1 check (minimumLength >= 0), + maximumLength smallint not null default 100 check (maximumLength >= 0), + orderNumber smallint not null default 0, + ${recordColumns}, + foreign key (burialSiteTypeId) references BurialSiteTypes (burialSiteTypeId))`, + `create index if not exists idx_BurialSiteTypeFields_orderNumber + on BurialSiteTypeFields (burialSiteTypeId, orderNumber, burialSiteTypeField)`, + /* + * Burial Site Statuses + */ + `create table if not exists BurialSiteStatuses ( + burialSiteStatusId integer not null primary key autoincrement, + burialSiteStatus varchar(100) not null, + orderNumber smallint not null default 0, + ${recordColumns})`, + `create index if not exists idx_BurialSiteStatuses_orderNumber + on BurialSiteStatuses (orderNumber, burialSiteStatus)`, + /* + * Cemeteries + */ + `create table if not exists Cemeteries ( + cemeteryId integer not null primary key autoincrement, + cemeteryName varchar(200) not null, + cemeteryDescription text, + cemeteryLatitude decimal(10, 8) + check (cemeteryLatitude between -90 and 90), + cemeteryLongitude decimal(11, 8) + check (cemeteryLongitude between -180 and 180), + cemeterySvg varchar(50), + cemeteryAddress1 varchar(50), + cemeteryAddress2 varchar(50), + cemeteryCity varchar(20), + cemeteryProvince varchar(2), + cemeteryPostalCode varchar(7), + cemeteryPhoneNumber varchar(30), + ${recordColumns})`, + /* + * Burial Sites + */ + `create table if not exists BurialSites ( + burialSiteId integer not null primary key autoincrement, + burialSiteTypeId integer not null, + + burialSiteNameSegment1 varchar(20), + burialSiteNameSegment2 varchar(20), + burialSiteNameSegment3 varchar(20), + burialSiteNameSegment4 varchar(20), + burialSiteNameSegment5 varchar(20), + + cemeteryId integer, + cemeterySvgId varchar(100), + burialSiteLatitude decimal(10, 8) + check (burialSiteLatitude between -90 and 90), + burialSiteLongitude decimal(11, 8) + check (burialSiteLongitude between -180 and 180), + burialSiteStatusId integer, + ${recordColumns}, + foreign key (burialSiteTypeId) references BurialSiteTypes (burialSiteTypeId), + foreign key (cemeteryId) references Cemeteries (cemeteryId), + foreign key (burialSiteStatusId) references BurialSiteStatuses (burialSiteStatusId), + unique (cemeteryId, burialSiteNameSegment1, burialSiteNameSegment2, burialSiteNameSegment3, burialSiteNameSegment4, burialSiteNameSegment5))`, + `create table if not exists BurialSiteFields ( + burialSiteId integer not null, + burialSiteTypeFieldId integer not null, + fieldValue text not null, + ${recordColumns}, + primary key (burialSiteId, burialSiteTypeFieldId), + foreign key (burialSiteId) references BurialSites (burialSiteId), + foreign key (burialSiteTypeFieldId) references BurialSiteTypeFields (burialSiteTypeFieldId)) without rowid`, + `create table if not exists BurialSiteComments ( + burialSiteCommentId integer not null primary key autoincrement, + burialSiteId integer not null, + commentDate integer not null check (commentDate > 0), + commentTime integer not null check (commentTime >= 0), + comment text not null, + ${recordColumns}, + foreign key (lotId) references BurialSites (burialSiteId))`, + `create index if not exists idx_BurialSiteComments_datetime + on BurialSiteComments (burialSiteId, commentDate, commentTime)`, + /* + * Funeral Homes + */ + `create table if not exists FuneralHomes ( + funeralHomeId integer not null primary key autoincrement, + funeralHomeName varchar(200) not null, + funeralHomeAddress1 varchar(50), + funeralHomeAddress2 varchar(50), + funeralHomeCity varchar(20), + funeralHomeProvince varchar(2), + funeralHomePostalCode varchar(7), + funeralHomePhoneNumber varchar(30), + ${recordColumns})`, + /* + * Contracts + */ + `create table if not exists ContractTypes ( + contractTypeId integer not null primary key autoincrement, + contractType varchar(100) not null, + orderNumber smallint not null default 0, + ${recordColumns})`, + `create index if not exists idx_ContractTypes_orderNumber + on ContractTypes (orderNumber, contractType)`, + `create table if not exists ContractTypeFields ( + contractTypeFieldId integer not null primary key autoincrement, + contractTypeId integer, + contractTypeField varchar(100) not null, + fieldType varchar(15) not null default 'text', + fieldValues text, + isRequired bit not null default 0, + pattern varchar(100), + minimumLength smallint not null default 1 check (minimumLength >= 0), + maximumLength smallint not null default 100 check (maximumLength >= 0), + orderNumber smallint not null default 0, + ${recordColumns}, + foreign key (contractTypeId) references ContractTypes (contractTypeId))`, + `create index if not exists idx_ContractTypeFields_orderNumber + on ContractTypeFields (contractTypeId, orderNumber, contractTypeField)`, + `create table if not exists ContractTypePrints ( + contractTypeId integer not null, + printEJS varchar(100) not null, + orderNumber smallint not null default 0, + ${recordColumns}, + primary key (contractTypeId, printEJS), + foreign key (contractTypeId) references ContractTypes (contractTypeId))`, + `create index if not exists idx_ContractTypePrints_orderNumber + on ContractTypePrints (contractTypeId, orderNumber, printEJS)`, + `create table if not exists BurialSiteContracts ( + burialSiteContractId integer not null primary key autoincrement, + contractTypeId integer not null, + burialSiteId integer, + contractStartDate integer not null check (contractStartDate > 0), + contractEndDate integer check (contractEndDate > 0), + + purchaserName varchar(100) not null, + purchaserAddress1 varchar(50), + purchaserAddress2 varchar(50), + purchaserCity varchar(20), + purchaserProvince varchar(2), + purchaserPostalCode varchar(7), + purchaserPhoneNumber varchar(30), + purchaserEmail varchar(100), + + funeralHomeId integer, + funeralDirectorName varchar(100), + + ${recordColumns}, + foreign key (burialSiteId) references BurialSites (burialSiteId), + foreign key (contractTypeId) references ContractTypes (contractTypeId), + foreign key (funeralHomeId) references FuneralHomes (funeralHomeId))`, + `create table if not exists BurialSiteContractFields ( + burialSiteContractId integer not null, + contractTypeFieldId integer not null, + fieldValue text not null, + ${recordColumns}, + primary key (burialSiteContractId, contractTypeFieldId), + foreign key (burialSiteContractId) references BurialSiteContracts (burialSiteContractId), + foreign key (contractTypeFieldId) references ContractTypeFields (contractTypeFieldId)) without rowid`, + `create table if not exists BurialSiteContractComments ( + burialSiteContractCommentId integer not null primary key autoincrement, + burialSiteContractId integer not null, + commentDate integer not null check (commentDate > 0), + commentTime integer not null check (commentTime >= 0), + comment text not null, + ${recordColumns}, + foreign key (burialSiteContractId) references BurialSiteContracts (burialSiteContractId))`, + `create index if not exists idx_BurialSiteContractComments_datetime + on BurialSiteContractComments (burialSiteContractId, commentDate, commentTime)`, + /* + * Interments + */ + `create table if not exists IntermentContainerTypes ( + intermentContainerTypeId integer not null primary key autoincrement, + intermentContainerType varchar(100) not null, + orderNumber smallint not null default 0, + ${recordColumns})`, + `create index if not exists idx_IntermentContainerTypes_orderNumber + on IntermentContainerTypes (orderNumber, intermentContainerType)`, + `create table if not exists IntermentCommittalTypes ( + intermentCommittalTypeId integer not null primary key autoincrement, + intermentCommittalType varchar(100) not null, + orderNumber smallint not null default 0, + ${recordColumns})`, + `create index if not exists idx_IntermentCommittalType_orderNumber + on IntermentCommittalTypes (orderNumber, intermentCommittalType)`, + `create table if not exists BurialSiteContractInterments ( + burialSiteContractId integer not null, + intermentNumber integer not null, + isCremated bit not null default 0, + + deceasedName varchar(50) not null, + + birthDate integer, + birthPlace varchar(100), + + deathDate integer, + deathPlace varchar(100), + + intermentDate integer check (intermentDate > 0), + intermentTime integer check (intermentTime >= 0), + + intermentContainerTypeId integer, + intermentCommittalTypeId integer, + + ${recordColumns}, + primary key (burialSiteContractId, intermentNumber), + foreign key (burialSiteId) references BurialSites (burialSiteId), + foreign key (intermentContainerTypeId) references IntermentContainerTypes (intermentContainerTypeId), + foreign key (intermentCommittalTypeId) references IntermentCommittalTypes (intermentCommittalTypeId)) without rowid`, + /* + * Fees and Transactions + */ + `create table if not exists FeeCategories ( + feeCategoryId integer not null primary key autoincrement, + feeCategory varchar(100) not null, + isGroupedFee bit not null default 0, + orderNumber smallint not null default 0, + ${recordColumns})`, + `create table if not exists Fees ( + feeId integer not null primary key autoincrement, + feeCategoryId integer not null, + feeName varchar(100) not null, + feeDescription text, + feeAccount varchar(20), + + contractTypeId integer, + burialSiteTypeId integer, + + includeQuantity boolean not null default 0, + quantityUnit varchar(30), + feeAmount decimal(8, 2), + feeFunction varchar(100), + taxAmount decimal(6, 2), + taxPercentage decimal(5, 2), + isRequired bit not null default 0, + orderNumber smallint not null default 0, + ${recordColumns}, + foreign key (feeCategoryId) references FeeCategories (feeCategoryId), + foreign key (contractTypeId) references ContractTypes (contractTypeId), + foreign key (burialSiteTypeId) references BurialSiteTypes (burialSiteTypeId))`, + 'create index if not exists idx_Fees_orderNumber on Fees (orderNumber, feeName)', + `create table if not exists BurialSiteContractFees ( + burialSiteContractId integer not null, + feeId integer not null, + quantity decimal(4, 1) not null default 1, + feeAmount decimal(8, 2) not null, + taxAmount decimal(8, 2) not null, + ${recordColumns}, + primary key (burialSiteContractId, feeId), + foreign key (burialSiteContractId) references BurialSiteContracts (burialSiteContractId), + foreign key (feeId) references Fees (feeId)) without rowid`, + `create table if not exists BurialSiteContractTransactions ( + burialSiteContractId integer not null, + transactionIndex integer not null, + transactionDate integer not null check (transactionDate > 0), + transactionTime integer not null check (transactionTime >= 0), + transactionAmount decimal(8, 2) not null, + externalReceiptNumber varchar(100), + transactionNote text, + ${recordColumns}, + primary key (burialSiteContractId, transactionIndex), + foreign key (burialSiteContractId) references BurialSiteContracts (burialSiteContractId)) without rowid`, + `create index if not exists idx_BurialSiteContractTransactions_orderNumber + on BurialSiteContractTransactions (burialSiteContractId, transactionDate, transactionTime)`, + /* + * Work Orders + */ + `create table if not exists WorkOrderTypes ( + workOrderTypeId integer not null primary key autoincrement, + workOrderType varchar(100) not null, + orderNumber smallint not null default 0, + ${recordColumns})`, + `create index if not exists idx_WorkOrderTypes_orderNumber + on WorkOrderTypes (orderNumber, workOrderType)`, + `create table if not exists WorkOrders ( + workOrderId integer not null primary key autoincrement, + workOrderTypeId integer not null, + workOrderNumber varchar(50) not null, + workOrderDescription text, + workOrderOpenDate integer check (workOrderOpenDate > 0), + workOrderCloseDate integer check (workOrderCloseDate > 0), + ${recordColumns}, + foreign key (workOrderTypeId) references WorkOrderTypes (workOrderTypeId))`, + `create table if not exists WorkOrderBurialSites ( + workOrderId integer not null, + burialSiteId integer not null, + ${recordColumns}, + primary key (workOrderId, burialSiteId), + foreign key (workOrderId) references WorkOrders (workOrderId), + foreign key (burialSiteId) references BurialSites (burialSiteId)) without rowid`, + `create table if not exists WorkOrderBurialSiteContracts ( + workOrderId integer not null, + burialSiteContractId integer not null, + ${recordColumns}, + primary key (workOrderId, burialSiteContractId), + foreign key (workOrderId) references WorkOrders (workOrderId), + foreign key (burialSiteContractId) references BurialSiteContracts (burialSiteContractId)) without rowid`, + `create table if not exists WorkOrderComments ( + workOrderCommentId integer not null primary key autoincrement, + workOrderId integer not null, + commentDate integer not null check (commentDate > 0), + commentTime integer not null check (commentTime >= 0), + comment text not null, + ${recordColumns}, + foreign key (workOrderId) references WorkOrders (workOrderId))`, + `create index if not exists idx_WorkOrderComments_datetime + on WorkOrderComments (workOrderId, commentDate, commentTime)`, + `create table if not exists WorkOrderMilestoneTypes ( + workOrderMilestoneTypeId integer not null primary key autoincrement, + workOrderMilestoneType varchar(100) not null, + orderNumber smallint not null default 0, + ${recordColumns})`, + `create table if not exists WorkOrderMilestones ( + workOrderMilestoneId integer not null primary key autoincrement, + workOrderId integer not null, + workOrderMilestoneTypeId integer, + workOrderMilestoneDate integer not null check (workOrderMilestoneDate >= 0), + workOrderMilestoneTime integer not null check (workOrderMilestoneTime >= 0), + workOrderMilestoneDescription text not null, + workOrderMilestoneCompletionDate integer check (workOrderMilestoneCompletionDate > 0), + workOrderMilestoneCompletionTime integer check (workOrderMilestoneCompletionTime >= 0), + ${recordColumns}, + foreign key (workOrderId) references WorkOrders (workOrderId), + foreign key (workOrderMilestoneTypeId) references WorkOrderMilestoneTypes (workOrderMilestoneTypeId))` +]; +const initializingUser = { + userName: 'databaseInit', + userProperties: { + canUpdate: true, + isAdmin: true, + apiKey: '' + } +}; +export async function initializeDatabase() { + const sunriseDB = sqlite(databasePath); + const row = sunriseDB + .prepare("select name from sqlite_master where type = 'table' and name = 'WorkOrderMilestones'") + .get(); + if (row !== undefined) { + return false; + } + debug(`Creating ${databasePath} tables...`); + for (const sql of createStatements) { + sunriseDB.prepare(sql).run(); + } + sunriseDB.close(); + await initializeData(); + return true; +} +async function initializeData() { + debug(`Initializing data...`); + await addRecord('BurialSiteTypes', 'Casket Grave', 1, initializingUser); + await addRecord('BurialSiteTypes', 'Columbarium', 2, initializingUser); + await addRecord('BurialSiteTypes', 'Mausoleum', 2, initializingUser); + await addRecord('BurialSiteTypes', 'Niche Wall', 2, initializingUser); + await addRecord('BurialSiteTypes', 'Urn Garden', 2, initializingUser); + await addRecord('BurialSiteTypes', 'Crematorium', 2, initializingUser); + await addRecord('BurialSiteStatuses', 'Available', 1, initializingUser); + await addRecord('BurialSiteStatuses', 'Reserved', 2, initializingUser); + await addRecord('BurialSiteStatuses', 'Taken', 3, initializingUser); + await addRecord('ContractTypes', 'Preneed', 1, initializingUser); + await addRecord('ContractTypes', 'Interment', 2, initializingUser); + await addRecord('ContractTypes', 'Cremation', 3, initializingUser); + /* + * Fee Categories + */ + await addFeeCategory({ + feeCategory: 'Interment Rights', + orderNumber: 1 + }, initializingUser); + await addFeeCategory({ + feeCategory: 'Cremation Services', + orderNumber: 2 + }, initializingUser); + await addFeeCategory({ + feeCategory: 'Burial Charges', + orderNumber: 3 + }, initializingUser); + await addFeeCategory({ + feeCategory: 'Disinterment of Human Remains', + orderNumber: 4 + }, initializingUser); + await addFeeCategory({ + feeCategory: 'Additional Services', + orderNumber: 5 + }, initializingUser); + /* + * Work Orders + */ + await addRecord('WorkOrderTypes', 'Cemetery Work Order', 1, initializingUser); + await addRecord('WorkOrderMilestoneTypes', 'Funeral', 1, initializingUser); + await addRecord('WorkOrderMilestoneTypes', 'Arrival', 2, initializingUser); + await addRecord('WorkOrderMilestoneTypes', 'Cremation', 3, initializingUser); + await addRecord('WorkOrderMilestoneTypes', 'Interment', 4, initializingUser); +} diff --git a/database/initializeDatabase.ts b/database/initializeDatabase.ts new file mode 100644 index 00000000..e285d8e2 --- /dev/null +++ b/database/initializeDatabase.ts @@ -0,0 +1,523 @@ +// eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair +/* eslint-disable no-secrets/no-secrets */ + +import sqlite from 'better-sqlite3' +import Debug from 'debug' + +import { DEBUG_NAMESPACE } from '../debug.config.js' +import { sunriseDB as databasePath } from '../helpers/database.helpers.js' + +import addFeeCategory from './addFeeCategory.js' +import addRecord from './addRecord.js' + +const debug = Debug(`${DEBUG_NAMESPACE}:database/initializeDatabase`) + +const recordColumns = `recordCreate_userName varchar(30) not null, + recordCreate_timeMillis integer not null, + recordUpdate_userName varchar(30) not null, + recordUpdate_timeMillis integer not null, + recordDelete_userName varchar(30), + recordDelete_timeMillis integer` + +const createStatements = [ + /* + * Burial Site Types + */ + + `create table if not exists BurialSiteTypes ( + burialSiteTypeId integer not null primary key autoincrement, + burialSiteType varchar(100) not null, + orderNumber smallint not null default 0, + ${recordColumns})`, + + `create index if not exists idx_BurialSiteTypes_orderNumber + on LotTypes (orderNumber, burialSiteType)`, + + `create table if not exists BurialSiteTypeFields ( + burialSiteTypeFieldId integer not null primary key autoincrement, + burialSiteTypeId integer not null, + burialSiteTypeField varchar(100) not null, + fieldType varchar(15) not null default 'text', + fieldValues text, + isRequired bit not null default 0, + pattern varchar(100), + minimumLength smallint not null default 1 check (minimumLength >= 0), + maximumLength smallint not null default 100 check (maximumLength >= 0), + orderNumber smallint not null default 0, + ${recordColumns}, + foreign key (burialSiteTypeId) references BurialSiteTypes (burialSiteTypeId))`, + + `create index if not exists idx_BurialSiteTypeFields_orderNumber + on BurialSiteTypeFields (burialSiteTypeId, orderNumber, burialSiteTypeField)`, + + /* + * Burial Site Statuses + */ + + `create table if not exists BurialSiteStatuses ( + burialSiteStatusId integer not null primary key autoincrement, + burialSiteStatus varchar(100) not null, + orderNumber smallint not null default 0, + ${recordColumns})`, + + `create index if not exists idx_BurialSiteStatuses_orderNumber + on BurialSiteStatuses (orderNumber, burialSiteStatus)`, + + /* + * Cemeteries + */ + + `create table if not exists Cemeteries ( + cemeteryId integer not null primary key autoincrement, + cemeteryName varchar(200) not null, + cemeteryDescription text, + cemeteryLatitude decimal(10, 8) + check (cemeteryLatitude between -90 and 90), + cemeteryLongitude decimal(11, 8) + check (cemeteryLongitude between -180 and 180), + cemeterySvg varchar(50), + cemeteryAddress1 varchar(50), + cemeteryAddress2 varchar(50), + cemeteryCity varchar(20), + cemeteryProvince varchar(2), + cemeteryPostalCode varchar(7), + cemeteryPhoneNumber varchar(30), + ${recordColumns})`, + + /* + * Burial Sites + */ + + `create table if not exists BurialSites ( + burialSiteId integer not null primary key autoincrement, + burialSiteTypeId integer not null, + + burialSiteNameSegment1 varchar(20), + burialSiteNameSegment2 varchar(20), + burialSiteNameSegment3 varchar(20), + burialSiteNameSegment4 varchar(20), + burialSiteNameSegment5 varchar(20), + + cemeteryId integer, + cemeterySvgId varchar(100), + burialSiteLatitude decimal(10, 8) + check (burialSiteLatitude between -90 and 90), + burialSiteLongitude decimal(11, 8) + check (burialSiteLongitude between -180 and 180), + burialSiteStatusId integer, + ${recordColumns}, + foreign key (burialSiteTypeId) references BurialSiteTypes (burialSiteTypeId), + foreign key (cemeteryId) references Cemeteries (cemeteryId), + foreign key (burialSiteStatusId) references BurialSiteStatuses (burialSiteStatusId), + unique (cemeteryId, burialSiteNameSegment1, burialSiteNameSegment2, burialSiteNameSegment3, burialSiteNameSegment4, burialSiteNameSegment5))`, + + `create table if not exists BurialSiteFields ( + burialSiteId integer not null, + burialSiteTypeFieldId integer not null, + fieldValue text not null, + ${recordColumns}, + primary key (burialSiteId, burialSiteTypeFieldId), + foreign key (burialSiteId) references BurialSites (burialSiteId), + foreign key (burialSiteTypeFieldId) references BurialSiteTypeFields (burialSiteTypeFieldId)) without rowid`, + + `create table if not exists BurialSiteComments ( + burialSiteCommentId integer not null primary key autoincrement, + burialSiteId integer not null, + commentDate integer not null check (commentDate > 0), + commentTime integer not null check (commentTime >= 0), + comment text not null, + ${recordColumns}, + foreign key (lotId) references BurialSites (burialSiteId))`, + + `create index if not exists idx_BurialSiteComments_datetime + on BurialSiteComments (burialSiteId, commentDate, commentTime)`, + + /* + * Funeral Homes + */ + + `create table if not exists FuneralHomes ( + funeralHomeId integer not null primary key autoincrement, + funeralHomeName varchar(200) not null, + funeralHomeAddress1 varchar(50), + funeralHomeAddress2 varchar(50), + funeralHomeCity varchar(20), + funeralHomeProvince varchar(2), + funeralHomePostalCode varchar(7), + funeralHomePhoneNumber varchar(30), + ${recordColumns})`, + + /* + * Contracts + */ + + `create table if not exists ContractTypes ( + contractTypeId integer not null primary key autoincrement, + contractType varchar(100) not null, + orderNumber smallint not null default 0, + ${recordColumns})`, + + `create index if not exists idx_ContractTypes_orderNumber + on ContractTypes (orderNumber, contractType)`, + + `create table if not exists ContractTypeFields ( + contractTypeFieldId integer not null primary key autoincrement, + contractTypeId integer, + contractTypeField varchar(100) not null, + fieldType varchar(15) not null default 'text', + fieldValues text, + isRequired bit not null default 0, + pattern varchar(100), + minimumLength smallint not null default 1 check (minimumLength >= 0), + maximumLength smallint not null default 100 check (maximumLength >= 0), + orderNumber smallint not null default 0, + ${recordColumns}, + foreign key (contractTypeId) references ContractTypes (contractTypeId))`, + + `create index if not exists idx_ContractTypeFields_orderNumber + on ContractTypeFields (contractTypeId, orderNumber, contractTypeField)`, + + `create table if not exists ContractTypePrints ( + contractTypeId integer not null, + printEJS varchar(100) not null, + orderNumber smallint not null default 0, + ${recordColumns}, + primary key (contractTypeId, printEJS), + foreign key (contractTypeId) references ContractTypes (contractTypeId))`, + + `create index if not exists idx_ContractTypePrints_orderNumber + on ContractTypePrints (contractTypeId, orderNumber, printEJS)`, + + `create table if not exists BurialSiteContracts ( + burialSiteContractId integer not null primary key autoincrement, + contractTypeId integer not null, + burialSiteId integer, + contractStartDate integer not null check (contractStartDate > 0), + contractEndDate integer check (contractEndDate > 0), + + purchaserName varchar(100) not null, + purchaserAddress1 varchar(50), + purchaserAddress2 varchar(50), + purchaserCity varchar(20), + purchaserProvince varchar(2), + purchaserPostalCode varchar(7), + purchaserPhoneNumber varchar(30), + purchaserEmail varchar(100), + + funeralHomeId integer, + funeralDirectorName varchar(100), + + ${recordColumns}, + foreign key (burialSiteId) references BurialSites (burialSiteId), + foreign key (contractTypeId) references ContractTypes (contractTypeId), + foreign key (funeralHomeId) references FuneralHomes (funeralHomeId))`, + + `create table if not exists BurialSiteContractFields ( + burialSiteContractId integer not null, + contractTypeFieldId integer not null, + fieldValue text not null, + ${recordColumns}, + primary key (burialSiteContractId, contractTypeFieldId), + foreign key (burialSiteContractId) references BurialSiteContracts (burialSiteContractId), + foreign key (contractTypeFieldId) references ContractTypeFields (contractTypeFieldId)) without rowid`, + + `create table if not exists BurialSiteContractComments ( + burialSiteContractCommentId integer not null primary key autoincrement, + burialSiteContractId integer not null, + commentDate integer not null check (commentDate > 0), + commentTime integer not null check (commentTime >= 0), + comment text not null, + ${recordColumns}, + foreign key (burialSiteContractId) references BurialSiteContracts (burialSiteContractId))`, + + `create index if not exists idx_BurialSiteContractComments_datetime + on BurialSiteContractComments (burialSiteContractId, commentDate, commentTime)`, + + /* + * Interments + */ + + `create table if not exists IntermentContainerTypes ( + intermentContainerTypeId integer not null primary key autoincrement, + intermentContainerType varchar(100) not null, + orderNumber smallint not null default 0, + ${recordColumns})`, + + `create index if not exists idx_IntermentContainerTypes_orderNumber + on IntermentContainerTypes (orderNumber, intermentContainerType)`, + + `create table if not exists IntermentCommittalTypes ( + intermentCommittalTypeId integer not null primary key autoincrement, + intermentCommittalType varchar(100) not null, + orderNumber smallint not null default 0, + ${recordColumns})`, + + `create index if not exists idx_IntermentCommittalType_orderNumber + on IntermentCommittalTypes (orderNumber, intermentCommittalType)`, + + `create table if not exists BurialSiteContractInterments ( + burialSiteContractId integer not null, + intermentNumber integer not null, + isCremated bit not null default 0, + + deceasedName varchar(50) not null, + + birthDate integer, + birthPlace varchar(100), + + deathDate integer, + deathPlace varchar(100), + + intermentDate integer check (intermentDate > 0), + intermentTime integer check (intermentTime >= 0), + + intermentContainerTypeId integer, + intermentCommittalTypeId integer, + + ${recordColumns}, + primary key (burialSiteContractId, intermentNumber), + foreign key (burialSiteId) references BurialSites (burialSiteId), + foreign key (intermentContainerTypeId) references IntermentContainerTypes (intermentContainerTypeId), + foreign key (intermentCommittalTypeId) references IntermentCommittalTypes (intermentCommittalTypeId)) without rowid`, + + /* + * Fees and Transactions + */ + + `create table if not exists FeeCategories ( + feeCategoryId integer not null primary key autoincrement, + feeCategory varchar(100) not null, + isGroupedFee bit not null default 0, + orderNumber smallint not null default 0, + ${recordColumns})`, + + `create table if not exists Fees ( + feeId integer not null primary key autoincrement, + feeCategoryId integer not null, + feeName varchar(100) not null, + feeDescription text, + feeAccount varchar(20), + + contractTypeId integer, + burialSiteTypeId integer, + + includeQuantity boolean not null default 0, + quantityUnit varchar(30), + feeAmount decimal(8, 2), + feeFunction varchar(100), + taxAmount decimal(6, 2), + taxPercentage decimal(5, 2), + isRequired bit not null default 0, + orderNumber smallint not null default 0, + ${recordColumns}, + foreign key (feeCategoryId) references FeeCategories (feeCategoryId), + foreign key (contractTypeId) references ContractTypes (contractTypeId), + foreign key (burialSiteTypeId) references BurialSiteTypes (burialSiteTypeId))`, + + 'create index if not exists idx_Fees_orderNumber on Fees (orderNumber, feeName)', + + `create table if not exists BurialSiteContractFees ( + burialSiteContractId integer not null, + feeId integer not null, + quantity decimal(4, 1) not null default 1, + feeAmount decimal(8, 2) not null, + taxAmount decimal(8, 2) not null, + ${recordColumns}, + primary key (burialSiteContractId, feeId), + foreign key (burialSiteContractId) references BurialSiteContracts (burialSiteContractId), + foreign key (feeId) references Fees (feeId)) without rowid`, + + `create table if not exists BurialSiteContractTransactions ( + burialSiteContractId integer not null, + transactionIndex integer not null, + transactionDate integer not null check (transactionDate > 0), + transactionTime integer not null check (transactionTime >= 0), + transactionAmount decimal(8, 2) not null, + externalReceiptNumber varchar(100), + transactionNote text, + ${recordColumns}, + primary key (burialSiteContractId, transactionIndex), + foreign key (burialSiteContractId) references BurialSiteContracts (burialSiteContractId)) without rowid`, + + `create index if not exists idx_BurialSiteContractTransactions_orderNumber + on BurialSiteContractTransactions (burialSiteContractId, transactionDate, transactionTime)`, + + /* + * Work Orders + */ + + `create table if not exists WorkOrderTypes ( + workOrderTypeId integer not null primary key autoincrement, + workOrderType varchar(100) not null, + orderNumber smallint not null default 0, + ${recordColumns})`, + + `create index if not exists idx_WorkOrderTypes_orderNumber + on WorkOrderTypes (orderNumber, workOrderType)`, + + `create table if not exists WorkOrders ( + workOrderId integer not null primary key autoincrement, + workOrderTypeId integer not null, + workOrderNumber varchar(50) not null, + workOrderDescription text, + workOrderOpenDate integer check (workOrderOpenDate > 0), + workOrderCloseDate integer check (workOrderCloseDate > 0), + ${recordColumns}, + foreign key (workOrderTypeId) references WorkOrderTypes (workOrderTypeId))`, + + `create table if not exists WorkOrderBurialSites ( + workOrderId integer not null, + burialSiteId integer not null, + ${recordColumns}, + primary key (workOrderId, burialSiteId), + foreign key (workOrderId) references WorkOrders (workOrderId), + foreign key (burialSiteId) references BurialSites (burialSiteId)) without rowid`, + + `create table if not exists WorkOrderBurialSiteContracts ( + workOrderId integer not null, + burialSiteContractId integer not null, + ${recordColumns}, + primary key (workOrderId, burialSiteContractId), + foreign key (workOrderId) references WorkOrders (workOrderId), + foreign key (burialSiteContractId) references BurialSiteContracts (burialSiteContractId)) without rowid`, + + `create table if not exists WorkOrderComments ( + workOrderCommentId integer not null primary key autoincrement, + workOrderId integer not null, + commentDate integer not null check (commentDate > 0), + commentTime integer not null check (commentTime >= 0), + comment text not null, + ${recordColumns}, + foreign key (workOrderId) references WorkOrders (workOrderId))`, + + `create index if not exists idx_WorkOrderComments_datetime + on WorkOrderComments (workOrderId, commentDate, commentTime)`, + + `create table if not exists WorkOrderMilestoneTypes ( + workOrderMilestoneTypeId integer not null primary key autoincrement, + workOrderMilestoneType varchar(100) not null, + orderNumber smallint not null default 0, + ${recordColumns})`, + + `create table if not exists WorkOrderMilestones ( + workOrderMilestoneId integer not null primary key autoincrement, + workOrderId integer not null, + workOrderMilestoneTypeId integer, + workOrderMilestoneDate integer not null check (workOrderMilestoneDate >= 0), + workOrderMilestoneTime integer not null check (workOrderMilestoneTime >= 0), + workOrderMilestoneDescription text not null, + workOrderMilestoneCompletionDate integer check (workOrderMilestoneCompletionDate > 0), + workOrderMilestoneCompletionTime integer check (workOrderMilestoneCompletionTime >= 0), + ${recordColumns}, + foreign key (workOrderId) references WorkOrders (workOrderId), + foreign key (workOrderMilestoneTypeId) references WorkOrderMilestoneTypes (workOrderMilestoneTypeId))` +] + +const initializingUser: User = { + userName: 'databaseInit', + userProperties: { + canUpdate: true, + isAdmin: true, + apiKey: '' + } +} + +export async function initializeDatabase(): Promise { + const sunriseDB = sqlite(databasePath) + + const row = sunriseDB + .prepare( + "select name from sqlite_master where type = 'table' and name = 'WorkOrderMilestones'" + ) + .get() + + if (row !== undefined) { + return false + } + + debug(`Creating ${databasePath} tables...`) + + for (const sql of createStatements) { + sunriseDB.prepare(sql).run() + } + + sunriseDB.close() + + await initializeData() + + return true +} + +async function initializeData(): Promise { + debug(`Initializing data...`) + + await addRecord('BurialSiteTypes', 'Casket Grave', 1, initializingUser) + await addRecord('BurialSiteTypes', 'Columbarium', 2, initializingUser) + await addRecord('BurialSiteTypes', 'Mausoleum', 2, initializingUser) + await addRecord('BurialSiteTypes', 'Niche Wall', 2, initializingUser) + await addRecord('BurialSiteTypes', 'Urn Garden', 2, initializingUser) + await addRecord('BurialSiteTypes', 'Crematorium', 2, initializingUser) + + await addRecord('BurialSiteStatuses', 'Available', 1, initializingUser) + await addRecord('BurialSiteStatuses', 'Reserved', 2, initializingUser) + await addRecord('BurialSiteStatuses', 'Taken', 3, initializingUser) + + await addRecord('ContractTypes', 'Preneed', 1, initializingUser) + await addRecord('ContractTypes', 'Interment', 2, initializingUser) + await addRecord('ContractTypes', 'Cremation', 3, initializingUser) + + /* + * Fee Categories + */ + + await addFeeCategory( + { + feeCategory: 'Interment Rights', + orderNumber: 1 + }, + initializingUser + ) + + await addFeeCategory( + { + feeCategory: 'Cremation Services', + orderNumber: 2 + }, + initializingUser + ) + + await addFeeCategory( + { + feeCategory: 'Burial Charges', + orderNumber: 3 + }, + initializingUser + ) + + await addFeeCategory( + { + feeCategory: 'Disinterment of Human Remains', + orderNumber: 4 + }, + initializingUser + ) + + await addFeeCategory( + { + feeCategory: 'Additional Services', + orderNumber: 5 + }, + initializingUser + ) + + /* + * Work Orders + */ + + await addRecord('WorkOrderTypes', 'Cemetery Work Order', 1, initializingUser) + + await addRecord('WorkOrderMilestoneTypes', 'Funeral', 1, initializingUser) + await addRecord('WorkOrderMilestoneTypes', 'Arrival', 2, initializingUser) + await addRecord('WorkOrderMilestoneTypes', 'Cremation', 3, initializingUser) + await addRecord('WorkOrderMilestoneTypes', 'Interment', 4, initializingUser) +} diff --git a/database/pool.js b/database/pool.js index 2bcd4a3d..f4f0a526 100644 --- a/database/pool.js +++ b/database/pool.js @@ -1,8 +1,9 @@ import { Pool } from 'better-sqlite-pool'; import Debug from 'debug'; import exitHook from 'exit-hook'; -import { lotOccupancyDB as databasePath } from '../data/databasePaths.js'; -const debug = Debug('lot-occupancy-system:lotOccupancyDB:pool'); +import { DEBUG_NAMESPACE } from '../debug.config.js'; +import { sunriseDB as databasePath } from '../helpers/database.helpers.js'; +const debug = Debug(`${DEBUG_NAMESPACE}:sunriseDB:pool`); const pool = new Pool(databasePath); export async function acquireConnection() { return await pool.acquire(); diff --git a/database/pool.ts b/database/pool.ts index fdce4bb3..9d5c38b7 100644 --- a/database/pool.ts +++ b/database/pool.ts @@ -2,9 +2,10 @@ import { Pool, type PoolConnection } from 'better-sqlite-pool' import Debug from 'debug' import exitHook from 'exit-hook' -import { lotOccupancyDB as databasePath } from '../data/databasePaths.js' +import { DEBUG_NAMESPACE } from '../debug.config.js' +import { sunriseDB as databasePath } from '../helpers/database.helpers.js' -const debug = Debug('lot-occupancy-system:lotOccupancyDB:pool') +const debug = Debug(`${DEBUG_NAMESPACE}:sunriseDB:pool`) const pool = new Pool(databasePath) diff --git a/debug.config.d.ts b/debug.config.d.ts new file mode 100644 index 00000000..7901ca7b --- /dev/null +++ b/debug.config.d.ts @@ -0,0 +1,2 @@ +export declare const DEBUG_NAMESPACE = "sunrise"; +export declare const DEBUG_ENABLE_NAMESPACES: string; diff --git a/debug.config.js b/debug.config.js new file mode 100644 index 00000000..381e10ff --- /dev/null +++ b/debug.config.js @@ -0,0 +1,6 @@ +import { DEBUG_ENABLE_NAMESPACES as DEBUG_ENABLE_NAMESPACES_DYNAMICS } from '@cityssm/dynamics-gp/debug'; +export const DEBUG_NAMESPACE = 'sunrise'; +export const DEBUG_ENABLE_NAMESPACES = [ + `${DEBUG_NAMESPACE}:*`, + DEBUG_ENABLE_NAMESPACES_DYNAMICS +].join(','); diff --git a/debug.config.ts b/debug.config.ts new file mode 100644 index 00000000..e05b0c35 --- /dev/null +++ b/debug.config.ts @@ -0,0 +1,8 @@ +import { DEBUG_ENABLE_NAMESPACES as DEBUG_ENABLE_NAMESPACES_DYNAMICS } from '@cityssm/dynamics-gp/debug' + +export const DEBUG_NAMESPACE = 'sunrise' + +export const DEBUG_ENABLE_NAMESPACES = [ + `${DEBUG_NAMESPACE}:*`, + DEBUG_ENABLE_NAMESPACES_DYNAMICS +].join(',') diff --git a/docs/README.md b/docs/README.md deleted file mode 100644 index 5a13c4cf..00000000 --- a/docs/README.md +++ /dev/null @@ -1,43 +0,0 @@ -[Home](https://cityssm.github.io/lot-occupancy-system/) - -# Help Documentation - -**Thank you for taking the time to read the documentation.** - -![Lot Occupancy View](images/lotOccupancyView.png) - -## 👶 Getting Started - -[**Terminology**](terminology.md)
-Understanding the key terms used in the Lot Occupancy System. - -## 👩 User Documentation - -[**Lot Occupancies**](lotOccupancies.md)
-What are occupancy records? - -[**Work Orders**](workOrders.md)
-What are work orders? How do they work? - -## 🦸‍♀️ Power User Documentation - -[**Keyboard Shortcuts**](shortcuts.md)
-Shortcuts to speed through tasks in the Lot Occupancy System. - -## 💼 Administrator Documentation - -[**Fee Management**](adminFees.md)
-Administer fees that apply to occupancy records. - -[**Occupancy Type Management**](adminOccupancyTypes.md)
-Maintain the types available for occupancy records. - -[**Lot Type Management**](adminLotTypes.md)
-Maintain the types available for lots. - -[**Config Table Management**](adminConfigTables.md)
-Maintain simpler, list-like tables include work order types, -work order milestone types, lot statuses, and lot occupant types. - -[**Map Images**](mapImages.md)
-How to create images compatible with the Lot Occupancy System. diff --git a/docs/adminConfigTables.md b/docs/adminConfigTables.md deleted file mode 100644 index 5e8cb3f1..00000000 --- a/docs/adminConfigTables.md +++ /dev/null @@ -1,25 +0,0 @@ -[Home](https://cityssm.github.io/lot-occupancy-system/) -• -[Help](https://cityssm.github.io/lot-occupancy-system/docs/) - -# Config Table Management - -![Config Table Management](images/adminConfigTables.png) - -The Config Table Management page updates simpler configuration tables -that are, for the most part, list-like. - -The tables that can be updated on this page include: - -- Work Order Types -- Work Order Milestone Types -- Lot Statuses (referred to as "Burial Site Statuses" in the screenshot) -- Lot Occupant Types (referred to as "Burial Site Occupant Types" in the screenshot) - -When updating any list items, it is important not to change the meaning of the items. -When in doubt, rather than renaming a list item, delete it, and create a new one instead. - -## Related Links - -- [Occupancy Type Management](adminOccupancyTypes.md) -- [Lot Type Management](adminLotTypes.md) diff --git a/docs/adminFees.md b/docs/adminFees.md deleted file mode 100644 index 91134625..00000000 --- a/docs/adminFees.md +++ /dev/null @@ -1,19 +0,0 @@ -[Home](https://cityssm.github.io/lot-occupancy-system/) -• -[Help](https://cityssm.github.io/lot-occupancy-system/docs/) - -# Fee Management - -![Fee Management](images/adminFees.png) - -Fees can be applied to [occupancy records](lotOccupancies.md). -Each fee includes the following properties. - -- A category, name, and description. -- Filter options by occupancy type and/or lot type. -- Fee and tax amounts. - -## Related Links - -- [Occupancy Type Management](adminOccupancyTypes.md) -- [Lot Type Management](adminLotTypes.md) diff --git a/docs/adminLotTypes.md b/docs/adminLotTypes.md deleted file mode 100644 index 8b25011e..00000000 --- a/docs/adminLotTypes.md +++ /dev/null @@ -1,10 +0,0 @@ -[Home](https://cityssm.github.io/lot-occupancy-system/) -• -[Help](https://cityssm.github.io/lot-occupancy-system/docs/) - -# Lot Type Management - -![Lot Type Management](images/adminLotTypes.png) - -Each lot record, refered to as a "burial site" in the screenshot, is assigned a type. -Those types can have custom data fields associated with them. diff --git a/docs/adminOccupancyTypes.md b/docs/adminOccupancyTypes.md deleted file mode 100644 index e5005d41..00000000 --- a/docs/adminOccupancyTypes.md +++ /dev/null @@ -1,14 +0,0 @@ -[Home](https://cityssm.github.io/lot-occupancy-system/) -• -[Help](https://cityssm.github.io/lot-occupancy-system/docs/) - -# Occupancy Type Management - -![Occupancy Type Management](images/adminOccupancyTypes.png) - -Each occupancy record is assigned a type. -Those types can have custom data fields associated with them. - -## Related Links - -- [Lot Occupancies](lotOccupancies.md) diff --git a/docs/cemeteryWorkflowDeceased.md b/docs/cemeteryWorkflowDeceased.md deleted file mode 100644 index 9a6a87cc..00000000 --- a/docs/cemeteryWorkflowDeceased.md +++ /dev/null @@ -1,33 +0,0 @@ -[Home](https://cityssm.github.io/lot-occupancy-system/) -• -[Help](https://cityssm.github.io/lot-occupancy-system/docs/) - -# Cemetery Management System Workflow - Newly Deceased - -_The following workflow describes a process that can be used when the Lot Occupancy System is used -as a Cemetery Management System._ - -## Step 1: Search for a Related Preneed Occupancy Record - -![Occupancy Search](images/lotOccupancySearch.png) - -If the deceased purchased preneed services, find them now. - -![Occupancy View](images/lotOccupancyView.png) - -It is important to note what services have been paid for, -and who is entitled to the services. - -## Step 2: Create the New Interment or Cremation Occupancy Record - -![Occupancy Edit - More Options](images/lotOccupancyEdit-moreOptions.png) - -If a preneed occupancy record exists, you can save time by copying the preneed record as a new record. - -If no preneed occupancy record exists, a new occupancy record should be created. - -## Step 3: Create a Work Order Associated with the Occupancy Record - -Ensure the necessary milestones are included. - -## Step 4: Complete the Work Order \ No newline at end of file diff --git a/docs/images/adminConfigTables.png b/docs/images/adminConfigTables.png deleted file mode 100644 index 553bc301d03d26e84c2c3b177cfe5179d35648a8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 31947 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 PJeKAe?bCUuF5muNM0mDt diff --git a/docs/images/adminFees.png b/docs/images/adminFees.png deleted file mode 100644 index 220845c2431bcb77932cfc8c8b867f55c8e26d64..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 50895 zcmb@t2UJr{)HWJl>8MB%6a*rK-c&jW7-*EccjEhg|9{uIcddWjweHbyk~8Pb?Afzt&$FLBC;Y03;ZZhzHV6cA z6p7G7K_Co{5Xj*ymVdyN#7P%saAI(QUx7m)`7!JVHyOci=xqe*3Iq}?4uL#;0)gy- zOAluu5dX6f$h;#2qVXC6;qxYxU%LPbm~I&x>OpAqe{ZTXYGZ-kXE1aj;<{d1_% z>!TBR9D>w?n?D#>q+oEiyN&7+g~5{Lz2&f;GizoD`;S0(=||rma2!Cc|NHA9^w8fgP{hB#S-Ac^V;TOQ|34N#mOuz3=H9z^ z&pw!3w;gFp-89sBYyGzcM?c0n1={SEY7J#QDTYEerV-Z-X@2d(lm!I}WAeYviAp0H z+X%FpWgTju4t0owXKKr(X5*g(_P@e_QVewjJr>hIju50!X>%j;m@N*H?cc(a`tb7g zMhw}7=CmH8Q?!yLyn~@onRTdpm~AEH|0<9}(B^bwg!h=Yd#G(0UX&OGv%wd+gg+HWcilQZpwJ zlnjM!4~1e5IjSv6&IQYR8UBh*3t29ETl1q-6yZhtonB3TG}MS5i`Cg>PUzLn+fRr= z&;8m+U#$F`y5V)!Mt|x4cpd9d?sH+Z+FS-zNuyMdnM3GwZOOEaSJl=U(BOAr>S~KZ zjmNg#F#2FZ7_*R5in3V+H*MB9x2Z1Bi+$U*dPU(}-;o--rNz+xGX|i?7X@VMav!zj z>*5B!+=X?I4F!%2(Z(sO&vkx&ISyfBo2%nID49Q@nIVdd%k52c2$500KhA*d(t!`C zmF|77SzD>zh)hQ>=?qdDg?Cgjp_56Lw9SxIp7G_16>`Og&CKgC3HMx%!eXdP?;`0! zGIn$IJBQ)G?7FKZgH+n@uO&6YVVl<~R`yi<|I~~iw%nl~FAs6ST!{l&g@mR4LIEfE zz~){XWv5X`KEdccYOYa-dcQ+sEzY+^U`>~tWt8{N6k)}8s9E9H$ZlKU;0p|=$#bf{}Fru>UT>XD*b);NN&$dpiWzGpwG|2R=^SR-`&f$RJv&3C@5 zYmBzGlh!ua*p>^1Y-zzX3t{aM#tpj$AH0+xwjRj9h!i~n_xc@NIAf4??S<^Aqx>B{ zM)j^V!>pROPVVZcTDKQ$w~&g zF$`)%7Zqb+fxNWdPB5xFW6y<`H*zSzD(+Vo?g`e+q=l&2Lk9J6eh6=zx#2ts%IMYV zBhboacnMc7ibzRGaoDGrdfdB5Z5-KMi8&pT?d$uZ=&;8TxJ~K6QZsq1%zF&G(KD<- zxftbp$Gt-COM!fRz|40J9goC5ancB}b0|LS_e-a;KRKTECQr;|B);^bmur_V^M8oz zd0luZ5ARGj22aNJJCmVW*sTwP+S`A8lOsdtw^MzqznAB1q?+agrA$|c?c>iE#A;P2 zP@kb7TJlvERuXRUbr~_*$-!2=(i*^SK{awGPIzDkHyV4M5zYn=Xjr9{dx%J#PJbkt7`>jT+--t==;8z1B8IjbKuu z9-cv}z&bB!EdEbWmYAP>mkD?MuyBQcqU#kLb+Hk%#n9&xqeG61%*FVur&HIm9BRtf z`CKqtt64Q$p;`S4XOMfbeJf!S&wISq-A*^;hRu9kXyW4`5))ESJ3G&qzv}!}<8F=2 z+m{KNyCfkv5{nJVF&v_q*KpP5Eb@upXsTWIY->iMGKJNL*q0J7T*ndcgQlX&D}17_ zV|5mD6!})*bBeY-u8Z4T%5j*(J}DXk=d( zT8p9S@ue+Ea3QZly07vVBz*cYg1eJ zsSo5(U$mk(|0cTChVSTyjFzQGze?9hTVg}Mf(D3&NKiPqStzKaZHsmj%3pOLol8D$4ymH@YAgoVS z;X3Z1&u7&s;GZ0mH^}xVVhE9{J)Zq$ki2=eKV5%m7)_O~13*z8v+qcK%44ev$PM%p*Lx@e4@bm6buX|#+~Ra`VBn{-J^+4Axr zDvRSX9tUi@KPwr*IH-BETitkEoXT7K9?Ck_S znMHR?I&ID5%}Dctfc!!m#u0=0R#o1L!v5z>>Y67=yN(ZAntp7{XKB@bevR~Ew!#%X zU9!Eh`D;+p0VU8|bIdLC7ov3f$GIzR_L;*le85OkOYDpsCrmIX{TgnZlSuRz(Q2Ep zTf~QcEqitY?xP`xz#;{umYU)=Xo<8oN?y(Msz6DU*W+%6V$%TW}@4-U>KKJiQ)?TK3 zKIb{&Y|TxiP1W^&sM#Hzo}O;e+3PWuh~X99Q)sSP02QXCimfhV}2q!gJ2POQRGaCeAD&t`ob#)DUzyd<p~stEGMGSL-;F`c&I$*OCM2!BSqk9Oa_&n1_BJ1_A@`tGfy$w?GgCtya0t2U zysbL8pZ_PlUS0&#&xjP5t#znK)keoA#4#Yh^95Au>EQ^|6(iFDduH=Wf%oA)4Xk~? z2%X&Ra~r&*$we#=sq`f_9`>r_+zboKt##0DLos5qq8J;0AA)MQiSViQ;V(F!XqTt# z(Tkin5aUxObr3&4Lvp{+w0l0$tDJ&xsx-`6?y4W*saSv0N6chWpUB4YiP1{tEiL730OV zBvmp5Jq;@Q80930vGAbH* zB8tKiU4wWl_Nf%wR0zgz)xCxmuH~@5i=q6WjXk1ZX7WdDfu zKV>?*Xk%9KqvNLYmJ^pdaMFmBw@pmg)PBEbpLbwKsX?U2zIcs?8rVq=7d8Xj;vY!A zD5CAZ&5jD_&fS!F&XfZ&toGEFFeAd%s_fD7btq z7d%{kieJl>*@B4?$!+R(KH_oz?fE)MtkeQqn>XBLvoiJC*Roah!^n`$*B4wMH;Eih zua4IcnoRb{5cL>bf$ok6vwEs%?WwQxmpdF+kYpErmtu2x1kYEhZJLm$;o_`b zvz2^(z!ewU$5j)07LiJdn*|=ZKih0Ddjxa%{HlCs0aS}R`COYeD6AfuUAa$6-^V1< zHik?oe|`o^RBvS^6l#)bW3&lw%udya=gOpSa&KFB$6KgpuwWBGs*GR|;63#Mx?5<{ zC_qBj6cDWziJhSh=Ma0OW8Uk&MTI>BMl2RS#@KjsFA~-%L0mgBHTMm=RTDeuAmw3D z9eE53^%tbYW)w`A47Snoq1SOLokA6Jr;lOgQ5aoK-H)A#U)AlAHAnj6$^ttfpoYIZtnYz134x;cIv;je8pB7a=q zROUGQBk`YVP~l+w()-hcd(j(@R7%Qb;xG%A90yU2)$4)6p?kTQx$TV*jHW~AY|VqI zpKI4Nufz#0Xg=H#M3?xBx(ak(fRxHWAb0oQEnUbe*WuW6=cv&g3SbTJH^fz+rR1Wg zA~BxZW;)xmmej1=pF(J+EoQ)$HQd%|i;G6zlF*G)9+PYduU4=YI*ct#%#q zs!p%3@3@g7chzLu3Oh9GYIXy)*WwZjwg+`qS{E;op*zc5ph=0)bq_{XIdB!~Q)p zu>O1gKNSBTZXd^X{YOUJDeU(U`TvEe_)>js4Lu|iwV?zBokV-JDnoD_v^X#=35T+ zD4)U0H1OSN%V1!(ZI6C^9J^V|fnMF5>%0#S-e^_z-%atVcJ1Xzek{*9@}t1PMB|oV zfN9QWy^igsG>?YMsYBsiM=q}HY@~ZM>oht9x3G1vV-73|`zuR=j4kQIagqtHaTnpX zJlGSoLGi|Qj?;=km%cz-TU*0sb%i6?JLWnwmozvJvx?u+xiX+ILh-nZAS)T~t&P{m zwWg7{a!)-Jx)u_q>N{}KRhe?YA_&hR~M=!pR)r*Q%np1-r?m6=3+%Mpgi;N@a3@Z1XzXSL$uB+|9& zb{)l6;Yh18hx;tb6gULPG+xGrB*&wP57wLtUFI{>%@y;CLwEb9o@<9RSnV7{CTd&Q zpZ@s|X1ij<&d#p2U|K7NK(6|MNzmRkB9}KO@|yH~h9Zy`Hv1K8jjF!{gdJy?d!J~p z;X8e~A;C8gC7n=?VnWL8{9au2kWWlWO`R$ScIU~4-(ns#Fg*dw7i4`*&j8fq?> z-Zpgz7?`EaTbiQRWH8kF+=Jbkz3#X+!x5b@^^EUy(MbHAX;A-2S+?Gxqj7Cnp9z=j zc!=HI-7Dzr3b~}8-!5%G&kBcv6+68>CLX%=@!27Wfi=zpF*92Gxb0%b7buC3B<0LW zEGttV`Ec+eqAufnG<^N``B;iui4dIaGcO;}UJoate3%6lVEBdaEi`B-!bk2x+ zfzuM=xd3I?R3%50(iZ#PJ*5=IeZi_?J%9aOo%eC#k|aXHH0?sr`XrPEMKWKXxW>-T zz8k8Y-Y!aaH`UOvU!r$KO`dB|?%ulfjjYuof+)XkiyOZ+p>V%}U!R;cca*oFAXe$L zq}nSfBn}nV`r4HX-THNu9e)F!R}o+2pkrYlA47baxMCSpQ+YB!7ERPIKx)y(#X?>? z$=E=eOxQDwu>u-%HdEZYu{j5E5=fkfe48Oj;)XZIMhjEDKeX~WxAg3=Y)5F~Ra5!I zmYI!!p!cZX@#Y`CQ8>$M`SjFO|I4yB ze3}qCpDeNpepN?hLPMMiU&Rm=-^y_$-hw=oXTdZ1@?7J~Opg)p5n`hT&aT2(p(Exjo>uH)G8H=`u>k0%x5gO!B56xZ-)Tq5ZcA*>?Gc zb!+ljrzPAi3GenaCFw>Mp!z=Ktz6Irqv@6%V%F> zZxDDhP^25FqJTgCJs=dZ8fDZTbH%@*nFM_zT@)l|0C+6B`YD*`VB%g+_B&J7) zRpSb8o}~bYXR4xXR&NjitkXswQG0D`;N+I!kQyhKr?>IxuR&RW!FfTE6kS+Ykkf~J z_8ivOiK>~uW%*zV1%w3zW;?-xLK$j1 z;0_*GdOPpeaDQ5lx%26UM)&x3d}peWR;^R7Z|dP7Z)~tU zG0@$iB#*&f*PVfc90Y@es=E}6_w>)CS4_B_I3*q-wIIj6c8<%mvSQI7LCjpv12>K^ z^2_ccgCE-as$+Uh6}#%&%AZW$)9JVvXBLIj+U6Ph)&D17o0iSO^?N%?C2|(uZ&XvwF#oVw68#6t5m7Z0+sSe8{OjXe!aE$w=RS5Z*E6wuRiM?= z2PF6b{du|{af0~Z5J5gbg*`LU&KS#61RboG-)Eg(@siF7XnVCz>Qt>o2i9$U^{z0EF`FDh_*lmJ+MDMlMx6Fc|pK z&%WDXtWd1+P)`uqz(*P09^TyVvKy>Sa5F@D`fZ7jgol)q&~G@fPBOntvS%(A%1RIDGivZL(4tuzC25}`f#!62}CgfJ75eNhzq@s(U{mbKl(XwIls%>cS(J(`QKi+9S^Ya=+?hsv>jy4@+ z2-m|qHiaQE|8UtF1;@)l=pzk*e7_8Q=Gr@3c|JlU2fceBLpEl3$$&JG0ZRW5i17ct z_#r1ZaYeztdPOmJ+L*oaK~&d5b$ey`YV)8iNaKMvh?)SAoET`XG}!Q8$;kCiqF=p; zTYhM9KKB~>{(nD@!|W^ng`5nm@bP-~zl~kQ{l8v@Fog3d{0n3Mclkx!gSAWlLf!xM z{QvDnCKKFnf2F_Y1~1^M{{@;*1iRhki2tdnRgNPh*?Y8 zw{1QJ&8gk_Qgla9mL;A-9iJM_6j-UOSZk~Ja_B!v;PW4#b~{ZU(nphedu`4qsmj}} z1ZRN+#a(!N%>${qjJKgx_veD~lI#CUd7Su}wIkP(W{y(3zqcgXUUh%6Of@Z~#&3FS z>)T-oW;ky6i(l2L2t)AHo?vjrKa*Pl zDdZuF&raX5tl5gYQ@9HNST@wNa^ti3$4g@F1C?o*HB_EQG`g>#sfE>EorE-4w~TqQ zp;Enq)Gsy`@uz!BaA3O_;T`1d0aJk*UnkOLlV!Oi!ppY&^U>fnHbbT^PwW`ym7drv zVQPN^(2Wgz59sEd)Xu3nn_Wa)$9ZG1j}}%A_%{ObYM~djJhev-6g-1xah%re<6>t@C<)Sa$WY~N0_GigN{FbfbkmGesImd0RCau z;P1pdP8??I05ORP0llBvYJ>06OewYBnJCo=lI>X4BA$?g({FpTaIiU$;6Ul&L$8JJ z)7G3~dnIe=Uxjyi_(sYDoUbx8xjJ_Y-19PG{dXoi&CG8FqUVe`#+WKMw~QTvXWb|R zj;tM^dNAje$FD5qq8B7o>|rsX^%ws-nOXUS8IE@hl?2PF-N%o`5S0f#DrTa8UF0uz zYQLA(LylD+d)i{D(EoBP2Aob0EmxmH*T(ulmXx^|F(4o@m&G2q`aRNG<^!(mEw{X^x>-H zY`C3t!bfhpuLBkK=COA4_1%y_DYjqeM7gzX9x-ua;R1?a;Zgv~1)q)pE?B0ub?T>DlXfUvoq-i7 z5HyvW#?nFC=FW5#+u(2Qt%|9>#GUDdHP5j~%`+w6v;-9a;lZ%O|G9{>4%1TGf8s$M zUF814faRIkk4&U_PMO}7+2Akk4NDL5A4@289p5y=1*{BvCYnnpyhN&ZD*kM1>!?3Q zZ;jO5Yo;KW(3&1RCn^63dgyD3*Z9x&c1!6Kn%}Q$r;k*HY=h`9i(4o=JNp92l)gtb zxfzhm2THvh_+}zj8C}un;Zuh3`I7;`&+_y00b$VqJG!y40rIoHWb5DsdUh2+OHbjR ztu23&DW&MD7ioIlo8lC?3 z%1k-p@~F66-b+(nYX=9@;GR!QUwayOe61KrbFF%OuFB%d2HPMPjEClAXM;K=#=8tU z73cD_fw-}CW+{b3(rG^AMXLpUQ$+VPH40?>e=GC zCZVO4=4PY10DK2P!X=T=ur-eAeh(Fgoldi=<1pkOeDXDkX@Cd6s_+uc)0>7hE`*Rh zUOoGA(sJf4@eNd+o&D*hEM+KTOP?FP#Mm?=qU+{r-W_#~TYgpYX=gPxQ_iKnVsHfp zEN^E;RDGSnZT?c?wet!p>toSVJsnPoATmePO8s_Qv$ou;xQX^^-{(}@ zlv7$2sI{s~_#MgY;S)@BqtQ4)TnvaGc+h;$Fo%q3kwl<4z!;er+~@ZF;BxhC^Op&< zu1W%Nw~_LlKgiqDV0-q~T5{_h-u}FSSNS-(Q~EF|j0+{-2?>nCX`}+7R15^+pN_IU z4x|`n?RZ>hdSSPNM$Ao2#K2N&Di1^}E=&-PzSFW?=*{*x@&y`pd+mWh6JWN^zQIoF z+*M9*Uw9#U3O-iagssl6u3j$HlSzp990~@&p#d1~kU!i_B}MK^_o!+6uM+49wx?iv z-nn@bF5?Z%&nu<*WM_W5)y=#c@?!g%^a) zROdgaJPPM(`pt8I+y(dn3`X&}$)*o)%8cufzXi*zYs8HSC#{`EQa5vy+&q<1T6IDe zj=GGP*4&p@Mm>ifdP#uprshf~M2uYBz;JR{M@_(hL#ge_8+l5Kiw*$YG3`E%tXob! z>Q)RxbTnUX{^sSxta}{3!AjOYLS|quaj&>>0aHABE&9kM_E)trct+hD=+F)aIVs!e zz}t}wChSkK8*)GF2gCaKM#zuPWm$yy{PPvc($O)c>Uh+&HsYlP?*q>LX}CaxkWiG?4#qc0+8(9t*Mu%o}&8e*}vgqO$qpNAnM zzU=7)=%wLbLJ#>_;)Dock>KzEoK#c>L14XUQArDuzMw6GglWd zj&+LVIsILo(x8s?o?A~*5e#qe>o9Bkyy&s>Ej_Iu@_`Eze4hEg7czt?Ghk z$^sWU6W)GyTB$L$v$Do7n{K9M9^;{o# z+hd~Y3fakx8|~*BxlzyGtGj-P2$oMYHae?TErTRd#*ozI?O=y-*1c~){7pk#xia!Q z&~9vp(9$=LoN_&Bp|e}nb=;ec+~TPhSh&7A zvZ3;hlw{eUzBDC1Q2{_)t@R1Q+&GJLuU-^^mX##^^km0(z06LR_6K)Mvf<+{x!soU zcu2PKAw8}fe1N_y&>EasJ0Do=gI*7;{LBrDTID&Y_iU6`xu}A^|7PkZ=u?e1bD+a0J zsez8YRG#+0aM|+Ld#7PK&Arkj6sJyc`TEI`L;Z=13xFs*EQzSy3GZf|do=xXP#g~x z>@z>(M1A&3+!Yrjc;I@1pw3af!#r|%U971Kxl!9ML12Y>)N4$OdU@{6pN$RUFzIk~ zarT~vtLRV~%E%vFKp0vQ2QB_xH6W;5)JH+WzporhBPy!#Ud=2j4q>d5=RU z&l%;IYfPVGtV@*l_hdnNnB|z#0@W!~@f0 zsPu)qg*-6*1XY*m(>4bHg;Z68XG`M02t4I`l$3Gc7kd_zWkj#r?J6&9*G+Y1Bb>$` zKA`f84B?i!4ptwYz6fNw9Q>y94SPqidvDr<@$it9s_o&Bm9X(}iO+Tw4W&G9GO>Vq zGL{2uxkX$vSM*&|9R7ow_Xii2XmV3WFqs+s;#rd-a_L64in!~nEw21}Wi>0l&pLof z9osb%2Jr83B4<#)>&b!6l#(g8NJiJ~<)MjZ%)+6+(7_gijNs@LgYTX1`XEeII8vS1u1YhEGgEBAMKltlF)L#tZ#(|HD%G744Y9>?FFO+?^5TAV^0Ift ziW-K(QJj0ThB|JEBS6VZ$V>S*PA{u*VV^+j?;DKzagkkfxBjTY-GU$SWJ)C|)d#tS z^ai~$Kag}%cN#iDT;^?GiAxIhJ21J!fWW7)(| zEfZowyC`Mq%`6DVdn!BRJc{H~Xm-P!=dr(gb$W@ug6@T61e=gbCW&N=ZK zj?f+I;Fh~ZIJf;qmkh_1+gzaiw#g~!eVnrMZuzHSO%#Kx`!(^g&p6eo+Sur%t8iAB@j_8F007<2SFxHVA;RDr&x&Dd_`pDzs|~Jz;qW1P zRKs+Ox8gAKu^*R@FdsYZeJ5YjXYxg8yaoh0u*Vt5CB?>c6HDntF*b3m^u39C*P?HN zopX_TIB{Xk&f7zpbj0Gxhs;dF)!^#R7eA;t$as9SgY!l3{7t2%)vI52X z_^>cq#jjHMV|pmV;JUy`A9H+ub!!bco^(z_OGNy?dVbo_)O^#ykt`F<+rz;x3yc|YSzek!@h{`PDlrU$C81L^4 z!@3e_;7#7dZ~W;aTeqJIEW0Y{(WEp2MnO?&4O#(#syUuOFOh0^#ZQf&B2NhDNRPiHuQ7_h zjvlEu@o2v1%pJ~x%7Y~Tu8-tvnew^tdLpHrWR~d^UR>Adqbm~< z=MAw8*F9#GWc1sV`~o5vE0Xo%Q1pEj(q~D&&5VZUPDJW&30Lry*O^$Ian9>`u5dIR z3c?!@(J#Jz27>wrZY2{Im3H z<1Q`BLly5Q-imR%FQMC>`XNX=T_M5f{J>k8 zjfbT$gh|!=l7DR6l-t_cfP6Mt^6Bk>w-_||SYm`Lzj2|l0$8$3jMv+%eWhOMTF8To zMz3y{=jG*jjcB{{HZ(MVE!po;NvWw(h^+BTdH zz2V!5J9Je70y)d(XNJR0L^54{QeulkWxBj@%%p>qH-W1c!MiCJaR#Z?tf)b|A*>l0 zAk$y|2gn8xd>a-6MhdJt{-;ijb{WWP#Q#`%4T7GFy=xLaFWOJB&>5aXkgoybi~WVC zW>hyaT@a~?$H6mz;(56AWh0HhWz-}+#I2!YR9$q)(G6g(!tA)`h^Ai3Gv$eMxcGXM($N(%Utw=D-LPTWf`oWlwAq45_HXF^zRKc+L`$zDCVUthpE*1^6IZFHw4eK_ne(j6mm^}(`v0fi`>3dut zC$GWzPn!y)N_5b&)L-A=#dja<1i_(7_p^umWi-V+T`;5WEjQF?F4ttl3eHB{2?b~L#VT<%%elCk`3OYgx$ zA>XOygoWPRk;)^lLWKE7r6krR|$OfL)Gati?OI6(H4W@j6s1ONkS`<7n+Ui;qO zUX*}p!4V|A^rj)b{jG)GG8MX<9w)YfDd0teEB-JB);BX+3!u?-PHlR3`mA9uCQXCD z%-_dVq=(`&S;AM~op!SdXvKO&6PqiKMP59Ma|wiZCAdj@~!*pvcT4X(kD z6KzWG)eC}b!fZIyO0(R5!J^8322bBbl~>%g;P0BU8~p?{AQ}oA`5HJ9#`o7|Pcp!R zw}%3AM0eqTr5eisMPPeuoH6~Ku&+G@Wo2_Lcws%zpI{;Fe=Um15H}7d0)iH-9*rY2 z033MSW_&otBHX09I^CMGQn_&~@vlrdQ>lT&WkDMsG*D+>baBJ^y<)YM>=o=Q)wH#> z!Con=8Gtn>CMNh4?0=>${`q5@mGbok3;tQmz2VC6zq8{=G&Ee4@iC(61kv2Az}-MH zu_Yku%jBjB&f{D}{Vhud*Wh4{8;VOyqDSt~%E1s0f4P77e>zrvf5JcycW&vhcL@;QVAH6{w}HOAHd4qDpj&{e1=`!sO-xVp|A9M3N* z>Kaqs94K~|Mj)fRHqIdcQGM_BQy84fGT&<-iYT~{aSG(8@FO+HfS@M@^D^W$P_Nj8 zl{Ha@&36r>3^H^)-+~P~+h-CDGJd}mB|-JEh^pjzdE>j16A+jKj>w$6nOumv*(;ma z0-PT>fC@W1JEI@*MCvOmT~Gc3Wn6L&4z?~IL^^2J#1QTftJcBpf%yIv;g4Ca1tzjB zypPerheZ&o_x{{f;ujDQP~wL`3=Y+Oh|HBep^XiI<;o^>3cJo_LXifkp}MLnD*RCf zm5Dj4ZmpBR`8e{;PA9y8@@?>!JW+45( ztM}}Trw+X1HF6LOo9}RAXp$=1OpRnmks;CPTYvr#W}~9?-m`IaUN|xhAp*Amj?TM% z%d!dzD+9$ci7i^|KSVt}&<8tf^fhgYyfR|y{Lg<47}JSs3YfBMHxYvHL=X6Z1J+_7)bViI(kwY-dx486eC}Np-~BqZK;~V zL6fl)jWNteGpls-1Q}g}f_CRJ)8%<10VP_#Qh)0{VCE%E2&0pS{!>tML~8y1-wFEk z0bj-FMbV&HHv_oOw9gCn4$v#%Z}@Jo!aNgixTX428~IpJ!9n~-!;i9HGVEjs2~ z;&E6@lA=o*dT$P(e)T2l+ap`2HT-6QUu$_M0*9lH32Hc50s%Y)OpLKgEX)hDzcYFw zPe;^?EIC5J2!ZSrvFDqiUFg+pyZ$7jHu?6x`nF@e`R9^eK*dh5oOVzjzgQvc*9svlPC}J&Vszcda1Kk$ZL2u6f2Cm!Geg9{YqRov@IT|-Y z$cy=FMF3kYVua^hUI6Cv8g4l?q@>?tSaVy}pvw%t$7iZ_kXu7l!^Sty&%0q5T>bsG zz~0IXF+?@XZgOmX;?Ui3j)Gfneg}XxkWG`p)rJLcCO3~5n&&KyVwn5&RyVjni?Z2S z8`fXw!m;G|@H0z?LKsD=>g^~(>jW`QXZKoR|H02ca0aPw0C268FMRf$Y1@M1gu*s| z+sgO4+1v5KFd`LbJsj%oQ^C3<$M0%Q-_v7p?}s*FEmC9SdQ!q229M~W$OUhtJW{ntgIOa zJFWChS0GHH!>-@_rI5ut_S!0=*rLD{`!Z_j7{ZgKgR(u6-ZI6@#|IX$#p4+Od6(w@ zqg2({M)yeyh?3T-%F2TuqA`fhfSI<`k`rl4KO0o4J!=X;X3J10sBX^sgQzJ?)P_q_ z(wRo3Xa+9(HG3cI+`keEJf~rd(AKtm$RQ8;g6Z}30<$y6I3L*q>2>3(g~+@4gwZG;rd`dQoeqsg9hKOL}&D&lu3n)UVm-mIr68 zK1w`W&K2^*^e}7HSq#&kLoN*zw^)9$@8!72$2d1!=8~9O9aenbPH?W&gqjJ1N4$=q zxq644libQmr!}KTiVK`nMX;L+HS2T5Q7!HQiDB$+*TLSGlS*)urdvC}0kd-Tw|)yd zJb`+;!^^=6Z_4NjX4Coeb?=V;=~5|Wi*few_*r7rebmFC%`jj#n)kBqIpn<_w?hXB zflC8oN0;T<@N6-5LOevrG5@y;h}y^RT^l%F4H&OX8?!7wFn||`COS371-Jk`nGoCN z3IoUMSY38O_>7G+xDmUcOM&826F|zV4u? zAl%t2$%5~@mVYC@;$fv{Q!L20*;NGt2znAYL;-=$uTMQijgEtDXNq9T^om!s89-5Q zuiQ8~FuUnI5K&wf6BVU?#brM>zE&mjy$3#nzYDxIH=~+c$m8fiKNf+(b7gyLJeE^X z805#1%E81FO1fK{P8b<<(_w9|H0~ICd*^=A}tzi#%3S#Cvw%1G;rA60H^IrVX;)!&^ZG3zWUVe_=d3{`0 z^k>^#34cPQK;)ChAX(&9ePFmpI>;!^?C*8(@8J-qKJIp|s4grM|7f?aeSTkA$2}!? zIT9u^IR7o?Ct5CKrMivLH6#C2*<%cKr#DU|zVA24!)1HgmfRFulFgjvwmk_vj)NIF zanlNS?6ev*urw;_Xu>PN(%mP%^i^^CX)JWDFh75c1#cG(r8B!=(UR_Nc)w)Jb0pzz zMdxmUon_BSla8OgWYLrYqi?_`7kjj{v{;Xpu#avY*^J7n`mK#VXkJO4V#j}q@6`R7 zK2a+qE924gbey@R;Z1OF2|F9=tWu_PXNLw}^rkQ-+)UB>aDeliVdk^bIw4cD+nH#H z1|MuB8Z~n#PgRhU>-sSV9QIOzzA-k%;m;Ro8V0z6cb99k{oe|*iE)VyQXT!RxCmjC z?w60U<#=EV`oOq_31OFLiC41O8TptRp-7DZ&y|hF8fsOq!!h}}La4vITtB0f$ZgGl z#UCQK0nWz87f0IVsSBJA=ixbG7;?aKI)9CQS}EGIG|Q3WGnvitwh^+UqYR2vlXNvz zR@l<2;kI--g6B?PYh#L?JZybI^JQj~;9@M4(QqGe(gpYhfGN|3!WN3E&(Cpbv5CB^ ze%Rkhs@gj=TL^9XlJRQs2cJ-5KmiL1hTROGXrB{Y5-oHnOmWXc?9|TtoOQQqU1^zl z@oK{q!yvU??@%_gus^xAH(&~k!nZhaa_Ms}THG~jrHWcW&Q1y1eT|6ZzQV=FCjU~8 zp7#1?F$bI>MGS;3b|FK<*7LXc7TZd1H%7l4+NG1wQgKjqahx4)JO;T%fvFKhcVa&* z#-I~gr}$gW$(FDT@TSs|V0KHO$yd4PSPj(2>+lY#;~uY#_vG35 zSJxPu6n?(deNK3!Yh6XgsjrE!J_2v4%SV+gFuzI1ZpQZKR+R@da!j6@*;=;6dEg|F z1o?ZmTZ~O>fGC?&b)aULp2jS5H>StE?symjUtig>rwY1ILKLB2+Z++b}O7!tqRX-w?7fpT4X^G5giG4(33r8AxRH*PtjXewP` zW6<7J9Y`um$4Yw0k{4!8F=yafhtd%dMK0PJBT{=yRKNTH=zYI#ZH7LZ<_^U18CYVL za@E>3q!n{TpKCsbDzlHtD?fPLJ@x7X2JrfO2Wz>SHwl)O?Zy%sOXAzR6AqRetnx2q z;yR0SPYE7Xj>kF)lEgGG;f6uPx6f_QzAkxv<|Z7%f+DMwQpbe|!J6GzkQD%`_Jv`5-@bi)S3T^(%%uspV(6YeZnT%QLZr{{!-F23Mb1~4H# zoV}e5Pbm5bc!U14%IBK$ zlD+*I`;G6KgKH;F^~NjN*=K1E+x>+vq3ylfTeljPkMc#B{!~`EsbgJp@zs z4C3%PD5rMJ2}7KgRCh-X4TF9tq%1)V{xu+nkLE#@S9)E7Lx&Uo>m~; z=aSQGX2qB#91xZ?^-H_#I@Z#}4gVXUR#}C_7O?65x}Wm?Bwe`#GRP7U3PaY_irEeWR+l+5yy>D#z><|BBToQ?R=OrN_p$sA;6H;LKlN*{HU9czbt#5s|2#^7<3h)aH zEAU1pQ+Ia0P(e6UWwIW@lfc4-?RpEfs}9`-z=pe~%748I(E$b=JKa3x?@iR7#hqkBRb-#8SYhSXhkY}!0Lj|R&zaJ>%meL4RZ zZEpe(<=?iA`xPbHNVdqtAhJ}JEJY*BjJ1Z8U0JeL_OjL#QD}@UyE15!eG4I_tckIc z$dX+f3d#SxMs@%0=eh6adH>JzzVo?%cb8eN>$`u?^Ei+5`05hxg&vcr@SOD?jnGKc z7Vxm!aZ{;DZt~G7Qk0=&%I`VE}D7w*l(AcYhq4n;tni^5vlxVq!#kZX0mrn)D zRR)qMsdibFqbfY`jGwoO&bGjA|syUA=j=9SK3MoGuc$vPTTvZ)It)1OvpU#(*AtW_G zi3T{{QOQ#_7$gUF=usyHhY6#0dr;VejD#rZV(!Syze0rqrkQuwW*o?^J~NPz{(LP# z@<#$oQ5tXO=0by(KxPi^uvZ7S;M3a98XKz+O)>F_iSFg))s7dQV?XO{|nrnGapFX|tW^YowUWQ?z-pF6qPK_*e zn=kovR!-=Qd(Qs@wa{3oIaQbj_=Wt)ma?KEcmLpt*6<(=;wJhc`gIt|c^jcahQD1D zDi8P%V6{Xk08K{J7C-0y0^|tNxAzGIM6n>a9NVQ08m@U_n?!(&Z0dFIv=?m z9XuPcN!D-w=Zo;Aje=MMHu(Hm7cJC^{0M%q{_FqQMbaryjERY9*}C5M8FU<|N+6b``ajJO%FMENhgr2T$;~KE^0rQ^I!t)R8MmMYi2=!9~a4)v$k*2$} zN;^dt&CBP8a&5bd1k4na4$8~-o_m&gR!oRXOUt?=0oVhr1agkL2C;GM%ly3bul5PM zjlx~YtMHP>&dLy!@qX)xT3z(}}%!r`IDR?WPOeZww*t!J(!m|1Ml4}Z|3 z1E~El!{w4_x^T-qbEK$MX%PmKr)1xkOuk2mfiPnX0U>)Z(0gS}Rn}$3>x&;@B?tK2 z<@ylGWA7{d>=&z|*^OC=Fe@m=NYS1M52olr-qH~El7hX%G!s?5l+S*bFNB4?gPjQ` zY7rlv7+D$aJ`CxV%TdWXbLk-gov-L_O;&VufHBBO zIEG%@5Kh;_#$lU0SECrZ*CG?Eya;+`@Sq?wBys6*+6X{w9FceQ_-1&5AC64*%?x zB@5-~4nsr3`2df7j&eAH0mYz$zBUT)_SPKTnOU`4puk5o+6dkZhU6iwbk0{U@I z&Z2NGBs{if>g~ux6<4;_a4C*v5=W&Vkm2k*ZOFyYVEdfA6+p6pdd}5n(N-3q=mNnDQ@0lo%ug=)!UcW}2*ug|vi+H4hu5(t!`w8)~98dvv zWI=WZ>$o@pJu^`8EvI5m!E4Tx?~C_*n}%DNY1Y-S7?jLlioxrApq@bajn|m1= zLN?&KKsCZ-jTF8cZPIc+->$o;hVKHQq8`1i#6K}^9s)SA^+1l&Q8kzs7{9LNc{kp+ z;5K9~^?rMTTI!RfC%C)Jmfs8cIpTi1@Uvhi_^&R>ko>CN)v=Q(fL*TEsasvhFS3lh z%^4M?(Pcm>Os8&8tU1uDu_7yTeiI$gF>258H@=si_`39TaGR5j%}e#8ByAynY++#` zj<Bp^7;wTX zdo%2-Ub3T43fxCKigXG3?w*W6EotszL1*DV6DU9G{TocG1^B}04@P0r+83R*oLd!x z(pm&?@-4e~G}+k54#iXRJndc1`0y9P*piTs?)h1USuY04TH5wF9(Hx;)h{y6p4wt5 zUcW=7(PU3^QD(YX)!3@635mTpZINdS##Qh>%=41Oi^uSu-#ID5)J1(_tzhk00|PYm z!KMeRZ#yK6SVazFi>iNAkpm&w30S#J@Iw>&cxK`z?wu`yx}^aGHk#dP5L2Z78z!g#|jXmGN{sCt@!K2XQd&=`6% z=*MN^2Y(niWTApl@=R?Ko#p^;~J19W(U+C8)zQUTY3Dj*nRF$d|DoN-H)z$60LDEQsI54-8Uu z@SytULNQYbD2D0#_OAp^i|)?8?ND4kaN(#|I3?f_dJ9Rt^M~`-r613q69$fY81C58 z=)Ba-=NB21Q{NNLt5{IaN$4=y#;8=!81Lno{PqilCFnGfP-2->6Q_s~ko`ibD%NG? zAd~GmrA1^wZiA$gXc>D^V%o8wAX?xG-9ZHcoA0x5Z{M2Z1I} znM^asy57wu>HdmO3`Fg@X4X7M{m^y$cEad=q_Z}ppGp)+=s@lIyU_)IPoglFPd32OKYypfLqZ zFePjsGAHh0aeaj{I`_5WlYMVu!)KmCi0TEgCT)6_@>7n2$rbMy(zlqsvO}5j1Z97q z*E3b~wMzvv$&E1)6*PEETiBj6{!>K2{MRMlr+1Q+_dSUW=L;-szv|f88)%}G>S)Q( zpn%u%1gmaqHrO?x8~Q)DWgV<_`W9ik%0gb;`>xOF+x?>KK9+T34~(~geIB+9^uP(q z$;l~UQF4%!Y{=07$9CO7e2bwNxTKjEsWZgUZUeO&4r!72Z-* z?&p=1#LU~5nR*sr#Y@;ENoM4p&(E!efhW?#jx{K|(_PMT-&A6J&e~ewt82yNn?3=WJ~=oRMUn&zHj% z;zHA5_+D%-c{$>gV9aT}2|D63SF_6flb`gGw+HB{f(J}DQHpxq++3Tm0e1jBuwhKs zQt`RH-p0>6`}HNL@5SGpdnOXCo=8Y9;8j*ypy*AmLEBIQ+mcyJa)a3w7~%5slN?suv?@wNU9l^P%QSLdfc zx;caT0UHy8S^K;9{ANNk$C|6f<@fXraswgLOeaPwuqk=*LCPjNYmmIVlwQ4aIJU+W z_ViAmX$9q0CZqRxUL~Of2M*7#Q79C0_;452<7&2HVIZ*m};KhaK!Wz3sIl`i3g~qYKEyCwGE~<8zxjL?nhR2-PJ#3{H5a|H-h@l zXm50Mbga2#Lp`&5I2Lm%4IcBpBGrQ*Yjlw-9?Om?NZ5R9VFU7{GH8}s$yf?B`xcP> zTlp9m;k$~Le~COoalf*!Y?}VNUiE9vR!h+%d4Gpv`Ey;@z*dCvyo5(~lR7dxw4X24fM`Fr2 zAo=Y6)6{g}Z(lm#z2~)SlidlT^yS*wjTolO!?ht6pm(~Lj}OVQVrK`$5PYTW_2>5R z@uegrjLh>IVVD-9OZ_Gy4fDEJ4J&%U)xYwwxI@eL6(jyt&C!TMP=tcEeR~#MWs8*M z`>Q_GlzYrYZM{M_k$@8PI}n#}KddSB=J2i4l4>4__D5%UA&Q#HXH#Y)N3d=$B8q|1HH|}mTZvCM4H3K#Dskq)6OCGz0^Hn0{e%e&9{MGBV{LGh(oY}FxWVx5^TB& z2Hejn>Dq1Iu!CAYEoW13l{RwUP6n`73=M?U)$?N|AUfppsb=#_CPZ5Ddn1&grL^d* z7?jQ8>6Jrwt^=dVfsVl*oGOuifXrrC2-1y&A_zbUs4PBV2bKv(M{vpL7PaQNFoYNQ z0pd%b_`z_4BjA5uy$)pjeGsFylZ~mJ^$=ckEy8Y284HU_pw!JfjyAS zzpi44Pdw5+jlkiz+Z~tful3yU;C_NZR%c71e7ln@Bq?UkevJ9>n3;*x84BQ<{f&29 zTI4jX+C|v!l%IyhP)Q&ySyi0G%0W5VOEj%j=)gI#hxe&1Z#Kph+!q)28ps7}b3jt0 ztg6_h{yua=TrgS`TV?t1 zsA_pnuQl|YaQu0RMtG>t(@)PqcGq;`Jbi<@yi;bu6BI75e$rDguSmMz_9W41#XPZ&N&O_z zde;F?$jKmGY2WJLV85aKyMrN-B=)k;Ox5EzEKqWm7|tW_I`r(XI8x1fx0DsrJzF+0 zP|kuHZIN{5rbU|}V07GV^IkkSj1#w16!DPv7 zX47~>**c2jWQEY~B%gj#IY>aa`+DuiQYT8aoJ_GBlsr8ZGxg#c zmT#!8b5@49DzwyyyzcO=`+ze@^(V8x)3jvA+`eQp{_yhR1{xd%xtV_MsSz(|Qg2_q zR|uo%v8_Y-RyTRJwMtxmz@tD%fgl687AnruoVbww-cskhmvQDtSN!eIC2qgsN%{mN=ByBfeSW~ z#pv#?E~Y>gA4QX_PS>)xtv3S;XLRqMw3}>mPHJtqKPfyQK2A(B_yuJNps_|k)VyTH zv8iM$j?i&ufJX<@Cm{@oD40suV45QK4vieQH3+f*87BSEJ)M9snB}DObvhKs`?cof zz}|n!q%=?k6YI$3ZZo(|`i|viutJ>FaYhp*c#_I}utp@O>*qEz@5BigZM5aK(W08dZO+{iBCMJ=FkBhjAZMZndmY);(R#wHV??)e5 zG2~7wh}Yj!<6aO|V_&QI?w+xlEc1XYDNtM;ukh1fen~;cb39ns=6%N_3#((|7h*;@ zn~O|@Phakj@odkX>TrM-fElqYj9tFrm2DWgnD}#7R7@($XgmZh11~8lf$V4X!B@xY z{DpNg#rHHn?=87{;Ydkb9G7!&-JSUSt^NYe-uhz-3l)0KmbxGpbpOkaVK$~GhJE+gusDv|W) zVVIbzq(|fx54A7Fb!|Hw$+i*Rmn+O$LXmFzeLs8_@D*W5_MFF%#&A}E8y1vk&R*NO z(p1Xp_x`}iY{T{(jWO4Up>SLSR-b`wHj7(Mx3FRaai9>VP%L@0#%|^`L<%^U3bzZ zMHZthLWgg_++lmeWh2NQqfDwc64j7eREiZT8aj9gjwM88@U(Y`ksKapjy1dT+=%mB zC2PJuv=ZBd82kt|IW>Slf8#is4&kN3z(Zlv81$ZkrH#y847Yue)oxE16o@163mE~;|+n|f3EHhQ@4s@ z0Ako>h2QU0)_t(k&+V2^LS{M!OlJ^bA96?502qp}0MJ$}C=Rl4(0qme@HSbO!T$XD z^S-p#`Sbi~9-(*dN=izWUJwHY!N|wRV;Zzop03+SP@va0*<*B8( zd-sSQMI(vx@$I_qvg&LNr@Er_lHO+P19qditm{cz$zhRU#A^`91rgi~3Z66f+BtM% z`sq4qYj5t4%$WgJbNH%w{4 zceV}>KX`1kfRylU#@rF6qcBn$!c#Q zbM-K!3Pf;*&wl+79CqbS`>f7moRHb4&5XSrk1Z%anVJi1m-$cS5TMX_bipjG z?HNMKr;R)0-~aA{);7NeCi3<55+U{dHA0a$k)q)lCJ!UmP9oqa(rsZy82UgMM#cfc z07iD5|HZ}e3ozl*)6>76sHIZzmF61A^nklwi!m}bc97;?ZJ7SC^wqCEz0D5%?B7%N z*)>hAl&_8VeqjViA&_Q6nh)6le--GTJ^O>2geXbzQ7z`X%2!*~Cah;QtBO8>hTT)Y ziNXsrCbvM6@N0S?Ag4huHq)5^I1Um>_xI8!D;?&x3t(kWh*gMujVTeZ?nGbj0?+gV zgi$t>hzQ-aMZoJCxC|oM+1cFzFaCBU)K|3Mwjtj*yYDWb*b8Zafr00~=v~m$N+-=t z&dfa4_wdh-(M;D&e?CbQi^+>7kRP>^P#%W}Y+}c&ik{_fx;EF>2H2J=5pHmr=;Zd) zK(u$UTzdG%2CHqtq_q9lf8>5Z^=tk$y0-5!D0_U&8iLe|s_4d|-TX2qDF*X9ATKd=ijv%#J%n3u>1L2S5O#zYFq19+@xszB8`fS*z{-G11Je^*d?z{lGwmUc<*B zZo4t80Q~xNn|UQEdgbi6dTe&s(f^~Zy^;G!q)Hs z^5Qt2+0H`@#a&0|t>@Rs-O@kCIPinEMM`v>LKu=EWFtKOR9o?8X}W@=RB=obZ(?MW zU$bj4sYKBQL)E)M05uGfJDa)=5doe5YLMljY{QhV{akS?dpkUQUh*)QUL|p;C3Th} zj`4-D3$Y+W`{e#5429wHWA$C1cX4R2y5N^0@V~)geEsFvC#c@N=ULrByzggTI)rZB z6Wf*itGv`$xu8VxMaB2cW*&8lCQa{zI`z3Ba~d-ROms6qCDV>Q*bm;_p_GiczxesF zx{Ukn&f}B>@YZKy&f8Ui-rmgGqJYRzx=_Z$=dKOz?EWlecwIDFQzEv#-zIF=o_}w10|x?!O2Up;vAU{ zJl(?rTbAFW;uKU2V>-y3x{bPTx6r9KMyTE*xS*G?3=NY@ADUkTp=^N1dgMlm!_J27 z?GGvj7@4TB4AzFr%E}rTgVRzQak!y|2P+uz_oVuaZzie;r>r&`l>+>*NYQI{`l#d~5%Q(wLrD0U<8ZN5V> zH*Pb4unMt%!)WObCK5WN@81(E1m_*Sik%n8IcH4wTJSXZDoY(_#EdK=qqB>)azZ>A z?WQLzA96d4Z^~YTV0|Ii)4j<>c&!&BAc*xm2vIDMDzMM(Hz^#M^F^3zJxM#D;KmpS zA?=5)A*iLhNv~Nm8|C(>wkKSy2|@L~bq>c>exb8uduW(NeXm2`u((jbEnsEoa%Yt5!GgJQgq3$!-NY6DG@d5OIkke`~V?r4}+gJSs+2NGR zTcxu7e*2xX5L6Y`V`TjU!}}KxC^pu*J1vy9zQg(m$>WEIfLQY{*U0~$FzI{@xUACL zVdq$ZFb{bRej;^oW(o>+Qb0@A|nGMOVSvMHp zuDI{T)sMNhDD&d?vjNste%7bhSm&FUgM;V_6Cj4=zJN<+uAG*LO%lW35r28dnnT31 z`v8}v9dW-SNA-$;N||ZPz?KLHgzbLKSpZvRs++bMe#k2urN}{ETDp3G&g@bJD|!55T^c-|CmOU*Q{sa2^*;uC$a;0)G+hp+=nhFb?myFa^dBjx~~x zWe=c>jyYE(f=d>R!d-r0Yp|b<{N`T!UUYAF_N=Bd*0?%mUOuJVno@Ps85NWPsvv8UY`W8@lPrfHo18jhS!~o z=NcCFWDp53tt{v;nF3n4pxn!@y!xGY~d&BbS9_1{y{w_x#Ml5q36B0xDc;rT4psrH^i$E3)Yml8@eT<^|wNT6bE7S zq3)-G829Xr(<(pJD&p>ENg-x~i4ayts>0pjgoVO~Nd+zeEG7a_NRsOt5ZS04C~&`( zkdm^)^XBx)b%1mGmAvoDwXj)&2rm@UC+dncgUI9q@$OfyW!iUDVXRx8q^B5W^{V?W zGLpi~dg|3br3|5WvS3^@iWZZEMZSTmDbF6ux~=GJ%RRVk&wP*)RHD7ZGca0KN~+0!J1M#G-=tXeJ+g?Uz};ZvG)Z zqZx$%`->a=SQx$f`uf>1`(SQbTy=KNKDocBv=GvPW1C>cyqEJd^2|KB|8aKqLgvvV zo_K%ifa~^N9FjZ=rIc17Luw=yF zKS_M2K`_gP<``S1n1Qlwbd$}2Q_p|=cBe!!u^%=KH+NNw$%F}JfE+ymwdtn&Zx;3 z^3+*o3>>2*l1j@HbWdj*uKV+?kXU3p(a{kl0mQ}SHJJ14$mA@@aJsmswZPZeS;sh^ z>d+BmV@f2vbn~D2R!9sqd^claAKK`k>rCI?fZvqK^6`q5!|q-&_kJvU2`6sy`^wnp zv~+KhKyp-|ewKgOLQ$eoxYfb-i%AAG&L(|2)sOUldH)kBsL37gU|sEVTh=>iOdwb% z36nbD)!ZCfv_U}NLlWOgl5|pu(?RA7{U4GBdTecNi}vl6ba-|6d)SqP;u&51Zu#l{ z92+i0zn57DNSA!iX=&7Uo&DGtHzt>nTsojY!MinoAA{W=+8UvIRRUJ9LIScQZ< z$Dgc=uhNa1WqCtFN?e{uiFo$w2~LwuW1}xE!RJ91P%UD-t+BYhj6>m@MWF&`&5E}_ z_s`8MQ4uXg>ue_c*VVEnveD#)wq#U#1|Tu8NFdNr>)csNXLQshe7vi+ej)ZzesYXd zlgn1yzJ*9pnYtMZ31#4I(%Sy#7S^pBBIpp39L(Zts4(`UpVv2B;4P8c!cX@AB(y$B z;9uH=M+^#NUV(VfJ%T%E*3o>8mGA7NA$#(58L|{06VF`(pCGU`{P&;pXTUf( z#SX?n&EH(xgftz_dwTiQVfEg{A*VkblE~eLV$1wFSrQpI;5mj z_4Mi6-eK4stUm+^DanraoJxN!f!fh;QowvcfiMNjP$#{st}$k=@kYOI<5K+D=X zf?sKbnUs>Y8*SFxFtFvUpbcaO|0;5^Bo-$?c>GFRTYKUr6YJMgR&6aFxSEILL)duB zlSD!p4I+8}0)UWRf=#R||7dVyBscwGzLUPVtQ7nf7#54VK6iHc51L1UfNC@6eC z$y$;9`Vc?1=51_jtgw(!k%`&Czd;=W7}sP?vR~(D0~YFYUasU#f`II>xNhl@e4#k^ z8a|Y@exZN*myyw&Le(Dfj~SY$kH8HG@-^}PZ$skGCol&7fG{dV->C(K%w14XWCx=9 z{EN|b1{YRONWweME^f#q5iR_jcx7i0fL+t&i$Pa{C6vSqo}xF%KSOP^C9ENN)?a5JgN zhcR*HOL|~k%F#NQ!?XDX1th8O@!%%`&~ciQSO-vtZ~U9_*)ITqTnX=V==7IXRNOP@ zxw4#Dm|4PIya)+90CI?dOi{~nv}R!YZX{A->BC3`E&sU~Zd?`OMcD@eI>W2jXs%0l zEj0@iF0u6Xo}OJy2p0FMd^h@5Z!aWn=#!9YPI>2-Pr~ zGa`E@#W-^amXXMdjsvDNn&k(o0baLxJBk%Sav3OWt*A@-l}+j#;cbi5{mp zb~6;N0hLNUCao~)l^+?j0z#JQ_>iKOBs%QDO*Srg;EYY3`JZ7Tr&!RPtlQZA9zWgB zC%=!^D5nvfE2&%|cA)=kq`#;FnQw9$2&Uqs#mDU(q}!{2R*@G0z;IUY8ZNrYy+C#5 z<+`I$L}w{y{0So6fI4`$Kb4{*sR9D!69uB3-}@CpE;$Yp$SDxO1Neyh2CT*qN!L7H zuua3^1aYo60fk;z$T#^r@-=?EkaRb7oA4np%&5O&4k4lt59o#1(u^JH41a z7_mcR1E-<&6D=R$uloxf4z4%K@%v$I0;gma?D56`U;>5>M}E&D%Z(zp-XR_d=?8c=LD2*rU8z+!Dp>j`tkhNf*=^VXg3& za(EOP`?J}}NEXsRgt&ef+`xL?V;`7>kSUS|=vkDXf1i5z$PwZ2D3_L?(5sNUfKv}g z^^PHvtD^vAPycFJeVjmU=+pB!M?%?OD7)j>oiy)!9A_A*3ce@UpX4P@0(0TkBd#Ad z?~wh>b)!Q&_@(`LIgCje!)(J5JktpgY?7AN8EYq4nvJZtBC~A+0nJYCzwJ|m#^Tx! zeitABN5g;WK+IgmfF^STjsb=-n>#5L#V}T<*Zz^!7BCU2%Ucl{6`8jL>&*iDumTd; zn8or+8O6DO%5Otqr}p)gNu;4Bve8}kdu=2z(sS{r1Y zp8O<4V4IoV%|=eGv~zgPDY*GoHSqCLTtcdOfH(_umR^CZUJ6?s7?_F9PW+v$z>PHHj;1p`i$?NoM;4h8$@x=WOd3l(j8>f z*3lW;3a(NI?vC0(k)i>HCZ2B4QCd! zV7^Go;F#g4LM@jc3Of)_YKVzcUI$K$Sxy+_nmMhi#^h#aQ=HhC0*8|H*wm!pq}YZo zhhobsut@XxSz6Vw|WgNl1fJXX+j~rW;g43a1 zdF(};jlXuIS9uKrM%|V>ddFId)IfAYIm2P?nD~v#gqG%Jw9H{}XUN2IUHsgzvaTd1 z6YGBnY`;glo_3(k0-lu<14P0t#zAb3u7?{_z&q|9!mBjOO!{hKkEh3lFp?@mG&5Qx z?~J+1Kgr${F8$eZ?z~dG3JJ9YwPIw#Q`3WV&w~}Qio9Bk;a zO8c~$aD65wby66R*JcgxUl#+^l-#?|;ey7IrLum@*yh?Hjt0q1Cm88aI3h{H{l`<# zc7#TsTCbk?PIAViHpFN4B$WW?b=`LWWd+nuE0pb^t=XONFs)8m<4fZ zpgb;tniZ{dY-uO=Lv8&Of!n~y-v+v^;GX~J=wK6u(TWr|?En@Kg&Xz^P#4-8t!FUC zCMKZm2KW{3dFtw%bOwUKRmAsc!R+vWiD9Cnnm0ZD9FT-mWQyqM`>G#lO83 z1&{zE;aOt{8w@~(<&4lUUmz$wy0n zS0I)ZEq)CfXssY6l{QH)RV>Qd40JgLFL8UIFBF36`QSbhQX^~1fQs*JdDX5jI7iWjW(dbRh$xC|se?Ek`zO+9B)Y95G zZ7>j#Ow|4T-p73TKG03l1$DPyp26g?e;w)l;lm_KN2m4@r;0H^HW+vzh5Va`OVLM; zl;h+>UMctP)!XrcW)DRDXStd{E8+W!^&6Hye$Z4lDkKYW3gdlzBP@8%9?}5*V-@$-;u7Mjyn+-`nPt#JpWZ*9( zBxKDyD<@p}p=ei97>k-~l+2jEu-CK!xSph{$iKzzBTy74vifx(wSSloj2x4tlR0!~ zUnBXz3JW@6eR!xY7bXxiozdc+8H**TDzQ zH4uf&Np_K8sVdZxyfKCvo%A;8+G+ehdBaiC{PhmaKs3;Oh&se4!#-;o%NDB1eS-|_ zG?9BN@Mt9Z50r>g1!DO$yaQQ~=qWN7(%CTXrs3gXcq-5&1cgSLQ#y?Pb=`-)D6LNG>t^^yWBdYq!#cSa{U6jGJYK~^hI<$l61@8}j*ocR?E=zeXVPePp#=AC*Xh zt(OwH2iX8qz7_d`2@`-n#|f%xFiq*4#F5?Lm#OlZK z#^mpZ9!#ZD$Dbay{S$0Lkg0!ou>Z!@-T2~V@$?c^1!Df-K*=AXLoui0?QLuVy`i;` zT8lK-HQxE<*E&uUr57N-ZulBAUXp1mok>0Td@ZT*MR|Ft%#bFv?%2-w#0LAmv*7#} zQGREczS~rXQV$6j7rP+<4^4XQ96K4j{%is6?|kSl5=>h zreJ2}#b|Zp$hf|)*q|y&c~aVAp|vdeU|t+8%8!;&KY)cp2$l^+8x4ayjsvsi1RQ+; zM_kF7v7pa+coZvN&Cbb5R`TOUmKRu%E&M&@Ij?i|Fyi%?p&n|*#?diekd^@~0zNf< zwVG6obbP+^Dx{M5N52`*R@;hcR{hq}D^vYoRR32>+u2>?qW>zU<1U|O}3Uk|&x(7uzgrL;y?f8m2GaLMehKWd{YfIY-Xy~IIxaiK z(^K-PEZC)olM4*R3Bp`g((#{H!eu|sFqT)++k^Zke&$~h0l-msEKl!~x^#|baHsEM zs$BS}7#wEEYHC#2HRG!>b^f}PVXz#@Ah+@Ez2v70ieKJi>5i!dRn#&x@QIO|1f0JO zW$M<+&yI|5rjQ;x)zde~eom6`q}sRyD|X9!Tj{8`Y<8>%k@hz{j+hp%^h?<({ca5s zch64KF_HRC`5+2=DD3JkbieP8_)tENQ-hcJMREQQjGC6qGipr?4!Va3?Z-7#*%f>- zG|0Teu-!1&BHh#Gvvh@5OY)S-fIi&>!#Zz(ukXg3wFVzUG^(dSgE;dJEKuS4jHdKO z@)sG_!`5G=>4hI&2B>b^Z13>aE|MF51+?>QW0x=tis3(ffoQ)e~DTQ-)~gANyU<*+9ZoJh-o zMB$q$r~+ff1KoB%mAOIVr%(;wQ2OWijwlVH?;CBVR(phNz#Tv5X?Sa<0dj!k_c#X} zJ$7U!E^VA#n2{uWLb*?!;0`Nte%gOf+;Ie@xWlfHP6j9p9BTPk6a>7aMY5!IZ)$3M zG&QZ5vmOY*G~z9*Rf-A|+4@Duo1(0X$?vX#$m1YAj(<0fw>&YUOxe0#_MAZBn?svK zCa^z~9sW4prBBbC^tD4LgHo-`Mipr))9w5 zi`|Z)L08^#4C9jqxfilBX1$-o>K|{a%0frK7TTTImUD+;@qnsqgr46^(n3PZl)K|nVb+y@)a8@!EdlhX(M7#xa&7tUB|8w$ z!)pF!Jp6c7zRl5H0*lFSbDphrrvP(^>~7L2FPyeWFJeA~4a7zO3*NZ0W%Nq85v&-M zFX9w>f5u94-Zw-@$RzA?^R%D7eZ`EfC7GRXRU|-^(IJXOxvK5 z-S_VoJ#+sRdE7MHa8I~Ztc@4=9N-HFG`9bPKi;Yj3~$#UU^q{qnPIW;67CQmsh)CYHwVm#b!scJ$H9NxDDX=H zzQ7lNTmgTBSy2*(I8RG2weqrhf3hwnUjX#NVX^d(Spb|%Q*yDm`uaOG_~5^J=uVqC zbz0x3ltz>4#WlMk26nKcNV*POPW-ZtCRR0~t_8#|wS}#I`AG-(HKZn6Rl~0wWj6Uv zR#|+o9^jlyHqZs1OeYfwaBjj733b66IattZK8JvXUK$FXWX>(a685F4%^%CkGjT^+ zXS#Q;ofqVjM;PkI!UWFv(@dXhs7W<9AX3Ca0D9Fzq5w`u50D2P$CAIqn}D!S-tG92 zABZF_7$){NOG(Xd9!z>Tc8LBzJ$2H7yjy>tAg~nk& zsf@loZc-j3$8o?%xpS=8_%(Zmsl>=9q~|&asL8vhy^ncFJZ=$`yW;2NFR!JkX}p(u zFL;PX9}@HIHtsj?2(|gtkC%1qO(KiBc9qTsg{}%BvCtz` zdFcYw=GH@$um73nK5+xp8@Fln2=5xF%MiYLvL?_q1ft^HRaY4lSjZ(Gui*&RM`C>> zE(jr38PG)g-gab^sg9d~75&OG()EK3N%p4a9>$*;HkWn)8@~Vezh=V|_aqPM9JnGK z`K9>VrL}*{hlk9m#1lJ@s`ETCz%cnsCSIC5*oNb%nCT|Y5Xj$_&t+dm1}JD_*@U9( z9p5Y+lGz*TN?PEhr1zhQIe8)`$Roxb%1st^5MVCbHZ4SB`7gbf(qgA2SY5vfv#u_q2z+zQFYw?FxT<`iCBBY*WLXL*k%w5|QG{*&P9}@E|kS4e7_;B9BJ2 zN6tx#)$Fm$LI!lSdlNB2>x3-VCNR}${1(MXQ>RRhBsIz^o)&5UMIp#ZF`&rXuDLD&jqHXH zw&v@;g&%x2Nb}EZ6+H3w^41cI4E8cUs#MzZKbW#AiY7gU=w#YS8ig4lau%siz%cB6QeE%hA-Lk!2s>!?O(u zDsKDr6C{y7Q5OE7dHslM0oTaG*BK-K>Fo|b49GTFn49Z*Cqw{q{PQ~#%zb+Q!hgKn zvJv8{vTgTBI{H3iybwZ`>J04DlO)OfDQ1T<2ET9JqwY&+nY73}EbwUL)(wKa!`lWX zNCCL{!wo#-wnx~m-;V>qdwN`~@G4&@YLbb2sf|T*Iige4OoE9V%%N7Wj_@HZRW61E z#}%px#Yv%rQF7{m9)NUfL6McWaTd4MhFv8!qy<%i38t;5PrpJC;SUCpP}A zgVs4n$dE#EoqqKjiIKXztUw?mc+4JnZ$cSFw-F>Ap(g&vPNzn4GhoVLr2M{X8o*?r zeM%yC*-1|=ET3F_49F0T2?6@jxTb9|olR-Qp}ERn6d*pcr8K?0mDLSel2?y0aA%=E zf69YIDu_%wL1yQEB}Ho_o!SPDEFA{ld(_0DZgr2Pnxrj!2H>#UO~*HSzbLQ0~8`0K~NbP>(v%_x7#tc#_v;+J`@nAm?n9l$FIP z(81O_QHGKaM=P79;^3EbtM=pu-{;{-vcCz4uk56l=XOsoICke`=jK|JxsH7qYYJG3 zUH_l*>ZIPF_jGpYJMU@9cNb=LX(=zy(zRkG%v|GfeZHiw4oH90x3@q<$Qq*$K*K@~ zYNYJhya0fOT1_yTQ#KcPam#&`Ut1L6lYTh<5zd9Mu&DN4nCi?rll$~dzn3c)QZ5M# zxJ5y`HuXbfQ3lzjI6vP7X%rXdix-U*Z-2{$k>tHs)z!O~fw!Rz?Wl=sM5f_`^r-NHXc@9OUMqbd)fDU zQEZ3SKM5aE^B<~5v=9ykhyQxhZp+}EzB~a$?>#(AWwfiuWRAO3gs}hi>3OdImQ_i478_HI>%;v_)e( zWYt7IrqK@E^AVsv^$v`fgL&q)ZiY`TF7Yo+B5fkxx=LzkT8| z0$TB3j`qfY(#nR36zI0S0^W&W$npy8ji69oSc?)SWj zu*~S@<6z*~dI4D@Rqsal#kWu3#Ke}}OvtU*9_Qu`K5-EMW+2jrp7V1RAI+=%lN=FZ z$umR9rx^sjTLUDP?ES8A?t=0P*LwtByOs?)>p!EsXom-2=_hAP2R}SVDwucr>FQ#? zD3%5J$?`tzd@fSg9@iX;Y6$c>Rr12zUq4S8#Pku_{kNbdd@Y%gRGbEi{Gc5nL7TKD zT9xLpC2=2NQ9G{uT;t0&Ul8h}ahVY9eo)=-R`{c{k4W+#IdY^7jnvgiJRu<=9Q9kE zA4UeeX?dAmWG_vXpHqo+X$Tr<@aj14uO~Grethco^@ENF*>We+xFIO}?-S74wB_{K z5F<$r^!Slc{xo1<{dfdK4xNr}D*-hCEys_fA;Hez&8dXPlzYx{gPQ-fQ$vWP93p~$ zy&<43E3$iVjrwlf!beamu=;ynlVa6;t8%hfc#9(_<9mNDj+II#{)vcguf7ip2dLv9 zsST;)tB_YgcdhL&#i<7ZHk41N3I#mKp`NgBFSoP*5mDn+ATi<5v{D)pp@ZA(q+t!V zgW(gpAy|jQ!bsGYeimzPB$}yArRrfwp$bbu7oCuW`HCcPmQsZY)+^mG<6w6OR}aH| z98=(iu(yylKwQ1`9sk%a^1qXVhwl#T;FI4-gnq87s?tq6R{>g=PhpicmG}k%*+uzF zAQ%YJPZF{H)d9-UQcNBY?fvyEIB>Pvf7RQU6QPnjgNChAk#c$c&(#&Ty`Yxt3yO^4 zAgb*2y3~uYBx38t#dpyET;I|w8{vpH44eQ=+xiGaHUxLjan4Nf_lEYj4w(%VEmL91pIwg-pgCTZ;IBv&@5IgCh z4>BhjJ9s)49|bLQnwt8L@1WBBvErjr_N>%}7N>I*kd_5qZjdAQL4&=5!hR|Dn(MVK zy!!ENA?GPQhDnQ~3!kcgE{`zcMIqP@dM@jdU2wo3a1mPAJQ=AaJK;3nj)?M3&p}TD z^q9~ZoLmEY{X`OKmD-&`-NO_PlI#jgk$fOd@TQp;u#>;bY0*!%Y4E)sbItzH>4Eto zjBo~^3L+=PL0O#F1tZFS#~}pwA|K}0cADyU!22u0_DADUJl|{#Xdu+&%gw_{UVW+qiE3ur{}? zl}TlZMQ=|}kHFod!|vkk>V?+US`YYe=KrjVUUN>om)X)SLZ*1fy(H0Rto8xIlzNa2 z{^9J*l^AV9A3kSk&AoBlGAt}?wzp8jYu|z;&c@*iA{7qe_wFFP25R2k>gl(2@MAp6 z{y!o#_C}1P@3Jg15N-q&0C(QF6VExYK4RpfC)V!JIay$keuEaVa5g=ov78;bCW0gK ze;5hiHnrHQxjF?cGw78q)*BX#T5Zbp^>!Zl()Y?{kN`*4k=ZusfDZS1(v$HnGAy%; z21HO?7l;%yDdLLn`(XIqWm8I`oXhh|Kl?&S8@4yXQC`w)k)yWR?9VK&LW!yO<{qHz z1^Oj+C>+oGRNe}wmeo+DM>bD`itnQGmn5{Nwh==HKGyFfR=J$%wvc%1Teqy%AQ((z@ZyuGNdy zaIWrKN;46C2HglR=oV{PhHXOF0}w6h?YgGj=?AAe)T=W8L~n!1M}1ZP)qt=1ea>=b zdO-yj8yR%*AscRavzF6A*E~?HNK@H=%MuP|06o{AocBQ#-a~DnGn7Eql#-P#30U*b zHa8QtO6rk8MB|zD66N;Yf)h8j!(lgreQ7c-V50SYjz$ln0bZPTpnDp}J3jo1|9z@$ z;ZlO+T7@Q2iwlz#$Q=cacR zxo(&~J16zIp%mqx3*>Erp7U@;9mymPI=R=cHx_S@*d|Iaopw;+jD8s z{%cFG&Tc6SCt$Iyj)6R4^0UthEI79ow*gbbc1`BR_w<}Rm@l*YJuYtYX=mAYYU~q( z$bJK(BJ`7`mtk37)`Y{Ag&WzLjXC=6pX5JPFbhigf;Au)|C+PDPX$w8UR2_;1m}s) z2lUpKpS*nT@>UW#ZD3I;;K%f!&+6C^Nr@RhP9=e~&EXR8)5H!3p#Z=)s_04I&a$PX z?DRpN+0XiyYhOv;lhRfzbZg9bAG|JyKKrEwqO2Iohtw(#o-2_M%r+2(+%wYa|F5@m z4~MF4`#;^twjv^ti9y+iB$7tSOfpI$V|xoVm}EDKLQ_dejUlp&GH9~Rwh$qeWHO?=$G7yGGu+~;>aO}gMPGKy7N^ETBaJe1lGpA@J-IFc#XwoEb-COT^ zLo~p8qWgVZuU`3;Fis?Zx?S#q_hd<#gUiWBE?}H9v>v5&&yq*m!yai%AO)7A0Qw~x zBo5DSXOt$eT`hjTIziLXlZ`R43YbK60`g(T+@l}2*iEI$VM!9{HSaXz-Yc*}q<83T z+yhAVbBqpFJ`s=RQ=Bl6?-;i$XY64qFrxxXJm0+S^UTHFA4}fFL*M-y`dSmbSs)7A z(^P<3_*4^sK;JI_$X?*6=-2Jo#iykql)mpt6HyTPvEwP%mYl9->+crq!Ups;^T7xg zd{4HbF#3q5cDSXo?_2gXLd`Za4UntP)@@raRlYY60_%Eor#pKVdruPblYsfQ-wC}4 z8tU`I2G_l24V=oRkPX7IWzHI*4ZwWv;`=d)ma~TZsL6h5-h2wqq}kPJHHt<{+0vBn z05$ii(9Fub8-@4kH2Mta{7eK5ZZ4DRVymVl>b&(|j58EgM;IN7rLXB43#khFbDlY-fgr7pH`ECuCiOEq!IupAHQ^*nCbt7p18u$uoxLt7~4vw5{8- zaR_!8G)u8vHsl=ioqVH?*SA~lNu(>y>5D#FUG;Fy>}xbPq$QV4|EO`^Q+@^3A}$Pr zz$@2*2bx@nr7))IG%Te3M6pd;QRl~}VH^N3I}awOKW}V~evZ?tVsGj`0$lkKj(MzU zi$+1D9M;z%K3WLKk2O)sBPX&{Zo;5u#wcaA zh=0jMErg_QE(M6c@Ai*VktF~k{i)SkkFL%PT{bTQHie!mTa%>bxHwqjRGM%9=U!8c&e7d z-ZSUW4PiQ*Nn?JK>bhBW9~`fL#e)JXn-_qoR>?+rza%@W0Uce zwSBd!cSE;h;aR7p|BWw>^fd3Gs@;ZHh~QJ)mNqsJ!IMhbS9VT8* zQCtG5IR<8-$t_yDyauT|kVwxCYRsYfM8~cto&zwMVRpBRLf?5{1;P!pW?ruH)J*`_ zc#eRuR&)fS`gyv?eNv5)Zprc=kzOo?6jUcr{{7dy8%idm1$de2uB@dWdkDtL`+xkL zlK=eI4Er{sbAG0=(rT72O4;NUZu_R&Z9Qq9YfU~Z)e0}xa&|V}9KK{BH&Ahf2e1iu zkhG>>tN>mmn35rs^xVAaJ|eHqDiMpj0b{p;v>o!!>$E|A+0?;E?f|Gpd`u<8c4+^t zE?G17YhmbbD=@G+fP5j7=Ks4J5SMrVKC-!j4ahM>D*oSFQU8O#4Bqg43OS@e_y(@{ z!#3!ZtyJp`s!)|78Dr<-bpuM*K7o2EIa&JGMnw)2hdgaIsx7}YD?9P)Kp>UG%6|Nt zNcO-11hN}_p7>!_SlRmyzBG@jthjrz?@6Y46^Q)tMi#BW4+fQePl~~OZ>M+16;KK9 z=IkG;V%4!ImaHcGm*PwSROyisSf)jsI48%-F*~1bDiCm*i+krVn2 z01i%uolS&0AUg0@BW&uKiz!JoBH zjSq(}XHe!Ff?dFC{eaXx0>WpoBeyv30C=s!W#xm=dOdo2+e^~re+Mbotb6sdKip+W zo#%M^<3;NMYMzRQ;CoKyUVSPc7HGEN*2I))EEVKKhp54*izoh*irnM>FbHM|-$3L5 z$mWDHc@ntnnpG&n>&Fx(pCF#|I-N+ZW6-NvOVzIg@Lb~y$nz1GJ?9NNIC8fNb= zyTe<(Hgb16DJwktQl#23k2sb1Zk}xqk5jE}eaeOPQ{NC;ig3)$$x{hl&dk<3I*Fn| z9t9q2o<_dxI9Sguk0nGCN+O->kJt}gW#Bqitya6e-o(#M(zUWN{l?a-O^NlO9NDSD z<%PyYpcMUWFMn^M-*m9>czfVEJ5HC68}dtYj%{}c7I3+`PkuLkVBgRKVx_xBL3@8) zhtTNrQ^j5~-g9EdF`dOeSrH|F_er#ez_lolB!jKh{$mF|T?)X=WM^h72E$A_`8Ldy zi>@!v_ZGO!7ha^J*bP5VhqzRR<;`y9dU!mUi|m-EC1_;{aJpwmXRkx$3bELzI`Qiag)aVr##Sv+K)>ct?XJm&>zu}i z;*P<3(!DQMC-tkQ(!AKJ$z`skJ<6te2jw*q>Rqfms7X5K;@%HT2|%HM;EG|y(h@>1 z6`pIMC!%oj7CoKhY>lS;+F>4=Mk2{iYYE&bbP7pn}-sPrwLBdlU7I=@F1 zW^nMuDV@RJ{&7Uqy8QE%+O})4#AMu$FjehuR8tm%6ErLQh5Bo^^5w8~tRC-P-#nE< z=%goFIU_Hqu6n4%G3V-sQ+H(YJBuN%uR#>l9E~$UO}Il*E;`uhs`sxe-8XB+@A8(I zoX1_40BVWfVtXJxw^YWZNrElMFa$}n`Zv8wKCyHm;Z1l^J6ITE>3n9Sds?FFU5#ZY z?{IU|LeBz;!@qC-U4rR17zj$mWUg4bK9Z`CN;U$e`9}Wvn-peB;rLd?<0Wq}kH#0& zHev=d`^Vsf^juwk4ukt1J^@<|SD z_we1k<|=B}LeKYzhFi1)iMzn!FvTCw)gW0tZ19JNlB3r(sF{MrNv^IB^4`?eUXyZ+ z%iVIq22jbgFexl~7xXKKDSd^ps|~0zHpUMx3ZO|>wB_t$KXtl{z(AP#;)gQU|FP3E zc1CjNJ}Ro++1R<*N0Xy^%~JMEqri**BqO^SQza(?&|D^cu8k9(HT4flaliXXMDQ3b zi(-4r4=@dC8hI@=WS=@j?{R#3M8_TTZPNnycHXP6?T!&w(%eQN#dIBt_nnHJ!GBRr z4LCu61B7*_5B2r~^(2uY`vETtue+G$Ak?lCE%dL7Eq6Vi$5(WnJh=s%1Pg+UXY-Ix zp;gY|!c-vF_RZW9_edhyTPPadtW*S22NNL0oW`K=5^)o|jQjedbu6R9-KP}M*o@Y} z8VGQK0S^TMRNIsUiP9%wmNMvu3s+~8V2VOa9{1Hc*&I(BJX>`gE4BH#u`ivb#-c!^ z1u0OP58c6R@z{GQTpb;+N8&Nb-o3nMQn_9z?7mwXdqKLVuCtIrZ%Qmolg{6h%R>{_ zvR^9P2B*{{^k@xiX@2-6dMD z(fJ+@aebVery)f!V)dBW!1)OETAztJ13B+^RdvzIrJXFs9jf|Z8Ym!`=k*k8l-SO!kRjI?*72O{Yd=B z07-f`qf(X<(T81W)W4xL^Zb}_HDd`J%^=IM+WB#r_^ov#70ey(G+UYGFhj9YyyHmc zcv%g38ya^S6$WGd(jAjqp`&c)1p>H_m>EvELuceK%(A`aKKo#CR`?rqOIdGZE;ot) z2RfMsRzP1u(r6_b3o|$(ae1slrWb@1n=EBT#drxxkc7fIEi%VOHn*2&d7T)!%kMWT zw;XV;OffX^*^0J5)F0g`}1Yg`}o1vRp(+Qi|p$q z23lK%z+G@@X9&H2d6~J}HF(;H+PM`@3?@kYZO82QFevI^{|Rsh9tKRT81O>am-@B| zBG8lN)-)@)V=^)_Kp+wBDeKzGE&2glp zt`SBP?%5*NOet#2Ip?hwV5J*`C~MX!!*Odcq7+64C$ul+@0JuOvdWE|J34i6@F1%e zKibyFC7*Br;~XQggC8Ae3ci`gvpie;w*dAbpO6u9$$a%yG}ogV*ah59zzR2A6SR8}etmNmb8B!|q;#0zg}-``r3sa`snGh)>%jT!Jr59K{+xwObX>sYgd!E0AJj;|+W z9VcZwo+)Z)*Vbc`zh}t~p<%9JebaifNkBF42DV4tbWNQ)fVel5JeIZ|M*-FK%KZc2 zAgSD$wHMB;{yLX{Izu7I4ddLsqIHoLm``r9NpWPCO>yh`QKz#vfHO~rZFE$J-1R;y zh-tERab~#3t*`ARe*SqR2>WhdZ9X_?#;PTV=3@+nsuZJ$pwJJTSnw#_Umjw~6k40k zGb_wgh+_PtFl$Y{2m=apVFf~AhV#JNlg1Gs$goKfH|MfRiSIEA2SsA>W7LlI90eMd zw@^e>vJOU|_LT`&x7^;V6!a6zP*)t)%ae@@1+vf(OJ|>c$nvK1FsxW=`oA5X!XAo; zda&%3M-vetFsmPiZW^qEJPYKeS*c%IucK`=7QAUt=NXx{=B6p6f%=De#e8YrjwNq> zs5T0{o(}#>QSO@KT=BvvB`j`1G988E8ne{iDhVVf&uwZSx3a`=#rIQ$cYbn$I9uiw zQ(sozG@I+gnoVchZ4)WeAqqRi4XBhq>=$f{`wA+I?U2t?bH!R~ysqELbI#ypM1JQ~s`JKe^^p`huxW5qTN9rsi%; zSWu$@_vAFfJ&CTnk_QeOZ({JK&taueVRQQPDIecz!Ub!--)OT`2nxD;8QcP{Awh($ zodx&A{@`QDetKA{lO`*;y?7^b+>tdSmam)tC02poTy^R7Q<0Z5{;?_)S%qi~$VrXh zGKrM}Y`mMgD1z}DMXI>vk#z{1C$VRPV8;M;$K6rfB0J2Byv^NO{EOmAG_&oIdEc+hDTQcEK-IeKT# zgc-fmIwt!YsuJeR+bDgSLFCFBf%!5K3!f{5ru1WOqAG&=|dNamZ`8Ooz4vZ+~zj{}`fe|#$?&m># zfZ8F-M}NfxLDJ7R7V3ONmtx}Z1it@ru1U#ZX@upEkJP)|%*Io820tHPw0tdux_#xM z_}{*<{0W98%kotlo(s8z(x3^2eAw&^VTBPuP7k&s8_8hD{O|NRw37b$LZ0^qu#ZWN zgT^)k^$B10DgFKO&tXdV5oiA5U+}X3mOGcI0?|w~WySO9C7O3EYP7)AF`;bJS$caO zW@+I6XgFEVtM?~;50D7oK9iBhSz8s?IXXAI8kjI$#rtg*l7}SaBMv6daIY9kyltsa zutpWcmvWR@EX{-u&>sNAujtMw5D=uQ{bxHI%f{q+avi!)Vwm!!Wm=zQVB}%#(w`l z3xxeIKo!(o3}AyYTKur+s*NjlF}p4()}{-iP?K9J4n~z)L8Q4grfj&b{<<{zckMi& zMm@{P#=x-=505>V1vM4%@xa7vVmKJN4eZ1m*yXXzR@>vpgI$lUgf69vU)%L+sjE4R zGWjGY=e}EV^Nl5v!qOHSM3+D$S$5K&2N0EzQiHmQVq2--TH#_xDN z%7IMQU`RzvnbQc*8#v+~qlTbqAb0zqd;Qzizd8|IM>@~M#VL}Xc#_$*w|6SVkAMBd z!p(%t@Z>&{rpYFX*V4lDfX5Rs{Mk6bjN4TW!<@1=iI8fat0SvT*y1ml5ULA?hJ5-a zbZ+9-~ZmHgXs zbyvxq>SnO7nJR7ag0n9an|g}X*;B`dU&aI-pt|$b@=mQ;5l*VUrONijaAHg5N*UI8w8C!?s+R z{#W}-p5c^IJ?{61IdrWBZm2_ZIPayeyZWb%qQX*yq@;AgT_zjGxv1XB7s=( zlNpt3O~sv}HatoKG=;(j&nIz64mVO*F|P8X7fhu#b+Uo$s8@aUN4NY&#x+B~BZSN4 zb|FoMwHort*IX5olkaOJRpQf8#G@_Ii3)eUv!9G^ja)B}ZK- zc3iSAyiJ#MB-6eXqd0it^0cR1zb9ELdOw=D#aL>6#GfkC;ga=KiEQys&zvxZ3$K}_ zIK8&OaU3^=yxw?0gUPaL47eNPWAZb<8St%b7&E{3Gc+lD^m(Q% zU2xR6QcKm27?P&5c8)a0nejl8%VeTXM33%cYa(0>IQa2FHpOd-*`yf519*uNx=d+P z@tcl(Y;-QzY9-mA_GeUMg|!EQwYQXNu;F?-)v}X2J#Rj4sy{p_fPv*>Zan*j1o{>R zt7rnf{1$39{Ns@E9NzpvvxQ`kF?H0Aj?A#RbRmc3M2Y)4neq|K!a}E)zpb&t0M>j+ zL|G}cL_tjgC?Ed1TB#@Qh%3Q@GeOQ7sD1S%0}kTnv9LHq^A##^-@_)023BK%Z+Og1 zIZ>q7)2Uq)QbBO+WpoHSXb+^3>h90WI5vK5A$Ts`{qo)x6yHSxPgn(J*TAQ(S`O z>Db?a9=w3l+T_`p=e>u!F237Unj%JpM{Sr|kz0PslH zY*R=qKTH&1GI~X?yxtF3M;)5TObjzE^eH#rYL81_qq=mAifo^|X-$1576-nzkp1Nt zf^g{N3A7*kEnDgQ(9>C|cv;ptDGSJ*Nvrl4*$umA&Z)Jx1dbbKC)YbCNq_sLwr|1M zL62I(XX6g}d-6#0;rtG0JZ)rW5dE8>R02Q9Q12(@%QHx^+UA_Ew8lnUjD~)$WL#v6 z?)IYi7|WVCgqlWa?=*Y*ZTUzh+m?IVT((zwJ5gunnxO{aioPggT5%m zrPaH}1f!~q^Pbx0mq(TlLF7FrfBNOqLW%1!Ir_97p7U82XOBYT{(_~i& zYF3{KN`aTCj(ZR4vJ)VM*?`w&tHKFsFPp%}DCxL+mQQ96JFQx!)=0y!8^paIXoT3>c$zaqC`$0*%weY&3i{?pk+V zF_yNey^dvS&w!UegZmqp#0ghF`LSB~M|1(yxeE^SGzWebR2%GPNDf?A4D% zYqt_D10G~P#i{8l>;>wdaN&Es?6yM#dIY7YNlCTke5smO3zGg#?x)2T708R-=6G-40JH?f!tlEXz>OCG0GuhT)RIu zf#hoh7k}jZ{53McI|X0JSq@?G(C|3D0^7I@74T2khV{x_p>GVtKEL(6nm^qf;3)@E z-?kieQ9is1+y}OEz?7;YS(YXKt0v|YC|Uj2Z8-ma4u>n1FtX9#%poQ&2mu2)k;vEf z?fe!bh}bxH?g>ee=sf|Zo!`3?&?E?>g3xQoav`9G{o3-2fTsso48Sz_L1GA7f>#{~ z=r%41{XGKBiOpxyhug0JC!?qu026&nz@Zq4S*$piENKYnu*5WR%`3QJKGmvebkI|jZ)6g@zi1TU#$gbZAj}=#a=d?K5Nmt z%ipc&y;)33&;_rFW>W6JU$ja`A@rtg!`D&lLei4h)&^jDfC%U8ZyV;JpjpL2D}nI% zkVn6$oncn}3BqT8)Ljcyghr5(Qs*8I{=fG$*fAcTPOP(b-|(ZmJTp4O z{L*d;1dBYE!v0Rn%$LDRasF5D%AQHz`1OcG3l1XKpAIBl6toZx<@oh5xV|9b^6Lsn zi;N8s(!(`-KRfOxtL3?0EA&i8k!1+vO%Ptb#Qyvo1}+86c^`uRRH(cuJH8tg=vJ>O zz_q|Ff>wdg$3K7P;9_}(x`|_ zKtq!z9YnxD=p{e`Nxng!`&sW=@9$gRAHPw;@#LI2Gkf;za_#FFsi&jGc8K>76B85L z%^TN|OicTmnV9y9{j(RGNxCbo0e&`u9@bA+$H;}iPm;x>^F+F<9 z#6$(B9?dW@d0%8=BHd+TQhde4#Pu+(R$m!>all$z>pBx-_fKYh?n`in<>3u8PbQ`# zjk`a4THNw%!R<^puU|Fv8(N^DA6oPW&#*W-joXiR3@5J`)(^f8=G*Qwq(CB^^%(m( z@v-}&?8k?OnA--NClX$#=Uv)s6!}Ik^U4AH>od2Xf0RDT)1~|M?d_K*_Gw}G`JU*B z4kQh{XeoX0BX*dg&3&rc&xca842|NWhb`TP43a#w7i{jU@Mw>y~r z?V`65X>U*bO(c#72J8?cap>h}-^;~+dxP1*1RK_y>&BJjDF?^>DC6W0>w*C&YGcc| zme`&@*XR*WLqV>qBaGmS6xO*{5Ik=&ZZvlGhTf6fpw$${M!dnn zkhX8TtI5Q415Yi|6K71dGZZLt!BEgkzwDO zkFHo-9X~bM_IIwC7}v4wm06R(j1cF|wN*lsqzZYYxuJ})@+SYwRUJ_#S$Xp+SK3I+ zNbu(9`3JlGy?>XuI`1HG%8gE7cfGN*bqOD|8qeNl>BmqS-|m!AqlT|L8>AU9-S<;9 zIhQ8&XNZi*bxDZ^dS_KUqh%Ylb!jt=(%vA$DBb4LJw@qAP$NFrYxtx+^^&M~%|hky zWj;9w!#s){=U`&GtMWc@b8%zCXIs0k*u08PMls}w2caD;RUoi+wsc{73!X|r?+|7g zqm>zB%Ua=BdKvpWi(jC}BtgbjOIZ2WXy>mR3&Y#n+cuZKQ`U%Tn>C&3YUl?0#O{|* zEjrBzbUJ<54WB-aVtPcLeW{P$(}(VVV!Zh zYItXBxeO)2u;A-Qxon)(wh0Qd7^(=~-pH%^HJj6a3XIt@ynd}US#lf*E@OLy7hk#TzX}f!STMG^AAq zq9%CTC%!MwS2PPl-`7`EGCxvd;8wR&^)pJ+r)o@fpU$@;46?wrKE&79ByelO$qY^` zK3438r}+f#wrwE9Qx&m{UlyJVj@-Q!MCDM@>v+mY!O}dQL0g)W3}I}KGe(H2Re_tX zs*+6i&#kKkfx9;fc>~ZFzK9eSW15pk3;K@@@JSZ9!tBl^GklZ>=@ljn6e@LVXq;|Y zS{0Oiu|a=vX(>KeFrQjo0*78W)a&A`^cnBeA&gj3&-&Dd*?!HEly}ef_3;+q%#LP< zljarY@LD89k7OBGXpRnt2xLKL2VGo(6hVeC2iXM-as0}D?_tmgSdg`oUfT;*{oe09 zToREqyAr(HSOZwqg<%_dPe{utUv7Nas?zSkvj3hd*&>kGfr+=7M#e_)^mLxSm4Ch& zWnmKa2^0!N7&|DXrpD+W-^no2mhhv#s9e325G{$T}GAAV1GU#zHk zKy63tv__x7ctda3^+%fRb}D@tP9y!bWd&JR}hXf(PvbbY>L>|~&p z(H@FLfjC3cUOFmW$@k=k;#N4XpdeU);l4-@M05yk#zEckqQ@Yg?>+CR`Qsc=I<zrlza)88%2sub_`sksxlg#e7_C z89!w*?@%NX(P`fim!j`EiASnW>ZW$(_XM6uq}ExaAsZ+gQWVPURQ-}gz+~$_#zd}g zMq1r6Jw=T&{4!p}e12m3Y$W3PfQ@yZmb3QbDe8QgThOw{ibA5alg(rV_(2*cKO61* zUV(7KDJFfmkFha_%KBFGhnEPrr=F5Du4exi=}&ZGW3y#V$D|L?Ncbt{#O}Nr`a5FV zaNk3Luh<4ru9&jVnvI387uL~*!Y3@4jF$#CH#b`;T}mz1zEs>Bs%-XK{U{^icZwa> zoy(`eF1g4`DuiZK9Fv+O(b%l=<>Hth-N_2rj==HlvGJYuzkfFyHdRt)?<_aWfBQmm zu6^5B)Wr5(!o!b?{yz`@VCX7_^ z7y12q9cAv0{t}nRXGMgV5nS5zq}dlmQHc!F%eRD`KQiAc+eZqIUSj+Tlw7AV;*^K{8Ezqd zb^*W8)r>ZD{aRlVo=#Z`nO<-}iC=|hs~XmcX5Vq0%74p0iLcG!8<(0x3On?al_b2E z7Sq8$To9;S|JISAh70&c%9a+8`MJ|!-lrG5;c>a~;=)-{ZpUSl075VNg$BH@h9kF| z;T*(eopEXMp{7;sPd~#+^ONeK^D?;Mx-x!$OUCIbJjrtOqMgkS^6FP-v6-UZnQ!u`fxn7^?s)n}_eDCv81JI*bLUm&%34As6AvROwZu8uB+ zT+)N9pkI0sed%$Rwc1V^A_8|FuUX5#plC`Pyo=4lC#=T4C<&c6?~A|5IAi9PuGmLy zvdQh4ZspqUUbT4IbmzP(3)9?HI1QD+e&h%>+JhchemsUMs0tLF;&A5uk|72;bkLh# zv+nkL>D8>G&{-Lt#24NoRSnuH=;UYv!UV%xi}ZPJZEfwPn+ke;Y8*Y?^&^l@8V`B6 zx>Lf}uufGQr_^7tKNggeKi>lwj%?9I5+z1ylV^$L}jY|0sqnCB;U&K~Ov znlx?hXLHWNl>SC!BB^B<{b9e~p<4$VG|Kf7+}zoRVtB`jP|EsvJ0sew7(8w@ z%eJ39{LGyvke-#itTa=O2;yM+5s7R72CPLkYV}(lJ+kLO-@?#%0&FY2h~|CI5#h+S zxO1qxECp|KVJR*?-fg_WlHSduB}Lz_#O}myDoR=Ma7R$^v1%m@rC|`i#nXP(N#Ye> zR}=9hY9V_2W!(Xt@$dd5#*V`{gRB%kPMw)!jArDb-KBQe@xnxdZG-}j?VN#z0$-LW z^fjhoC&v}ueA%=rKN=&s<6>5&YW1IE4@JZ(ZHGBAXO zruU%7h8g*jj9=PnwG_1fv|7mYx>_Ca8qpWACEZx_t57SsF%gMrPSKar91D<-Ln3Y_ z%&s*kBOL#UcY!y<9LzX=fWZd|tI(Wd;^j260(3m8kpUg%nMlq2>M@!eru1h@f2zIU zSI?0OBf`f>OlS|hkF9lvTIh{Rr)Rnym#fwv?d^rf@-p$0{Wxr{;28}$T)$GPjEh{1 zm(5Le3q+KYImsuqY#Q>`a%>r96}s70ah^X5gG$Z^&OY-468`yIYFK{C)_B84nobfe z?9KHeZAwknN*`$8W%VjMAj$Md(2OxcXEnv>b_5=5P^|A7Pk7JxdeUO0uX=Fe_?S0so~2pG)4F!Tkl^1hEz=>CQ~DZ0 z`wMK>Vs3`%HWf*F~#R)TnjW~}D=g7yVz;)TX5kP>cC^#{j>*tCEA6CX~ z=@ldlJfUCh^kf2-YG@lgP*4m9qJ!tX=KKNas=O&JZuBFGP*P$1N)vDL((A}Q)jX&cV8A>5LJL4Fi z6`pI>7BD-J=?`)rdQ2O-zjF|q1)%Z_$BCsM!`Uj?#z96e(R+zVLY=gJk7`!Kg@zE0 zG~pT;6r`h>mm2mbk{mly}(&`;qc+f417>?2QvA zjuK0myXB3XOa#{KAQH`u)lrG}k3^y)Ic z+IJj3R!PiIqu+8KzjWvL=8g&O_J#goJEu1NqUnO6#${5ixtW%Oz#}yikVKZyQeLLL zl`?NQP!eAAL;G5VG=lPz&RB=S>1M=5)Nsube(;h{i(m)^Pa$L%&n*}9HRUuHI^9Yv z+T5`{mF~}k0qNvvftY73P9IvF+op=_^m zm;Vgw_L&=@p=U;D&ZzAUboD|j-e9L5EEUC~$={iZ-01bdbKuj@~xz zIQ#d@e^G<~;tKzs_!l+!7iah{jPUP?|LYz93%e+)NB;ghRwl$=X#d{_?@n~L=^_69 zz5@TxCI4RVzfSyL@Aw~G+#OwQS2x&HefWFqV8?v0Q&ib*uX-&Ae`31t82D(8&iF9^ za;TLbsGTMh_wdqa-DXb)eH|pcg>JtGHO5WHJsv!`6(`!ay-vOnyw26q+`O|8B|`iX zc^sP*K#;5%czm!=H=EeT)GJrKpmqK--|qOy1(>CV?M3mb5sy~!DsJBF=yq_N#rmd{ z*Jj(?wWbM&0T0R5O}ji{Lhv0AHnBo)j{1@p(%+rO!PHqDll9|PW$U5ZpZ>r4a!)HINL2|h^5=x(DVzdg2Qpq3P{HqNMyz=3@q!0CVoxjjBpP z7sjfy?s7D_xdBbtyV80mk)^*6m7eXyDgsRuVtr-t|l|1Mgq_xR1d~V@B82<#3gvF;_hiChddyR-ZbW(rk zkH<(IU0ue{gKGbb_}#yscQe}-EouOd7f>lMv9Yy%dj>H$m33F8^=f+On>TM@>hDNh zdzdocV33z2Mx73cK&$GBPD<{-p1v+M)q|(2ahv~E6Hs@KU+@xvKEGlmIVMkpRKj@0 zy^~NNzHSQRmlZk1>ut{jS%`)#KM}m8s~i4+vUa>IY+xr>&7b@x*iEH;shF`YjN^5q z?R-j0Y$h=>>?^WfN;f7#syf$cCNO)|W5exbXAxI=Q*^pAtia z6NC|PElthWuU|`8RG$u*Em8+~#y4+Kp{sY|kc##Ca-K98>%CIVZpFN=Ai_XzPVN|iV8~Vu1P_`3lpIAG@dK){->VAj{4=# ztf71kL=(LKeZ=O?6nV-IrL|h4khSlIJ|Pu%LpOJ(r+_AG_Te&UKYHMp(nXAPy3VeY zZ{(^URN$l0u~;n0@d~D&xz@TKW(US-V9?W*t+k+7UR9M1V9cWhn2gGY)KsZ9qp{kx z4khxjH$n(_ASJOI_jp6JIqjxy-Rh6GT9%zzIdY0bTTQs#C+mIeyw8H|@7BYof&Tqa zh|ni*^=01XIYBMXHK3xI2a9Y6{V3DPo#{#@59Yq`k^2RQHjVWQ@gn*d{GtvR|62}|ij+k|l6XBLKp*|x+rmmeaF$bVcqZeq;m5Hq*!Xi>GD|`Id^8X^ zIh)&!BKbaV<7Cs+)Knp^;f@C$pPQ@ItIbegtPB_q7FJXkL8HBkwPpGJoB$ipRsmy)lfriiymBs3?r}8EO{yl<$I$0+VyanhR^yaK*lo#zt0}8@vZSepsBkA?T5Y57}R8C3{QNx_ zY*6NlCQE!nS`5}hR$%s67N+1z?(RxQI*$Td$DHwQ!a}uW{M`p%N8`x^f%B4`le>GL zDuI>RH-~^PQCe?~I?*%ds=a0sHzM}Igc8nKIdAJz27R8uI3u(2A|G;^AXFk9xDymv z!Y)Swh%cmf`Hue_*#FurwMbIm_g1M}ea~fSmi5xjaflcw=zP{{!r%)tJviAZkM+ut z1^mY;afiT07C~tjka^sSK=L}hQA&NM2rR}KZG94~mIK0+)?p#TJB7)2g%4yG^$nOR zyfRG@${;=E7S?i0UJD}e6~0uEm9>3^O@r0b&v@6WBlNMJ&Ovb=nR&1IQu7ZNoUrDa zc~B=YR=~OHp8(tkOdHPDC2f04cg6oerl$BWl0M-B`Kb2UCtPyDT{sMYJ&h7qs#+zq z&|}#p*=0LNp>;0v<;=&}Sg;N5Uxd8ENDXremqrhI*}bSTe0P(9TT}}WqMC<(ppptT z>{3eC3Ij8!xuLk!N~=rD-aS9iyj!)K`JeZpyjyk+4{5`$`eg!iSXnI$Nt!MU0yagz z(K#K#^Xpr4Ty34ATKi+919zrWh!L;R@?L|~M1{2KJfWUiIfdia0Fs$}pkqglS53TS zl8GGZ_$_IHHW@c{OJ39uQ?00~;v2l?uzGu_kRORFc95+1exY0*dx>Nkw#w6R%E)u_ z3c-@hI4LINcDtcZR}46Fy(Hw`D=s3Cu=Z@4wQ%L#yvHRadC8ta->q9DPRbpVSh|CC z==otHIL7$VxIGShfClh3s;Mg8MqDzZkN3uYMTe}u3&qt2f9oPw8A|tDj;%xvc^>PF zYtFqpe;>uE&(e4l`aqNvW@AoVI~fwHFwA#@MLj1r1g|=X`}xr%zARFZG%2HgL6-OU zv20AYsn8FFqrC zzneqXJ7rq@~6Q)l+8UZ09v+*_zSd*s3!{%`Nw zFDD{Z;la1^QE(%d^e2|iD0un;+naKs9!)$-Fx2cdvY`EX=;ty_K%&>FRT#8r$$Y!- zvX`@Sp;L}jQExVeKKr_3qrmcxxp|+ESC2u8Rf5A=?O8)Yo~Ltb>KjbQYc7zbx@i4p zB&*e`%N4imL|j(icCbo*(0h;s&*;nuI9nX!K9`YEn*I=cB0Ky^Y^c>9Gk=>aIrMk* zr{B0S(r#=OWEh0s+x*c)eQ#_iP6G}t#5RBI|H#_r>h@35k(3P>)P2~7Y%(gPjF>gM zCa(w2_PSw0c>GcrxJ&}SfJ#8`jqag+C=FKiAE|P`b3_Vz`;T{Py(BU7j?L^2w-7D6 zn#2z)_&tG`byNb{0D`tmOvAK)nhX=I+4|PmogY2<4;$04SP7pqX|9P**r{o#)wBDvp2k6@x}$vNF~>Eg+^6{4q?M5JCG;#N{jCLW6xHHNRfoA!^Y z{g^excdbM{C!H1&sDCo}uu~?IU|;a`F~adg-_Vdq>TI($?A;v+Bexq{tIB5}r(ly{ znaPM|X$6mnyl@A_PKVz88lw%@4m1RG6w}LAnA-AQhl@hF3m`et;MxroA003u?2yl@ zk*AERrKfRdz3ciizoG)J)#D+J;#H@*=Wz`YacLQ9Gl~M8A5A)stM-1^qY0hSte8G~ zk(9mks>=RjfS1&Dc+g$J|bMcqIeM&4G@O}x|QZQ{CbBgnaI)h69}!2@$o3^ku& zZ6w7ju%z7J@xE`Q8z=++fz6!BxZx-Y1$+#nqv~(fe-qk=QXv{k-u5pIIqlHinAqLp z6OSYax2j+N6WB&PvChz2nn(@Lq0i$wb_P-DQUb8OY_}ZMbNUrF&Xk0zdpZjaQ$UCc z?SFJ2w>E~`N&OS`Ivpeak|H}>2k0Q#Opc(A{1FETvHoc? zt)CB*ZvHHIk{QrpV|Lx+x`N01=@!ymJiUxrBxX-Xln)`0h3?^54 zU*2`3+I>>9MrE&a9z=aDJ2)I`w zJ`6go!}oaP^)m@Sck9ETnQBAx^YbJ3-IwY&PfmweT3T}AULg^=mw-pqsPB93{5m-Q4vH5B*}|(H46e4xbhfp% z8S3qh<9aA2l81Uue&*Jvn>gr>wpo#M8OC>%xat{_P3JUn}+zVDZxQ*n#2tK)h9qsIji$lBii_wq#JucTa^ zbP)r%irICCg6{@J=QcSapRP)rCFhD-L?A^b6N@r0r;57)#|!aXiz%6b<8$Bmujla{k>0^IyI^Eky)-1TgO+tZ!E@&00VE*201`aqj)JPHRUA?T-i=Dmh|Le9{!+wR z_no=a!4gG%tVs3L+Cjjd6~;gfx8g84#?Lt8jTn8-Gs@4k;MqfqCJ1w{zp1a&H8{{f zt3V%=gM)(~3pPArrgP(ay*~Pc7I3^Up9c@xwr~x<3RR<}K?rXprNWk%oU@umok!5R z&g#!q2kZ`%UO>pc?icaTpGo&7A+c&`I(>U-{DXhlizKl9)OMB|rv0lb5&5bPLt2GVuxgFk@u=61LOt*x(h-t+;Rt=RleabNF7HE&X+h7dZ0;H0FBLq0x24FW9b{sHeO*$m;e=U;*#vcMXAL;%g+`V1@z0Xzc4O<eU z#>Vg8_S^eNv$H%rJnm6hYfn@I*6*uZy%XxiEcDYQbtqhI-@ofMwSp?t3jkAON^H-7 zVUW97f%$oG82a#V;+n3m?v{gXDkDY4K@Wi`y#>wB&cbVMoxK^i>w)(pB9VKGP*9AE zl{JN5!Q)HbM#5Pwk`A0*K-qLYcXB?*ZK(X_xP4E~ZDti8Frl*Db{x76=Y-gjD$&RF z5%+I&q$zkV|GX-fcMv-F4=_@Y*e%PQZ^|B15s3Km%1Yy5;lei|J>0Ei8nrmk*0HcAW50uUP0e#Br;kBpZ}dU|?u zo5}=8X3`o-a7b9K#<3^Iht0klNB-t`#%4K8mA zq3zN0?VU7v2Rk1M0?-Pen&HIWRFB`rZ!pYCzbe07x^#)1jZNWr43~t(WxwUj?gC9C zgxbd5ix$s0YnWo@-Veytu6H&yywyisf$Ia@=sJAQk7%S~-Te8tVtRxt55nDCT-a{1 zf==FGV0Lzrk31S~beFYk{9}sY03rtqqmOvx{T4IpHKb$cais8^&Bo70?%$8IFn3W* z%~gCFDqX#%uUhC?`=R}q(iM!y@Yl0Wn=WVLPaEz>umC>FR^i~tNSi{;ZTMUXC(Lf2 zMKe$yxdTOUF){m3+Pyu$0HJor#-|JS#VZ&1jMG+O*EE2V!R$iuuXP4tl@5Z{!M%d> zUWzKRvge-6tqWV77_JRcMgOa2KK1OQBO@bYVvl}}F&Huk)qHtCcoE-Nz- z6n|itUyjou)OaXsmE&AGS;{*%a&D(mx3{C~#SQbtDM420LGWE{CpWjnGcpN(^b*3% zzD?XVLlNuM;Qi~@;Bl@_(O91QHn}WnDcwU%_ z-0Lnf4R%FLi#Vw+ylN3B3qX+cS%<@h4UG~@_wS1|gZD)hIg{s8mRUQK8lO`_oA+79 zM1Ik42Uy6eg$dYcp(1%|`z}OvbaZrM`9QL{U}U~8m&`k6)yqbl>B`3D#?PQkxA4av zhRA}|U!KY$6x}7Sw|0Bx-%w~8yW5KQ$cnoxEzMyx0XF*N=So)i#BbyJN`4SeTS?d6 zO@Y~wG13{Gy6p|-Y*5gQ)_516X(>JthY65-TL6&z-ub$YPInir)4;dDAe{CoIY>kv zx|Q2gshgCEsTA2>nb87?+~Sh_rAx^#rwc2QyE?Pj05(t5D_sRHY*+AMp3g4p*w`h5 zv|QL!NtO`79hkr8OG;^$lqgUXxBhBiy8g1L<6(;St>oY5CaU6=N4%K}i680$2yl`j z?rY+ta+cQDg}v%`OqNd=;lzbDC5U&tV0MX^)%?kukS4Q6o-NdSO6-fJb~Fq!^t?@e ztu(j%SyCAB&YXn>3CzVWJwzQVXWzbv+wg3vY*S^&SkY;H_8{E6`gOuLzb{3Y301Rt zN{WW1-$v8q((+*B?Z&7^oG!72L@7P}LD=&1s)A5*6ty}wzB=5AWI9e%WBt zjXNU%t$P^|^a;09zd*BwCEc3V2H*J>^uc83BRN+h4o@*pDVicAqU2y$Sh8t{s`~Li9D& zcc?3HNzg?UH?Zw%6QdfoV4JgrkRAF8sD(056EDh)#20P(=S62a1z82 zV^&?yUixa~;ng^3`^-E$b{C4O2a+_ZAf7BmX0BbKr({uu-mY%sSyrT26}?#zmcS-f zAp}&SfiKd64pV*&X27Dg;E>>Z$DRxMonVt9OtD%nIbYxfFMQY={W(MmG4u(4;CwaO z-yO!8>lfe1?a^HF2VSbwh!tE> z(zfVW?uS8QGksK}i4RYsj0j*0=d~rSRh7x&t&D2xIW5u z4bzY&+LH33;$Sj$$z&rabh*rOq4F|b(EYbYG%sqDJN@ZaB2u?~8Yg(lDKDY))ZmqV zA?TJ6fD-fo4CU+X5IB*1JfQe3UBKJ0InNpU2IG^2?7RBG)m3Qj+b`a5?CW5FuLNyB zL+Q*cAj6*@&oaqL^OD$g0k4B2p0gOP!0c|wU$B6)(kWH=3%-lUl@_-XY3m@T<$YCB z^a9B%n1Pna=n9nZ{Padz^20+mnXqOByXpbQSReGzqUSKzdtwX^bC}p=!y;suWVcPs z%VZ}mxo%b4(6r~>X?QuEx-z_Aq>~L);1GYB+$Jk=Iq(C*B+j5Qt=;!X|K>>ELYYgI zN?7If*jMj!1N}mZf7Bpd`TT7+TeCTE4QuiHP^e%c*f&Cs5-KZsb1C;OhaDYSwRfAh zz-o`n$Nw zj2QH~Z8Bw@BNeGhW{qBOKVThXuy~?aM5U|b=a*s-9UW5r`8Lm(JN+73i!hUwn5{C6 z@(V>BpDLbDTZ>Ly4sq)3axsvjw$Rx>FI%CzD`cT{Jg2wO%tFCD&UTD9dag)UzijA1 zG%PoaxzM4Lv@Y1;-y(6}*v?8}!!60P_;ub%|Av5nQo1b`Dz{i=Rj+n7&so4lE0p6C zuF0-?Q087H)lLoU<+;3Uq>!k1{VLR(IPg$@MVv$dP#bDu0arh9>7kdM zAzSM=h^q*@ax8pD(@!AP5Zc}1t3j65Zu30a93Co$b>bSM@+w^H2(x35m+C%s*$Zy5 zC;Ae*vHQ8RFw}p#UnEN7R94R^YtPC$;E`d%EDP$b9$EpFJvdC_ou3CmTo(VIxNO&B z+DN9OV{8lvk5ztqP;pK*ycMnvfq``@S48b0%t=biC*!F-!V~7a8J3^gUeO|pijhO) zlEi`Uzw>m^EUZ%lPXx$wGH+e!ikJt^A;+X^w>Fq=s3(%0lJhZ6k!QUPq_JLt?=bX{ zYAM!o*d#7&!I-IzlcdB9M zKL!BMssTg}(l|_H$F$i(&v>By|*0q_}#Th37hbV%|BY(j& z3nU*YY78OPik6L|35O~dzb2dwP5%r^_m8d3emj+)cQf0|X<>?&g=Bws493by#N-_^ zxeh1SBm7qHeYMkTKn`iYpCO)ex`*X(y{xXTuAvfj(H;`R2Q=BY?ZvG{p%k3+FwVm# zF{QQ;CLDQ!JP-+ENdvYmV_VpJSbjC4;cm=I&@slx{ycfo66xKH;8sDui0#ipx^3JC z`TIYxCko2V&}}z==1wY?PfV2p53!Ok+bIoqIdgv37S`eus{-|zg$oVU;o5Vh2PIV8 za2j1>W3IN6{T6VIum#;O3QQI9iKUO@84|bQw8yrGZ?7MAD834b)fkvRJdjxuinWkC z`MV@zlFM(;iCd4Vs;Y+1b^`^DGQ^dO${&ElaJE(vw6`ABe-HSms51zzuKo8zu6i^2&meR5^ z&+O((m*I6^P;V=Ium%u;Lt+m>1zGYT0I1l+SO5yeXK7LEl^<}>D113>r=&z`r&tQm ziI8l7*{jL>iSm4f*974pSasJvpBG^^$Z26?fKY$FZfM)vco7Vfn%h0tp8xaogmj{` zn|OD21MkHKw^F?1Ka|AswdP$*;1Z7lae>PA*&~!NXg?&jM#zUlF=gVg^N7J4_i)<1 zTL=J9xXyjgH^}`WOzsB=$ca2ts^~6uc4LY!owmK%^5YiS{c^oj!i^$9DDBm&2&6Nn z^gv>F$C5u)w4w+@7sB)z5MGGC%fWP?JV%_K$Y?PCOm;*c)BDt<4>-{qWs0%S{L{uI zpUM(m#m+LYXF?zlbI%KH3iY5Cx_(cO_c5;10dz(R2WrHc6MdWYv&1IAP!95_# zI;dWG@W6pXao9xCZ20rFY*8pAB*sAH;>Gu9MhH1cqA_6f@V%D{(B1&H>9jd0U*>{a z{vjo`(!5G7Bct)^p|i352zYwy8uwWZTD&G~U^~(PuFes!PcEuN259y?o2vVzkJv7M zsvKVeR_n%%0&IQ5X@gHv^&58csCt>}!iR|uTwG!u=A9#uzb$n`H^thHhcvP%*RJu! za$`zM`^t#6R5fd&ha5A$7`FC5WpUqg7mXUrp2P8l55n|;~S=mL%4 z(f9{q!e(;UCBLVL8awE!QK%^xU5C4OuORf~`sXq;RO&gYR#bb<;n=+Z9?N%Xbbv3M zfJXZ&@miZ+d(%2=Ekq$N2@J1Mr;{jDp!*eu17ZCD7WHY`Upcoa#a6=K=#`uyLj81V zYATz##6aH1mbR};5w!2T+hvvJh8LqbbCCf_h`0g=76gwGW{tlYhp{v6Y$)+-z_`C)2taHcch@oi_Z|p$4GSBleIhdeWKI5-jGV)=1fuOV`m7 z|00-*916B}xYlRZ$&Eq2r2$l@17o6??xV`zS@Zms-{_$@myHZtwACF;ZD1idGk8pM zki1+^61K!&al2c61Gvsc8~|S4qpzk3hI{HgQVTAYU|~>j807C_g*@hiEa4*$=TVpH z%Dog_G8+AMHN}%oy{z^tTPt2OeZdKMn?C}|s=Op(c5xyG$pN$DN0`Cq6P{PvTzAQK z$orhwJ)j{SN||fsdy@CrL8BY#}0J3Nuv- zU#=ZM!m_w`n1I08m^}UC#QYw$Q^eA$4!5ITP(S|ua`~u1-vK=WU>FER=e4kF2ETD_ z)5qBMfB*g+K#73ap$L!`)Wq=UvjI%E!o2ZdoVBg(xdJSB2P0%JxoIUm*f^e;TsEWQ z>FJ3^GXUlm$FI;mKJK>OmzJyritFH{ek?e9n2qgbh4XEA?0hZVJ^UPhmMW_^Y3lI$ z`ugRj(}YiH`%d+p6$STZWsJRfBSewNY`f|^fpCnk-eBiAvck3 z{xHI9g`|KE?zNMVmbTvck=MiLk#4d~Ff)fN8Y@p!)YB9Q86Of75}bk}!+ zg`o;Cz}ECoUZ6ClG^S%SgJuYajA6ff48#Yt{aN2!4O_&@qbKV z5;KFx8aeDs?1sBpKhZoRaUI^YSzB8>Rlb!d{V-IpUc)IF_@I0&43aw4`xU9_|JoJ1 z>OUx$2CCG;!WICM9veXLbO7)ttKpgV5voVl7aKOgGsxwH>F$A7CPCs9&&bt`jDA=`GLZG#8`oHMnT?Zb7^%kiQX@N^Wx@AdH+zEIzI0IbUSOW4^J z`T{s{Sz9A`n#(WUghVj&ge(eoWv~|AD`!?xQ@XQgV=i?jD{X7ErSe@U607L#l${LZ zq0s+?Y&!k%Y{-boU^_0ATZx9?*7-4pw+_fk(j%v;QZ2)*P z8zv$ZwTuSIyFjib3?i1FFuFuM?ZEh1Ze6_V6|IV@e;Oh?$vj)FoTZQLN@%kK80jV6 z>BSnE{Z!4b`35!L<@5;zW65P#`1r|ZolLmiL<3et%>@^@)AnQ3+aLKz`k+kUb1=&p zf1f2@*fcP-b0&nqrFvg``({dQu4zSOt`KL~z>HNcyJ%l{u}BZ71AKc`@-e32TnyGh zMqV@zqtAJCTJ)8g*YCmJJJPks@{PIYzJD!QKmT~OU-I2?2y^`S@i5CdgyR6<5g;b0 zPMQIWCdSWRgnyb{XYP3sU++aiH)*?-G zVqtbWE^wbfM#c+8Bf@5xNyySl;PRQQ@-0wpNHPCVc>qx(^(e3X5FxRl#8XOuXmOP& zv@X67id#L$Vo6+&#MGYk$8;O)*>*fLfylp8pcJn>b(S>CMV-{mI^rbkmhOCHy231u z)cefuHSO(D%eAQoe2p(+wc=-xyg-^Ro4VT=)=VA2GaP-JE^cmu0Buxz-I>pG_Uu_; zFR4>m9UVHsv^F^tplUN@;8qvr=X(Qpq(q^yLvmNYT19}Gg5~Y%LtSMYq?~f&rAC*b z@_amg+(vBHiwZ1svz3#UH;WMtWpoTGXJzRv%bPQx9hwnFS>Az)qYE$C@r)YRZ~z%0 zkLgPy;IYbh#+o?E1Zk-qU?=Y~)Z5dOJ^t(mkesPXqagr}*2mMqD~C4T5@*f0{9eL| zg#1%bOpQ1+YSg<_N7sI%`h{v)O!U|w{a8}<0u>#h8`u3tcD`DoS4R)3eYIly(B`B8 zXO*DwvSTTMiA`${F^>mC^TTvs6}c-HO6_67WMY^Fwaj!nxif<%a9=l#nV6ilpCxuH z=$0Pnb8k;9{rOp$j^MpH6sAuIbNq*?h_m^A^RmSm1k1|D!~*~Ze{viI&C2GTHGa2f zuT4StGq(3Y0KVuMyH zc)ovR#A4p>8is?QkMQRJMUhSblmqP#SfA+vY%L=Bn;e)Lc>G7+Npw*V3w!6=I(CpD zTt4j2{HIo*shKFf^GOJHz9lxYPBXpD;I?^}+{Sr|QD;H=2RHt!t+ zi9d7}rbn-4mX`W&gM6Z_eCiy6g>$#)0_roMY~<+X=H}`uFAKg~18OAJyzjr&`u|0> z{kQi1JrhA$n=CuEnf|~<4RQ4Pw=VbbZ`nA@iJX1ARlGSJ_%MElSM|!#>6WB)oO{o1 zCGe4VF6I@}RYQ^L+1+bE#q203gzO$YLUQ~+jzEp)&n=M${-5`lsi^+B_I;i=q|E5} zFux55hUXt#ISM8z=p}K|w&tv!M(wtaS`e*0M&gc|nrh(B zx}||s%OJOssoJKb1w+K_dNbgmN|K7h4o`L$oP~NJcRM>fe}8|+-3A90OrTpF+S=N! zt*xS>qJ@Qp8fJEVL?l*HHhDGZO$|m9&j6F^>v;sjwG!8K!ix-`4_jkdWg1-L=HTEA z!mJgM&j`R36^V(9i;Ia_)CYK<-0d~8zIRzT~_1qsUO5;l%tSW!L#aES7&QgeNtXwz5zVli~yvJ zU^Zk4MdV+)ZhP}o({l-x{QHKQyHr2kq-|9K+8a(6fKYcGMS zhp3mp;`yNixS_h4SHD zdflVH^g6KtSsSj=yWX+o)5gI?&7qh&5~I&WreL9&rw5m!h(t^#@2C{DoPWy15?^I^B{_ZBYbBO0Hk@4Kqf*JGYuQ+Y z|2+|DR-)=r0p9gku>M17i_Fo0+ZhheS;EuVnZHeYn7p%?kpH8~eUpSl0GxvL z+E7xDunDv4mDm`3PAug%kkB?j=nnHC;XLHs{}qBs>OD|tc|^Y2*{R}d?8p2IzlKK) zM3>Gyxdx(G?i!K_0qo~)pF1iO`I20=VmmgyA3#($he6Qw+_D>v#GY`zCAYiRcL3-{ zlyQ2T<%$BttZW~Bxl08F?00`i%J|PafVa7Z7J*r*Pz!;)s8b}8$Y0yG0-Gk03dThW zvoOrQk_ACF$SfgyYTbk<-0lptayb?T$%+&eMlULtLTfiU=_j(*zWW4DD+qQ7KbwjF z6`@!Xh7@s+z0<3O3;GJMHOrVPE40j{|DBt?itj*is(dsXv%04b6xGsHYd{$O{{2U` zBfFC>X#f2AF$q0n%oC10Ij<5PA8c855BHY$vTW5x_CQSz+wtkQu)d`=0^!hq2TCAB zxhDE#NymxV$^CYE7ye#Qz551`TlsNFOhlumv{YJ6t@GdRcXmF2Qb$%P$rIkm^;+A% z;kyOFo3A;qE5HO{8Q=HNjwpfyf$s@`?(L4pT?A6o_upssh4-*r$@i2mg(#?3aDOdU zvcLn0A#DQlMj5Jb9{IU@ZRU_gosWyZzgbatO5SxiOV$w#5{UukZr3p~F@4F$5Jb`= zK@I-2lRjJ}+bS8fq@=&EX+&tj!Lc%e(xoN%2D4wk4&m6DWw;CRwSG{#b^CUDbaH+^ z+?Bwj$Mu2Hm^@ay673f9>$hf9mFv#0ZM7iyTS_N3WWgYQbM)eJ?)CQOT!E#)jdf?C zjNj3@@h*Nl*m2$)MQa1gTPl)RRpYYYx4cV_?8?ma39!Q5p}Jy_v5GJhJU1uDqsBtj z%AXqqqn&92lWQABfT*C$SW8mtRIQwxUK@921Z39 zxz$#BdW82^%`*kJbT6YlnH!EbG7OJ(2R$gZIy2Stg^BK*yUURb^~BIf^*jaZ2<_5*ASk59PU}e4_4<9 zGV2dxq&Xi`W6>d#&HF8YGh|Kxt#W!0Q5j&AYUIBr{nHg?={=?%?c6K)WH9`I)6DZt9XW+MgExFZi zZJU>kGa^UE?JLJ{RzcgoLqFaiU3mf(GdkUP0(skkKJLsfE}*xjO!Nue)EhlLJz(pC zggo-NFwiWRZ%w~<7G`pC5+J_60O8(x*(M+`5by)rMeL+g3?XKbUBVysiIGIX%;KW4 z@E&M?-YIB(e8wK{v-@7bl1h#F>v*FdIAjC0Lvod}6KoR*%thU$;Naj43P=mFDtu3n ziz78<`T6++Hbxfk1r5Oe00pz(80kbrq#d9}82Q8i%m7UGMZ&v|q#R`ar%zWg9GR7+ zn66`qP_J8<34X;l#P0TJS{@fPBE7MG`=9{7D!IVvj?-e4r%XLX=|%X0uiMBazsZKH zWcA+v)82PRHMMnX+dUTSqJY3bMM$Jb6%c|-4+tbA6lqEo1e7L9wW3l55;PP+U=uph z1q5t>1O*LEnpg-WC`wfj?{C3;+}M{|ZCkgHw@=1A{pWV! zt8y8X4>5=tDsoO|QUHVr&!tHB%N6gM>J1kjRT;Ej&D0iX7H z_rSmapd1$hyu3&QDnP0jS-0}09`E^{!Z)#O@-c+i+uO^oVQR`@O$9Zx9TgA_OI^^w+ee)GR z^VzmpC&wHi;b_`>TazrO`ciTVttcLDZX1vlhcS&ryqvQtnx4XVE@Gbz_Z=CEdeRYd z^LVRtoQ%;8B7=k#?jFHm*3$PhndK0J6{1Z!pH5kcUAntI_AY! znl|HyY5K!7ZKpTy7?Z5wXA-X){c$zY0iAD{=XE1eq!XqiKsJBxZ>znQ@jfT8mWVkb zCrf%uR@K(kdaE!jW~ViN{~>EquOy#g#|V|iww32U{Ggmc5WXOcKhkD(TiVm(_%oBX za_Qh&Zn67#JgwoS-%n@NTmI6{TGXT-`SIs^4#ozSj7`Q;Dubay(U?OFp=FI>S{M}W zoGMd@X}B=}3|36`dW&3;3zaRJE3loBRR- z#@!kHcAlO^52N+=O@$@gJ7;scu*yoRp(8vZ0y{yPjl(0+4QWGWK0ZFuG`)Q>goY{` zbLaE6aEnwuaRau&T&DrgCbQGOWOVJ1-|m800@xyAL95QOs`2l$Wo)Lbj5Jv`np*r(v|kcE*! zoq`hpYo_M&$-DgV8WrS-#g9w*^{JV44?=A;8k^#8D(I{^_ZBi2&_#x(KXvZm(|*f* zE{boVSFI_ISq9Q!#-OSr6^T9n1q zn>nI7w7(^jzu~FSN@E>Nyud7z-(WiXyzM|D(9XWMHnMA6SC58vjm#X3XgJ?-M$k`x z=5AC0DSgmiYOij&Yyal?gbeSC(ECBP9n4j!+;U&r6rZ1a8q9U+iVG_1JbGUuVnRN* z@rb6D*6P)(4=E{y(XMK?OF17+z7uaZ9j5$tXeh&|-{lgFpU*S5Y^Z+Ip9nJ8DaV)_ ztMOaN(X{c9y?d9Nuf0f&O{d`hXxlh_A8fshvXpaSM=)n#3iiM7#zZ}$2a}93)UeLu zLj=72JsY1ugj8-s75Bp0KYpKCI0mw>D@ys{o(peia@!Fx=Z7P4%}86%sYvtN?R0{mzy2myUeM7Z*3X!=xgjU5C<0DJ5M)N_S81_S%RN?*Yn12 zD*N&qo9kkm%39Bw4OU8tvSb_$f#{ZBKY7#@%Cws^4QSDP2 zzsmTjD06Fk#b!n5D~#}^CM@g9U<8QGuhijI_@xS$Wk=qM>9IcXS(LTBK_uMqdO`w@ z9(<4Su5ER+LCCP8_4+71zkb&fwD2rS1(}-_18Nt(T!2bUpqH1Izw?x{v$ek&9a>bS ztMZOu(37cQ6dqO3M7GLKqX>z^DB{WQ?(UA)+ef}cbPZ@nc)7A2^zr=93V<&O*7Kjo zPpv;Gw@$7-`*$u=j*U8uPChV{pS;Z4mt3TzMmQ|t2Ep|X2d3eU<%;S0jZ@Nfy z<_gKAX4Qo{DURI1XGR9d4G?D=!>loFSzBvy6lrT_NItB-wX=YSTqNeTT)&}RntLLJ znW-mzn^_+1EKQ@xroV`#e4cW=J`^XyqhXs%a-4b378VchQULHdztI9eKc{WpDr#oC z)AhXWQeXr(1%AF55Nclj^=)@ei*eIdoXrhss)t0`c@KwKS`q#8w%wbzOKX;WXx@>T zLkv9kZTisNPaFHH1yb<=X@C@MAyNP_R-UV9qwUi{m3sq%hCY>dDqwiq}D8rl8 z5YmZTYJ*h_3LU5(D(bmYQ8tH+tFSBxO^{#ZIrQpY3A-|T?fUiW!@|Q|dmfB25nZxM zJGfCMa>0EovSkfvts$QO!sQgkJ#QZ$NYerbP<65%XEUO_{1Orp^blg(}k3kb)0e{;4x~Z zXgZG7CcKe+gj73WE$6UtE>tvwX8d!`4mZ1bA4dgUm3dqN*>3J248aSlR;_An78bP! z@UKXma1Ca4+iQrC_*5ogS&^p9b5IR4avVd(GEIH7v=o_8r>gK5*lk}tVv|LLRF+}3 zQ1OVDPU!I{@9B@Ly{{VJD0Ez~o^==zZ}|kdL_Dd6nNq$#??Q$7iTZB~j2AUpcMpXF z2Tts41!nBj@cLDTSz%u(9pNwTdA4SJ+O0`1Ox7e+RaMnp(V4_%TG&61&5GW7^Xdb8 zShcd~ga=xm?dFB39c>*K9Ncm;AZwh^!9G?wVfBKFA5zCc>Jhdp<4pUT&|M}c4uqo zY|y-`36-?mcdBgCgclXbp5$P*5 zmGQ#Mf$_3|?kvID8Q0p@202TFhgA85-{2Lcq)w(Cqzbds=~p|OzWM6ww@N@DW-P!p zcFo7U-O`J#*GjGRDz$uQB58qhFN7y@z+SLCPITcU%|$S??$8OYLgh#i9aCXMwk|GsKO((9;FSxwu?wSf3F8or1k-A7+bb&5 zv{nRS;m;MYj)5{yawXu0T@K;RxE6CO0PvdAI<8!|>v_gWngAKnW_epiRV|}3U&UwW zT&X*3gn2A;ftgDA@eKm5f)-#PkeEAC%`qIFqb&%aQ!{FyI^f9Mcu7 zeniX?W51O6RHn8*3<3;wd#~dC4T@{!u)yUlwvfNju#F|r+1Z~^Q zEHU0c){^jp68O*k;vbjZ@eQ4{4}q$*oU0*rrJ!RJj%3Ox)iP0L{Zv_4hpr($^{`yB ztiJ?;i+LsR9lLSxm58vffZ7&e-C!a_N9|l_Gx2Yus|TZq(}j^S>|Hulp~HP@Kfqh_ zcueG$_d>hTLYHtM6l$Dq`M~!g$_S6&V}V}@ClImQ5Ds?jM?Z*O=kg%IYP%+-6`h)3 zpTmKy@cc77PbXY9rO>~!-9Q86nq%kQ-*;NjKlJP#+$d1?n9yhV$3xkTjN2afjc(qk7|A#dS4AIydtnD0TtQQ9txOR!Lr zyp$B-3SJSGn^sq#u$2740dUYp{PT}xh*y|23ZNxNkzpzPo%NG!BseUPJMY7N(U&Wj1 zN2h_6#pE)4`IaQjO@6>U@LI-u8_UVYeO72a&vaN<8!)kxc(rby<66I7yOQ*hRpTqs zkx$_}=++vqmcH$;eqfZ47{4eEyT%v!eDOd7gN^~7LkKo2ndrN!(if7r)j}9qXNz1S zO$qbrfGkEUp9w0Dijs+sVhvGWPj6@Cp?H_Zdq&m}4=t7V=0elbzaNpcpQAh-e+UUJ zAT?b6iCAKD+OV3+JU(+vbln>hKM6$QMAH+NM%7%nM8c|_(Ma*_ini+j7j~5!*`7ZO zuzj6N^R3J*)ceKh8d3XeG#agQ=VQpv3Yricjt&kC62A8aMVR{qG0W0RcpU+6@P4-c zMGE)nsWT7*O6eHJeTq_pAqa>cXH?u!GGf3WR+;^Mh@F!ahVtPz_>t!t3AJtgo7Tmd2bxF!g-Z_|_OY!9kuljT;|MYmW{^4Kc z{;{fh!210Am5#AQ74~?3)w^R~qraZhu@5_0FuO-DVJl|&>T2#D z-TZRLERlZJrY} zlW#no&O_J{aM6u2qy3W0oq2lH9Xo$mvwO?W>2-SQIUy{M~U#69!t5<(10%HCHJ$0qgEYw!M~|De+ch^xtJPyJJ3^P-%4I#qMZ zEc-OdY1=XcO-ee9Arv?>$-sciel**2Rr!#&s`EIdhyc@cZv?5r1JN{cFnUdyQVYjrss^fG+yRg%t4TG5K$&QJH! zDz2==BJ^OkX~jJavQ^W`HTdC~)|5EgU82qpBp2th@RFRqa!PcrN8Z-#6%F^d1)NCp zw8$nb_2Wx5Zklphr#~a(EPzvel~L33YEtp)IYJY-@sP=mSGbBOdP(zQk;-zfo3B_1 z^^2f$8%=FRVTwBl#cp}9B+O&y>y3MKoxsBqW`j_ONgJ?-x`ct&@Q0@hp2vHGt`Q@{ z;AO^5NTf&G%!pG#B@Cy}XAEo{^n4~wLmbELTD48~OgOY+oyYBxiCN3S;||qF@G|4l+8McYSol1`#9oyglY zV0~B1nq8MlY4SAf8doMH#Rb}^3?Aw0FjM<$SajeoOwH2O6-+L-A-nx|BltcI46AKK z@IK)Hjhl7m+{^i`nD8{D5HodkBNUB$J&6wYj7#|*#}hVgzL|9|NCKJI1&9!o?rxLX zbS2PrXl=-%*aeM%EBmjt5yEEwmL8lhf3MaY6L4`2{g1i>hrjTv*HLZbmpK1#Y99ah z-QbH^e8_)KahZGvsu!oFV1R&^2MtaAE#Cg)mnDC#U3k#u7FP?1>qXVVe|!P3fTmAZ z3z_{=SsniSRnEP*hOt*l1SJ*x7w10VF8_T(GM6JXmP+{FqN)pjJGNMr4}wONb^8Uc zc^?DNN7E2*PZbtL3K^20am=0xez(NMSA5np$0+GxYYAREcMLKCR2fmWoTx(WH&8bl z&`4L#MJ`Ynm zUF73m+ECFl4Z}xI$;T%qB}pnoL1SgeAhJ1t)VrNL`QD^vcDo1{dJzNiS<3#TX zua!t>hHsdl|JO@wHBdLLs(gWv>sVyg*6bC*shtkkuGMT~MOD=xAaDXZ)4r$^0B(JH z%kU(``ohr`S?-}ygcf+;?Lft4rUpqxv(4{?oiy4oSa^T$q{+oM6(cx>1$ZAvgkmeq zHFaPw1Ry=_J*R3|abtIke$x6~Q*q6M(0xh}x72GAN#?c5thC=|f|?M?LZWZRVkAzFxyN9^R&_CW#hsqBrH+ zMlM=w08^&FO`CxBM?!|z0M@l&TOnGH`w>z~*DLgtCSrszu(TyxZKalyyKFFS7z>nO zbkY0fYw=dUFij8U$Cz^=XtxxpBlTFWg5oJ@h76~Qm)y_&F(r^H5pxL#6InKbta%g3 zy^R*Wq(alzPWqJyyjukcUx43ZIqa^>IT5MT)u7Xho~SFsN1Aht!<}#TnO!zOU(u0D zu=#x@A6>`SjybIZb=#c7+@$+doMT$09H@xW6e&tZulIJLuB_eCj2dJYMg7F^`%=-7 zk>QtJTr2(R0H+mHwzggOI;Wt*Pl9reJY#;0AF8ac%NfwrtFIgTi*M2NA zSgv>}RTUR+lP*C|%OuSWrAC5(2WDqEhbVS<$`lSWGt4O}G=a)Y+VQ)g+ZJajA2p-+ z_H}fcc8gGnR^=Yox_6pYcX`!VQJ^PbGOR%?J$+4d=o~J+~Xq4d(funv| zt62!zB!Pi<`4%4^KQnVd4f9zYJdcKs=!iv&`#{16rJxmx--gTvKs#5T`^u;esOU>ff0$D{bR9Y zQG5A#@rls`a&q1hR^WGifLVUn^6Sry*1jWklGQUeGbwSLD`!s^4shfy!H- zr;n1h$nholKK$}G81#P357KiKG}%7=`0e5OS<{!(QO*yS$G&vXz@&28wTO_<+Rtij zB}v>4Ehm&)Y{*`5u_AfQpO_<^HuK%C%GCZj{iXri*z9yb8f5xw(^#!XVa5P~V<}q) zC1n5~Vju8G+c!0fzql}xmc4dKiGkW|TF9*d+tX89gp&5{%hXx~rfK~5L8vvd=4`add-e6}S%BF*Jtw|@S8(H0Xc6IDBFd^TW`K|dS24_>Nhw!XSNI5CVo@YUefPZx zIR%9qd>lZO!(#y0!)!nJO6~L$6rvjJK9r{()7KB-@1!JO8&St-X=y=liTUy4`1@{4 zL^CKmRD-_N_VxLWeJgXQS=d@$^U|fty6XG%m*QMC)amSnOX`!JmW?y1!OwK|b}xKw z$WNglQ&H)3`bPo-{0fk)6V_A1Vj^#2Ro*?~Xm?pY&9cfu@0fq>#s_erf09wf9>Fx0y<`Blvw&{oX)@puYD0~znvFSpVWMWF z$I9xVcmEp1-#*xVo8_NCw>V{bn&4*ES~rzJv3^r_dY{ap7@D}zLdcdUyd?Zs0~4KH z7Xh*W?;6;2Jmb7~lVJGs^Ya(lLOsr$$-kFc3QorKd0%iz$(E+9NsL^PK&(!>^RRGgIr0?}J=OKHI><>p<&l=a*WKxoOd9h!z1k;c`XA-=) z3-??wee2gr+`YV717Fi_wHoCR4g5sG|NX#S-|L%9@alY58KBLaMH2Ks zF@3BP&RdpFKAaj5aXVMd2k8T5Vl-y#9t)+v$78ngCz{V%x88nBsM{&0On%uWTiRf) z8e_D{$;+4=hfy6`9bm6ivgd+A+9NE+zD3Qt;$uVL_A@UY#xxIZO!76GFZ=u`fZ(SB zK46|Nvp~AR^vOuaGA0uwgCP%ExN=I;){+f|Cun2&-;Z~lXiZsFt+cw+?ah6mv$w=i zqa&}foB~u=)9^&m_=E)6tMuJ@ZN0s@XD~BrH0M+6J>{%GDZ0tjsOl$S<)C*J6yCgk zeNQ#PsB8CBfw!A$Jd^=J=)zaotNq?&ffO+(9I8vEltn1Jdkj=iv;pmclo$9q7x783 zjtmP9)ey6KG8x=T5c}|z)cO6jt>kBIfwxi0pI*d;5V_^vdcPbbc9{f%|F5qgLmC*a z6Ya#q?@_%FmMjA1`t|FH#vi{K4DQYg{z`K0<)xqI5mv__E!AOV!Pl=(IeKJCWz@+N zrpzWBmgTJe_a+>eg`%u76EZ^iWb?d2k}H`aea?i%hs?mr3ervb4{p$Ze2{JG>%xU{ z>aObi$OXY1o%GoUl1awMv>fC=|8?ue-ftUaZa)cN-dUA-6(4*r%iC-Hc9LY*e%8)C zChKBt!;X-j;#JJ>CE>W)Rx{y%j4Ve9e{T@v)Np{Cv|S)C^|;gHmsw=iK+PM>>P7 zp4aLp*6za!BW44SOl+0uFP`Q+AhNSdd2M~j4f^vjj|=Rv_Um7+Fx`k({86%eTHKBG z#P7_4zPX~o_ZvbCSQ>ghG|+~DC0J^7L!I<|XK#qAby^{3wf}OyP}Tp3Zy1)d-s@@; z0O(+!Z5z4B5zKAWLcJ$nPR(}7fIvQ%=h1vu1sfppcF63mR_xOPOI@#~JN2T?%^44f z@^W%K*(O4QYUL(O#=(L|ut>8h}1c1;iUsPC3iRHWe%l*04_YU?h)l|xx=Fc?S` zJb4*qjS7RRM6O8%(nGx|kb!*oHfvu2wu6fIu-+2(D3)PTbtxbG1wM+3DawD?d3Z40 zN@VZLLR2~kPVfgk+se@h!NX&Ar=g(%Jn-`v-bIyc+C~|MPxP2kv~6?VWDaqU+F_s> zwI0c)gOZX}S!sU3R#!Jvr4Y6ev*=>Bx63OjVYMX9Ft(@nai|D?6&&g#%h4cF*E%fV zpiF{8ZIO5j17Oh&_Sg5}$IEjLqF}T?sythkTevwphvZ?GwBiPFGo8Vc4P}8pLWN!~ zOs)32U(yw6uwe>Zv*8Q~s{;^UH$Z`0gE%$b*+Q0VMab5%LH&6j( z(3DfZ8QEzqPAJ68F+Mr&zC{}ct`o&$sIcW1YVq73z-Ri>(PiRSTo1@4^mi1=S^Q*Z zWGBr7)|FK*)0n|xu`Gb>%#x<9|7{li1HI``M+$~c%g3`;Eyf8r1O~pX=>a>y@HQUs zkKaV}V~<5{K-p7DiP4M37^Ie(MrqK=O%!6zuir>~V;oZ*FmaNE7<$+hbwWly7K7T^ z+4&2UnR|C-qXde{jI+L}It=)}U4$C0yxvZcNMTC_eto<;Yop?!Lw;cSdMPEobRes? zD6+SM7!pCkczv*zaJP)x?M609Z}nx0Z3;4;8Mg~LR3fHCzo08Op`X!h~YTKo>e z)K2mjsh9>kKzFhel9DSHG@PpuIqpRT-JLYf~f^IBVfvO5x{ZhB>CjMe3@T$cz1}NuRpWA9c`>WTWb{*cF3A@~NX#Wu zmA9fL@a}ZHZumutEzL6oZrZ~iP37BUSrEOpJ|D=!BaaBDa({9b_nPk`Jo9g@u)sJo64*l{(W8fX?{1v^3`( zwmZ7HN%Wwg!|Vi#e!vXWr#(Tbrs5t*3_6RkmV+^ub z<=O-eE>S{&fph^ja=75Rn3{^;h-bvjBpES&&K^N)AC& zxk`W8z@g>XgSd~EhAlBT@)|--;*%bfM}5fUtN9L4&043QMRe;QtsespuAjpYipDbQ zf814>KmMFP^I_PQPoQS7Y}J+#WqIYm=D(>rASx-+3=Vq4H+8(4sDJDjpy7A;sEw@q z_$3+Zc$-CPv1)OV2JNBbVE?%9X>Qb#b}c2JQ4342N9q_A2%y=Le3#+@F@?7qA%?-j zjccsuNkW-^Mb;9-AF^o%S${a;N{uBqk2~2!`?ekz#FW}nJC{Oi3Pg#hPNQ;fInv6( zcR6b=kiA%Oz>pmUxv~h@bCyaD5o-+uj1DJg(;8W5r=i|aSTv>ekrynFyTh>BAI_zV zhTo)s+#B}d{e|6dz?tmcrMmPM`28n(8M*-1X-U(-c7%g>*RFmS4y3}N<)KRqwI-Eo z!v^^PJy^mW8-X$2DIKNV8fXHQ{S61fTr{Qs19>4a05pR|sRR-#!@>q*kurT|ZB)SHXy0ee~=J9Z4Hrc(Ru!E*O3LIV(FKoZy(;upf*rcbYKk0<_o z8&iqQnA*={S=nFaAZ2ae!O|UwSgBu2N5?l>v;V-S&LUs{HzghdSSm!txE5S*lbrX0 z9q=kgEB4DHE|6gY+QrRHA0ZOrGf^JT4M|-degZ@=I-H;43mPYfu#rG33OJwv)My_%T@|f*u81^K5fvnGxpSsCkHRde>e!TGnprf%I$kKH=6nJrV zv+o*Xv!g+u@+wE6hDw2R3NWEW?K6msji8N9JAiD1CIUA15l$C`RWypveJa^R08V~F zzo>l zXx9S)>iD`J=U&=5I7%1Uv#kk7O|RfFII}oZUAZ5NS3G#IOrHV~0@yRqbTXwp{QTtZ zG$Mvh+=qrHxiy>wr4?cb4D|K6iw_NsWRjdAmPIl*HC0XW*k`cyAhDYmrX2z<_SC>8 z5GsDt+B5JXSFT){t)5l9sbn%Ow20MY5&y<&Oe5M}zm~$`A~cpfOQ&SUZ$&QH9>btW zl0lPRHX+|+#|}58ugQ+Br|qeQ#3qMr9uWNkQ5M?^o&}pQP)@x~FKiyu0H9*5x8Z^~ z0}Ei~;J^TMHleV&dbRATh4;2Li)uMDSH8^a1v=~qGM5>fvFF`bC9FI`p9 z3q)Qme!`AYQS0rGTOa~!Yqr=C42sY=M@B>dxwnhzwLyH68mV za$;bYn~bbcMk&imx9(A9M>r}c4x#L|0|3qC&vg@F5fQN03qZH;-X$~3A%;dkICLIJ zghMHI8-QyAcyH~8v?tJiFd!T3h%9Z_lb!;k_T1hgM*}Png^9bFO!gKEQ71DiO!_RD zhcNc~HG$9xz5eHxC1d+pj7j^cS=J8$qdZY_-?tvse2_#3XLgn>FfWD)-P&6SJ1ryI z<}!7A+m$hfg9Hitf$=VjV}o_jx1~K@*WW}b&oR6pmUz5Qr|qpjF5jxPz7ry9(qY4( z2HJ~HrBPb_jwPXPzD+w4Juzg(*$DP^;OpZ6-1sPNK!YrjGjTieC;|b!_fM+b;GpBI zu8saGKc%GW)U0lve3!jeK&-;Mf^ z`<>Uc$ZGtgGy;bC?ZXI9joK`Z*~ZUJ$tbRj(sU#vwDBu}uT0X7AXY|gEhM*; zSD8eB0&g-__u|lu|Ie?Px7&icH}vc%>6kdPD`qUO4>z4KuCm8AQ?Gf(MmrWwqCBfe z7+JD1mIwB!L%1}>o!@19-ufKO#kXvACroQmmT!`7=IKbim86e~)GLZqVn0mU`<0c4 zqO@-q-b@2H>&{6?oi7-TX)D?q5PfX>$%$=lVV~smkFLQxDf??YGu2N`iQqoC>=f)w zcQhmL{`K4tqGr|h65I9o3osQ$9P@N|>!yxBgMDC<*w=;Y1`Az;#5uO0J@CB8c)yfvDsH{&kD` zQcGso!xSwHIHK$>38ES;a1t1Y+X3GFc#=<1LN6Pp+elzUk@786fh0G~w#%>Y8jtTE5lQ*L#1I!`coiPbnSvx*aXA z!x0TK;3yNYE!m`w!7L;iz*5-|gL^lf`_y(HCgdVOzB@wrB>q5`t&w*&RCDC>=Mp*& zdS^tZNqzUp<~+z`3@{NadTOezhetH)0>B}^U4@Ix>R%e{BJ9J# zemENKfBudRZG6ncVDliT=G~y0gR(i4we0X`&(WA9SM4PKk+Pbd%sK0z`>V~f=fC$G zT7%C2MR0D99>QQqO_n&$TV}&ZUv0kNgMFZul1{&Tr-bkhYCruY#Aq!u*eM zSU;%J4##2-q81bsaWRELh&2w0{~ zV5wM0#5A1!Wpu>=n6h9rr2#gX?=cc@XthI;*>9gb7<2!m?ED6#w)tQF18n*H7R)bG z?*#;Ra5yr0m|E;_^KUZ;2snZXS7$vzkE8PO$LKAPeS(&lIFB-MP&y9o`#ac_3ivpI z3$_k%3|d1QEZmcYl=g8s>~w;*v2*wt_^icrZUrdpv@B{DJ!@+-(q&CS-8 z=TJTlaD8GL(prWgGd^rU0LtT(ZJx!(zB07Uas=J;KJ(Srs=fKuswkFxtH z+yY8~xt_{>E%MbMdMS^?=*a@iJu$W&2)g-+0DKxzS*pL@e2k4`q z%DPrMXa|6^f^q;xe;0uPngaPJD6*f5vt(NWP0p=9vjM+m(-orC++6RDpr8>T>%`6f zH0b{+Uo;gs^#NjmOE*wG8sD_c_y@wjr>p?war8N}@KmHGgc#ed6?gY;gcgQQM|bcA zaxv_%>Lm89A{bwOrmq^_vbwrjfm)cE=>(RHFV@r*q1f4KXAvVA7jTNQv&FC>}>pn-^1g*%i8T`x$9#eG9d96s%{o^%H%Q0=$-_XwW5$X)c~zT79eD^?9r@pcyweo> zukwuqV_DEKDKE0DC`8q(xRXRuQEKYbz=JeBO)iLWTiOmONJl-^srrelZ!<}kbWEBd ztO1^btFbYrEKDUau2TB8`L=BTPi;vn81W01gVW<5fCnSW+AkB9I<)KpWKMZ{Jk+Bx zMLtgpnS*R7GPF+G3m4j~31w4zGVBNy>i{_Pk{kr3#^i2AfXE|_yfUqCYZrNaz%Tg| z5XhkCa;~+sx9`hJzbymaMcPyFY|?`vcSXpGMZl?>hqQdNZSO|=!#OPito1h>_4V}u zkiolBLwV(3V6%^6j1G$6C+gyeD3q6!Kr>FY%9oJn@p^ZpIimxZG)TfrQ53%elmTmV zlPjNs8q&`y$aq!^xJ~EB$o~a!1nFiVrXR2ZqfAl(9{jY=mU!>|j9~$zr8}NyUwdz_ z>zS6Go?RtkxkqE)508$@hY;HgxmxK)S;vP{Pp0CQ1&j%RZL#X#n#r^0?tjVT3BYGo zrifdvq!RbuhrBW8&ntj5h-m<{=SHuNA|PoHsqMVHfy~yT9M^I1fS7lCTxu+`y%mKr z$3vLfWHMRD{7>(dA0cqQz*!$lB_2QZ zf?ceYp%gW{e+M-rv+CK#wje}k*3`PvzX64uAmFg&rseEt=+^v3AS}I|d-k%)=OY0x z7gQ*kB&P68)&gUnlIp3u5IV~|#Mqe{OwTHhtCOD@ar9WbJG?0iFT+|rpPa8p2jpyAeQM63`=_03ab z;KoA8veYUBD1SF&WI7P_Wl6kXaFV1QPT$kQP_Kpb&QOUgeRAn5$Ygh&&ZvtN@N?1{ z{~FPM(y^UHDa;tlI}H`89*51;W+ODHowx9`ve;#7zk$CRwQm=6uBx+1N7G*(}CC|4k ziNK$ukQRI3uvPUJsSB2Y@}*wYNN}T4U-%JBlA_-%@MKJK3^c=WWGi~~b=ZG5a*ewK z#(qg|(XN>p5F(`MX4)l+$c^VmAioV}jh8V-P}ye^Tm{fkR*+n1iXfaFr~UrtveS^& zM;qs)e5k*FQc-R_c~w5{mOl}N?rzw1?K!i&(S?LS;xo}jhRksi0~R*OWZXHDR7bGJ zW0)D~xGvp?_@j`H;pXkx!xlUTvmN}hlyd_hx!c9##`q(}uXa9h*1J>O$G}bOnduBX zxC&8LlnH3Lv|4rSRlvdlPfU+UxYI3shTYDr<68BGN2XG$h!IjAB_|Z?c9P_BT4NAW z_fV=qBAIzT%XfenlF07XCVPjAnVxXLU+8=D_HtyZte(MMqcv8zq@bVSwl)B_s!@o7 zKb&76lec+*phXr52@tifPTOw%V|F%ViqlOw;s^v-)JF<#Oz^VeLQp7(brxok-V2%6 zQid4&{w&A!xq?xe7t(Lw^2i?d$MXXJ9DJ&1F9GVtrlSAhq#w#To7lLx11{N=|P|pOLSlCO$)XVOqm%Wm$hdunaMEZcV zw7Ap(aVaU1l&q4Rl#<+m{Ra*x9XP;B4-@zgH@Kd$b8@)wpKp*oxOhY2^x8tWVTq20 LzIxu#6PN!FTSWrj diff --git a/docs/images/adminOccupancyTypes.png b/docs/images/adminOccupancyTypes.png deleted file mode 100644 index 5fe5e67944199e4d60e54576cb3c51fe5f6388b2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 39413 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%0DbA9NdB4Zdri$v83L+M3&z%{H+;(nF8OnR|8V@o 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≧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 BTdM#7 diff --git a/docs/images/configTableSorting.png b/docs/images/configTableSorting.png deleted file mode 100644 index 1e80cbcdff4d5262592ee4d663226f59ff17ffce..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2534 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 diff --git a/docs/images/lotOccupancyEdit-moreOptions.png b/docs/images/lotOccupancyEdit-moreOptions.png deleted file mode 100644 index b1fb2b669a3a1f37d1ae20033be1f3b8756a5066..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8793 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 diff --git a/docs/images/lotOccupancySearch.png b/docs/images/lotOccupancySearch.png deleted file mode 100644 index 4b071d2d1134ac0025501f4cea464e8458bb2bdf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 80524 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 diff --git a/docs/images/lotView.png b/docs/images/lotView.png deleted file mode 100644 index 4319080e6ae9fbc258d92c64c0a760cc1296d204..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 49446 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 D+c*X7 diff --git a/docs/images/mapImageLotConfig.png b/docs/images/mapImageLotConfig.png deleted file mode 100644 index a2c9e02cc7e0bb80b4f020c7bda5bd36a09f2fee..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4725 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 S>0>SoQ1Niv=UU}_B>8VyqLC8- diff --git a/docs/images/workOrderEdit.png b/docs/images/workOrderEdit.png deleted file mode 100644 index 0d1eb77190e2e679009d14f00975f1522b139bea..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 53180 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 Vi2qfp5OzSFK6&;;-p_Ww{Rg98f+PR{ diff --git a/docs/images/workOrderMilestoneEdit.png b/docs/images/workOrderMilestoneEdit.png deleted file mode 100644 index bc875dbffcb98a96949214fd9d90378ebd616b3b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7994 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 diff --git a/docs/lotOccupancies.md b/docs/lotOccupancies.md deleted file mode 100644 index bc34bff9..00000000 --- a/docs/lotOccupancies.md +++ /dev/null @@ -1,60 +0,0 @@ -[Home](https://cityssm.github.io/lot-occupancy-system/) -• -[Help](https://cityssm.github.io/lot-occupancy-system/docs/) - -# Lot Occupancies - -![Lot Occupancy Edit](images/lotOccupancyEdit.png) - -Lot occupancies records track the people who occupy lots. -In the context of a cemetery management system, occupancy records can track the names of -preneed owners or those interred in burial sites. - -## Main Details - -Occupancy records include the following details. - -**Occupancy Type**
-Occupancy types are [completely customizable](adminOccupancyTypes.md), -and can be used to categorize the nature of the occupancy. - -**Lot**
-_"Burial Site" in the screenshot._
-The location where the occupancy is taking place. - -**Start Date**
-_"Interment Date" in the screenshot._
-The date when the lot is considered occupied. - -**End Date**
-The date when the lot is no longer considered occupied. - -**Additional Fields**
-Additional fields can be added to the occupancy record depending on the selected occupancy type. - -## Occupants - -Occupancy records can have any number of people associated with them. -In the context of a cemetery management system, -occupants may be preneed owners, funeral directors, or the deceased. -Each occupant can include an occupant type, name, address, phone number, and email address. - -## Comments - -Comments offer open logging that can track various details that arise throughout the occupancy. - -## Fees - -![Add Fee](images/lotOccupancyAddFee.png) - -Occupancies can have fees associated with them. The available fees depend on the set occupancy type -and the related lot type. - -## Transactions - -Transactions are used to pay down applied fees. - -## Related Links - -- [Occupancy Type Management](adminOccupancyTypes.md) -- [Fee Management](adminFees.md) diff --git a/docs/mapImages.md b/docs/mapImages.md deleted file mode 100644 index 2d57de47..00000000 --- a/docs/mapImages.md +++ /dev/null @@ -1,42 +0,0 @@ -[Home](https://cityssm.github.io/lot-occupancy-system/) -• -[Help](https://cityssm.github.io/lot-occupancy-system/docs/) - -# Map Images - -Map images rely on SVG (Scalable Vector Graphics) files. - -While many SVG editors exist, we recommend [Inkscape](https://inkscape.org/), -a free and open source vector graphics editor. - -## Structuring the SVG Files - -The SVG format has the ability to group together elements using a `` tag, -and to set an `id` attribute on `` and `` tags. -These two features are heavilty relied on by the Lot Occupancy System. - -![Screenshot of Map Image Structure](images/mapImageStructure.png) - -Take the screenshot above. - -- The map has two main sections, D and E. -- Within each section, there are groups 1, 2, and 3. -- Each group has a north side (N) and a south side (S). -- Each side has 3 or 6 lots. - -The `id` for the top leftmost lot is `E-1-N-1`. -The `id` for the bottom rightmost lot is `D-3-S-3`. - -![Lot Image Configuration](images/mapImageLotConfig.png) - -In order to link the lot record in the application to the lot path in the image, -the `id` attribute of the `` tag should match the Map SVG ID set on the lot record. - -Non-exact matching can also be done. If all lot paths in the SVG image are grouped, -and those groups have their `id` attributes set, the application will for the first matching -path or group, removing pieces from the end of the configured Map SVG ID. - -For example, if the application comes across a new lot with Map SVG ID `E-1-N-7`, -there is no exact match. The application will then look for `E-1-N`, -which will match a group of six lots. The six lots will be highlighted -until the map is revised with the new lot. diff --git a/docs/shortcuts.md b/docs/shortcuts.md deleted file mode 100644 index 4ae151eb..00000000 --- a/docs/shortcuts.md +++ /dev/null @@ -1,63 +0,0 @@ -[Home](https://cityssm.github.io/lot-occupancy-system/) -• -[Help](https://cityssm.github.io/lot-occupancy-system/docs/) - -# Keyboard Shortcuts - -Note that the key combinations needed to access the keyboard shortcuts -vary by browser and operating system. - -For example, the Mozilla Firefox web browser running on Windows uses Shift + Alt, -while most web browsers running on Mac machines use Control + Option. - -See [MDN's documentation on the accesskeys](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/accesskey) -for assistance identifying the combination for your web browser - operating system combination. - -## All Pages - -| Shortcut Key | Description | -| ------------ | ------------------------------------ | -| 0 | Go to main dashboard. | -| 1 | Go to Work Order search. | -| 2 | Go to Occupancy search. | -| 3 | Go to Lot search. | -| 4 | Go to Map search. | -| h | Open the Help website. | -| x | Log out of the Lot Occupancy System. | - -## Search Pages - -| Shortcut Key | Description | -| ------------ | --------------------------------- | -| n | Create a new record. | -| f | Focus on the first search filter. | - -## View Pages - -| Shortcut Key | Description | -| ------------------------------ | ----------------------------------------- | -| e | Switch to edit mode. | -| , (or <) | Move to previous record (when available). | -| . (or >) | Move to next record (when available). | - -## Edit Pages - -| Shortcut Key | Description | -| ------------ | ---------------------------------- | -| f | Focus on the first editable field. | -| v | Switch to view mode. | - -## Other Shortcuts - -### Quick Sorting - -![Configuration Tables](images/configTableSorting.png) - -Configuration tables with up and down arrow buttons can be reordered one position at a time -by clicking the arrow buttons. - -To send an item to the bottom of the list, -hold the Shift key when clicking the down arrow button. - -Similarly, to send an item to the top of the list, -hold the Shift key when clicking the up arrow button. diff --git a/docs/terminology.md b/docs/terminology.md deleted file mode 100644 index 3d2ee2d9..00000000 --- a/docs/terminology.md +++ /dev/null @@ -1,26 +0,0 @@ -[Home](https://cityssm.github.io/lot-occupancy-system/) -• -[Help](https://cityssm.github.io/lot-occupancy-system/docs/) - -# Terminology - -_Note that is is possible to substitute the default terminology using the application's config file._ - -| Term | Description | Cemetery System Alias Example | -| --------- | ---------------------------------------------- | ----------------------------- | -| Map | The highest level object, a group of lots. | Cemetery | -| Lot | The smallest occupiable piece of land. | Burial Site | -| Occupancy | A reservation on a lot for a specific purpose. | Occupancy | -| Occupant | A person associated with a lot occupancy. | Occupant | - -For example in the context of a cemetery system, John Doe has passed away and has been interred. - -- John Doe would be considered an **occupant**. -- An **occupancy** record would be created with **no end date** and associated with his **burial site (lot)** of choice. -- The **burial site (lot)** is associated with the **cemetery (map)** where John is buried. - -For example in the context of a marina, Jane Smith and her boat are renting a slip for a week. - -- Jane Smith, and possibly the others on her boat, would be considered **renters (occupants)**. -- A **reservation (occupancy)** record would be created for the duration of her stay, and associated with the **slip (lot)** of choice. -- The **slip (lot)** is associated with the **marina (map)** where the slip is located. diff --git a/docs/workOrders.md b/docs/workOrders.md deleted file mode 100644 index a727d222..00000000 --- a/docs/workOrders.md +++ /dev/null @@ -1,59 +0,0 @@ -[Home](https://cityssm.github.io/lot-occupancy-system/) -• -[Help](https://cityssm.github.io/lot-occupancy-system/docs/) - -# Work Orders - -![Work Order Edit](images/workOrderEdit.png) - -Work orders track tasks associated with lots and/or occupancies on lots. -There are several sections that make up each work order, -and can be used to track various details associated with the work. - -## Main Details - -Work orders include the following main details. - -**Work Order Number**
-Note that when creating a work order, if the work order number field is left blank, -a new work order number can be generated based on the format of your choice. - -**Work Order Type**
-The work order types are [completely customizable](adminConfigTables.md) -and can be used to categorize work orders. - -**Description**
-The work order description can describe the overall theme of the work order, -and include details that may not fit into other places on the work order. - -**Open Date**
-The starting date for the work order. - -**Close Date**
-The date the work order is considered complete. -Further updates to the work order are not permitted after the work order is closed. - -## Related Lots and Occupancies - -In order to track where the work is taking place and who is affected by the work, -work orders can be linked to lots (burial sites in the example above) -and occupancies. - -## Comments - -Comments offer open logging that can track various details that arise throughout the work order. - -## Milestones - -![Work Order Milestone Edit](images/workOrderMilestoneEdit.png) - -Work orders can be broken up into actionable items, called milestones. -Milestone types are completely customizable and can be used to categorize milestones. -The date, and optional time, track when the milestone is scheduled to be completed. - -Milestones appear on the main application dashboard, -and can be linked to calendar applications like Microsoft Outlook. - -## Related Links - -- [Config Table Management](adminConfigTables.md) diff --git a/eslint.config.d.ts b/eslint.config.d.ts index 54ee6e2d..6b517f8e 100644 --- a/eslint.config.d.ts +++ b/eslint.config.d.ts @@ -1,2 +1,2 @@ -export declare const config: import("@typescript-eslint/utils/dist/ts-eslint").FlatConfig.ConfigArray; +export declare const config: import("@typescript-eslint/utils/ts-eslint").FlatConfig.ConfigArray; export default config; diff --git a/eslint.config.js b/eslint.config.js index ed780fd8..b0e667fc 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -11,10 +11,11 @@ export const config = tseslint.config(...configWebApp, { 'warn', { cspell: { - words: [...cspellWords, 'ical', 'preneed', 'ntfy'] + words: [...cspellWords, 'autoincrement', 'ical', 'preneed', 'ntfy'] } } - ] + ], + '@typescript-eslint/no-unsafe-type-assertion': 'off', } }); export default config; diff --git a/eslint.config.ts b/eslint.config.ts index 284789c5..03645d8e 100644 --- a/eslint.config.ts +++ b/eslint.config.ts @@ -12,10 +12,11 @@ export const config = tseslint.config(...configWebApp, { 'warn', { cspell: { - words: [...cspellWords, 'ical', 'preneed', 'ntfy'] + words: [...cspellWords, 'autoincrement', 'ical', 'preneed', 'ntfy'] } } - ] + ], + '@typescript-eslint/no-unsafe-type-assertion': 'off', } }) diff --git a/handlers/admin-get/lotTypes.d.ts b/handlers/admin-get/burialSiteTypes.d.ts similarity index 100% rename from handlers/admin-get/lotTypes.d.ts rename to handlers/admin-get/burialSiteTypes.d.ts diff --git a/handlers/admin-get/lotTypes.js b/handlers/admin-get/burialSiteTypes.js similarity index 81% rename from handlers/admin-get/lotTypes.js rename to handlers/admin-get/burialSiteTypes.js index 5fd2443d..706f49f0 100644 --- a/handlers/admin-get/lotTypes.js +++ b/handlers/admin-get/burialSiteTypes.js @@ -1,5 +1,5 @@ import { getLotTypes } from '../../helpers/functions.cache.js'; -import { getConfigProperty } from '../../helpers/functions.config.js'; +import { getConfigProperty } from '../../helpers/config.helpers.js'; export default async function handler(_request, response) { const lotTypes = await getLotTypes(); response.render('admin-lotTypes', { diff --git a/handlers/admin-get/lotTypes.ts b/handlers/admin-get/burialSiteTypes.ts similarity index 84% rename from handlers/admin-get/lotTypes.ts rename to handlers/admin-get/burialSiteTypes.ts index afd91b2f..07ad006b 100644 --- a/handlers/admin-get/lotTypes.ts +++ b/handlers/admin-get/burialSiteTypes.ts @@ -1,7 +1,7 @@ import type { Request, Response } from 'express' import { getLotTypes } from '../../helpers/functions.cache.js' -import { getConfigProperty } from '../../helpers/functions.config.js' +import { getConfigProperty } from '../../helpers/config.helpers.js' export default async function handler( _request: Request, diff --git a/handlers/admin-get/ntfyStartup.js b/handlers/admin-get/ntfyStartup.js index 4381f40f..dadc634b 100644 --- a/handlers/admin-get/ntfyStartup.js +++ b/handlers/admin-get/ntfyStartup.js @@ -1,4 +1,4 @@ -import { getConfigProperty } from '../../helpers/functions.config.js'; +import { getConfigProperty } from '../../helpers/config.helpers.js'; export default function handler(_request, response) { if (getConfigProperty('application.ntfyStartup') === undefined) { response.redirect(`${getConfigProperty('reverseProxy.urlPrefix')}/dashboard/?error=ntfyNotConfigured`); diff --git a/handlers/admin-get/ntfyStartup.ts b/handlers/admin-get/ntfyStartup.ts index ced61ee8..2d3c1659 100644 --- a/handlers/admin-get/ntfyStartup.ts +++ b/handlers/admin-get/ntfyStartup.ts @@ -1,6 +1,6 @@ import type { Request, Response } from 'express' -import { getConfigProperty } from '../../helpers/functions.config.js' +import { getConfigProperty } from '../../helpers/config.helpers.js' export default function handler(_request: Request, response: Response): void { if (getConfigProperty('application.ntfyStartup') === undefined) { diff --git a/handlers/admin-get/occupancyTypes.js b/handlers/admin-get/occupancyTypes.js index 7d32b2d1..686813b1 100644 --- a/handlers/admin-get/occupancyTypes.js +++ b/handlers/admin-get/occupancyTypes.js @@ -1,5 +1,5 @@ import { getAllOccupancyTypeFields, getOccupancyTypes } from '../../helpers/functions.cache.js'; -import { getConfigProperty } from '../../helpers/functions.config.js'; +import { getConfigProperty } from '../../helpers/config.helpers.js'; import { getPrintConfig } from '../../helpers/functions.print.js'; export default async function handler(_request, response) { const occupancyTypes = await getOccupancyTypes(); diff --git a/handlers/admin-get/occupancyTypes.ts b/handlers/admin-get/occupancyTypes.ts index c24ec75b..b2c6a40f 100644 --- a/handlers/admin-get/occupancyTypes.ts +++ b/handlers/admin-get/occupancyTypes.ts @@ -4,7 +4,7 @@ import { getAllOccupancyTypeFields, getOccupancyTypes } from '../../helpers/functions.cache.js' -import { getConfigProperty } from '../../helpers/functions.config.js' +import { getConfigProperty } from '../../helpers/config.helpers.js' import { getPrintConfig } from '../../helpers/functions.print.js' export default async function handler( diff --git a/handlers/api-get/milestoneICS.js b/handlers/api-get/milestoneICS.js index 28c3b160..6644a6e3 100644 --- a/handlers/api-get/milestoneICS.js +++ b/handlers/api-get/milestoneICS.js @@ -1,7 +1,7 @@ /* eslint-disable unicorn/filename-case, @eslint-community/eslint-comments/disable-enable-pair */ import ical, { ICalEventStatus } from 'ical-generator'; import getWorkOrderMilestones from '../../database/getWorkOrderMilestones.js'; -import { getConfigProperty } from '../../helpers/functions.config.js'; +import { getConfigProperty } from '../../helpers/config.helpers.js'; import { getPrintConfig } from '../../helpers/functions.print.js'; const calendarCompany = 'cityssm.github.io'; const calendarProduct = getConfigProperty('application.applicationName'); diff --git a/handlers/api-get/milestoneICS.ts b/handlers/api-get/milestoneICS.ts index 9ab4d492..69ec8f2a 100644 --- a/handlers/api-get/milestoneICS.ts +++ b/handlers/api-get/milestoneICS.ts @@ -6,7 +6,7 @@ import ical, { type ICalEventData, ICalEventStatus } from 'ical-generator' import getWorkOrderMilestones, { type WorkOrderMilestoneFilters } from '../../database/getWorkOrderMilestones.js' -import { getConfigProperty } from '../../helpers/functions.config.js' +import { getConfigProperty } from '../../helpers/config.helpers.js' import { getPrintConfig } from '../../helpers/functions.print.js' import type { WorkOrderMilestone } from '../../types/recordTypes.js' diff --git a/handlers/lotOccupancies-get/edit.d.ts b/handlers/burialSites-get/edit.d.ts similarity index 100% rename from handlers/lotOccupancies-get/edit.d.ts rename to handlers/burialSites-get/edit.d.ts diff --git a/handlers/lots-get/edit.js b/handlers/burialSites-get/edit.js similarity index 91% rename from handlers/lots-get/edit.js rename to handlers/burialSites-get/edit.js index 4238823f..3c2b4949 100644 --- a/handlers/lots-get/edit.js +++ b/handlers/burialSites-get/edit.js @@ -1,7 +1,7 @@ import getLot from '../../database/getLot.js'; import getMaps from '../../database/getMaps.js'; import { getLotStatuses, getLotTypes } from '../../helpers/functions.cache.js'; -import { getConfigProperty } from '../../helpers/functions.config.js'; +import { getConfigProperty } from '../../helpers/config.helpers.js'; export default async function handler(request, response) { const lot = await getLot(request.params.lotId); if (lot === undefined) { diff --git a/handlers/lots-get/edit.ts b/handlers/burialSites-get/edit.ts similarity index 91% rename from handlers/lots-get/edit.ts rename to handlers/burialSites-get/edit.ts index 18ef8d5a..faedae2d 100644 --- a/handlers/lots-get/edit.ts +++ b/handlers/burialSites-get/edit.ts @@ -3,7 +3,7 @@ import type { Request, Response } from 'express' import getLot from '../../database/getLot.js' import getMaps from '../../database/getMaps.js' import { getLotStatuses, getLotTypes } from '../../helpers/functions.cache.js' -import { getConfigProperty } from '../../helpers/functions.config.js' +import { getConfigProperty } from '../../helpers/config.helpers.js' export default async function handler( request: Request, diff --git a/handlers/lotOccupancies-get/new.d.ts b/handlers/burialSites-get/new.d.ts similarity index 100% rename from handlers/lotOccupancies-get/new.d.ts rename to handlers/burialSites-get/new.d.ts diff --git a/handlers/lots-get/new.js b/handlers/burialSites-get/new.js similarity index 92% rename from handlers/lots-get/new.js rename to handlers/burialSites-get/new.js index 37ae6159..99c88404 100644 --- a/handlers/lots-get/new.js +++ b/handlers/burialSites-get/new.js @@ -1,6 +1,6 @@ import getMaps from '../../database/getMaps.js'; import { getLotStatuses, getLotTypes } from '../../helpers/functions.cache.js'; -import { getConfigProperty } from '../../helpers/functions.config.js'; +import { getConfigProperty } from '../../helpers/config.helpers.js'; export default async function handler(request, response) { const lot = { lotId: -1, diff --git a/handlers/lots-get/new.ts b/handlers/burialSites-get/new.ts similarity index 93% rename from handlers/lots-get/new.ts rename to handlers/burialSites-get/new.ts index c3f50a14..f9fbb7ac 100644 --- a/handlers/lots-get/new.ts +++ b/handlers/burialSites-get/new.ts @@ -2,7 +2,7 @@ import type { Request, Response } from 'express' import getMaps from '../../database/getMaps.js' import { getLotStatuses, getLotTypes } from '../../helpers/functions.cache.js' -import { getConfigProperty } from '../../helpers/functions.config.js' +import { getConfigProperty } from '../../helpers/config.helpers.js' import type { Lot } from '../../types/recordTypes.js' export default async function handler( diff --git a/handlers/lots-get/next.d.ts b/handlers/burialSites-get/next.d.ts similarity index 100% rename from handlers/lots-get/next.d.ts rename to handlers/burialSites-get/next.d.ts diff --git a/handlers/lots-get/next.js b/handlers/burialSites-get/next.js similarity index 87% rename from handlers/lots-get/next.js rename to handlers/burialSites-get/next.js index 821aec81..805d3774 100644 --- a/handlers/lots-get/next.js +++ b/handlers/burialSites-get/next.js @@ -1,4 +1,4 @@ -import { getConfigProperty } from '../../helpers/functions.config.js'; +import { getConfigProperty } from '../../helpers/config.helpers.js'; import { getNextLotId } from '../../helpers/functions.lots.js'; export default async function handler(request, response) { const lotId = Number.parseInt(request.params.lotId, 10); diff --git a/handlers/lots-get/next.ts b/handlers/burialSites-get/next.ts similarity index 89% rename from handlers/lots-get/next.ts rename to handlers/burialSites-get/next.ts index 555c8f25..56ec09c7 100644 --- a/handlers/lots-get/next.ts +++ b/handlers/burialSites-get/next.ts @@ -1,6 +1,6 @@ import type { Request, Response } from 'express' -import { getConfigProperty } from '../../helpers/functions.config.js' +import { getConfigProperty } from '../../helpers/config.helpers.js' import { getNextLotId } from '../../helpers/functions.lots.js' export default async function handler( diff --git a/handlers/lots-get/previous.d.ts b/handlers/burialSites-get/previous.d.ts similarity index 100% rename from handlers/lots-get/previous.d.ts rename to handlers/burialSites-get/previous.d.ts diff --git a/handlers/lots-get/previous.js b/handlers/burialSites-get/previous.js similarity index 88% rename from handlers/lots-get/previous.js rename to handlers/burialSites-get/previous.js index 01b95241..fa956542 100644 --- a/handlers/lots-get/previous.js +++ b/handlers/burialSites-get/previous.js @@ -1,4 +1,4 @@ -import { getConfigProperty } from '../../helpers/functions.config.js'; +import { getConfigProperty } from '../../helpers/config.helpers.js'; import { getPreviousLotId } from '../../helpers/functions.lots.js'; export default async function handler(request, response) { const lotId = Number.parseInt(request.params.lotId, 10); diff --git a/handlers/lots-get/previous.ts b/handlers/burialSites-get/previous.ts similarity index 90% rename from handlers/lots-get/previous.ts rename to handlers/burialSites-get/previous.ts index 79cd0f47..572e2aa1 100644 --- a/handlers/lots-get/previous.ts +++ b/handlers/burialSites-get/previous.ts @@ -1,6 +1,6 @@ import type { Request, Response } from 'express' -import { getConfigProperty } from '../../helpers/functions.config.js' +import { getConfigProperty } from '../../helpers/config.helpers.js' import { getPreviousLotId } from '../../helpers/functions.lots.js' export default async function handler( diff --git a/handlers/lotOccupancies-get/search.d.ts b/handlers/burialSites-get/search.d.ts similarity index 100% rename from handlers/lotOccupancies-get/search.d.ts rename to handlers/burialSites-get/search.d.ts diff --git a/handlers/lots-get/search.js b/handlers/burialSites-get/search.js similarity index 89% rename from handlers/lots-get/search.js rename to handlers/burialSites-get/search.js index 570ddfb7..f590ccc6 100644 --- a/handlers/lots-get/search.js +++ b/handlers/burialSites-get/search.js @@ -1,6 +1,6 @@ import getMaps from '../../database/getMaps.js'; import { getLotStatuses, getLotTypes } from '../../helpers/functions.cache.js'; -import { getConfigProperty } from '../../helpers/functions.config.js'; +import { getConfigProperty } from '../../helpers/config.helpers.js'; export default async function handler(request, response) { const maps = await getMaps(); const lotTypes = await getLotTypes(); diff --git a/handlers/lots-get/search.ts b/handlers/burialSites-get/search.ts similarity index 90% rename from handlers/lots-get/search.ts rename to handlers/burialSites-get/search.ts index 0695f7b0..5d023aed 100644 --- a/handlers/lots-get/search.ts +++ b/handlers/burialSites-get/search.ts @@ -2,7 +2,7 @@ import type { Request, Response } from 'express' import getMaps from '../../database/getMaps.js' import { getLotStatuses, getLotTypes } from '../../helpers/functions.cache.js' -import { getConfigProperty } from '../../helpers/functions.config.js' +import { getConfigProperty } from '../../helpers/config.helpers.js' export default async function handler( request: Request, diff --git a/handlers/lotOccupancies-get/view.d.ts b/handlers/burialSites-get/view.d.ts similarity index 100% rename from handlers/lotOccupancies-get/view.d.ts rename to handlers/burialSites-get/view.d.ts diff --git a/handlers/lots-get/view.js b/handlers/burialSites-get/view.js similarity index 89% rename from handlers/lots-get/view.js rename to handlers/burialSites-get/view.js index 9b3f2f3b..f11ecd5f 100644 --- a/handlers/lots-get/view.js +++ b/handlers/burialSites-get/view.js @@ -1,5 +1,5 @@ import getLot from '../../database/getLot.js'; -import { getConfigProperty } from '../../helpers/functions.config.js'; +import { getConfigProperty } from '../../helpers/config.helpers.js'; import { getNextLotId, getPreviousLotId } from '../../helpers/functions.lots.js'; export default async function handler(request, response) { const lot = await getLot(request.params.lotId); diff --git a/handlers/lots-get/view.ts b/handlers/burialSites-get/view.ts similarity index 90% rename from handlers/lots-get/view.ts rename to handlers/burialSites-get/view.ts index a5d9d197..b89517ca 100644 --- a/handlers/lots-get/view.ts +++ b/handlers/burialSites-get/view.ts @@ -1,7 +1,7 @@ import type { Request, Response } from 'express' import getLot from '../../database/getLot.js' -import { getConfigProperty } from '../../helpers/functions.config.js' +import { getConfigProperty } from '../../helpers/config.helpers.js' import { getNextLotId, getPreviousLotId } from '../../helpers/functions.lots.js' export default async function handler( diff --git a/handlers/lotOccupancies-post/doAddLotOccupancyComment.d.ts b/handlers/burialSites-post/doAddLotComment.d.ts similarity index 100% rename from handlers/lotOccupancies-post/doAddLotOccupancyComment.d.ts rename to handlers/burialSites-post/doAddLotComment.d.ts diff --git a/handlers/burialSites-post/doAddLotComment.js b/handlers/burialSites-post/doAddLotComment.js new file mode 100644 index 00000000..4bcec715 --- /dev/null +++ b/handlers/burialSites-post/doAddLotComment.js @@ -0,0 +1,10 @@ +import addLotComment from '../../database/addLotComment.js'; +import getLotComments from '../../database/getLotComments.js'; +export default async function handler(request, response) { + await addLotComment(request.body, request.session.user); + const lotComments = await getLotComments(request.body.lotId); + response.json({ + success: true, + lotComments + }); +} diff --git a/handlers/lots-post/doAddLotComment.ts b/handlers/burialSites-post/doAddLotComment.ts similarity index 100% rename from handlers/lots-post/doAddLotComment.ts rename to handlers/burialSites-post/doAddLotComment.ts diff --git a/handlers/lotOccupancies-post/doAddLotOccupancyFee.d.ts b/handlers/burialSites-post/doCreateLot.d.ts similarity index 100% rename from handlers/lotOccupancies-post/doAddLotOccupancyFee.d.ts rename to handlers/burialSites-post/doCreateLot.d.ts diff --git a/handlers/burialSites-post/doCreateLot.js b/handlers/burialSites-post/doCreateLot.js new file mode 100644 index 00000000..2737f657 --- /dev/null +++ b/handlers/burialSites-post/doCreateLot.js @@ -0,0 +1,12 @@ +import addLot from '../../database/addLot.js'; +import { clearNextPreviousLotIdCache } from '../../helpers/functions.lots.js'; +export default async function handler(request, response) { + const lotId = await addLot(request.body, request.session.user); + response.json({ + success: true, + lotId + }); + response.on('finish', () => { + clearNextPreviousLotIdCache(-1); + }); +} diff --git a/handlers/lots-post/doCreateLot.ts b/handlers/burialSites-post/doCreateLot.ts similarity index 100% rename from handlers/lots-post/doCreateLot.ts rename to handlers/burialSites-post/doCreateLot.ts diff --git a/handlers/lotOccupancies-post/doAddLotOccupancyFeeCategory.d.ts b/handlers/burialSites-post/doDeleteLot.d.ts similarity index 100% rename from handlers/lotOccupancies-post/doAddLotOccupancyFeeCategory.d.ts rename to handlers/burialSites-post/doDeleteLot.d.ts diff --git a/handlers/burialSites-post/doDeleteLot.js b/handlers/burialSites-post/doDeleteLot.js new file mode 100644 index 00000000..f0d87eee --- /dev/null +++ b/handlers/burialSites-post/doDeleteLot.js @@ -0,0 +1,12 @@ +import { clearNextPreviousLotIdCache } from '../../helpers/functions.lots.js'; +import { deleteRecord } from '../../database/deleteRecord.js'; +export default async function handler(request, response) { + const lotId = Number.parseInt(request.body.lotId, 10); + const success = await deleteRecord('Lots', lotId, request.session.user); + response.json({ + success + }); + response.on('finish', () => { + clearNextPreviousLotIdCache(lotId); + }); +} diff --git a/handlers/lots-post/doDeleteLot.ts b/handlers/burialSites-post/doDeleteLot.ts similarity index 100% rename from handlers/lots-post/doDeleteLot.ts rename to handlers/burialSites-post/doDeleteLot.ts diff --git a/handlers/lotOccupancies-post/doAddLotOccupancyOccupant.d.ts b/handlers/burialSites-post/doDeleteLotComment.d.ts similarity index 100% rename from handlers/lotOccupancies-post/doAddLotOccupancyOccupant.d.ts rename to handlers/burialSites-post/doDeleteLotComment.d.ts diff --git a/handlers/burialSites-post/doDeleteLotComment.js b/handlers/burialSites-post/doDeleteLotComment.js new file mode 100644 index 00000000..69b8e818 --- /dev/null +++ b/handlers/burialSites-post/doDeleteLotComment.js @@ -0,0 +1,10 @@ +import { deleteRecord } from '../../database/deleteRecord.js'; +import getLotComments from '../../database/getLotComments.js'; +export default async function handler(request, response) { + const success = await deleteRecord('LotComments', request.body.lotCommentId, request.session.user); + const lotComments = await getLotComments(request.body.lotId); + response.json({ + success, + lotComments + }); +} diff --git a/handlers/lots-post/doDeleteLotComment.ts b/handlers/burialSites-post/doDeleteLotComment.ts similarity index 100% rename from handlers/lots-post/doDeleteLotComment.ts rename to handlers/burialSites-post/doDeleteLotComment.ts diff --git a/handlers/lots-post/doGetLotTypeFields.d.ts b/handlers/burialSites-post/doGetLotTypeFields.d.ts similarity index 100% rename from handlers/lots-post/doGetLotTypeFields.d.ts rename to handlers/burialSites-post/doGetLotTypeFields.d.ts diff --git a/handlers/lots-post/doGetLotTypeFields.js b/handlers/burialSites-post/doGetLotTypeFields.js similarity index 100% rename from handlers/lots-post/doGetLotTypeFields.js rename to handlers/burialSites-post/doGetLotTypeFields.js diff --git a/handlers/lots-post/doGetLotTypeFields.ts b/handlers/burialSites-post/doGetLotTypeFields.ts similarity index 100% rename from handlers/lots-post/doGetLotTypeFields.ts rename to handlers/burialSites-post/doGetLotTypeFields.ts diff --git a/handlers/lots-post/doSearchLots.d.ts b/handlers/burialSites-post/doSearchLots.d.ts similarity index 100% rename from handlers/lots-post/doSearchLots.d.ts rename to handlers/burialSites-post/doSearchLots.d.ts diff --git a/handlers/lots-post/doSearchLots.js b/handlers/burialSites-post/doSearchLots.js similarity index 100% rename from handlers/lots-post/doSearchLots.js rename to handlers/burialSites-post/doSearchLots.js diff --git a/handlers/lots-post/doSearchLots.ts b/handlers/burialSites-post/doSearchLots.ts similarity index 100% rename from handlers/lots-post/doSearchLots.ts rename to handlers/burialSites-post/doSearchLots.ts diff --git a/handlers/lotOccupancies-post/doAddLotOccupancyTransaction.d.ts b/handlers/burialSites-post/doUpdateLot.d.ts similarity index 100% rename from handlers/lotOccupancies-post/doAddLotOccupancyTransaction.d.ts rename to handlers/burialSites-post/doUpdateLot.d.ts diff --git a/handlers/lots-post/doUpdateLot.js b/handlers/burialSites-post/doUpdateLot.js similarity index 100% rename from handlers/lots-post/doUpdateLot.js rename to handlers/burialSites-post/doUpdateLot.js diff --git a/handlers/lots-post/doUpdateLot.ts b/handlers/burialSites-post/doUpdateLot.ts similarity index 100% rename from handlers/lots-post/doUpdateLot.ts rename to handlers/burialSites-post/doUpdateLot.ts diff --git a/handlers/lots-post/doUpdateLotComment.d.ts b/handlers/burialSites-post/doUpdateLotComment.d.ts similarity index 100% rename from handlers/lots-post/doUpdateLotComment.d.ts rename to handlers/burialSites-post/doUpdateLotComment.d.ts diff --git a/handlers/lots-post/doUpdateLotComment.js b/handlers/burialSites-post/doUpdateLotComment.js similarity index 100% rename from handlers/lots-post/doUpdateLotComment.js rename to handlers/burialSites-post/doUpdateLotComment.js diff --git a/handlers/lots-post/doUpdateLotComment.ts b/handlers/burialSites-post/doUpdateLotComment.ts similarity index 100% rename from handlers/lots-post/doUpdateLotComment.ts rename to handlers/burialSites-post/doUpdateLotComment.ts diff --git a/handlers/lots-get/edit.d.ts b/handlers/cemeteries-get/edit.d.ts similarity index 100% rename from handlers/lots-get/edit.d.ts rename to handlers/cemeteries-get/edit.d.ts diff --git a/handlers/maps-get/edit.js b/handlers/cemeteries-get/edit.js similarity index 92% rename from handlers/maps-get/edit.js rename to handlers/cemeteries-get/edit.js index d5d5ecfc..1862c0ed 100644 --- a/handlers/maps-get/edit.js +++ b/handlers/cemeteries-get/edit.js @@ -1,7 +1,7 @@ import getLotStatusSummary from '../../database/getLotStatusSummary.js'; import getLotTypeSummary from '../../database/getLotTypeSummary.js'; import getMap from '../../database/getMap.js'; -import { getConfigProperty } from '../../helpers/functions.config.js'; +import { getConfigProperty } from '../../helpers/config.helpers.js'; import { getMapSVGs } from '../../helpers/functions.map.js'; export default async function handler(request, response) { const map = await getMap(request.params.mapId); diff --git a/handlers/maps-get/edit.ts b/handlers/cemeteries-get/edit.ts similarity index 93% rename from handlers/maps-get/edit.ts rename to handlers/cemeteries-get/edit.ts index 7997b9a0..7f8f7a81 100644 --- a/handlers/maps-get/edit.ts +++ b/handlers/cemeteries-get/edit.ts @@ -3,7 +3,7 @@ import type { Request, Response } from 'express' import getLotStatusSummary from '../../database/getLotStatusSummary.js' import getLotTypeSummary from '../../database/getLotTypeSummary.js' import getMap from '../../database/getMap.js' -import { getConfigProperty } from '../../helpers/functions.config.js' +import { getConfigProperty } from '../../helpers/config.helpers.js' import { getMapSVGs } from '../../helpers/functions.map.js' export default async function handler( diff --git a/handlers/maps-get/new.d.ts b/handlers/cemeteries-get/new.d.ts similarity index 100% rename from handlers/maps-get/new.d.ts rename to handlers/cemeteries-get/new.d.ts diff --git a/handlers/maps-get/new.js b/handlers/cemeteries-get/new.js similarity index 87% rename from handlers/maps-get/new.js rename to handlers/cemeteries-get/new.js index eb3d7ea3..ff091619 100644 --- a/handlers/maps-get/new.js +++ b/handlers/cemeteries-get/new.js @@ -1,4 +1,4 @@ -import { getConfigProperty } from '../../helpers/functions.config.js'; +import { getConfigProperty } from '../../helpers/config.helpers.js'; import { getMapSVGs } from '../../helpers/functions.map.js'; export default async function handler(_request, response) { const map = { diff --git a/handlers/maps-get/new.ts b/handlers/cemeteries-get/new.ts similarity index 89% rename from handlers/maps-get/new.ts rename to handlers/cemeteries-get/new.ts index 691fa3a9..6930f9d3 100644 --- a/handlers/maps-get/new.ts +++ b/handlers/cemeteries-get/new.ts @@ -1,6 +1,6 @@ import type { Request, Response } from 'express' -import { getConfigProperty } from '../../helpers/functions.config.js' +import { getConfigProperty } from '../../helpers/config.helpers.js' import { getMapSVGs } from '../../helpers/functions.map.js' import type { MapRecord } from '../../types/recordTypes.js' diff --git a/handlers/maps-get/next.d.ts b/handlers/cemeteries-get/next.d.ts similarity index 100% rename from handlers/maps-get/next.d.ts rename to handlers/cemeteries-get/next.d.ts diff --git a/handlers/maps-get/next.js b/handlers/cemeteries-get/next.js similarity index 87% rename from handlers/maps-get/next.js rename to handlers/cemeteries-get/next.js index ddccde04..1fe5922c 100644 --- a/handlers/maps-get/next.js +++ b/handlers/cemeteries-get/next.js @@ -1,5 +1,5 @@ import getNextMapId from '../../database/getNextMapId.js'; -import { getConfigProperty } from '../../helpers/functions.config.js'; +import { getConfigProperty } from '../../helpers/config.helpers.js'; export default async function handler(request, response) { const mapId = Number.parseInt(request.params.mapId, 10); const nextMapId = await getNextMapId(mapId); diff --git a/handlers/maps-get/next.ts b/handlers/cemeteries-get/next.ts similarity index 89% rename from handlers/maps-get/next.ts rename to handlers/cemeteries-get/next.ts index fc059e0f..3e12d9be 100644 --- a/handlers/maps-get/next.ts +++ b/handlers/cemeteries-get/next.ts @@ -1,7 +1,7 @@ import type { Request, Response } from 'express' import getNextMapId from '../../database/getNextMapId.js' -import { getConfigProperty } from '../../helpers/functions.config.js' +import { getConfigProperty } from '../../helpers/config.helpers.js' export default async function handler( request: Request, diff --git a/handlers/maps-get/previous.d.ts b/handlers/cemeteries-get/previous.d.ts similarity index 100% rename from handlers/maps-get/previous.d.ts rename to handlers/cemeteries-get/previous.d.ts diff --git a/handlers/maps-get/previous.js b/handlers/cemeteries-get/previous.js similarity index 88% rename from handlers/maps-get/previous.js rename to handlers/cemeteries-get/previous.js index da0f7988..4037474f 100644 --- a/handlers/maps-get/previous.js +++ b/handlers/cemeteries-get/previous.js @@ -1,5 +1,5 @@ import getPreviousMapId from '../../database/getPreviousMapId.js'; -import { getConfigProperty } from '../../helpers/functions.config.js'; +import { getConfigProperty } from '../../helpers/config.helpers.js'; export default async function handler(request, response) { const mapId = Number.parseInt(request.params.mapId, 10); const previousMapId = await getPreviousMapId(mapId); diff --git a/handlers/maps-get/previous.ts b/handlers/cemeteries-get/previous.ts similarity index 90% rename from handlers/maps-get/previous.ts rename to handlers/cemeteries-get/previous.ts index d40f3854..ffa9de55 100644 --- a/handlers/maps-get/previous.ts +++ b/handlers/cemeteries-get/previous.ts @@ -1,7 +1,7 @@ import type { Request, Response } from 'express' import getPreviousMapId from '../../database/getPreviousMapId.js' -import { getConfigProperty } from '../../helpers/functions.config.js' +import { getConfigProperty } from '../../helpers/config.helpers.js' export default async function handler( request: Request, diff --git a/handlers/maps-get/search.d.ts b/handlers/cemeteries-get/search.d.ts similarity index 100% rename from handlers/maps-get/search.d.ts rename to handlers/cemeteries-get/search.d.ts diff --git a/handlers/maps-get/search.js b/handlers/cemeteries-get/search.js similarity index 78% rename from handlers/maps-get/search.js rename to handlers/cemeteries-get/search.js index cda635f0..a1793296 100644 --- a/handlers/maps-get/search.js +++ b/handlers/cemeteries-get/search.js @@ -1,5 +1,5 @@ import getMaps from '../../database/getMaps.js'; -import { getConfigProperty } from '../../helpers/functions.config.js'; +import { getConfigProperty } from '../../helpers/config.helpers.js'; export default async function handler(_request, response) { const maps = await getMaps(); response.render('map-search', { diff --git a/handlers/maps-get/search.ts b/handlers/cemeteries-get/search.ts similarity index 83% rename from handlers/maps-get/search.ts rename to handlers/cemeteries-get/search.ts index f54a4614..60e3566a 100644 --- a/handlers/maps-get/search.ts +++ b/handlers/cemeteries-get/search.ts @@ -1,7 +1,7 @@ import type { Request, Response } from 'express' import getMaps from '../../database/getMaps.js' -import { getConfigProperty } from '../../helpers/functions.config.js' +import { getConfigProperty } from '../../helpers/config.helpers.js' export default async function handler( _request: Request, diff --git a/handlers/lots-get/view.d.ts b/handlers/cemeteries-get/view.d.ts similarity index 100% rename from handlers/lots-get/view.d.ts rename to handlers/cemeteries-get/view.d.ts diff --git a/handlers/maps-get/view.js b/handlers/cemeteries-get/view.js similarity index 91% rename from handlers/maps-get/view.js rename to handlers/cemeteries-get/view.js index 6c193ec6..2c2d7539 100644 --- a/handlers/maps-get/view.js +++ b/handlers/cemeteries-get/view.js @@ -1,7 +1,7 @@ import getLotStatusSummary from '../../database/getLotStatusSummary.js'; import getLotTypeSummary from '../../database/getLotTypeSummary.js'; import getMap from '../../database/getMap.js'; -import { getConfigProperty } from '../../helpers/functions.config.js'; +import { getConfigProperty } from '../../helpers/config.helpers.js'; export default async function handler(request, response) { const map = await getMap(request.params.mapId); if (map === undefined) { diff --git a/handlers/maps-get/view.ts b/handlers/cemeteries-get/view.ts similarity index 92% rename from handlers/maps-get/view.ts rename to handlers/cemeteries-get/view.ts index 155ee2d9..b44653e6 100644 --- a/handlers/maps-get/view.ts +++ b/handlers/cemeteries-get/view.ts @@ -3,7 +3,7 @@ import type { Request, Response } from 'express' import getLotStatusSummary from '../../database/getLotStatusSummary.js' import getLotTypeSummary from '../../database/getLotTypeSummary.js' import getMap from '../../database/getMap.js' -import { getConfigProperty } from '../../helpers/functions.config.js' +import { getConfigProperty } from '../../helpers/config.helpers.js' export default async function handler( request: Request, diff --git a/handlers/lotOccupancies-post/doCopyLotOccupancy.d.ts b/handlers/cemeteries-post/doCreateCemetery.d.ts similarity index 100% rename from handlers/lotOccupancies-post/doCopyLotOccupancy.d.ts rename to handlers/cemeteries-post/doCreateCemetery.d.ts diff --git a/handlers/maps-post/doCreateMap.js b/handlers/cemeteries-post/doCreateCemetery.js similarity index 100% rename from handlers/maps-post/doCreateMap.js rename to handlers/cemeteries-post/doCreateCemetery.js diff --git a/handlers/maps-post/doCreateMap.ts b/handlers/cemeteries-post/doCreateCemetery.ts similarity index 100% rename from handlers/maps-post/doCreateMap.ts rename to handlers/cemeteries-post/doCreateCemetery.ts diff --git a/handlers/lotOccupancies-post/doCreateLotOccupancy.d.ts b/handlers/cemeteries-post/doDeleteCemetery.d.ts similarity index 100% rename from handlers/lotOccupancies-post/doCreateLotOccupancy.d.ts rename to handlers/cemeteries-post/doDeleteCemetery.d.ts diff --git a/handlers/maps-post/doDeleteMap.js b/handlers/cemeteries-post/doDeleteCemetery.js similarity index 100% rename from handlers/maps-post/doDeleteMap.js rename to handlers/cemeteries-post/doDeleteCemetery.js diff --git a/handlers/maps-post/doDeleteMap.ts b/handlers/cemeteries-post/doDeleteCemetery.ts similarity index 100% rename from handlers/maps-post/doDeleteMap.ts rename to handlers/cemeteries-post/doDeleteCemetery.ts diff --git a/handlers/maps-post/doUpdateMap.d.ts b/handlers/cemeteries-post/doUpdateMap.d.ts similarity index 100% rename from handlers/maps-post/doUpdateMap.d.ts rename to handlers/cemeteries-post/doUpdateMap.d.ts diff --git a/handlers/maps-post/doUpdateMap.js b/handlers/cemeteries-post/doUpdateMap.js similarity index 100% rename from handlers/maps-post/doUpdateMap.js rename to handlers/cemeteries-post/doUpdateMap.js diff --git a/handlers/maps-post/doUpdateMap.ts b/handlers/cemeteries-post/doUpdateMap.ts similarity index 100% rename from handlers/maps-post/doUpdateMap.ts rename to handlers/cemeteries-post/doUpdateMap.ts diff --git a/handlers/maps-get/edit.d.ts b/handlers/contracts-get/edit.d.ts similarity index 100% rename from handlers/maps-get/edit.d.ts rename to handlers/contracts-get/edit.d.ts diff --git a/handlers/lotOccupancies-get/edit.js b/handlers/contracts-get/edit.js similarity index 94% rename from handlers/lotOccupancies-get/edit.js rename to handlers/contracts-get/edit.js index aa5ab17e..bee627d0 100644 --- a/handlers/lotOccupancies-get/edit.js +++ b/handlers/contracts-get/edit.js @@ -1,7 +1,7 @@ import getLotOccupancy from '../../database/getLotOccupancy.js'; import getMaps from '../../database/getMaps.js'; import { getLotOccupantTypes, getLotStatuses, getLotTypes, getOccupancyTypePrintsById, getOccupancyTypes, getWorkOrderTypes } from '../../helpers/functions.cache.js'; -import { getConfigProperty } from '../../helpers/functions.config.js'; +import { getConfigProperty } from '../../helpers/config.helpers.js'; export default async function handler(request, response) { const lotOccupancy = await getLotOccupancy(request.params.lotOccupancyId); if (lotOccupancy === undefined) { diff --git a/handlers/lotOccupancies-get/edit.ts b/handlers/contracts-get/edit.ts similarity index 95% rename from handlers/lotOccupancies-get/edit.ts rename to handlers/contracts-get/edit.ts index a0a24ccf..5b8830fc 100644 --- a/handlers/lotOccupancies-get/edit.ts +++ b/handlers/contracts-get/edit.ts @@ -10,7 +10,7 @@ import { getOccupancyTypes, getWorkOrderTypes } from '../../helpers/functions.cache.js' -import { getConfigProperty } from '../../helpers/functions.config.js' +import { getConfigProperty } from '../../helpers/config.helpers.js' export default async function handler( request: Request, diff --git a/handlers/lots-get/new.d.ts b/handlers/contracts-get/new.d.ts similarity index 100% rename from handlers/lots-get/new.d.ts rename to handlers/contracts-get/new.d.ts diff --git a/handlers/lotOccupancies-get/new.js b/handlers/contracts-get/new.js similarity index 95% rename from handlers/lotOccupancies-get/new.js rename to handlers/contracts-get/new.js index 08f9cd1f..8f22d07a 100644 --- a/handlers/lotOccupancies-get/new.js +++ b/handlers/contracts-get/new.js @@ -2,7 +2,7 @@ import { dateToInteger, dateToString } from '@cityssm/utils-datetime'; import getLot from '../../database/getLot.js'; import getMaps from '../../database/getMaps.js'; import { getLotOccupantTypes, getLotStatuses, getLotTypes, getOccupancyTypes } from '../../helpers/functions.cache.js'; -import { getConfigProperty } from '../../helpers/functions.config.js'; +import { getConfigProperty } from '../../helpers/config.helpers.js'; export default async function handler(request, response) { const startDate = new Date(); const lotOccupancy = { diff --git a/handlers/lotOccupancies-get/new.ts b/handlers/contracts-get/new.ts similarity index 95% rename from handlers/lotOccupancies-get/new.ts rename to handlers/contracts-get/new.ts index bdfdc7b8..aa672696 100644 --- a/handlers/lotOccupancies-get/new.ts +++ b/handlers/contracts-get/new.ts @@ -9,7 +9,7 @@ import { getLotTypes, getOccupancyTypes } from '../../helpers/functions.cache.js' -import { getConfigProperty } from '../../helpers/functions.config.js' +import { getConfigProperty } from '../../helpers/config.helpers.js' import type { LotOccupancy } from '../../types/recordTypes.js' export default async function handler( diff --git a/handlers/lots-get/search.d.ts b/handlers/contracts-get/search.d.ts similarity index 100% rename from handlers/lots-get/search.d.ts rename to handlers/contracts-get/search.d.ts diff --git a/handlers/lotOccupancies-get/search.js b/handlers/contracts-get/search.js similarity index 88% rename from handlers/lotOccupancies-get/search.js rename to handlers/contracts-get/search.js index 00a7f6b4..09a0732d 100644 --- a/handlers/lotOccupancies-get/search.js +++ b/handlers/contracts-get/search.js @@ -1,6 +1,6 @@ import getMaps from '../../database/getMaps.js'; import { getLotTypes, getOccupancyTypes } from '../../helpers/functions.cache.js'; -import { getConfigProperty } from '../../helpers/functions.config.js'; +import { getConfigProperty } from '../../helpers/config.helpers.js'; export default async function handler(request, response) { const maps = await getMaps(); const lotTypes = await getLotTypes(); diff --git a/handlers/lotOccupancies-get/search.ts b/handlers/contracts-get/search.ts similarity index 89% rename from handlers/lotOccupancies-get/search.ts rename to handlers/contracts-get/search.ts index cde30194..b259434b 100644 --- a/handlers/lotOccupancies-get/search.ts +++ b/handlers/contracts-get/search.ts @@ -5,7 +5,7 @@ import { getLotTypes, getOccupancyTypes } from '../../helpers/functions.cache.js' -import { getConfigProperty } from '../../helpers/functions.config.js' +import { getConfigProperty } from '../../helpers/config.helpers.js' export default async function handler( request: Request, diff --git a/handlers/maps-get/view.d.ts b/handlers/contracts-get/view.d.ts similarity index 100% rename from handlers/maps-get/view.d.ts rename to handlers/contracts-get/view.d.ts diff --git a/handlers/lotOccupancies-get/view.js b/handlers/contracts-get/view.js similarity index 91% rename from handlers/lotOccupancies-get/view.js rename to handlers/contracts-get/view.js index 252510fb..7a6dd4d4 100644 --- a/handlers/lotOccupancies-get/view.js +++ b/handlers/contracts-get/view.js @@ -1,6 +1,6 @@ import getLotOccupancy from '../../database/getLotOccupancy.js'; import { getOccupancyTypePrintsById } from '../../helpers/functions.cache.js'; -import { getConfigProperty } from '../../helpers/functions.config.js'; +import { getConfigProperty } from '../../helpers/config.helpers.js'; export default async function handler(request, response) { const lotOccupancy = await getLotOccupancy(request.params.lotOccupancyId); if (lotOccupancy === undefined) { diff --git a/handlers/lotOccupancies-get/view.ts b/handlers/contracts-get/view.ts similarity index 92% rename from handlers/lotOccupancies-get/view.ts rename to handlers/contracts-get/view.ts index 4686072e..5c8fe6b2 100644 --- a/handlers/lotOccupancies-get/view.ts +++ b/handlers/contracts-get/view.ts @@ -2,7 +2,7 @@ import type { Request, Response } from 'express' import getLotOccupancy from '../../database/getLotOccupancy.js' import { getOccupancyTypePrintsById } from '../../helpers/functions.cache.js' -import { getConfigProperty } from '../../helpers/functions.config.js' +import { getConfigProperty } from '../../helpers/config.helpers.js' export default async function handler( request: Request, diff --git a/handlers/lotOccupancies-post/doDeleteLotOccupancy.d.ts b/handlers/contracts-post/doAddLotOccupancyComment.d.ts similarity index 100% rename from handlers/lotOccupancies-post/doDeleteLotOccupancy.d.ts rename to handlers/contracts-post/doAddLotOccupancyComment.d.ts diff --git a/handlers/lotOccupancies-post/doAddLotOccupancyComment.js b/handlers/contracts-post/doAddLotOccupancyComment.js similarity index 100% rename from handlers/lotOccupancies-post/doAddLotOccupancyComment.js rename to handlers/contracts-post/doAddLotOccupancyComment.js diff --git a/handlers/lotOccupancies-post/doAddLotOccupancyComment.ts b/handlers/contracts-post/doAddLotOccupancyComment.ts similarity index 100% rename from handlers/lotOccupancies-post/doAddLotOccupancyComment.ts rename to handlers/contracts-post/doAddLotOccupancyComment.ts diff --git a/handlers/lotOccupancies-post/doDeleteLotOccupancyComment.d.ts b/handlers/contracts-post/doAddLotOccupancyFee.d.ts similarity index 100% rename from handlers/lotOccupancies-post/doDeleteLotOccupancyComment.d.ts rename to handlers/contracts-post/doAddLotOccupancyFee.d.ts diff --git a/handlers/lotOccupancies-post/doAddLotOccupancyFee.js b/handlers/contracts-post/doAddLotOccupancyFee.js similarity index 100% rename from handlers/lotOccupancies-post/doAddLotOccupancyFee.js rename to handlers/contracts-post/doAddLotOccupancyFee.js diff --git a/handlers/lotOccupancies-post/doAddLotOccupancyFee.ts b/handlers/contracts-post/doAddLotOccupancyFee.ts similarity index 100% rename from handlers/lotOccupancies-post/doAddLotOccupancyFee.ts rename to handlers/contracts-post/doAddLotOccupancyFee.ts diff --git a/handlers/lotOccupancies-post/doDeleteLotOccupancyFee.d.ts b/handlers/contracts-post/doAddLotOccupancyFeeCategory.d.ts similarity index 100% rename from handlers/lotOccupancies-post/doDeleteLotOccupancyFee.d.ts rename to handlers/contracts-post/doAddLotOccupancyFeeCategory.d.ts diff --git a/handlers/lotOccupancies-post/doAddLotOccupancyFeeCategory.js b/handlers/contracts-post/doAddLotOccupancyFeeCategory.js similarity index 100% rename from handlers/lotOccupancies-post/doAddLotOccupancyFeeCategory.js rename to handlers/contracts-post/doAddLotOccupancyFeeCategory.js diff --git a/handlers/lotOccupancies-post/doAddLotOccupancyFeeCategory.ts b/handlers/contracts-post/doAddLotOccupancyFeeCategory.ts similarity index 100% rename from handlers/lotOccupancies-post/doAddLotOccupancyFeeCategory.ts rename to handlers/contracts-post/doAddLotOccupancyFeeCategory.ts diff --git a/handlers/lotOccupancies-post/doDeleteLotOccupancyOccupant.d.ts b/handlers/contracts-post/doAddLotOccupancyOccupant.d.ts similarity index 100% rename from handlers/lotOccupancies-post/doDeleteLotOccupancyOccupant.d.ts rename to handlers/contracts-post/doAddLotOccupancyOccupant.d.ts diff --git a/handlers/lotOccupancies-post/doAddLotOccupancyOccupant.js b/handlers/contracts-post/doAddLotOccupancyOccupant.js similarity index 100% rename from handlers/lotOccupancies-post/doAddLotOccupancyOccupant.js rename to handlers/contracts-post/doAddLotOccupancyOccupant.js diff --git a/handlers/lotOccupancies-post/doAddLotOccupancyOccupant.ts b/handlers/contracts-post/doAddLotOccupancyOccupant.ts similarity index 100% rename from handlers/lotOccupancies-post/doAddLotOccupancyOccupant.ts rename to handlers/contracts-post/doAddLotOccupancyOccupant.ts diff --git a/handlers/lotOccupancies-post/doDeleteLotOccupancyTransaction.d.ts b/handlers/contracts-post/doAddLotOccupancyTransaction.d.ts similarity index 100% rename from handlers/lotOccupancies-post/doDeleteLotOccupancyTransaction.d.ts rename to handlers/contracts-post/doAddLotOccupancyTransaction.d.ts diff --git a/handlers/lotOccupancies-post/doAddLotOccupancyTransaction.js b/handlers/contracts-post/doAddLotOccupancyTransaction.js similarity index 100% rename from handlers/lotOccupancies-post/doAddLotOccupancyTransaction.js rename to handlers/contracts-post/doAddLotOccupancyTransaction.js diff --git a/handlers/lotOccupancies-post/doAddLotOccupancyTransaction.ts b/handlers/contracts-post/doAddLotOccupancyTransaction.ts similarity index 100% rename from handlers/lotOccupancies-post/doAddLotOccupancyTransaction.ts rename to handlers/contracts-post/doAddLotOccupancyTransaction.ts diff --git a/handlers/lotOccupancies-post/doGetDynamicsGPDocument.d.ts b/handlers/contracts-post/doCopyLotOccupancy.d.ts similarity index 100% rename from handlers/lotOccupancies-post/doGetDynamicsGPDocument.d.ts rename to handlers/contracts-post/doCopyLotOccupancy.d.ts diff --git a/handlers/lotOccupancies-post/doCopyLotOccupancy.js b/handlers/contracts-post/doCopyLotOccupancy.js similarity index 100% rename from handlers/lotOccupancies-post/doCopyLotOccupancy.js rename to handlers/contracts-post/doCopyLotOccupancy.js diff --git a/handlers/lotOccupancies-post/doCopyLotOccupancy.ts b/handlers/contracts-post/doCopyLotOccupancy.ts similarity index 100% rename from handlers/lotOccupancies-post/doCopyLotOccupancy.ts rename to handlers/contracts-post/doCopyLotOccupancy.ts diff --git a/handlers/lotOccupancies-post/doGetFees.d.ts b/handlers/contracts-post/doCreateLotOccupancy.d.ts similarity index 100% rename from handlers/lotOccupancies-post/doGetFees.d.ts rename to handlers/contracts-post/doCreateLotOccupancy.d.ts diff --git a/handlers/lotOccupancies-post/doCreateLotOccupancy.js b/handlers/contracts-post/doCreateLotOccupancy.js similarity index 100% rename from handlers/lotOccupancies-post/doCreateLotOccupancy.js rename to handlers/contracts-post/doCreateLotOccupancy.js diff --git a/handlers/lotOccupancies-post/doCreateLotOccupancy.ts b/handlers/contracts-post/doCreateLotOccupancy.ts similarity index 100% rename from handlers/lotOccupancies-post/doCreateLotOccupancy.ts rename to handlers/contracts-post/doCreateLotOccupancy.ts diff --git a/handlers/lotOccupancies-post/doGetOccupancyTypeFields.d.ts b/handlers/contracts-post/doDeleteLotOccupancy.d.ts similarity index 100% rename from handlers/lotOccupancies-post/doGetOccupancyTypeFields.d.ts rename to handlers/contracts-post/doDeleteLotOccupancy.d.ts diff --git a/handlers/lotOccupancies-post/doDeleteLotOccupancy.js b/handlers/contracts-post/doDeleteLotOccupancy.js similarity index 100% rename from handlers/lotOccupancies-post/doDeleteLotOccupancy.js rename to handlers/contracts-post/doDeleteLotOccupancy.js diff --git a/handlers/lotOccupancies-post/doDeleteLotOccupancy.ts b/handlers/contracts-post/doDeleteLotOccupancy.ts similarity index 100% rename from handlers/lotOccupancies-post/doDeleteLotOccupancy.ts rename to handlers/contracts-post/doDeleteLotOccupancy.ts diff --git a/handlers/lotOccupancies-post/doSearchLotOccupancies.d.ts b/handlers/contracts-post/doDeleteLotOccupancyComment.d.ts similarity index 100% rename from handlers/lotOccupancies-post/doSearchLotOccupancies.d.ts rename to handlers/contracts-post/doDeleteLotOccupancyComment.d.ts diff --git a/handlers/lotOccupancies-post/doDeleteLotOccupancyComment.js b/handlers/contracts-post/doDeleteLotOccupancyComment.js similarity index 100% rename from handlers/lotOccupancies-post/doDeleteLotOccupancyComment.js rename to handlers/contracts-post/doDeleteLotOccupancyComment.js diff --git a/handlers/lotOccupancies-post/doDeleteLotOccupancyComment.ts b/handlers/contracts-post/doDeleteLotOccupancyComment.ts similarity index 100% rename from handlers/lotOccupancies-post/doDeleteLotOccupancyComment.ts rename to handlers/contracts-post/doDeleteLotOccupancyComment.ts diff --git a/handlers/lotOccupancies-post/doSearchPastOccupants.d.ts b/handlers/contracts-post/doDeleteLotOccupancyFee.d.ts similarity index 100% rename from handlers/lotOccupancies-post/doSearchPastOccupants.d.ts rename to handlers/contracts-post/doDeleteLotOccupancyFee.d.ts diff --git a/handlers/lotOccupancies-post/doDeleteLotOccupancyFee.js b/handlers/contracts-post/doDeleteLotOccupancyFee.js similarity index 100% rename from handlers/lotOccupancies-post/doDeleteLotOccupancyFee.js rename to handlers/contracts-post/doDeleteLotOccupancyFee.js diff --git a/handlers/lotOccupancies-post/doDeleteLotOccupancyFee.ts b/handlers/contracts-post/doDeleteLotOccupancyFee.ts similarity index 100% rename from handlers/lotOccupancies-post/doDeleteLotOccupancyFee.ts rename to handlers/contracts-post/doDeleteLotOccupancyFee.ts diff --git a/handlers/lotOccupancies-post/doUpdateLotOccupancy.d.ts b/handlers/contracts-post/doDeleteLotOccupancyOccupant.d.ts similarity index 100% rename from handlers/lotOccupancies-post/doUpdateLotOccupancy.d.ts rename to handlers/contracts-post/doDeleteLotOccupancyOccupant.d.ts diff --git a/handlers/lotOccupancies-post/doDeleteLotOccupancyOccupant.js b/handlers/contracts-post/doDeleteLotOccupancyOccupant.js similarity index 100% rename from handlers/lotOccupancies-post/doDeleteLotOccupancyOccupant.js rename to handlers/contracts-post/doDeleteLotOccupancyOccupant.js diff --git a/handlers/lotOccupancies-post/doDeleteLotOccupancyOccupant.ts b/handlers/contracts-post/doDeleteLotOccupancyOccupant.ts similarity index 100% rename from handlers/lotOccupancies-post/doDeleteLotOccupancyOccupant.ts rename to handlers/contracts-post/doDeleteLotOccupancyOccupant.ts diff --git a/handlers/lotOccupancies-post/doUpdateLotOccupancyComment.d.ts b/handlers/contracts-post/doDeleteLotOccupancyTransaction.d.ts similarity index 100% rename from handlers/lotOccupancies-post/doUpdateLotOccupancyComment.d.ts rename to handlers/contracts-post/doDeleteLotOccupancyTransaction.d.ts diff --git a/handlers/lotOccupancies-post/doDeleteLotOccupancyTransaction.js b/handlers/contracts-post/doDeleteLotOccupancyTransaction.js similarity index 100% rename from handlers/lotOccupancies-post/doDeleteLotOccupancyTransaction.js rename to handlers/contracts-post/doDeleteLotOccupancyTransaction.js diff --git a/handlers/lotOccupancies-post/doDeleteLotOccupancyTransaction.ts b/handlers/contracts-post/doDeleteLotOccupancyTransaction.ts similarity index 100% rename from handlers/lotOccupancies-post/doDeleteLotOccupancyTransaction.ts rename to handlers/contracts-post/doDeleteLotOccupancyTransaction.ts diff --git a/handlers/lotOccupancies-post/doUpdateLotOccupancyFeeQuantity.d.ts b/handlers/contracts-post/doGetDynamicsGPDocument.d.ts similarity index 100% rename from handlers/lotOccupancies-post/doUpdateLotOccupancyFeeQuantity.d.ts rename to handlers/contracts-post/doGetDynamicsGPDocument.d.ts diff --git a/handlers/lotOccupancies-post/doGetDynamicsGPDocument.js b/handlers/contracts-post/doGetDynamicsGPDocument.js similarity index 100% rename from handlers/lotOccupancies-post/doGetDynamicsGPDocument.js rename to handlers/contracts-post/doGetDynamicsGPDocument.js diff --git a/handlers/lotOccupancies-post/doGetDynamicsGPDocument.ts b/handlers/contracts-post/doGetDynamicsGPDocument.ts similarity index 100% rename from handlers/lotOccupancies-post/doGetDynamicsGPDocument.ts rename to handlers/contracts-post/doGetDynamicsGPDocument.ts diff --git a/handlers/lotOccupancies-post/doUpdateLotOccupancyOccupant.d.ts b/handlers/contracts-post/doGetFees.d.ts similarity index 100% rename from handlers/lotOccupancies-post/doUpdateLotOccupancyOccupant.d.ts rename to handlers/contracts-post/doGetFees.d.ts diff --git a/handlers/lotOccupancies-post/doGetFees.js b/handlers/contracts-post/doGetFees.js similarity index 100% rename from handlers/lotOccupancies-post/doGetFees.js rename to handlers/contracts-post/doGetFees.js diff --git a/handlers/lotOccupancies-post/doGetFees.ts b/handlers/contracts-post/doGetFees.ts similarity index 100% rename from handlers/lotOccupancies-post/doGetFees.ts rename to handlers/contracts-post/doGetFees.ts diff --git a/handlers/lotOccupancies-post/doUpdateLotOccupancyTransaction.d.ts b/handlers/contracts-post/doGetOccupancyTypeFields.d.ts similarity index 100% rename from handlers/lotOccupancies-post/doUpdateLotOccupancyTransaction.d.ts rename to handlers/contracts-post/doGetOccupancyTypeFields.d.ts diff --git a/handlers/lotOccupancies-post/doGetOccupancyTypeFields.js b/handlers/contracts-post/doGetOccupancyTypeFields.js similarity index 100% rename from handlers/lotOccupancies-post/doGetOccupancyTypeFields.js rename to handlers/contracts-post/doGetOccupancyTypeFields.js diff --git a/handlers/lotOccupancies-post/doGetOccupancyTypeFields.ts b/handlers/contracts-post/doGetOccupancyTypeFields.ts similarity index 100% rename from handlers/lotOccupancies-post/doGetOccupancyTypeFields.ts rename to handlers/contracts-post/doGetOccupancyTypeFields.ts diff --git a/handlers/maps-post/doCreateMap.d.ts b/handlers/contracts-post/doSearchLotOccupancies.d.ts similarity index 100% rename from handlers/maps-post/doCreateMap.d.ts rename to handlers/contracts-post/doSearchLotOccupancies.d.ts diff --git a/handlers/lotOccupancies-post/doSearchLotOccupancies.js b/handlers/contracts-post/doSearchLotOccupancies.js similarity index 100% rename from handlers/lotOccupancies-post/doSearchLotOccupancies.js rename to handlers/contracts-post/doSearchLotOccupancies.js diff --git a/handlers/lotOccupancies-post/doSearchLotOccupancies.ts b/handlers/contracts-post/doSearchLotOccupancies.ts similarity index 100% rename from handlers/lotOccupancies-post/doSearchLotOccupancies.ts rename to handlers/contracts-post/doSearchLotOccupancies.ts diff --git a/handlers/maps-post/doDeleteMap.d.ts b/handlers/contracts-post/doSearchPastOccupants.d.ts similarity index 100% rename from handlers/maps-post/doDeleteMap.d.ts rename to handlers/contracts-post/doSearchPastOccupants.d.ts diff --git a/handlers/lotOccupancies-post/doSearchPastOccupants.js b/handlers/contracts-post/doSearchPastOccupants.js similarity index 100% rename from handlers/lotOccupancies-post/doSearchPastOccupants.js rename to handlers/contracts-post/doSearchPastOccupants.js diff --git a/handlers/lotOccupancies-post/doSearchPastOccupants.ts b/handlers/contracts-post/doSearchPastOccupants.ts similarity index 100% rename from handlers/lotOccupancies-post/doSearchPastOccupants.ts rename to handlers/contracts-post/doSearchPastOccupants.ts diff --git a/handlers/contracts-post/doUpdateLotOccupancy.d.ts b/handlers/contracts-post/doUpdateLotOccupancy.d.ts new file mode 100644 index 00000000..19d32e4d --- /dev/null +++ b/handlers/contracts-post/doUpdateLotOccupancy.d.ts @@ -0,0 +1,2 @@ +import type { Request, Response } from 'express'; +export default function handler(request: Request, response: Response): Promise; diff --git a/handlers/lotOccupancies-post/doUpdateLotOccupancy.js b/handlers/contracts-post/doUpdateLotOccupancy.js similarity index 100% rename from handlers/lotOccupancies-post/doUpdateLotOccupancy.js rename to handlers/contracts-post/doUpdateLotOccupancy.js diff --git a/handlers/lotOccupancies-post/doUpdateLotOccupancy.ts b/handlers/contracts-post/doUpdateLotOccupancy.ts similarity index 100% rename from handlers/lotOccupancies-post/doUpdateLotOccupancy.ts rename to handlers/contracts-post/doUpdateLotOccupancy.ts diff --git a/handlers/contracts-post/doUpdateLotOccupancyComment.d.ts b/handlers/contracts-post/doUpdateLotOccupancyComment.d.ts new file mode 100644 index 00000000..19d32e4d --- /dev/null +++ b/handlers/contracts-post/doUpdateLotOccupancyComment.d.ts @@ -0,0 +1,2 @@ +import type { Request, Response } from 'express'; +export default function handler(request: Request, response: Response): Promise; diff --git a/handlers/lotOccupancies-post/doUpdateLotOccupancyComment.js b/handlers/contracts-post/doUpdateLotOccupancyComment.js similarity index 100% rename from handlers/lotOccupancies-post/doUpdateLotOccupancyComment.js rename to handlers/contracts-post/doUpdateLotOccupancyComment.js diff --git a/handlers/lotOccupancies-post/doUpdateLotOccupancyComment.ts b/handlers/contracts-post/doUpdateLotOccupancyComment.ts similarity index 100% rename from handlers/lotOccupancies-post/doUpdateLotOccupancyComment.ts rename to handlers/contracts-post/doUpdateLotOccupancyComment.ts diff --git a/handlers/contracts-post/doUpdateLotOccupancyFeeQuantity.d.ts b/handlers/contracts-post/doUpdateLotOccupancyFeeQuantity.d.ts new file mode 100644 index 00000000..19d32e4d --- /dev/null +++ b/handlers/contracts-post/doUpdateLotOccupancyFeeQuantity.d.ts @@ -0,0 +1,2 @@ +import type { Request, Response } from 'express'; +export default function handler(request: Request, response: Response): Promise; diff --git a/handlers/lotOccupancies-post/doUpdateLotOccupancyFeeQuantity.js b/handlers/contracts-post/doUpdateLotOccupancyFeeQuantity.js similarity index 100% rename from handlers/lotOccupancies-post/doUpdateLotOccupancyFeeQuantity.js rename to handlers/contracts-post/doUpdateLotOccupancyFeeQuantity.js diff --git a/handlers/lotOccupancies-post/doUpdateLotOccupancyFeeQuantity.ts b/handlers/contracts-post/doUpdateLotOccupancyFeeQuantity.ts similarity index 100% rename from handlers/lotOccupancies-post/doUpdateLotOccupancyFeeQuantity.ts rename to handlers/contracts-post/doUpdateLotOccupancyFeeQuantity.ts diff --git a/handlers/contracts-post/doUpdateLotOccupancyOccupant.d.ts b/handlers/contracts-post/doUpdateLotOccupancyOccupant.d.ts new file mode 100644 index 00000000..19d32e4d --- /dev/null +++ b/handlers/contracts-post/doUpdateLotOccupancyOccupant.d.ts @@ -0,0 +1,2 @@ +import type { Request, Response } from 'express'; +export default function handler(request: Request, response: Response): Promise; diff --git a/handlers/lotOccupancies-post/doUpdateLotOccupancyOccupant.js b/handlers/contracts-post/doUpdateLotOccupancyOccupant.js similarity index 100% rename from handlers/lotOccupancies-post/doUpdateLotOccupancyOccupant.js rename to handlers/contracts-post/doUpdateLotOccupancyOccupant.js diff --git a/handlers/lotOccupancies-post/doUpdateLotOccupancyOccupant.ts b/handlers/contracts-post/doUpdateLotOccupancyOccupant.ts similarity index 100% rename from handlers/lotOccupancies-post/doUpdateLotOccupancyOccupant.ts rename to handlers/contracts-post/doUpdateLotOccupancyOccupant.ts diff --git a/handlers/contracts-post/doUpdateLotOccupancyTransaction.d.ts b/handlers/contracts-post/doUpdateLotOccupancyTransaction.d.ts new file mode 100644 index 00000000..19d32e4d --- /dev/null +++ b/handlers/contracts-post/doUpdateLotOccupancyTransaction.d.ts @@ -0,0 +1,2 @@ +import type { Request, Response } from 'express'; +export default function handler(request: Request, response: Response): Promise; diff --git a/handlers/lotOccupancies-post/doUpdateLotOccupancyTransaction.js b/handlers/contracts-post/doUpdateLotOccupancyTransaction.js similarity index 100% rename from handlers/lotOccupancies-post/doUpdateLotOccupancyTransaction.js rename to handlers/contracts-post/doUpdateLotOccupancyTransaction.js diff --git a/handlers/lotOccupancies-post/doUpdateLotOccupancyTransaction.ts b/handlers/contracts-post/doUpdateLotOccupancyTransaction.ts similarity index 100% rename from handlers/lotOccupancies-post/doUpdateLotOccupancyTransaction.ts rename to handlers/contracts-post/doUpdateLotOccupancyTransaction.ts diff --git a/handlers/permissions.js b/handlers/permissions.js index f2d6adfa..63f769b2 100644 --- a/handlers/permissions.js +++ b/handlers/permissions.js @@ -1,4 +1,4 @@ -import { getConfigProperty } from '../helpers/functions.config.js'; +import { getConfigProperty } from '../helpers/config.helpers.js'; import { apiKeyIsValid, userCanUpdate, userIsAdmin } from '../helpers/functions.user.js'; const urlPrefix = getConfigProperty('reverseProxy.urlPrefix'); const forbiddenStatus = 403; diff --git a/handlers/permissions.ts b/handlers/permissions.ts index fd7985d8..bb345b1e 100644 --- a/handlers/permissions.ts +++ b/handlers/permissions.ts @@ -1,6 +1,6 @@ import type { NextFunction, Request, Response } from 'express' -import { getConfigProperty } from '../helpers/functions.config.js' +import { getConfigProperty } from '../helpers/config.helpers.js' import { apiKeyIsValid, userCanUpdate, diff --git a/handlers/print-get/pdf.js b/handlers/print-get/pdf.js index e6347635..1fde905a 100644 --- a/handlers/print-get/pdf.js +++ b/handlers/print-get/pdf.js @@ -2,7 +2,7 @@ import path from 'node:path'; import { convertHTMLToPDF } from '@cityssm/pdf-puppeteer'; import camelcase from 'camelcase'; import { renderFile as renderEjsFile } from 'ejs'; -import { getConfigProperty } from '../../helpers/functions.config.js'; +import { getConfigProperty } from '../../helpers/config.helpers.js'; import { getPdfPrintConfig, getReportData } from '../../helpers/functions.print.js'; const attachmentOrInline = getConfigProperty('settings.printPdf.contentDisposition'); export async function handler(request, response, next) { diff --git a/handlers/print-get/pdf.ts b/handlers/print-get/pdf.ts index 2e237ef8..038195dc 100644 --- a/handlers/print-get/pdf.ts +++ b/handlers/print-get/pdf.ts @@ -5,7 +5,7 @@ import camelcase from 'camelcase' import { renderFile as renderEjsFile } from 'ejs' import type { NextFunction, Request, Response } from 'express' -import { getConfigProperty } from '../../helpers/functions.config.js' +import { getConfigProperty } from '../../helpers/config.helpers.js' import { getPdfPrintConfig, getReportData diff --git a/handlers/print-get/screen.js b/handlers/print-get/screen.js index c550d358..10f0f75f 100644 --- a/handlers/print-get/screen.js +++ b/handlers/print-get/screen.js @@ -1,4 +1,4 @@ -import { getConfigProperty } from '../../helpers/functions.config.js'; +import { getConfigProperty } from '../../helpers/config.helpers.js'; import { getReportData, getScreenPrintConfig } from '../../helpers/functions.print.js'; export default async function handler(request, response) { const printName = request.params.printName; diff --git a/handlers/print-get/screen.ts b/handlers/print-get/screen.ts index 0b980489..93c55107 100644 --- a/handlers/print-get/screen.ts +++ b/handlers/print-get/screen.ts @@ -1,6 +1,6 @@ import type { Request, Response } from 'express' -import { getConfigProperty } from '../../helpers/functions.config.js' +import { getConfigProperty } from '../../helpers/config.helpers.js' import { getReportData, getScreenPrintConfig diff --git a/handlers/workOrders-get/edit.js b/handlers/workOrders-get/edit.js index 9bdde438..9199d2a0 100644 --- a/handlers/workOrders-get/edit.js +++ b/handlers/workOrders-get/edit.js @@ -1,6 +1,6 @@ import getWorkOrder from '../../database/getWorkOrder.js'; import { getLotStatuses, getWorkOrderMilestoneTypes, getWorkOrderTypes } from '../../helpers/functions.cache.js'; -import { getConfigProperty } from '../../helpers/functions.config.js'; +import { getConfigProperty } from '../../helpers/config.helpers.js'; export default async function handler(request, response) { const workOrder = await getWorkOrder(request.params.workOrderId, { includeLotsAndLotOccupancies: true, diff --git a/handlers/workOrders-get/edit.ts b/handlers/workOrders-get/edit.ts index ae5e65c0..13eb2e2b 100644 --- a/handlers/workOrders-get/edit.ts +++ b/handlers/workOrders-get/edit.ts @@ -6,7 +6,7 @@ import { getWorkOrderMilestoneTypes, getWorkOrderTypes } from '../../helpers/functions.cache.js' -import { getConfigProperty } from '../../helpers/functions.config.js' +import { getConfigProperty } from '../../helpers/config.helpers.js' export default async function handler( request: Request, diff --git a/handlers/workOrders-get/view.js b/handlers/workOrders-get/view.js index 1ede1db2..817777e0 100644 --- a/handlers/workOrders-get/view.js +++ b/handlers/workOrders-get/view.js @@ -1,5 +1,5 @@ import getWorkOrder from '../../database/getWorkOrder.js'; -import { getConfigProperty } from '../../helpers/functions.config.js'; +import { getConfigProperty } from '../../helpers/config.helpers.js'; export default async function handler(request, response) { const workOrder = await getWorkOrder(request.params.workOrderId, { includeLotsAndLotOccupancies: true, diff --git a/handlers/workOrders-get/view.ts b/handlers/workOrders-get/view.ts index 9fb9b141..fd9b1e42 100644 --- a/handlers/workOrders-get/view.ts +++ b/handlers/workOrders-get/view.ts @@ -1,7 +1,7 @@ import type { Request, Response } from 'express' import getWorkOrder from '../../database/getWorkOrder.js' -import { getConfigProperty } from '../../helpers/functions.config.js' +import { getConfigProperty } from '../../helpers/config.helpers.js' export default async function handler( request: Request, diff --git a/helpers/burialSites.helpers.d.ts b/helpers/burialSites.helpers.d.ts new file mode 100644 index 00000000..a686d2f1 --- /dev/null +++ b/helpers/burialSites.helpers.d.ts @@ -0,0 +1,3 @@ +export declare function getNextBurialSiteId(burialSiteId: number): Promise; +export declare function getPreviousBurialSiteId(burialSiteId: number): Promise; +export declare function clearNextPreviousBurialSiteIdCache(burialSiteId?: number, relayMessage?: boolean): void; diff --git a/helpers/burialSites.helpers.js b/helpers/burialSites.helpers.js new file mode 100644 index 00000000..e6460acd --- /dev/null +++ b/helpers/burialSites.helpers.js @@ -0,0 +1,99 @@ +import cluster from 'node:cluster'; +import Debug from 'debug'; +import NodeCache from 'node-cache'; +import getNextBurialSiteIdFromDatabase from '../database/getNextBurialSiteId.js'; +import getPreviousLotIdFromDatabase from '../database/getPreviousLotId.js'; +import { DEBUG_NAMESPACE } from '../debug.config.js'; +const debug = Debug(`${DEBUG_NAMESPACE}:burialSites.helpers:${process.pid}`); +const cacheOptions = { + stdTTL: 2 * 60, // two minutes + useClones: false +}; +const previousBurialSiteIdCache = new NodeCache(cacheOptions); +const nextBurialSiteIdCache = new NodeCache(cacheOptions); +function cacheBurialSiteIds(burialSiteId, nextBurialSiteId, relayMessage = true) { + previousBurialSiteIdCache.set(nextBurialSiteId, burialSiteId); + nextBurialSiteIdCache.set(burialSiteId, nextBurialSiteId); + try { + if (relayMessage && cluster.isWorker && process.send !== undefined) { + const workerMessage = { + messageType: 'cacheBurialSiteIds', + burialSiteId, + nextBurialSiteId, + timeMillis: Date.now(), + pid: process.pid + }; + debug(`Sending cache burial site ids from worker: (${burialSiteId}, ${nextBurialSiteId})`); + process.send(workerMessage); + } + } + catch { } +} +export async function getNextBurialSiteId(burialSiteId) { + let nextBurialSiteId = nextBurialSiteIdCache.get(burialSiteId); + if (nextBurialSiteId === undefined) { + nextBurialSiteId = await getNextBurialSiteIdFromDatabase(burialSiteId); + if (nextBurialSiteId !== undefined) { + cacheBurialSiteIds(burialSiteId, nextBurialSiteId); + } + } + return nextBurialSiteId; +} +export async function getPreviousBurialSiteId(burialSiteId) { + let previousBurialSiteId = previousBurialSiteIdCache.get(burialSiteId); + if (previousBurialSiteId === undefined) { + previousBurialSiteId = await getPreviousLotIdFromDatabase(burialSiteId); + if (previousBurialSiteId !== undefined) { + cacheBurialSiteIds(previousBurialSiteId, burialSiteId); + } + } + return previousBurialSiteId; +} +export function clearNextPreviousBurialSiteIdCache(burialSiteId = -1, relayMessage = true) { + if (burialSiteId === -1) { + previousBurialSiteIdCache.flushAll(); + nextBurialSiteIdCache.flushAll(); + return; + } + const previousBurialSiteId = previousBurialSiteIdCache.get(burialSiteId); + if (previousBurialSiteId !== undefined) { + nextBurialSiteIdCache.del(previousBurialSiteId); + previousBurialSiteIdCache.del(burialSiteId); + } + const nextBurialSiteId = nextBurialSiteIdCache.get(burialSiteId); + if (nextBurialSiteId !== undefined) { + previousBurialSiteIdCache.del(nextBurialSiteId); + nextBurialSiteIdCache.del(burialSiteId); + } + try { + if (relayMessage && cluster.isWorker && process.send !== undefined) { + const workerMessage = { + // eslint-disable-next-line no-secrets/no-secrets + messageType: 'clearNextPreviousBurialSiteIdCache', + burialSiteId, + timeMillis: Date.now(), + pid: process.pid + }; + debug(`Sending clear next/previous burial site cache from worker: ${burialSiteId}`); + process.send(workerMessage); + } + } + catch { } +} +process.on('message', (message) => { + if (message.pid !== process.pid) { + switch (message.messageType) { + case 'cacheBurialSiteIds': { + debug(`Caching burial site ids: (${message.burialSiteId}, ${message.nextBurialSiteId})`); + cacheBurialSiteIds(message.burialSiteId, message.nextBurialSiteId, false); + break; + } + // eslint-disable-next-line no-secrets/no-secrets + case 'clearNextPreviousBurialSiteIdCache': { + debug(`Clearing next/previous burial site cache: ${message.burialSiteId}`); + clearNextPreviousBurialSiteIdCache(message.burialSiteId, false); + break; + } + } + } +}); diff --git a/helpers/burialSites.helpers.ts b/helpers/burialSites.helpers.ts new file mode 100644 index 00000000..c3964491 --- /dev/null +++ b/helpers/burialSites.helpers.ts @@ -0,0 +1,162 @@ +import cluster from 'node:cluster' + +import Debug from 'debug' +import NodeCache from 'node-cache' + +import getNextBurialSiteIdFromDatabase from '../database/getNextBurialSiteId.js' +import getPreviousLotIdFromDatabase from '../database/getPreviousLotId.js' +import { DEBUG_NAMESPACE } from '../debug.config.js' +import type { + CacheBurialSiteIdsWorkerMessage, + ClearNextPreviousBurialSiteIdsCacheWorkerMessage +} from '../types/applicationTypes.js' + +const debug = Debug(`${DEBUG_NAMESPACE}:burialSites.helpers:${process.pid}`) + +const cacheOptions: NodeCache.Options = { + stdTTL: 2 * 60, // two minutes + useClones: false +} + +const previousBurialSiteIdCache = new NodeCache(cacheOptions) + +const nextBurialSiteIdCache = new NodeCache(cacheOptions) + +function cacheBurialSiteIds( + burialSiteId: number, + nextBurialSiteId: number, + relayMessage = true +): void { + previousBurialSiteIdCache.set(nextBurialSiteId, burialSiteId) + nextBurialSiteIdCache.set(burialSiteId, nextBurialSiteId) + + try { + if (relayMessage && cluster.isWorker && process.send !== undefined) { + const workerMessage: CacheBurialSiteIdsWorkerMessage = { + messageType: 'cacheBurialSiteIds', + burialSiteId, + nextBurialSiteId, + timeMillis: Date.now(), + pid: process.pid + } + + debug( + `Sending cache burial site ids from worker: (${burialSiteId}, ${nextBurialSiteId})` + ) + + process.send(workerMessage) + } + } catch {} +} + +export async function getNextBurialSiteId( + burialSiteId: number +): Promise { + let nextBurialSiteId: number | undefined = + nextBurialSiteIdCache.get(burialSiteId) + + if (nextBurialSiteId === undefined) { + nextBurialSiteId = await getNextBurialSiteIdFromDatabase(burialSiteId) + + if (nextBurialSiteId !== undefined) { + cacheBurialSiteIds(burialSiteId, nextBurialSiteId) + } + } + + return nextBurialSiteId +} + +export async function getPreviousBurialSiteId( + burialSiteId: number +): Promise { + let previousBurialSiteId: number | undefined = + previousBurialSiteIdCache.get(burialSiteId) + + if (previousBurialSiteId === undefined) { + previousBurialSiteId = await getPreviousLotIdFromDatabase(burialSiteId) + + if (previousBurialSiteId !== undefined) { + cacheBurialSiteIds(previousBurialSiteId, burialSiteId) + } + } + + return previousBurialSiteId +} + +export function clearNextPreviousBurialSiteIdCache( + burialSiteId = -1, + relayMessage = true +): void { + if (burialSiteId === -1) { + previousBurialSiteIdCache.flushAll() + nextBurialSiteIdCache.flushAll() + return + } + + const previousBurialSiteId: number | undefined = + previousBurialSiteIdCache.get(burialSiteId) + + if (previousBurialSiteId !== undefined) { + nextBurialSiteIdCache.del(previousBurialSiteId) + previousBurialSiteIdCache.del(burialSiteId) + } + + const nextBurialSiteId: number | undefined = + nextBurialSiteIdCache.get(burialSiteId) + + if (nextBurialSiteId !== undefined) { + previousBurialSiteIdCache.del(nextBurialSiteId) + nextBurialSiteIdCache.del(burialSiteId) + } + + try { + if (relayMessage && cluster.isWorker && process.send !== undefined) { + const workerMessage: ClearNextPreviousBurialSiteIdsCacheWorkerMessage = { + // eslint-disable-next-line no-secrets/no-secrets + messageType: 'clearNextPreviousBurialSiteIdCache', + burialSiteId, + timeMillis: Date.now(), + pid: process.pid + } + + debug( + `Sending clear next/previous burial site cache from worker: ${burialSiteId}` + ) + + process.send(workerMessage) + } + } catch {} +} + +process.on( + 'message', + ( + message: + | ClearNextPreviousBurialSiteIdsCacheWorkerMessage + | CacheBurialSiteIdsWorkerMessage + ) => { + if (message.pid !== process.pid) { + switch (message.messageType) { + case 'cacheBurialSiteIds': { + debug( + `Caching burial site ids: (${message.burialSiteId}, ${message.nextBurialSiteId})` + ) + cacheBurialSiteIds( + message.burialSiteId, + message.nextBurialSiteId, + false + ) + break + } + // eslint-disable-next-line no-secrets/no-secrets + case 'clearNextPreviousBurialSiteIdCache': { + debug( + `Clearing next/previous burial site cache: ${message.burialSiteId}` + ) + clearNextPreviousBurialSiteIdCache(message.burialSiteId, false) + break + } + } + } + } +) diff --git a/helpers/cemeteries.helpers.d.ts b/helpers/cemeteries.helpers.d.ts new file mode 100644 index 00000000..5e21009a --- /dev/null +++ b/helpers/cemeteries.helpers.d.ts @@ -0,0 +1 @@ +export declare function getCemeterySVGs(): Promise; diff --git a/helpers/cemeteries.helpers.js b/helpers/cemeteries.helpers.js new file mode 100644 index 00000000..28dbe1ca --- /dev/null +++ b/helpers/cemeteries.helpers.js @@ -0,0 +1,15 @@ +import fs from 'node:fs/promises'; +let cemeterySVGs; +export async function getCemeterySVGs() { + if (cemeterySVGs === undefined) { + const files = await fs.readdir('./public/images/cemeteries/'); + const SVGs = []; + for (const file of files) { + if (file.toLowerCase().endsWith('.svg')) { + SVGs.push(file); + } + } + cemeterySVGs = SVGs; + } + return cemeterySVGs; +} diff --git a/helpers/cemeteries.helpers.ts b/helpers/cemeteries.helpers.ts new file mode 100644 index 00000000..eff252dd --- /dev/null +++ b/helpers/cemeteries.helpers.ts @@ -0,0 +1,21 @@ +import fs from 'node:fs/promises' + +let cemeterySVGs: string[] | undefined + +export async function getCemeterySVGs(): Promise { + if (cemeterySVGs === undefined) { + const files = await fs.readdir('./public/images/cemeteries/') + + const SVGs: string[] = [] + + for (const file of files) { + if (file.toLowerCase().endsWith('.svg')) { + SVGs.push(file) + } + } + + cemeterySVGs = SVGs + } + + return cemeterySVGs +} diff --git a/helpers/functions.config.d.ts b/helpers/config.helpers.d.ts similarity index 74% rename from helpers/functions.config.d.ts rename to helpers/config.helpers.d.ts index 0350a7fa..fe84a5ca 100644 --- a/helpers/functions.config.d.ts +++ b/helpers/config.helpers.d.ts @@ -1,3 +1,7 @@ import { configDefaultValues } from '../data/config.defaultValues.js'; export declare function getConfigProperty(propertyName: K, fallbackValue?: (typeof configDefaultValues)[K]): (typeof configDefaultValues)[K]; +declare const _default: { + getConfigProperty: typeof getConfigProperty; +}; +export default _default; export declare const keepAliveMillis: number; diff --git a/helpers/functions.config.js b/helpers/config.helpers.js similarity index 93% rename from helpers/functions.config.js rename to helpers/config.helpers.js index 3450932c..afb47f5d 100644 --- a/helpers/functions.config.js +++ b/helpers/config.helpers.js @@ -6,6 +6,9 @@ const configurator = new Configurator(configDefaultValues, config); export function getConfigProperty(propertyName, fallbackValue) { return configurator.getConfigProperty(propertyName, fallbackValue); } +export default { + getConfigProperty +}; export const keepAliveMillis = getConfigProperty('session.doKeepAlive') ? Math.max(getConfigProperty('session.maxAgeMillis') / 2, getConfigProperty('session.maxAgeMillis') - secondsToMillis(10)) : 0; diff --git a/helpers/functions.config.ts b/helpers/config.helpers.ts similarity index 94% rename from helpers/functions.config.ts rename to helpers/config.helpers.ts index a42b0c20..b86ac409 100644 --- a/helpers/functions.config.ts +++ b/helpers/config.helpers.ts @@ -19,9 +19,13 @@ export function getConfigProperty( ) as (typeof configDefaultValues)[K] } +export default { + getConfigProperty +} + export const keepAliveMillis = getConfigProperty('session.doKeepAlive') ? Math.max( getConfigProperty('session.maxAgeMillis') / 2, - getConfigProperty('session.maxAgeMillis') - secondsToMillis (10) + getConfigProperty('session.maxAgeMillis') - secondsToMillis(10) ) : 0 diff --git a/helpers/database.helpers.d.ts b/helpers/database.helpers.d.ts new file mode 100644 index 00000000..73c0839e --- /dev/null +++ b/helpers/database.helpers.d.ts @@ -0,0 +1,5 @@ +export declare const useTestDatabases: boolean; +export declare const sunriseDBLive = "data/sunrise.db"; +export declare const sunriseDBTesting = "data/sunrise-testing.db"; +export declare const sunriseDB: string; +export declare const backupFolder = "data/backups"; diff --git a/helpers/database.helpers.js b/helpers/database.helpers.js new file mode 100644 index 00000000..6a1637bd --- /dev/null +++ b/helpers/database.helpers.js @@ -0,0 +1,13 @@ +import Debug from 'debug'; +import { DEBUG_NAMESPACE } from '../debug.config.js'; +import { getConfigProperty } from './config.helpers.js'; +const debug = Debug(`${DEBUG_NAMESPACE}:database.helpers`); +export const useTestDatabases = getConfigProperty('application.useTestDatabases') || + process.env.TEST_DATABASES === 'true'; +if (useTestDatabases) { + debug('Using "-testing" databases.'); +} +export const sunriseDBLive = 'data/sunrise.db'; +export const sunriseDBTesting = 'data/sunrise-testing.db'; +export const sunriseDB = useTestDatabases ? sunriseDBTesting : sunriseDBLive; +export const backupFolder = 'data/backups'; diff --git a/helpers/database.helpers.ts b/helpers/database.helpers.ts new file mode 100644 index 00000000..6c3359db --- /dev/null +++ b/helpers/database.helpers.ts @@ -0,0 +1,22 @@ +import Debug from 'debug' + +import { DEBUG_NAMESPACE } from '../debug.config.js' + +import { getConfigProperty } from './config.helpers.js' + +const debug = Debug(`${DEBUG_NAMESPACE}:database.helpers`) + +export const useTestDatabases = + getConfigProperty('application.useTestDatabases') || + process.env.TEST_DATABASES === 'true' + +if (useTestDatabases) { + debug('Using "-testing" databases.') +} + +export const sunriseDBLive = 'data/sunrise.db' +export const sunriseDBTesting = 'data/sunrise-testing.db' + +export const sunriseDB = useTestDatabases ? sunriseDBTesting : sunriseDBLive + +export const backupFolder = 'data/backups' diff --git a/helpers/functions.api.js b/helpers/functions.api.js index bbe6c1af..151190ae 100644 --- a/helpers/functions.api.js +++ b/helpers/functions.api.js @@ -1,7 +1,8 @@ import fs from 'node:fs/promises'; import Debug from 'debug'; import { v4 as uuidV4 } from 'uuid'; -const debug = Debug('lot-occupancy-system:functions.api'); +import { DEBUG_NAMESPACE } from '../debug.config.js'; +const debug = Debug(`${DEBUG_NAMESPACE}:functions.api`); const apiKeyPath = 'data/apiKeys.json'; let apiKeys; async function loadApiKeys() { diff --git a/helpers/functions.api.ts b/helpers/functions.api.ts index 10086564..3ba3a764 100644 --- a/helpers/functions.api.ts +++ b/helpers/functions.api.ts @@ -3,7 +3,9 @@ import fs from 'node:fs/promises' import Debug from 'debug' import { v4 as uuidV4 } from 'uuid' -const debug = Debug('lot-occupancy-system:functions.api') +import { DEBUG_NAMESPACE } from '../debug.config.js' + +const debug = Debug(`${DEBUG_NAMESPACE}:functions.api`) const apiKeyPath = 'data/apiKeys.json' let apiKeys: Record | undefined diff --git a/helpers/functions.authentication.js b/helpers/functions.authentication.js index d5198394..88a140f0 100644 --- a/helpers/functions.authentication.js +++ b/helpers/functions.authentication.js @@ -1,5 +1,5 @@ import ActiveDirectory from 'activedirectory2'; -import { getConfigProperty } from './functions.config.js'; +import { getConfigProperty } from './config.helpers.js'; const userDomain = getConfigProperty('application.userDomain'); const activeDirectoryConfig = getConfigProperty('activeDirectory'); async function authenticateViaActiveDirectory(userName, password) { diff --git a/helpers/functions.authentication.ts b/helpers/functions.authentication.ts index fe668470..d4e44bc2 100644 --- a/helpers/functions.authentication.ts +++ b/helpers/functions.authentication.ts @@ -1,6 +1,6 @@ import ActiveDirectory from 'activedirectory2' -import { getConfigProperty } from './functions.config.js' +import { getConfigProperty } from './config.helpers.js' const userDomain = getConfigProperty('application.userDomain') diff --git a/helpers/functions.cache.js b/helpers/functions.cache.js index 9fee0366..433fb644 100644 --- a/helpers/functions.cache.js +++ b/helpers/functions.cache.js @@ -9,8 +9,9 @@ import getOccupancyTypeFieldsFromDatabase from '../database/getOccupancyTypeFiel import getOccupancyTypesFromDatabase from '../database/getOccupancyTypes.js'; import getWorkOrderMilestoneTypesFromDatabase from '../database/getWorkOrderMilestoneTypes.js'; import getWorkOrderTypesFromDatabase from '../database/getWorkOrderTypes.js'; -import { getConfigProperty } from './functions.config.js'; -const debug = Debug(`lot-occupancy-system:functions.cache:${process.pid}`); +import { DEBUG_NAMESPACE } from '../debug.config.js'; +import { getConfigProperty } from './config.helpers.js'; +const debug = Debug(`${DEBUG_NAMESPACE}:functions.cache:${process.pid}`); /* * Lot Occupant Types */ diff --git a/helpers/functions.cache.ts b/helpers/functions.cache.ts index 29c4203c..b266c27e 100644 --- a/helpers/functions.cache.ts +++ b/helpers/functions.cache.ts @@ -12,6 +12,7 @@ import getOccupancyTypeFieldsFromDatabase from '../database/getOccupancyTypeFiel import getOccupancyTypesFromDatabase from '../database/getOccupancyTypes.js' import getWorkOrderMilestoneTypesFromDatabase from '../database/getWorkOrderMilestoneTypes.js' import getWorkOrderTypesFromDatabase from '../database/getWorkOrderTypes.js' +import { DEBUG_NAMESPACE } from '../debug.config.js' import type { ClearCacheWorkerMessage, WorkerMessage @@ -26,9 +27,9 @@ import type { WorkOrderType } from '../types/recordTypes.js' -import { getConfigProperty } from './functions.config.js' +import { getConfigProperty } from './config.helpers.js' -const debug = Debug(`lot-occupancy-system:functions.cache:${process.pid}`) +const debug = Debug(`${DEBUG_NAMESPACE}:functions.cache:${process.pid}`) /* * Lot Occupant Types diff --git a/helpers/functions.database.js b/helpers/functions.database.js index b5a19f18..cd6d1b04 100644 --- a/helpers/functions.database.js +++ b/helpers/functions.database.js @@ -1,5 +1,5 @@ import fs from 'node:fs/promises'; -import { backupFolder, lotOccupancyDB as databasePath } from '../data/databasePaths.js'; +import { backupFolder, sunriseDB as databasePath } from '../helpers/database.helpers.js'; export async function backupDatabase() { const databasePathSplit = databasePath.split(/[/\\]/); const backupDatabasePath = `${backupFolder}/${databasePathSplit.at(-1)}.${Date.now().toString()}`; diff --git a/helpers/functions.database.ts b/helpers/functions.database.ts index 96e710bc..95bc0f53 100644 --- a/helpers/functions.database.ts +++ b/helpers/functions.database.ts @@ -2,8 +2,8 @@ import fs from 'node:fs/promises' import { backupFolder, - lotOccupancyDB as databasePath -} from '../data/databasePaths.js' + sunriseDB as databasePath +} from '../helpers/database.helpers.js' export async function backupDatabase(): Promise { const databasePathSplit = databasePath.split(/[/\\]/) diff --git a/helpers/functions.dynamicsGP.js b/helpers/functions.dynamicsGP.js index d71a95ee..a815d63d 100644 --- a/helpers/functions.dynamicsGP.js +++ b/helpers/functions.dynamicsGP.js @@ -1,5 +1,5 @@ import { DynamicsGP } from '@cityssm/dynamics-gp'; -import { getConfigProperty } from './functions.config.js'; +import { getConfigProperty } from './config.helpers.js'; // eslint-disable-next-line @typescript-eslint/init-declarations let gp; if (getConfigProperty('settings.dynamicsGP.integrationIsEnabled')) { diff --git a/helpers/functions.dynamicsGP.ts b/helpers/functions.dynamicsGP.ts index acc8a2ef..2564c705 100644 --- a/helpers/functions.dynamicsGP.ts +++ b/helpers/functions.dynamicsGP.ts @@ -8,7 +8,7 @@ import { import type { DynamicsGPLookup } from '../types/configTypes.js' import type { DynamicsGPDocument } from '../types/recordTypes.js' -import { getConfigProperty } from './functions.config.js' +import { getConfigProperty } from './config.helpers.js' // eslint-disable-next-line @typescript-eslint/init-declarations let gp: DynamicsGP diff --git a/helpers/functions.lotOccupancy.d.ts b/helpers/functions.lotOccupancy.d.ts index d147f9b6..d3813651 100644 --- a/helpers/functions.lotOccupancy.d.ts +++ b/helpers/functions.lotOccupancy.d.ts @@ -1,4 +1,4 @@ -import type { LotOccupancy, LotOccupancyFee, LotOccupancyOccupant } from '../types/recordTypes'; +import type { LotOccupancy, LotOccupancyFee, LotOccupancyOccupant } from '../types/recordTypes.js'; export declare function filterOccupantsByLotOccupantType(lotOccupancy: LotOccupancy, lotOccupantType: string): LotOccupancyOccupant[]; export declare function getFieldValueByOccupancyTypeField(lotOccupancy: LotOccupancy, occupancyTypeField: string): string | undefined; export declare function getFeesByFeeCategory(lotOccupancy: LotOccupancy, feeCategory: string, feeCategoryContains?: boolean): LotOccupancyFee[]; diff --git a/helpers/functions.lotOccupancy.ts b/helpers/functions.lotOccupancy.ts index d4bb2cd8..d55a41c9 100644 --- a/helpers/functions.lotOccupancy.ts +++ b/helpers/functions.lotOccupancy.ts @@ -2,7 +2,7 @@ import type { LotOccupancy, LotOccupancyFee, LotOccupancyOccupant -} from '../types/recordTypes' +} from '../types/recordTypes.js' export function filterOccupantsByLotOccupantType( lotOccupancy: LotOccupancy, diff --git a/helpers/functions.lots.d.ts b/helpers/functions.lots.d.ts deleted file mode 100644 index e43ad87b..00000000 --- a/helpers/functions.lots.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -export declare function getNextLotId(lotId: number): Promise; -export declare function getPreviousLotId(lotId: number): Promise; -export declare function clearNextPreviousLotIdCache(lotId: number | -1, relayMessage?: boolean): void; diff --git a/helpers/functions.lots.js b/helpers/functions.lots.js deleted file mode 100644 index e75afd60..00000000 --- a/helpers/functions.lots.js +++ /dev/null @@ -1,96 +0,0 @@ -import cluster from 'node:cluster'; -import Debug from 'debug'; -import NodeCache from 'node-cache'; -import getNextLotIdFromDatabase from '../database/getNextLotId.js'; -import getPreviousLotIdFromDatabase from '../database/getPreviousLotId.js'; -const debug = Debug(`lot-occupancy-system:functions.lots:${process.pid}`); -const cacheOptions = { - stdTTL: 2 * 60, // two minutes - useClones: false -}; -const previousLotIdCache = new NodeCache(cacheOptions); -const nextLotIdCache = new NodeCache(cacheOptions); -function cacheLotIds(lotId, nextLotId, relayMessage = true) { - previousLotIdCache.set(nextLotId, lotId); - nextLotIdCache.set(lotId, nextLotId); - try { - if (relayMessage && cluster.isWorker) { - const workerMessage = { - messageType: 'cacheLotIds', - lotId, - nextLotId, - timeMillis: Date.now(), - pid: process.pid - }; - debug(`Sending cache lot ids from worker: (${lotId}, ${nextLotId})`); - process.send(workerMessage); - } - } - catch { } -} -export async function getNextLotId(lotId) { - let nextLotId = nextLotIdCache.get(lotId); - if (nextLotId === undefined) { - nextLotId = await getNextLotIdFromDatabase(lotId); - if (nextLotId !== undefined) { - cacheLotIds(lotId, nextLotId); - } - } - return nextLotId; -} -export async function getPreviousLotId(lotId) { - let previousLotId = previousLotIdCache.get(lotId); - if (previousLotId === undefined) { - previousLotId = await getPreviousLotIdFromDatabase(lotId); - if (previousLotId !== undefined) { - cacheLotIds(previousLotId, lotId); - } - } - return previousLotId; -} -export function clearNextPreviousLotIdCache(lotId, relayMessage = true) { - if (lotId === undefined || lotId === -1) { - previousLotIdCache.flushAll(); - nextLotIdCache.flushAll(); - return; - } - const previousLotId = previousLotIdCache.get(lotId); - if (previousLotId !== undefined) { - nextLotIdCache.del(previousLotId); - previousLotIdCache.del(lotId); - } - const nextLotId = nextLotIdCache.get(lotId); - if (nextLotId !== undefined) { - previousLotIdCache.del(nextLotId); - nextLotIdCache.del(lotId); - } - try { - if (relayMessage && cluster.isWorker) { - const workerMessage = { - messageType: 'clearNextPreviousLotIdCache', - lotId, - timeMillis: Date.now(), - pid: process.pid - }; - debug(`Sending clear next/previous lot cache from worker: ${lotId}`); - process.send(workerMessage); - } - } - catch { } -} -process.on('message', (message) => { - if (message.pid !== process.pid) { - switch (message.messageType) { - case 'cacheLotIds': { - debug(`Caching lot ids: (${message.lotId}, ${message.nextLotId})`); - cacheLotIds(message.lotId, message.nextLotId, false); - break; - } - case 'clearNextPreviousLotIdCache': { - debug(`Clearing next/previous lot cache: ${message.lotId}`); - clearNextPreviousLotIdCache(message.lotId, false); - break; - } - } - } -}); diff --git a/helpers/functions.lots.ts b/helpers/functions.lots.ts deleted file mode 100644 index 6987b158..00000000 --- a/helpers/functions.lots.ts +++ /dev/null @@ -1,141 +0,0 @@ -import cluster from 'node:cluster' - -import Debug from 'debug' -import NodeCache from 'node-cache' - -import getNextLotIdFromDatabase from '../database/getNextLotId.js' -import getPreviousLotIdFromDatabase from '../database/getPreviousLotId.js' -import type { - CacheLotIdsWorkerMessage, - ClearNextPreviousLotIdsCacheWorkerMessage -} from '../types/applicationTypes.js' - -const debug = Debug(`lot-occupancy-system:functions.lots:${process.pid}`) - -const cacheOptions: NodeCache.Options = { - stdTTL: 2 * 60, // two minutes - useClones: false -} - -const previousLotIdCache = new NodeCache(cacheOptions) - -const nextLotIdCache = new NodeCache(cacheOptions) - -function cacheLotIds( - lotId: number, - nextLotId: number, - relayMessage = true -): void { - previousLotIdCache.set(nextLotId, lotId) - nextLotIdCache.set(lotId, nextLotId) - - try { - if (relayMessage && cluster.isWorker) { - const workerMessage: CacheLotIdsWorkerMessage = { - messageType: 'cacheLotIds', - lotId, - nextLotId, - timeMillis: Date.now(), - pid: process.pid - } - - debug(`Sending cache lot ids from worker: (${lotId}, ${nextLotId})`) - - process.send!(workerMessage) - } - } catch {} -} - -export async function getNextLotId(lotId: number): Promise { - let nextLotId: number | undefined = nextLotIdCache.get(lotId) - - if (nextLotId === undefined) { - nextLotId = await getNextLotIdFromDatabase(lotId) - - if (nextLotId !== undefined) { - cacheLotIds(lotId, nextLotId) - } - } - - return nextLotId -} - -export async function getPreviousLotId( - lotId: number -): Promise { - let previousLotId: number | undefined = previousLotIdCache.get(lotId) - - if (previousLotId === undefined) { - previousLotId = await getPreviousLotIdFromDatabase(lotId) - - if (previousLotId !== undefined) { - cacheLotIds(previousLotId, lotId) - } - } - - return previousLotId -} - -export function clearNextPreviousLotIdCache( - lotId: number | -1, - relayMessage = true -): void { - if (lotId === undefined || lotId === -1) { - previousLotIdCache.flushAll() - nextLotIdCache.flushAll() - return - } - - const previousLotId: number | undefined = previousLotIdCache.get(lotId) - - if (previousLotId !== undefined) { - nextLotIdCache.del(previousLotId) - previousLotIdCache.del(lotId) - } - - const nextLotId: number | undefined = nextLotIdCache.get(lotId) - - if (nextLotId !== undefined) { - previousLotIdCache.del(nextLotId) - nextLotIdCache.del(lotId) - } - - try { - if (relayMessage && cluster.isWorker) { - const workerMessage: ClearNextPreviousLotIdsCacheWorkerMessage = { - messageType: 'clearNextPreviousLotIdCache', - lotId, - timeMillis: Date.now(), - pid: process.pid - } - - debug(`Sending clear next/previous lot cache from worker: ${lotId}`) - - process.send!(workerMessage) - } - } catch {} -} - -process.on( - 'message', - ( - message: - | ClearNextPreviousLotIdsCacheWorkerMessage - | CacheLotIdsWorkerMessage - ) => { - if (message.pid !== process.pid) { - switch (message.messageType) { - case 'cacheLotIds': { - debug(`Caching lot ids: (${message.lotId}, ${message.nextLotId})`) - cacheLotIds(message.lotId, message.nextLotId, false) - break - } - case 'clearNextPreviousLotIdCache': { - debug(`Clearing next/previous lot cache: ${message.lotId}`) - clearNextPreviousLotIdCache(message.lotId, false) - break - } - } - } - } -) diff --git a/helpers/functions.map.d.ts b/helpers/functions.map.d.ts deleted file mode 100644 index 89887016..00000000 --- a/helpers/functions.map.d.ts +++ /dev/null @@ -1 +0,0 @@ -export declare function getMapSVGs(): Promise; diff --git a/helpers/functions.map.js b/helpers/functions.map.js deleted file mode 100644 index eb9d869b..00000000 --- a/helpers/functions.map.js +++ /dev/null @@ -1,15 +0,0 @@ -import fs from 'node:fs/promises'; -let mapSVGs; -export async function getMapSVGs() { - if (mapSVGs === undefined) { - const files = await fs.readdir('./public/images/maps/'); - const SVGs = []; - for (const file of files) { - if (file.toLowerCase().endsWith('.svg')) { - SVGs.push(file); - } - } - mapSVGs = SVGs; - } - return mapSVGs; -} diff --git a/helpers/functions.map.ts b/helpers/functions.map.ts deleted file mode 100644 index 56b89566..00000000 --- a/helpers/functions.map.ts +++ /dev/null @@ -1,21 +0,0 @@ -import fs from 'node:fs/promises' - -let mapSVGs: string[] | undefined - -export async function getMapSVGs(): Promise { - if (mapSVGs === undefined) { - const files = await fs.readdir('./public/images/maps/') - - const SVGs: string[] = [] - - for (const file of files) { - if (file.toLowerCase().endsWith('.svg')) { - SVGs.push(file) - } - } - - mapSVGs = SVGs - } - - return mapSVGs -} diff --git a/helpers/functions.print.js b/helpers/functions.print.js index ac6a5073..73a1d94b 100644 --- a/helpers/functions.print.js +++ b/helpers/functions.print.js @@ -2,7 +2,7 @@ import * as dateTimeFunctions from '@cityssm/utils-datetime'; import getLot from '../database/getLot.js'; import getLotOccupancy from '../database/getLotOccupancy.js'; import getWorkOrder from '../database/getWorkOrder.js'; -import * as configFunctions from './functions.config.js'; +import * as configFunctions from './config.helpers.js'; import * as lotOccupancyFunctions from './functions.lotOccupancy.js'; const screenPrintConfigs = { lotOccupancy: { diff --git a/helpers/functions.print.ts b/helpers/functions.print.ts index 5f2fe29c..020aacb3 100644 --- a/helpers/functions.print.ts +++ b/helpers/functions.print.ts @@ -5,7 +5,7 @@ import getLotOccupancy from '../database/getLotOccupancy.js' import getWorkOrder from '../database/getWorkOrder.js' import type { Lot, LotOccupancy, WorkOrder } from '../types/recordTypes.js' -import * as configFunctions from './functions.config.js' +import * as configFunctions from './config.helpers.js' import * as lotOccupancyFunctions from './functions.lotOccupancy.js' interface PrintConfig { diff --git a/helpers/functions.user.js b/helpers/functions.user.js index c259b894..0863eba2 100644 --- a/helpers/functions.user.js +++ b/helpers/functions.user.js @@ -1,5 +1,5 @@ import { getUserNameFromApiKey } from './functions.api.js'; -import { getConfigProperty } from './functions.config.js'; +import { getConfigProperty } from './config.helpers.js'; export function userIsAdmin(request) { return request.session?.user?.userProperties?.isAdmin ?? false; } diff --git a/helpers/functions.user.ts b/helpers/functions.user.ts index 2eaabf14..2533ab1a 100644 --- a/helpers/functions.user.ts +++ b/helpers/functions.user.ts @@ -1,5 +1,5 @@ import { getUserNameFromApiKey } from './functions.api.js' -import { getConfigProperty } from './functions.config.js' +import { getConfigProperty } from './config.helpers.js' export interface UserRequest { session?: { diff --git a/helpers/initializer.database.cemetery.d.ts b/helpers/initializer.database.cemetery.d.ts deleted file mode 100644 index bd4e162f..00000000 --- a/helpers/initializer.database.cemetery.d.ts +++ /dev/null @@ -1 +0,0 @@ -export declare function initializeCemeteryDatabase(): Promise; diff --git a/helpers/initializer.database.cemetery.js b/helpers/initializer.database.cemetery.js deleted file mode 100644 index 589f452c..00000000 --- a/helpers/initializer.database.cemetery.js +++ /dev/null @@ -1,245 +0,0 @@ -// eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair -/* eslint-disable @typescript-eslint/no-magic-numbers */ -import Debug from 'debug'; -import { lotOccupancyDB as databasePath } from '../data/databasePaths.js'; -import addFeeCategory from '../database/addFeeCategory.js'; -import addLotOccupantType from '../database/addLotOccupantType.js'; -import addOccupancyTypeField from '../database/addOccupancyTypeField.js'; -import { addRecord } from '../database/addRecord.js'; -import { initializeDatabase } from './initializer.database.js'; -const debug = Debug('lot-occupancy-system:initialize'); -const user = { - userName: 'init.cemetery', - userProperties: { - canUpdate: true, - isAdmin: true, - apiKey: '' - } -}; -export async function initializeCemeteryDatabase() { - /* - * Ensure database does not already exist - */ - debug(`Checking for ${databasePath}...`); - const databaseInitialized = initializeDatabase(); - if (!databaseInitialized) { - debug('Database already created.\n' + - 'To initialize this database with cemetery types, delete the database file first, then rerun this script.'); - return false; - } - debug('New database file created. Proceeding with initialization.'); - /* - * Lot Types - */ - await addRecord('LotTypes', 'Casket Grave', 1, user); - await addRecord('LotTypes', 'Columbarium', 2, user); - await addRecord('LotTypes', 'Mausoleum', 2, user); - await addRecord('LotTypes', 'Niche Wall', 2, user); - await addRecord('LotTypes', 'Urn Garden', 2, user); - await addRecord('LotTypes', 'Crematorium', 2, user); - /* - * Lot Statuses - */ - await addRecord('LotStatuses', 'Available', 1, user); - await addRecord('LotStatuses', 'Reserved', 2, user); - await addRecord('LotStatuses', 'Taken', 3, user); - /* - * Lot Occupant Types - */ - await addLotOccupantType({ - lotOccupantType: 'Deceased', - fontAwesomeIconClass: 'cross', - orderNumber: 1 - }, user); - await addLotOccupantType({ - lotOccupantType: 'Funeral Director', - fontAwesomeIconClass: 'church', - orderNumber: 2 - }, user); - await addLotOccupantType({ - lotOccupantType: 'Preneed Owner', - fontAwesomeIconClass: 'user', - orderNumber: 3 - }, user); - await addLotOccupantType({ - lotOccupantType: 'Purchaser', - fontAwesomeIconClass: 'hand-holding-usd', - occupantCommentTitle: 'Relationship to Owner/Deceased', - orderNumber: 4 - }, user); - /* - * Occupancy Types - */ - await addRecord('OccupancyTypes', 'Preneed', 1, user); - const intermentOccupancyTypeId = await addRecord('OccupancyTypes', 'Interment', 2, user); - const cremationOccupancyTypeId = await addRecord('OccupancyTypes', 'Cremation', 3, user); - // Birth Date - const birthDateField = { - occupancyTypeId: intermentOccupancyTypeId, - occupancyTypeField: 'Birth Date', - occupancyTypeFieldValues: '', - pattern: String.raw `\d{4}-\d{2}-\d{2}`, - isRequired: '', - minimumLength: 10, - maximumLength: 10, - orderNumber: 1 - }; - await addOccupancyTypeField(birthDateField, user); - await addOccupancyTypeField(Object.assign(birthDateField, { - occupancyTypeId: cremationOccupancyTypeId - }), user); - // Birth Place - const birthPlace = { - occupancyTypeId: intermentOccupancyTypeId, - occupancyTypeField: 'Birth Place', - occupancyTypeFieldValues: '', - pattern: '', - isRequired: '', - minimumLength: 1, - maximumLength: 100, - orderNumber: 2 - }; - await addOccupancyTypeField(birthPlace, user); - await addOccupancyTypeField(Object.assign(birthPlace, { occupancyTypeId: cremationOccupancyTypeId }), user); - // Death Date - const deathDateField = { - occupancyTypeId: intermentOccupancyTypeId, - occupancyTypeField: 'Death Date', - occupancyTypeFieldValues: '', - pattern: String.raw `\d{4}-\d{2}-\d{2}`, - isRequired: '', - minimumLength: 10, - maximumLength: 10, - orderNumber: 3 - }; - await addOccupancyTypeField(deathDateField, user); - await addOccupancyTypeField(Object.assign(deathDateField, { - occupancyTypeId: cremationOccupancyTypeId - }), user); - // Death Age - const deathAgeField = { - occupancyTypeId: intermentOccupancyTypeId, - occupancyTypeField: 'Death Age', - occupancyTypeFieldValues: '', - pattern: String.raw `\d+`, - isRequired: '', - minimumLength: 1, - maximumLength: 3, - orderNumber: 4 - }; - await addOccupancyTypeField(deathAgeField, user); - await addOccupancyTypeField(Object.assign(deathAgeField, { occupancyTypeId: cremationOccupancyTypeId }), user); - // Death Age Period - const deathAgePeriod = { - occupancyTypeId: intermentOccupancyTypeId, - occupancyTypeField: 'Death Age Period', - fieldType: 'select', - occupancyTypeFieldValues: 'Years\nMonths\nDays\nStillborn', - pattern: '', - isRequired: '', - minimumLength: 1, - maximumLength: 10, - orderNumber: 5 - }; - await addOccupancyTypeField(deathAgePeriod, user); - await addOccupancyTypeField(Object.assign(deathAgePeriod, { - occupancyTypeId: cremationOccupancyTypeId - }), user); - // Death Place - const deathPlace = { - occupancyTypeId: intermentOccupancyTypeId, - occupancyTypeField: 'Death Place', - occupancyTypeFieldValues: '', - pattern: '', - isRequired: '', - minimumLength: 1, - maximumLength: 100, - orderNumber: 6 - }; - await addOccupancyTypeField(deathPlace, user); - await addOccupancyTypeField(Object.assign(deathPlace, { occupancyTypeId: cremationOccupancyTypeId }), user); - // Funeral Home - const funeralHome = { - occupancyTypeId: intermentOccupancyTypeId, - occupancyTypeField: 'Funeral Home', - occupancyTypeFieldValues: '', - pattern: '', - isRequired: '', - minimumLength: 1, - maximumLength: 100, - orderNumber: 10 - }; - await addOccupancyTypeField(funeralHome, user); - await addOccupancyTypeField(Object.assign(funeralHome, { occupancyTypeId: cremationOccupancyTypeId }), user); - // Funeral Date - const funeralDate = { - occupancyTypeId: intermentOccupancyTypeId, - occupancyTypeField: 'Funeral Date', - occupancyTypeFieldValues: '', - pattern: String.raw `\d{4}-\d{2}-\d{2}`, - isRequired: '', - minimumLength: 10, - maximumLength: 10, - orderNumber: 11 - }; - await addOccupancyTypeField(funeralDate, user); - await addOccupancyTypeField(Object.assign(funeralDate, { occupancyTypeId: cremationOccupancyTypeId }), user); - // Container Type - const containerType = { - occupancyTypeId: intermentOccupancyTypeId, - occupancyTypeField: 'Container Type', - occupancyTypeFieldValues: '', - pattern: '', - isRequired: '', - minimumLength: 1, - maximumLength: 100, - orderNumber: 20 - }; - await addOccupancyTypeField(containerType, user); - await addOccupancyTypeField(Object.assign(containerType, { occupancyTypeId: cremationOccupancyTypeId }), user); - // Committal Type - const committalType = { - occupancyTypeId: intermentOccupancyTypeId, - occupancyTypeField: 'Committal Type', - occupancyTypeFieldValues: '', - pattern: '', - isRequired: '', - minimumLength: 1, - maximumLength: 100, - orderNumber: 21 - }; - await addOccupancyTypeField(committalType, user); - await addOccupancyTypeField(Object.assign(committalType, { occupancyTypeId: cremationOccupancyTypeId }), user); - /* - * Fee Categories - */ - await addFeeCategory({ - feeCategory: 'Interment Rights', - orderNumber: 1 - }, user); - await addFeeCategory({ - feeCategory: 'Cremation Services', - orderNumber: 2 - }, user); - await addFeeCategory({ - feeCategory: 'Burial Charges', - orderNumber: 3 - }, user); - await addFeeCategory({ - feeCategory: 'Disinterment of Human Remains', - orderNumber: 4 - }, user); - await addFeeCategory({ - feeCategory: 'Additional Services', - orderNumber: 5 - }, user); - /* - * Work Orders - */ - await addRecord('WorkOrderTypes', 'Cemetery Work Order', 1, user); - await addRecord('WorkOrderMilestoneTypes', 'Funeral', 1, user); - await addRecord('WorkOrderMilestoneTypes', 'Arrival', 2, user); - await addRecord('WorkOrderMilestoneTypes', 'Cremation', 3, user); - await addRecord('WorkOrderMilestoneTypes', 'Interment', 4, user); - return true; -} diff --git a/helpers/initializer.database.cemetery.ts b/helpers/initializer.database.cemetery.ts deleted file mode 100644 index 63d2ad92..00000000 --- a/helpers/initializer.database.cemetery.ts +++ /dev/null @@ -1,383 +0,0 @@ -// eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair -/* eslint-disable @typescript-eslint/no-magic-numbers */ - -import Debug from 'debug' - -import { lotOccupancyDB as databasePath } from '../data/databasePaths.js' -import addFeeCategory from '../database/addFeeCategory.js' -import addLotOccupantType from '../database/addLotOccupantType.js' -import addOccupancyTypeField from '../database/addOccupancyTypeField.js' -import { addRecord } from '../database/addRecord.js' - -import { initializeDatabase } from './initializer.database.js' - -const debug = Debug('lot-occupancy-system:initialize') - -const user: User = { - userName: 'init.cemetery', - userProperties: { - canUpdate: true, - isAdmin: true, - apiKey: '' - } -} - -export async function initializeCemeteryDatabase(): Promise { - /* - * Ensure database does not already exist - */ - debug(`Checking for ${databasePath}...`) - - const databaseInitialized = initializeDatabase() - - if (!databaseInitialized) { - debug( - 'Database already created.\n' + - 'To initialize this database with cemetery types, delete the database file first, then rerun this script.' - ) - return false - } - - debug('New database file created. Proceeding with initialization.') - - /* - * Lot Types - */ - - await addRecord('LotTypes', 'Casket Grave', 1, user) - await addRecord('LotTypes', 'Columbarium', 2, user) - await addRecord('LotTypes', 'Mausoleum', 2, user) - await addRecord('LotTypes', 'Niche Wall', 2, user) - await addRecord('LotTypes', 'Urn Garden', 2, user) - await addRecord('LotTypes', 'Crematorium', 2, user) - - /* - * Lot Statuses - */ - - await addRecord('LotStatuses', 'Available', 1, user) - await addRecord('LotStatuses', 'Reserved', 2, user) - await addRecord('LotStatuses', 'Taken', 3, user) - - /* - * Lot Occupant Types - */ - - await addLotOccupantType( - { - lotOccupantType: 'Deceased', - fontAwesomeIconClass: 'cross', - orderNumber: 1 - }, - user - ) - - await addLotOccupantType( - { - lotOccupantType: 'Funeral Director', - fontAwesomeIconClass: 'church', - orderNumber: 2 - }, - user - ) - - await addLotOccupantType( - { - lotOccupantType: 'Preneed Owner', - fontAwesomeIconClass: 'user', - orderNumber: 3 - }, - user - ) - - await addLotOccupantType( - { - lotOccupantType: 'Purchaser', - fontAwesomeIconClass: 'hand-holding-usd', - occupantCommentTitle: 'Relationship to Owner/Deceased', - orderNumber: 4 - }, - user - ) - - /* - * Occupancy Types - */ - - await addRecord('OccupancyTypes', 'Preneed', 1, user) - const intermentOccupancyTypeId = await addRecord( - 'OccupancyTypes', - 'Interment', - 2, - user - ) - const cremationOccupancyTypeId = await addRecord( - 'OccupancyTypes', - 'Cremation', - 3, - user - ) - - // Birth Date - - const birthDateField = { - occupancyTypeId: intermentOccupancyTypeId, - occupancyTypeField: 'Birth Date', - occupancyTypeFieldValues: '', - pattern: String.raw`\d{4}-\d{2}-\d{2}`, - isRequired: '', - minimumLength: 10, - maximumLength: 10, - orderNumber: 1 - } - - await addOccupancyTypeField(birthDateField, user) - - await addOccupancyTypeField( - Object.assign(birthDateField, { - occupancyTypeId: cremationOccupancyTypeId - }), - user - ) - - // Birth Place - - const birthPlace = { - occupancyTypeId: intermentOccupancyTypeId, - occupancyTypeField: 'Birth Place', - occupancyTypeFieldValues: '', - pattern: '', - isRequired: '', - minimumLength: 1, - maximumLength: 100, - orderNumber: 2 - } - - await addOccupancyTypeField(birthPlace, user) - - await addOccupancyTypeField( - Object.assign(birthPlace, { occupancyTypeId: cremationOccupancyTypeId }), - user - ) - - - // Death Date - - const deathDateField = { - occupancyTypeId: intermentOccupancyTypeId, - occupancyTypeField: 'Death Date', - occupancyTypeFieldValues: '', - pattern: String.raw`\d{4}-\d{2}-\d{2}`, - isRequired: '', - minimumLength: 10, - maximumLength: 10, - orderNumber: 3 - } - - await addOccupancyTypeField(deathDateField, user) - - await addOccupancyTypeField( - Object.assign(deathDateField, { - occupancyTypeId: cremationOccupancyTypeId - }), - user - ) - - // Death Age - - const deathAgeField = { - occupancyTypeId: intermentOccupancyTypeId, - occupancyTypeField: 'Death Age', - occupancyTypeFieldValues: '', - pattern: String.raw`\d+`, - isRequired: '', - minimumLength: 1, - maximumLength: 3, - orderNumber: 4 - } - - await addOccupancyTypeField(deathAgeField, user) - - await addOccupancyTypeField( - Object.assign(deathAgeField, { occupancyTypeId: cremationOccupancyTypeId }), - user - ) - - // Death Age Period - - const deathAgePeriod = { - occupancyTypeId: intermentOccupancyTypeId, - occupancyTypeField: 'Death Age Period', - fieldType: 'select', - occupancyTypeFieldValues: 'Years\nMonths\nDays\nStillborn', - pattern: '', - isRequired: '', - minimumLength: 1, - maximumLength: 10, - orderNumber: 5 - } - - await addOccupancyTypeField(deathAgePeriod, user) - - await addOccupancyTypeField( - Object.assign(deathAgePeriod, { - occupancyTypeId: cremationOccupancyTypeId - }), - user - ) - - // Death Place - - const deathPlace = { - occupancyTypeId: intermentOccupancyTypeId, - occupancyTypeField: 'Death Place', - occupancyTypeFieldValues: '', - pattern: '', - isRequired: '', - minimumLength: 1, - maximumLength: 100, - orderNumber: 6 - } - - await addOccupancyTypeField(deathPlace, user) - - await addOccupancyTypeField( - Object.assign(deathPlace, { occupancyTypeId: cremationOccupancyTypeId }), - user - ) - - // Funeral Home - - const funeralHome = { - occupancyTypeId: intermentOccupancyTypeId, - occupancyTypeField: 'Funeral Home', - occupancyTypeFieldValues: '', - pattern: '', - isRequired: '', - minimumLength: 1, - maximumLength: 100, - orderNumber: 10 - } - - await addOccupancyTypeField(funeralHome, user) - - await addOccupancyTypeField( - Object.assign(funeralHome, { occupancyTypeId: cremationOccupancyTypeId }), - user - ) - - // Funeral Date - - const funeralDate = { - occupancyTypeId: intermentOccupancyTypeId, - occupancyTypeField: 'Funeral Date', - occupancyTypeFieldValues: '', - pattern: String.raw`\d{4}-\d{2}-\d{2}`, - isRequired: '', - minimumLength: 10, - maximumLength: 10, - orderNumber: 11 - } - - await addOccupancyTypeField(funeralDate, user) - - await addOccupancyTypeField( - Object.assign(funeralDate, { occupancyTypeId: cremationOccupancyTypeId }), - user - ) - - // Container Type - const containerType = { - occupancyTypeId: intermentOccupancyTypeId, - occupancyTypeField: 'Container Type', - occupancyTypeFieldValues: '', - pattern: '', - isRequired: '', - minimumLength: 1, - maximumLength: 100, - orderNumber: 20 - } - - await addOccupancyTypeField(containerType, user) - - await addOccupancyTypeField( - Object.assign(containerType, { occupancyTypeId: cremationOccupancyTypeId }), - user - ) - - // Committal Type - const committalType = { - occupancyTypeId: intermentOccupancyTypeId, - occupancyTypeField: 'Committal Type', - occupancyTypeFieldValues: '', - pattern: '', - isRequired: '', - minimumLength: 1, - maximumLength: 100, - orderNumber: 21 - } - - await addOccupancyTypeField(committalType, user) - - await addOccupancyTypeField( - Object.assign(committalType, { occupancyTypeId: cremationOccupancyTypeId }), - user - ) - - /* - * Fee Categories - */ - - await addFeeCategory( - { - feeCategory: 'Interment Rights', - orderNumber: 1 - }, - user - ) - - await addFeeCategory( - { - feeCategory: 'Cremation Services', - orderNumber: 2 - }, - user - ) - - await addFeeCategory( - { - feeCategory: 'Burial Charges', - orderNumber: 3 - }, - user - ) - - await addFeeCategory( - { - feeCategory: 'Disinterment of Human Remains', - orderNumber: 4 - }, - user - ) - - await addFeeCategory( - { - feeCategory: 'Additional Services', - orderNumber: 5 - }, - user - ) - - /* - * Work Orders - */ - - await addRecord('WorkOrderTypes', 'Cemetery Work Order', 1, user) - - await addRecord('WorkOrderMilestoneTypes', 'Funeral', 1, user) - await addRecord('WorkOrderMilestoneTypes', 'Arrival', 2, user) - await addRecord('WorkOrderMilestoneTypes', 'Cremation', 3, user) - await addRecord('WorkOrderMilestoneTypes', 'Interment', 4, user) - - return true -} diff --git a/helpers/initializer.database.d.ts b/helpers/initializer.database.d.ts deleted file mode 100644 index cab8f5f1..00000000 --- a/helpers/initializer.database.d.ts +++ /dev/null @@ -1 +0,0 @@ -export declare function initializeDatabase(): boolean; diff --git a/helpers/initializer.database.js b/helpers/initializer.database.js deleted file mode 100644 index 9458960c..00000000 --- a/helpers/initializer.database.js +++ /dev/null @@ -1,127 +0,0 @@ -// eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair -/* eslint-disable @cspell/spellchecker, no-secrets/no-secrets */ -import sqlite from 'better-sqlite3'; -import debug from 'debug'; -import { lotOccupancyDB as databasePath } from '../data/databasePaths.js'; -const debugSQL = debug('lot-occupancy-system:databaseInitializer'); -const recordColumns = `recordCreate_userName varchar(30) not null, - recordCreate_timeMillis integer not null, - recordUpdate_userName varchar(30) not null, - recordUpdate_timeMillis integer not null, - recordDelete_userName varchar(30), - recordDelete_timeMillis integer`; -const createStatements = [ - /* - * Lot Types - */ - `create table if not exists LotTypes ( - lotTypeId integer not null primary key autoincrement, lotType varchar(100) not null, orderNumber smallint not null default 0, ${recordColumns})`, - 'create index if not exists idx_lottypes_ordernumber on LotTypes (orderNumber, lotType)', - `create table if not exists LotTypeFields ( - lotTypeFieldId integer not null primary key autoincrement, lotTypeId integer not null, lotTypeField varchar(100) not null, - fieldType varchar(15) not null default 'text', - lotTypeFieldValues text, isRequired bit not null default 0, pattern varchar(100), - minimumLength smallint not null default 1 check (minimumLength >= 0), maximumLength smallint not null default 100 check (maximumLength >= 0), orderNumber smallint not null default 0, ${recordColumns}, - foreign key (lotTypeId) references LotTypes (lotTypeId))`, - 'create index if not exists idx_lottypefields_ordernumber on LotTypeFields (lotTypeId, orderNumber, lotTypeField)', - /* - * Lot Statuses - */ - `create table if not exists LotStatuses (lotStatusId integer not null primary key autoincrement, lotStatus varchar(100) not null, orderNumber smallint not null default 0, ${recordColumns})`, - 'create index if not exists idx_lotstatuses_ordernumber on LotStatuses (orderNumber, lotStatus)', - /* - * Maps and Lots - */ - `create table if not exists Maps (mapId integer not null primary key autoincrement, mapName varchar(200) not null, mapDescription text, mapLatitude decimal(10, 8) check (mapLatitude between -90 and 90), mapLongitude decimal(11, 8) check (mapLongitude between -180 and 180), mapSVG varchar(50), mapAddress1 varchar(50), mapAddress2 varchar(50), mapCity varchar(20), mapProvince varchar(2), mapPostalCode varchar(7), mapPhoneNumber varchar(30), ${recordColumns})`, - `create table if not exists Lots (lotId integer not null primary key autoincrement, lotTypeId integer not null, lotName varchar(100), mapId integer, mapKey varchar(100), lotLatitude decimal(10, 8) check (lotLatitude between -90 and 90), lotLongitude decimal(11, 8) check (lotLongitude between -180 and 180), lotStatusId integer, ${recordColumns}, foreign key (lotTypeId) references LotTypes (lotTypeId), foreign key (mapId) references Maps (mapId), foreign key (lotStatusId) references LotStatuses (lotStatusId))`, - `create table if not exists LotFields (lotId integer not null, lotTypeFieldId integer not null, lotFieldValue text not null, ${recordColumns}, primary key (lotId, lotTypeFieldId), foreign key (lotId) references Lots (lotId), foreign key (lotTypeFieldId) references LotTypeFields (lotTypeFieldId)) without rowid`, - `create table if not exists LotComments (lotCommentId integer not null primary key autoincrement, lotId integer not null, lotCommentDate integer not null check (lotCommentDate > 0), lotCommentTime integer not null check (lotCommentTime >= 0), lotComment text not null, ${recordColumns}, foreign key (lotId) references Lots (lotId))`, - 'create index if not exists idx_lotcomments_datetime on LotComments (lotId, lotCommentDate, lotCommentTime)', - /* - * Occupancies - */ - `create table if not exists OccupancyTypes (occupancyTypeId integer not null primary key autoincrement, occupancyType varchar(100) not null, orderNumber smallint not null default 0, ${recordColumns})`, - 'create index if not exists idx_occupancytypes_ordernumber on OccupancyTypes (orderNumber, occupancyType)', - `create table if not exists OccupancyTypeFields ( - occupancyTypeFieldId integer not null primary key autoincrement, occupancyTypeId integer, occupancyTypeField varchar(100) not null, - fieldType varchar(15) not null default 'text', - occupancyTypeFieldValues text, isRequired bit not null default 0, pattern varchar(100), - minimumLength smallint not null default 1 check (minimumLength >= 0), maximumLength smallint not null default 100 check (maximumLength >= 0), orderNumber smallint not null default 0, ${recordColumns}, - foreign key (occupancyTypeId) references OccupancyTypes (occupancyTypeId))`, - 'create index if not exists idx_occupancytypefields_ordernumber on OccupancyTypeFields (occupancyTypeId, orderNumber, occupancyTypeField)', - `create table if not exists OccupancyTypePrints (occupancyTypeId integer not null, printEJS varchar(100) not null, orderNumber smallint not null default 0, ${recordColumns}, primary key (occupancyTypeId, printEJS), foreign key (occupancyTypeId) references OccupancyTypes (occupancyTypeId))`, - 'create index if not exists idx_occupancytypeprints_ordernumber on OccupancyTypePrints (occupancyTypeId, orderNumber, printEJS)', - `create table if not exists LotOccupantTypes ( - lotOccupantTypeId integer not null primary key autoincrement, - lotOccupantType varchar(100) not null, - fontAwesomeIconClass varchar(50) not null default '', - occupantCommentTitle varchar(50) not null default '', - orderNumber smallint not null default 0, - ${recordColumns})`, - 'create index if not exists idx_lotoccupanttypes_ordernumber on LotOccupantTypes (orderNumber, lotOccupantType)', - `create table if not exists LotOccupancies (lotOccupancyId integer not null primary key autoincrement, occupancyTypeId integer not null, lotId integer, occupancyStartDate integer not null check (occupancyStartDate > 0), occupancyEndDate integer check (occupancyEndDate > 0), ${recordColumns}, foreign key (lotId) references Lots (lotId), foreign key (occupancyTypeId) references OccupancyTypes (occupancyTypeId))`, - `create table if not exists LotOccupancyOccupants (lotOccupancyId integer not null, lotOccupantIndex integer not null, occupantName varchar(200) not null, occupantAddress1 varchar(50), occupantAddress2 varchar(50), occupantCity varchar(20), occupantProvince varchar(2), occupantPostalCode varchar(7), occupantPhoneNumber varchar(30), occupantEmailAddress varchar(200), lotOccupantTypeId integer not null, occupantComment text not null default '', ${recordColumns}, primary key (lotOccupancyId, lotOccupantIndex), foreign key (lotOccupancyId) references LotOccupancies (lotOccupancyId), foreign key (lotOccupantTypeId) references LotOccupantTypes (lotOccupantTypeId)) without rowid`, - `create table if not exists LotOccupancyFields (lotOccupancyId integer not null, occupancyTypeFieldId integer not null, lotOccupancyFieldValue text not null, ${recordColumns}, primary key (lotOccupancyId, occupancyTypeFieldId), foreign key (lotOccupancyId) references LotOccupancies (lotOccupancyId), foreign key (occupancyTypeFieldId) references OccupancyTypeFields (occupancyTypeFieldId)) without rowid`, - `create table if not exists LotOccupancyComments (lotOccupancyCommentId integer not null primary key autoincrement, lotOccupancyId integer not null, lotOccupancyCommentDate integer not null check (lotOccupancyCommentDate > 0), lotOccupancyCommentTime integer not null check (lotOccupancyCommentTime >= 0), lotOccupancyComment text not null, ${recordColumns}, foreign key (lotOccupancyId) references LotOccupancies (lotOccupancyId))`, - 'create index if not exists idx_lotoccupancycomments_datetime on LotOccupancyComments (lotOccupancyId, lotOccupancyCommentDate, lotOccupancyCommentTime)', - /* - * Fees and Transactions - */ - `create table if not exists FeeCategories ( - feeCategoryId integer not null primary key autoincrement, - feeCategory varchar(100) not null, - isGroupedFee bit not null default 0, - orderNumber smallint not null default 0, - ${recordColumns})`, - `create table if not exists Fees ( - feeId integer not null primary key autoincrement, - feeCategoryId integer not null, - feeName varchar(100) not null, - feeDescription text, - feeAccount varchar(20), - occupancyTypeId integer, - lotTypeId integer, - includeQuantity boolean not null default 0, - quantityUnit varchar(30), - feeAmount decimal(8, 2), - feeFunction varchar(100), - taxAmount decimal(6, 2), - taxPercentage decimal(5, 2), - isRequired bit not null default 0, - orderNumber smallint not null default 0, - ${recordColumns}, - foreign key (feeCategoryId) references FeeCategories (feeCategoryId), - foreign key (occupancyTypeId) references OccupancyTypes (occupancyTypeId), - foreign key (lotTypeId) references LotTypes (lotTypeId))`, - 'create index if not exists idx_fees_ordernumber on Fees (orderNumber, feeName)', - `create table if not exists LotOccupancyFees (lotOccupancyId integer not null, feeId integer not null, quantity decimal(4, 1) not null default 1, feeAmount decimal(8, 2) not null, taxAmount decmial(8, 2) not null, ${recordColumns}, primary key (lotOccupancyId, feeId), foreign key (lotOccupancyId) references LotOccupancies (lotOccupancyId), foreign key (feeId) references Fees (feeId)) without rowid`, - `create table if not exists LotOccupancyTransactions (lotOccupancyId integer not null, transactionIndex integer not null, transactionDate integer not null check (transactionDate > 0), transactionTime integer not null check (transactionTime >= 0), transactionAmount decimal(8, 2) not null, externalReceiptNumber varchar(100), transactionNote text, ${recordColumns}, primary key (lotOccupancyId, transactionIndex), foreign key (lotOccupancyId) references LotOccupancies (lotOccupancyId)) without rowid`, - 'create index if not exists idx_lotoccupancytransactions_ordernumber on LotOccupancyTransactions (lotOccupancyId, transactionDate, transactionTime)', - /* - * Work Orders - */ - `create table if not exists WorkOrderTypes (workOrderTypeId integer not null primary key autoincrement, workOrderType varchar(100) not null, orderNumber smallint not null default 0, ${recordColumns})`, - 'create index if not exists idx_workordertypes_ordernumber on WorkOrderTypes (orderNumber, workOrderType)', - `create table if not exists WorkOrders (workOrderId integer not null primary key autoincrement, workOrderTypeId integer not null, workOrderNumber varchar(50) not null, workOrderDescription text, workOrderOpenDate integer check (workOrderOpenDate > 0), workOrderCloseDate integer check (workOrderCloseDate > 0), ${recordColumns}, foreign key (workOrderTypeId) references WorkOrderTypes (workOrderTypeId))`, - `create table if not exists WorkOrderLots (workOrderId integer not null, lotId integer not null, ${recordColumns}, primary key (workOrderId, lotId), foreign key (workOrderId) references WorkOrders (workOrderId), foreign key (lotId) references Lots (lotId)) without rowid`, - `create table if not exists WorkOrderLotOccupancies (workOrderId integer not null, lotOccupancyId integer not null, ${recordColumns}, primary key (workOrderId, lotOccupancyId), foreign key (workOrderId) references WorkOrders (workOrderId), foreign key (lotOccupancyId) references LotOccupancies (lotOccupancyId)) without rowid`, - `create table if not exists WorkOrderComments (workOrderCommentId integer not null primary key autoincrement, workOrderId integer not null, workOrderCommentDate integer not null check (workOrderCommentDate > 0), workOrderCommentTime integer not null check (workOrderCommentTime >= 0), workOrderComment text not null, ${recordColumns}, foreign key (workOrderId) references WorkOrders (workOrderId))`, - 'create index if not exists idx_workordercomments_datetime on WorkOrderComments (workOrderId, workOrderCommentDate, workOrderCommentTime)', - `create table if not exists WorkOrderMilestoneTypes (workOrderMilestoneTypeId integer not null primary key autoincrement, workOrderMilestoneType varchar(100) not null, orderNumber smallint not null default 0, ${recordColumns})`, - `create table if not exists WorkOrderMilestones (workOrderMilestoneId integer not null primary key autoincrement, workOrderId integer not null, workOrderMilestoneTypeId integer, workOrderMilestoneDate integer not null check (workOrderMilestoneDate >= 0), workOrderMilestoneTime integer not null check (workOrderMilestoneTime >= 0), workOrderMilestoneDescription text not null, workOrderMilestoneCompletionDate integer check (workOrderMilestoneCompletionDate > 0), workOrderMilestoneCompletionTime integer check (workOrderMilestoneCompletionTime >= 0), ${recordColumns}, foreign key (workOrderId) references WorkOrders (workOrderId), foreign key (workOrderMilestoneTypeId) references WorkOrderMilestoneTypes (workOrderMilestoneTypeId))` -]; -export function initializeDatabase() { - const lotOccupancyDB = sqlite(databasePath); - const row = lotOccupancyDB - .prepare("select name from sqlite_master where type = 'table' and name = 'WorkOrderMilestones'") - .get(); - if (row === undefined) { - debugSQL(`Creating ${databasePath}`); - for (const sql of createStatements) { - lotOccupancyDB.prepare(sql).run(); - } - lotOccupancyDB.close(); - return true; - } - return false; -} diff --git a/helpers/initializer.database.ts b/helpers/initializer.database.ts deleted file mode 100644 index 304446a5..00000000 --- a/helpers/initializer.database.ts +++ /dev/null @@ -1,159 +0,0 @@ -// eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair -/* eslint-disable @cspell/spellchecker, no-secrets/no-secrets */ - -import sqlite from 'better-sqlite3' -import debug from 'debug' - -import { lotOccupancyDB as databasePath } from '../data/databasePaths.js' - -const debugSQL = debug('lot-occupancy-system:databaseInitializer') - -const recordColumns = `recordCreate_userName varchar(30) not null, - recordCreate_timeMillis integer not null, - recordUpdate_userName varchar(30) not null, - recordUpdate_timeMillis integer not null, - recordDelete_userName varchar(30), - recordDelete_timeMillis integer` - -const createStatements = [ - /* - * Lot Types - */ - - `create table if not exists LotTypes ( - lotTypeId integer not null primary key autoincrement, lotType varchar(100) not null, orderNumber smallint not null default 0, ${recordColumns})`, - - 'create index if not exists idx_lottypes_ordernumber on LotTypes (orderNumber, lotType)', - - `create table if not exists LotTypeFields ( - lotTypeFieldId integer not null primary key autoincrement, lotTypeId integer not null, lotTypeField varchar(100) not null, - fieldType varchar(15) not null default 'text', - lotTypeFieldValues text, isRequired bit not null default 0, pattern varchar(100), - minimumLength smallint not null default 1 check (minimumLength >= 0), maximumLength smallint not null default 100 check (maximumLength >= 0), orderNumber smallint not null default 0, ${recordColumns}, - foreign key (lotTypeId) references LotTypes (lotTypeId))`, - - 'create index if not exists idx_lottypefields_ordernumber on LotTypeFields (lotTypeId, orderNumber, lotTypeField)', - - /* - * Lot Statuses - */ - - `create table if not exists LotStatuses (lotStatusId integer not null primary key autoincrement, lotStatus varchar(100) not null, orderNumber smallint not null default 0, ${recordColumns})`, - 'create index if not exists idx_lotstatuses_ordernumber on LotStatuses (orderNumber, lotStatus)', - - /* - * Maps and Lots - */ - - `create table if not exists Maps (mapId integer not null primary key autoincrement, mapName varchar(200) not null, mapDescription text, mapLatitude decimal(10, 8) check (mapLatitude between -90 and 90), mapLongitude decimal(11, 8) check (mapLongitude between -180 and 180), mapSVG varchar(50), mapAddress1 varchar(50), mapAddress2 varchar(50), mapCity varchar(20), mapProvince varchar(2), mapPostalCode varchar(7), mapPhoneNumber varchar(30), ${recordColumns})`, - `create table if not exists Lots (lotId integer not null primary key autoincrement, lotTypeId integer not null, lotName varchar(100), mapId integer, mapKey varchar(100), lotLatitude decimal(10, 8) check (lotLatitude between -90 and 90), lotLongitude decimal(11, 8) check (lotLongitude between -180 and 180), lotStatusId integer, ${recordColumns}, foreign key (lotTypeId) references LotTypes (lotTypeId), foreign key (mapId) references Maps (mapId), foreign key (lotStatusId) references LotStatuses (lotStatusId))`, - `create table if not exists LotFields (lotId integer not null, lotTypeFieldId integer not null, lotFieldValue text not null, ${recordColumns}, primary key (lotId, lotTypeFieldId), foreign key (lotId) references Lots (lotId), foreign key (lotTypeFieldId) references LotTypeFields (lotTypeFieldId)) without rowid`, - `create table if not exists LotComments (lotCommentId integer not null primary key autoincrement, lotId integer not null, lotCommentDate integer not null check (lotCommentDate > 0), lotCommentTime integer not null check (lotCommentTime >= 0), lotComment text not null, ${recordColumns}, foreign key (lotId) references Lots (lotId))`, - 'create index if not exists idx_lotcomments_datetime on LotComments (lotId, lotCommentDate, lotCommentTime)', - - /* - * Occupancies - */ - - `create table if not exists OccupancyTypes (occupancyTypeId integer not null primary key autoincrement, occupancyType varchar(100) not null, orderNumber smallint not null default 0, ${recordColumns})`, - 'create index if not exists idx_occupancytypes_ordernumber on OccupancyTypes (orderNumber, occupancyType)', - - `create table if not exists OccupancyTypeFields ( - occupancyTypeFieldId integer not null primary key autoincrement, occupancyTypeId integer, occupancyTypeField varchar(100) not null, - fieldType varchar(15) not null default 'text', - occupancyTypeFieldValues text, isRequired bit not null default 0, pattern varchar(100), - minimumLength smallint not null default 1 check (minimumLength >= 0), maximumLength smallint not null default 100 check (maximumLength >= 0), orderNumber smallint not null default 0, ${recordColumns}, - foreign key (occupancyTypeId) references OccupancyTypes (occupancyTypeId))`, - - 'create index if not exists idx_occupancytypefields_ordernumber on OccupancyTypeFields (occupancyTypeId, orderNumber, occupancyTypeField)', - `create table if not exists OccupancyTypePrints (occupancyTypeId integer not null, printEJS varchar(100) not null, orderNumber smallint not null default 0, ${recordColumns}, primary key (occupancyTypeId, printEJS), foreign key (occupancyTypeId) references OccupancyTypes (occupancyTypeId))`, - 'create index if not exists idx_occupancytypeprints_ordernumber on OccupancyTypePrints (occupancyTypeId, orderNumber, printEJS)', - `create table if not exists LotOccupantTypes ( - lotOccupantTypeId integer not null primary key autoincrement, - lotOccupantType varchar(100) not null, - fontAwesomeIconClass varchar(50) not null default '', - occupantCommentTitle varchar(50) not null default '', - orderNumber smallint not null default 0, - ${recordColumns})`, - - 'create index if not exists idx_lotoccupanttypes_ordernumber on LotOccupantTypes (orderNumber, lotOccupantType)', - `create table if not exists LotOccupancies (lotOccupancyId integer not null primary key autoincrement, occupancyTypeId integer not null, lotId integer, occupancyStartDate integer not null check (occupancyStartDate > 0), occupancyEndDate integer check (occupancyEndDate > 0), ${recordColumns}, foreign key (lotId) references Lots (lotId), foreign key (occupancyTypeId) references OccupancyTypes (occupancyTypeId))`, - `create table if not exists LotOccupancyOccupants (lotOccupancyId integer not null, lotOccupantIndex integer not null, occupantName varchar(200) not null, occupantAddress1 varchar(50), occupantAddress2 varchar(50), occupantCity varchar(20), occupantProvince varchar(2), occupantPostalCode varchar(7), occupantPhoneNumber varchar(30), occupantEmailAddress varchar(200), lotOccupantTypeId integer not null, occupantComment text not null default '', ${recordColumns}, primary key (lotOccupancyId, lotOccupantIndex), foreign key (lotOccupancyId) references LotOccupancies (lotOccupancyId), foreign key (lotOccupantTypeId) references LotOccupantTypes (lotOccupantTypeId)) without rowid`, - `create table if not exists LotOccupancyFields (lotOccupancyId integer not null, occupancyTypeFieldId integer not null, lotOccupancyFieldValue text not null, ${recordColumns}, primary key (lotOccupancyId, occupancyTypeFieldId), foreign key (lotOccupancyId) references LotOccupancies (lotOccupancyId), foreign key (occupancyTypeFieldId) references OccupancyTypeFields (occupancyTypeFieldId)) without rowid`, - `create table if not exists LotOccupancyComments (lotOccupancyCommentId integer not null primary key autoincrement, lotOccupancyId integer not null, lotOccupancyCommentDate integer not null check (lotOccupancyCommentDate > 0), lotOccupancyCommentTime integer not null check (lotOccupancyCommentTime >= 0), lotOccupancyComment text not null, ${recordColumns}, foreign key (lotOccupancyId) references LotOccupancies (lotOccupancyId))`, - 'create index if not exists idx_lotoccupancycomments_datetime on LotOccupancyComments (lotOccupancyId, lotOccupancyCommentDate, lotOccupancyCommentTime)', - - /* - * Fees and Transactions - */ - - `create table if not exists FeeCategories ( - feeCategoryId integer not null primary key autoincrement, - feeCategory varchar(100) not null, - isGroupedFee bit not null default 0, - orderNumber smallint not null default 0, - ${recordColumns})`, - - `create table if not exists Fees ( - feeId integer not null primary key autoincrement, - feeCategoryId integer not null, - feeName varchar(100) not null, - feeDescription text, - feeAccount varchar(20), - occupancyTypeId integer, - lotTypeId integer, - includeQuantity boolean not null default 0, - quantityUnit varchar(30), - feeAmount decimal(8, 2), - feeFunction varchar(100), - taxAmount decimal(6, 2), - taxPercentage decimal(5, 2), - isRequired bit not null default 0, - orderNumber smallint not null default 0, - ${recordColumns}, - foreign key (feeCategoryId) references FeeCategories (feeCategoryId), - foreign key (occupancyTypeId) references OccupancyTypes (occupancyTypeId), - foreign key (lotTypeId) references LotTypes (lotTypeId))`, - 'create index if not exists idx_fees_ordernumber on Fees (orderNumber, feeName)', - `create table if not exists LotOccupancyFees (lotOccupancyId integer not null, feeId integer not null, quantity decimal(4, 1) not null default 1, feeAmount decimal(8, 2) not null, taxAmount decmial(8, 2) not null, ${recordColumns}, primary key (lotOccupancyId, feeId), foreign key (lotOccupancyId) references LotOccupancies (lotOccupancyId), foreign key (feeId) references Fees (feeId)) without rowid`, - `create table if not exists LotOccupancyTransactions (lotOccupancyId integer not null, transactionIndex integer not null, transactionDate integer not null check (transactionDate > 0), transactionTime integer not null check (transactionTime >= 0), transactionAmount decimal(8, 2) not null, externalReceiptNumber varchar(100), transactionNote text, ${recordColumns}, primary key (lotOccupancyId, transactionIndex), foreign key (lotOccupancyId) references LotOccupancies (lotOccupancyId)) without rowid`, - 'create index if not exists idx_lotoccupancytransactions_ordernumber on LotOccupancyTransactions (lotOccupancyId, transactionDate, transactionTime)', - - /* - * Work Orders - */ - - `create table if not exists WorkOrderTypes (workOrderTypeId integer not null primary key autoincrement, workOrderType varchar(100) not null, orderNumber smallint not null default 0, ${recordColumns})`, - 'create index if not exists idx_workordertypes_ordernumber on WorkOrderTypes (orderNumber, workOrderType)', - `create table if not exists WorkOrders (workOrderId integer not null primary key autoincrement, workOrderTypeId integer not null, workOrderNumber varchar(50) not null, workOrderDescription text, workOrderOpenDate integer check (workOrderOpenDate > 0), workOrderCloseDate integer check (workOrderCloseDate > 0), ${recordColumns}, foreign key (workOrderTypeId) references WorkOrderTypes (workOrderTypeId))`, - `create table if not exists WorkOrderLots (workOrderId integer not null, lotId integer not null, ${recordColumns}, primary key (workOrderId, lotId), foreign key (workOrderId) references WorkOrders (workOrderId), foreign key (lotId) references Lots (lotId)) without rowid`, - `create table if not exists WorkOrderLotOccupancies (workOrderId integer not null, lotOccupancyId integer not null, ${recordColumns}, primary key (workOrderId, lotOccupancyId), foreign key (workOrderId) references WorkOrders (workOrderId), foreign key (lotOccupancyId) references LotOccupancies (lotOccupancyId)) without rowid`, - `create table if not exists WorkOrderComments (workOrderCommentId integer not null primary key autoincrement, workOrderId integer not null, workOrderCommentDate integer not null check (workOrderCommentDate > 0), workOrderCommentTime integer not null check (workOrderCommentTime >= 0), workOrderComment text not null, ${recordColumns}, foreign key (workOrderId) references WorkOrders (workOrderId))`, - 'create index if not exists idx_workordercomments_datetime on WorkOrderComments (workOrderId, workOrderCommentDate, workOrderCommentTime)', - `create table if not exists WorkOrderMilestoneTypes (workOrderMilestoneTypeId integer not null primary key autoincrement, workOrderMilestoneType varchar(100) not null, orderNumber smallint not null default 0, ${recordColumns})`, - `create table if not exists WorkOrderMilestones (workOrderMilestoneId integer not null primary key autoincrement, workOrderId integer not null, workOrderMilestoneTypeId integer, workOrderMilestoneDate integer not null check (workOrderMilestoneDate >= 0), workOrderMilestoneTime integer not null check (workOrderMilestoneTime >= 0), workOrderMilestoneDescription text not null, workOrderMilestoneCompletionDate integer check (workOrderMilestoneCompletionDate > 0), workOrderMilestoneCompletionTime integer check (workOrderMilestoneCompletionTime >= 0), ${recordColumns}, foreign key (workOrderId) references WorkOrders (workOrderId), foreign key (workOrderMilestoneTypeId) references WorkOrderMilestoneTypes (workOrderMilestoneTypeId))` -] - -export function initializeDatabase(): boolean { - const lotOccupancyDB = sqlite(databasePath) - - const row = lotOccupancyDB - .prepare( - "select name from sqlite_master where type = 'table' and name = 'WorkOrderMilestones'" - ) - .get() - - if (row === undefined) { - debugSQL(`Creating ${databasePath}`) - - for (const sql of createStatements) { - lotOccupancyDB.prepare(sql).run() - } - - lotOccupancyDB.close() - - return true - } - - return false -} diff --git a/package-lock.json b/package-lock.json index bc78a85d..b2ffe7ab 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { - "name": "lot-occupancy-system", - "version": "1.0.0-alpha.14", + "name": "sunrise-cms", + "version": "1.0.0-dev", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "lot-occupancy-system", - "version": "1.0.0-alpha.14", + "name": "sunrise-cms", + "version": "1.0.0-dev", "license": "MIT", "dependencies": { "@cityssm/bulma-js": "^0.5.0", @@ -426,6 +426,7 @@ "version": "0.1.0", "resolved": "https://registry.npmjs.org/@cityssm/configurator/-/configurator-0.1.0.tgz", "integrity": "sha512-MGklw25IFyovef5/pYXF3XePkbLDuW0DxKoqPlD8Cwmk/ySXDBhKsDdVgKVcGVRD70k8538PhN5vA4U9cVhtQw==", + "license": "MIT", "engines": { "node": ">=18.0.0" } diff --git a/package.json b/package.json index 212ebef9..75e6fb56 100644 --- a/package.json +++ b/package.json @@ -1,36 +1,36 @@ { - "name": "lot-occupancy-system", - "version": "1.0.0-alpha.14", + "name": "sunrise-cms", + "version": "1.0.0-dev", "type": "module", - "description": "A system for managing the occupancy of lots. (i.e. Cemetery management)", + "description": "Sunrise Cemetery Management System, a web-based application that allows cemetery managers to manage their cemetery records.", "exports": "./app.js", "engines": { "node": ">=18.0.0" }, "scripts": { "start": "cross-env NODE_ENV=production node ./bin/www.js", - "dev:test": "cross-env NODE_ENV=dev DEBUG=lot-occupancy-system:*,dynamics-gp:* TEST_DATABASES=true nodemon --inspect ./bin/www.js", - "dev:test:process": "cross-env NODE_ENV=dev DEBUG=lot-occupancy-system:* TEST_DATABASES=true nodemon --inspect ./bin/wwwProcess.js", - "dev:live": "cross-env NODE_ENV=dev DEBUG=lot-occupancy-system:* nodemon --inspect ./bin/www.js", + "dev:test": "cross-env NODE_ENV=dev DEBUG=sunrise:*,dynamics-gp:* TEST_DATABASES=true nodemon --inspect ./bin/www.js", + "dev:test:process": "cross-env NODE_ENV=dev DEBUG=sunrise:* TEST_DATABASES=true nodemon --inspect ./bin/wwwProcess.js", + "dev:live": "cross-env NODE_ENV=dev DEBUG=sunrise:* nodemon --inspect ./bin/www.js", "cy:open": "cypress open --config-file cypress.config.js", "cy:run": "cypress run --config-file cypress.config.js", "cy:run:firefox": "cypress run --config-file cypress.config.js --browser firefox", - "test": "cross-env NODE_ENV=dev DEBUG=lot-occupancy-system:* TEST_DATABASES=true mocha --timeout 30000 --exit", - "test:startup": "cross-env NODE_ENV=dev DEBUG=lot-occupancy-system:* TEST_DATABASES=true STARTUP_TEST=true node ./bin/www.js", - "coverage": "cross-env NODE_ENV=dev DEBUG=lot-occupancy-system:* TEST_DATABASES=true c8 --reporter=lcov --reporter=text --reporter=text-summary mocha --timeout 30000 --exit", - "temp:legacy:importFromCsv": "cross-env NODE_ENV=dev DEBUG=lot-occupancy-system:* TEST_DATABASES=true node ./temp/legacy.importFromCsv.js", + "test": "cross-env NODE_ENV=dev DEBUG=sunrise:* TEST_DATABASES=true mocha --timeout 30000 --exit", + "test:startup": "cross-env NODE_ENV=dev DEBUG=sunrise:* TEST_DATABASES=true STARTUP_TEST=true node ./bin/www.js", + "coverage": "cross-env NODE_ENV=dev DEBUG=sunrise:* TEST_DATABASES=true c8 --reporter=lcov --reporter=text --reporter=text-summary mocha --timeout 30000 --exit", + "temp:legacy:importFromCsv": "cross-env NODE_ENV=dev DEBUG=sunrise:* TEST_DATABASES=true node ./temp/legacy.importFromCsv.js", "temp:so:exportMaps": "node ./temp/so.exportMaps.js" }, "repository": { "type": "git", - "url": "git+https://github.com/cityssm/lot-occupancy-manager.git" + "url": "git+https://github.com/cityssm/sunrise-cms.git" }, "author": "The Corporation of the City of Sault Ste. Marie", "license": "MIT", "bugs": { - "url": "https://github.com/cityssm/lot-occupancy-manager/issues" + "url": "https://github.com/cityssm/sunrise-cms/issues" }, - "homepage": "https://github.com/cityssm/lot-occupancy-manager#readme", + "homepage": "https://github.com/cityssm/sunrise-cms#readme", "private": true, "dependencies": { "@cityssm/bulma-js": "^0.5.0", diff --git a/public/images/maps/ssm.cemetery.holySepulchre-block-A-rows-1-52.svg b/public/images/cemeteries/ssm.cemetery.holySepulchre-block-A-rows-1-52.svg similarity index 100% rename from public/images/maps/ssm.cemetery.holySepulchre-block-A-rows-1-52.svg rename to public/images/cemeteries/ssm.cemetery.holySepulchre-block-A-rows-1-52.svg diff --git a/public/images/maps/ssm.cemetery.holySepulchre-block-A-rows-53-97.svg b/public/images/cemeteries/ssm.cemetery.holySepulchre-block-A-rows-53-97.svg similarity index 100% rename from public/images/maps/ssm.cemetery.holySepulchre-block-A-rows-53-97.svg rename to public/images/cemeteries/ssm.cemetery.holySepulchre-block-A-rows-53-97.svg diff --git a/public/images/maps/ssm.cemetery.holySepulchre-block-A-rows-B-T.svg b/public/images/cemeteries/ssm.cemetery.holySepulchre-block-A-rows-B-T.svg similarity index 100% rename from public/images/maps/ssm.cemetery.holySepulchre-block-A-rows-B-T.svg rename to public/images/cemeteries/ssm.cemetery.holySepulchre-block-A-rows-B-T.svg diff --git a/public/images/maps/ssm.cemetery.holySepulchre-block-A-urnRanges-52A-53A.svg b/public/images/cemeteries/ssm.cemetery.holySepulchre-block-A-urnRanges-52A-53A.svg similarity index 100% rename from public/images/maps/ssm.cemetery.holySepulchre-block-A-urnRanges-52A-53A.svg rename to public/images/cemeteries/ssm.cemetery.holySepulchre-block-A-urnRanges-52A-53A.svg diff --git a/public/images/maps/ssm.cemetery.holySepulchre-block-A-urnRanges-72A-73A.svg b/public/images/cemeteries/ssm.cemetery.holySepulchre-block-A-urnRanges-72A-73A.svg similarity index 100% rename from public/images/maps/ssm.cemetery.holySepulchre-block-A-urnRanges-72A-73A.svg rename to public/images/cemeteries/ssm.cemetery.holySepulchre-block-A-urnRanges-72A-73A.svg diff --git a/public/images/maps/ssm.cemetery.holySepulchre-block-A-urnRanges-97A-97B.svg b/public/images/cemeteries/ssm.cemetery.holySepulchre-block-A-urnRanges-97A-97B.svg similarity index 100% rename from public/images/maps/ssm.cemetery.holySepulchre-block-A-urnRanges-97A-97B.svg rename to public/images/cemeteries/ssm.cemetery.holySepulchre-block-A-urnRanges-97A-97B.svg diff --git a/public/images/maps/ssm.cemetery.holySepulchre-block-B-rows-1-52.svg b/public/images/cemeteries/ssm.cemetery.holySepulchre-block-B-rows-1-52.svg similarity index 100% rename from public/images/maps/ssm.cemetery.holySepulchre-block-B-rows-1-52.svg rename to public/images/cemeteries/ssm.cemetery.holySepulchre-block-B-rows-1-52.svg diff --git a/public/images/maps/ssm.cemetery.holySepulchre-block-B-rows-53-97.svg b/public/images/cemeteries/ssm.cemetery.holySepulchre-block-B-rows-53-97.svg similarity index 100% rename from public/images/maps/ssm.cemetery.holySepulchre-block-B-rows-53-97.svg rename to public/images/cemeteries/ssm.cemetery.holySepulchre-block-B-rows-53-97.svg diff --git a/public/images/maps/ssm.cemetery.holySepulchre-block-B-rows-B-T.svg b/public/images/cemeteries/ssm.cemetery.holySepulchre-block-B-rows-B-T.svg similarity index 100% rename from public/images/maps/ssm.cemetery.holySepulchre-block-B-rows-B-T.svg rename to public/images/cemeteries/ssm.cemetery.holySepulchre-block-B-rows-B-T.svg diff --git a/public/images/maps/ssm.cemetery.holySepulchre-block-C-rows-1-36.svg b/public/images/cemeteries/ssm.cemetery.holySepulchre-block-C-rows-1-36.svg similarity index 100% rename from public/images/maps/ssm.cemetery.holySepulchre-block-C-rows-1-36.svg rename to public/images/cemeteries/ssm.cemetery.holySepulchre-block-C-rows-1-36.svg diff --git a/public/images/maps/ssm.cemetery.holySepulchre-block-C-rows-B-U.svg b/public/images/cemeteries/ssm.cemetery.holySepulchre-block-C-rows-B-U.svg similarity index 100% rename from public/images/maps/ssm.cemetery.holySepulchre-block-C-rows-B-U.svg rename to public/images/cemeteries/ssm.cemetery.holySepulchre-block-C-rows-B-U.svg diff --git a/public/images/maps/ssm.cemetery.holySepulchre-block-D-babyShrine.svg b/public/images/cemeteries/ssm.cemetery.holySepulchre-block-D-babyShrine.svg similarity index 100% rename from public/images/maps/ssm.cemetery.holySepulchre-block-D-babyShrine.svg rename to public/images/cemeteries/ssm.cemetery.holySepulchre-block-D-babyShrine.svg diff --git a/public/images/maps/ssm.cemetery.holySepulchre-block-D-rows-A-L.svg b/public/images/cemeteries/ssm.cemetery.holySepulchre-block-D-rows-A-L.svg similarity index 100% rename from public/images/maps/ssm.cemetery.holySepulchre-block-D-rows-A-L.svg rename to public/images/cemeteries/ssm.cemetery.holySepulchre-block-D-rows-A-L.svg diff --git a/public/images/maps/ssm.cemetery.holySepulchre-block-D-rows-M-V.svg b/public/images/cemeteries/ssm.cemetery.holySepulchre-block-D-rows-M-V.svg similarity index 100% rename from public/images/maps/ssm.cemetery.holySepulchre-block-D-rows-M-V.svg rename to public/images/cemeteries/ssm.cemetery.holySepulchre-block-D-rows-M-V.svg diff --git a/public/images/maps/ssm.cemetery.holySepulchre-block-E-sectionCenter.svg b/public/images/cemeteries/ssm.cemetery.holySepulchre-block-E-sectionCenter.svg similarity index 100% rename from public/images/maps/ssm.cemetery.holySepulchre-block-E-sectionCenter.svg rename to public/images/cemeteries/ssm.cemetery.holySepulchre-block-E-sectionCenter.svg diff --git a/public/images/maps/ssm.cemetery.holySepulchre-block-E-sectionEast.svg b/public/images/cemeteries/ssm.cemetery.holySepulchre-block-E-sectionEast.svg similarity index 100% rename from public/images/maps/ssm.cemetery.holySepulchre-block-E-sectionEast.svg rename to public/images/cemeteries/ssm.cemetery.holySepulchre-block-E-sectionEast.svg diff --git a/public/images/maps/ssm.cemetery.holySepulchre-block-E-sectionWest.svg b/public/images/cemeteries/ssm.cemetery.holySepulchre-block-E-sectionWest.svg similarity index 100% rename from public/images/maps/ssm.cemetery.holySepulchre-block-E-sectionWest.svg rename to public/images/cemeteries/ssm.cemetery.holySepulchre-block-E-sectionWest.svg diff --git a/public/images/maps/ssm.cemetery.holySepulchre-block-F-rows-1-22.svg b/public/images/cemeteries/ssm.cemetery.holySepulchre-block-F-rows-1-22.svg similarity index 100% rename from public/images/maps/ssm.cemetery.holySepulchre-block-F-rows-1-22.svg rename to public/images/cemeteries/ssm.cemetery.holySepulchre-block-F-rows-1-22.svg diff --git a/public/images/maps/ssm.cemetery.holySepulchre-block-G-rows-1-32.svg b/public/images/cemeteries/ssm.cemetery.holySepulchre-block-G-rows-1-32.svg similarity index 100% rename from public/images/maps/ssm.cemetery.holySepulchre-block-G-rows-1-32.svg rename to public/images/cemeteries/ssm.cemetery.holySepulchre-block-G-rows-1-32.svg diff --git a/public/images/maps/ssm.cemetery.holySepulchre-block-H-rows-1-16.svg b/public/images/cemeteries/ssm.cemetery.holySepulchre-block-H-rows-1-16.svg similarity index 100% rename from public/images/maps/ssm.cemetery.holySepulchre-block-H-rows-1-16.svg rename to public/images/cemeteries/ssm.cemetery.holySepulchre-block-H-rows-1-16.svg diff --git a/public/images/maps/ssm.cemetery.holySepulchre-block-J-rows-1-18.svg b/public/images/cemeteries/ssm.cemetery.holySepulchre-block-J-rows-1-18.svg similarity index 100% rename from public/images/maps/ssm.cemetery.holySepulchre-block-J-rows-1-18.svg rename to public/images/cemeteries/ssm.cemetery.holySepulchre-block-J-rows-1-18.svg diff --git a/public/images/maps/ssm.cemetery.holySepulchre-block-K-rows-1-19.svg b/public/images/cemeteries/ssm.cemetery.holySepulchre-block-K-rows-1-19.svg similarity index 100% rename from public/images/maps/ssm.cemetery.holySepulchre-block-K-rows-1-19.svg rename to public/images/cemeteries/ssm.cemetery.holySepulchre-block-K-rows-1-19.svg diff --git a/public/images/maps/ssm.cemetery.holySepulchre-columbarium-O-P.svg b/public/images/cemeteries/ssm.cemetery.holySepulchre-columbarium-O-P.svg similarity index 100% rename from public/images/maps/ssm.cemetery.holySepulchre-columbarium-O-P.svg rename to public/images/cemeteries/ssm.cemetery.holySepulchre-columbarium-O-P.svg diff --git a/public/images/maps/ssm.cemetery.holySepulchre-columbarium-S.svg b/public/images/cemeteries/ssm.cemetery.holySepulchre-columbarium-S.svg similarity index 100% rename from public/images/maps/ssm.cemetery.holySepulchre-columbarium-S.svg rename to public/images/cemeteries/ssm.cemetery.holySepulchre-columbarium-S.svg diff --git a/public/images/maps/ssm.cemetery.holySepulchre-columbarium-T.svg b/public/images/cemeteries/ssm.cemetery.holySepulchre-columbarium-T.svg similarity index 100% rename from public/images/maps/ssm.cemetery.holySepulchre-columbarium-T.svg rename to public/images/cemeteries/ssm.cemetery.holySepulchre-columbarium-T.svg diff --git a/public/images/maps/ssm.cemetery.holySepulchre-columbarium-U.svg b/public/images/cemeteries/ssm.cemetery.holySepulchre-columbarium-U.svg similarity index 100% rename from public/images/maps/ssm.cemetery.holySepulchre-columbarium-U.svg rename to public/images/cemeteries/ssm.cemetery.holySepulchre-columbarium-U.svg diff --git a/public/images/maps/ssm.cemetery.holySepulchre-columbarium-V.svg b/public/images/cemeteries/ssm.cemetery.holySepulchre-columbarium-V.svg similarity index 100% rename from public/images/maps/ssm.cemetery.holySepulchre-columbarium-V.svg rename to public/images/cemeteries/ssm.cemetery.holySepulchre-columbarium-V.svg diff --git a/public/images/maps/ssm.cemetery.holySepulchre-columbarium-W.svg b/public/images/cemeteries/ssm.cemetery.holySepulchre-columbarium-W.svg similarity index 100% rename from public/images/maps/ssm.cemetery.holySepulchre-columbarium-W.svg rename to public/images/cemeteries/ssm.cemetery.holySepulchre-columbarium-W.svg diff --git a/public/images/maps/ssm.cemetery.holySepulchre-image.svg b/public/images/cemeteries/ssm.cemetery.holySepulchre-image.svg similarity index 100% rename from public/images/maps/ssm.cemetery.holySepulchre-image.svg rename to public/images/cemeteries/ssm.cemetery.holySepulchre-image.svg diff --git a/public/images/maps/ssm.cemetery.holySepulchre-mausoleum-east.svg b/public/images/cemeteries/ssm.cemetery.holySepulchre-mausoleum-east.svg similarity index 100% rename from public/images/maps/ssm.cemetery.holySepulchre-mausoleum-east.svg rename to public/images/cemeteries/ssm.cemetery.holySepulchre-mausoleum-east.svg diff --git a/public/images/maps/ssm.cemetery.holySepulchre-mausoleum-image.svg b/public/images/cemeteries/ssm.cemetery.holySepulchre-mausoleum-image.svg similarity index 100% rename from public/images/maps/ssm.cemetery.holySepulchre-mausoleum-image.svg rename to public/images/cemeteries/ssm.cemetery.holySepulchre-mausoleum-image.svg diff --git a/public/images/maps/ssm.cemetery.holySepulchre-mausoleum-niche-J-E.svg b/public/images/cemeteries/ssm.cemetery.holySepulchre-mausoleum-niche-J-E.svg similarity index 100% rename from public/images/maps/ssm.cemetery.holySepulchre-mausoleum-niche-J-E.svg rename to public/images/cemeteries/ssm.cemetery.holySepulchre-mausoleum-niche-J-E.svg diff --git a/public/images/maps/ssm.cemetery.holySepulchre-mausoleum-niche-J-W.svg b/public/images/cemeteries/ssm.cemetery.holySepulchre-mausoleum-niche-J-W.svg similarity index 100% rename from public/images/maps/ssm.cemetery.holySepulchre-mausoleum-niche-J-W.svg rename to public/images/cemeteries/ssm.cemetery.holySepulchre-mausoleum-niche-J-W.svg diff --git a/public/images/maps/ssm.cemetery.holySepulchre-mausoleum-niche-L-E.svg b/public/images/cemeteries/ssm.cemetery.holySepulchre-mausoleum-niche-L-E.svg similarity index 100% rename from public/images/maps/ssm.cemetery.holySepulchre-mausoleum-niche-L-E.svg rename to public/images/cemeteries/ssm.cemetery.holySepulchre-mausoleum-niche-L-E.svg diff --git a/public/images/maps/ssm.cemetery.holySepulchre-mausoleum-niche-L-W.svg b/public/images/cemeteries/ssm.cemetery.holySepulchre-mausoleum-niche-L-W.svg similarity index 100% rename from public/images/maps/ssm.cemetery.holySepulchre-mausoleum-niche-L-W.svg rename to public/images/cemeteries/ssm.cemetery.holySepulchre-mausoleum-niche-L-W.svg diff --git a/public/images/maps/ssm.cemetery.holySepulchre-mausoleum-niche-L.svg b/public/images/cemeteries/ssm.cemetery.holySepulchre-mausoleum-niche-L.svg similarity index 100% rename from public/images/maps/ssm.cemetery.holySepulchre-mausoleum-niche-L.svg rename to public/images/cemeteries/ssm.cemetery.holySepulchre-mausoleum-niche-L.svg diff --git a/public/images/maps/ssm.cemetery.holySepulchre-mausoleum-niche-M-E.svg b/public/images/cemeteries/ssm.cemetery.holySepulchre-mausoleum-niche-M-E.svg similarity index 100% rename from public/images/maps/ssm.cemetery.holySepulchre-mausoleum-niche-M-E.svg rename to public/images/cemeteries/ssm.cemetery.holySepulchre-mausoleum-niche-M-E.svg diff --git a/public/images/maps/ssm.cemetery.holySepulchre-mausoleum-niche-M-W.svg b/public/images/cemeteries/ssm.cemetery.holySepulchre-mausoleum-niche-M-W.svg similarity index 100% rename from public/images/maps/ssm.cemetery.holySepulchre-mausoleum-niche-M-W.svg rename to public/images/cemeteries/ssm.cemetery.holySepulchre-mausoleum-niche-M-W.svg diff --git a/public/images/maps/ssm.cemetery.holySepulchre-mausoleum-niche-M.svg b/public/images/cemeteries/ssm.cemetery.holySepulchre-mausoleum-niche-M.svg similarity index 100% rename from public/images/maps/ssm.cemetery.holySepulchre-mausoleum-niche-M.svg rename to public/images/cemeteries/ssm.cemetery.holySepulchre-mausoleum-niche-M.svg diff --git a/public/images/maps/ssm.cemetery.holySepulchre-mausoleum-section-T.svg b/public/images/cemeteries/ssm.cemetery.holySepulchre-mausoleum-section-T.svg similarity index 100% rename from public/images/maps/ssm.cemetery.holySepulchre-mausoleum-section-T.svg rename to public/images/cemeteries/ssm.cemetery.holySepulchre-mausoleum-section-T.svg diff --git a/public/images/maps/ssm.cemetery.holySepulchre-mausoleum-section-U.svg b/public/images/cemeteries/ssm.cemetery.holySepulchre-mausoleum-section-U.svg similarity index 100% rename from public/images/maps/ssm.cemetery.holySepulchre-mausoleum-section-U.svg rename to public/images/cemeteries/ssm.cemetery.holySepulchre-mausoleum-section-U.svg diff --git a/public/images/maps/ssm.cemetery.holySepulchre-mausoleum-west.svg b/public/images/cemeteries/ssm.cemetery.holySepulchre-mausoleum-west.svg similarity index 100% rename from public/images/maps/ssm.cemetery.holySepulchre-mausoleum-west.svg rename to public/images/cemeteries/ssm.cemetery.holySepulchre-mausoleum-west.svg diff --git a/public/images/maps/ssm.cemetery.holySepulchre-overview.svg b/public/images/cemeteries/ssm.cemetery.holySepulchre-overview.svg similarity index 100% rename from public/images/maps/ssm.cemetery.holySepulchre-overview.svg rename to public/images/cemeteries/ssm.cemetery.holySepulchre-overview.svg diff --git a/public/images/maps/ssm.cemetery.newGreenwood-columbarium-A.svg b/public/images/cemeteries/ssm.cemetery.newGreenwood-columbarium-A.svg similarity index 100% rename from public/images/maps/ssm.cemetery.newGreenwood-columbarium-A.svg rename to public/images/cemeteries/ssm.cemetery.newGreenwood-columbarium-A.svg diff --git a/public/images/maps/ssm.cemetery.newGreenwood-columbarium-B.svg b/public/images/cemeteries/ssm.cemetery.newGreenwood-columbarium-B.svg similarity index 100% rename from public/images/maps/ssm.cemetery.newGreenwood-columbarium-B.svg rename to public/images/cemeteries/ssm.cemetery.newGreenwood-columbarium-B.svg diff --git a/public/images/maps/ssm.cemetery.newGreenwood-columbarium-C.svg b/public/images/cemeteries/ssm.cemetery.newGreenwood-columbarium-C.svg similarity index 100% rename from public/images/maps/ssm.cemetery.newGreenwood-columbarium-C.svg rename to public/images/cemeteries/ssm.cemetery.newGreenwood-columbarium-C.svg diff --git a/public/images/maps/ssm.cemetery.newGreenwood-columbarium-D.svg b/public/images/cemeteries/ssm.cemetery.newGreenwood-columbarium-D.svg similarity index 100% rename from public/images/maps/ssm.cemetery.newGreenwood-columbarium-D.svg rename to public/images/cemeteries/ssm.cemetery.newGreenwood-columbarium-D.svg diff --git a/public/images/maps/ssm.cemetery.newGreenwood-columbarium-E.svg b/public/images/cemeteries/ssm.cemetery.newGreenwood-columbarium-E.svg similarity index 100% rename from public/images/maps/ssm.cemetery.newGreenwood-columbarium-E.svg rename to public/images/cemeteries/ssm.cemetery.newGreenwood-columbarium-E.svg diff --git a/public/images/maps/ssm.cemetery.newGreenwood-columbarium-F.svg b/public/images/cemeteries/ssm.cemetery.newGreenwood-columbarium-F.svg similarity index 100% rename from public/images/maps/ssm.cemetery.newGreenwood-columbarium-F.svg rename to public/images/cemeteries/ssm.cemetery.newGreenwood-columbarium-F.svg diff --git a/public/images/maps/ssm.cemetery.newGreenwood-columbarium-G.svg b/public/images/cemeteries/ssm.cemetery.newGreenwood-columbarium-G.svg similarity index 100% rename from public/images/maps/ssm.cemetery.newGreenwood-columbarium-G.svg rename to public/images/cemeteries/ssm.cemetery.newGreenwood-columbarium-G.svg diff --git a/public/images/maps/ssm.cemetery.newGreenwood-columbarium-H.svg b/public/images/cemeteries/ssm.cemetery.newGreenwood-columbarium-H.svg similarity index 100% rename from public/images/maps/ssm.cemetery.newGreenwood-columbarium-H.svg rename to public/images/cemeteries/ssm.cemetery.newGreenwood-columbarium-H.svg diff --git a/public/images/maps/ssm.cemetery.newGreenwood-columbarium-I.svg b/public/images/cemeteries/ssm.cemetery.newGreenwood-columbarium-I.svg similarity index 100% rename from public/images/maps/ssm.cemetery.newGreenwood-columbarium-I.svg rename to public/images/cemeteries/ssm.cemetery.newGreenwood-columbarium-I.svg diff --git a/public/images/maps/ssm.cemetery.newGreenwood-columbarium-J.svg b/public/images/cemeteries/ssm.cemetery.newGreenwood-columbarium-J.svg similarity index 100% rename from public/images/maps/ssm.cemetery.newGreenwood-columbarium-J.svg rename to public/images/cemeteries/ssm.cemetery.newGreenwood-columbarium-J.svg diff --git a/public/images/maps/ssm.cemetery.newGreenwood-columbarium-K.svg b/public/images/cemeteries/ssm.cemetery.newGreenwood-columbarium-K.svg similarity index 100% rename from public/images/maps/ssm.cemetery.newGreenwood-columbarium-K.svg rename to public/images/cemeteries/ssm.cemetery.newGreenwood-columbarium-K.svg diff --git a/public/images/maps/ssm.cemetery.newGreenwood-columbarium-L.svg b/public/images/cemeteries/ssm.cemetery.newGreenwood-columbarium-L.svg similarity index 100% rename from public/images/maps/ssm.cemetery.newGreenwood-columbarium-L.svg rename to public/images/cemeteries/ssm.cemetery.newGreenwood-columbarium-L.svg diff --git a/public/images/maps/ssm.cemetery.newGreenwood-columbarium-M.svg b/public/images/cemeteries/ssm.cemetery.newGreenwood-columbarium-M.svg similarity index 100% rename from public/images/maps/ssm.cemetery.newGreenwood-columbarium-M.svg rename to public/images/cemeteries/ssm.cemetery.newGreenwood-columbarium-M.svg diff --git a/public/images/maps/ssm.cemetery.newGreenwood-columbarium-N.svg b/public/images/cemeteries/ssm.cemetery.newGreenwood-columbarium-N.svg similarity index 100% rename from public/images/maps/ssm.cemetery.newGreenwood-columbarium-N.svg rename to public/images/cemeteries/ssm.cemetery.newGreenwood-columbarium-N.svg diff --git a/public/images/maps/ssm.cemetery.newGreenwood-image.svg b/public/images/cemeteries/ssm.cemetery.newGreenwood-image.svg similarity index 100% rename from public/images/maps/ssm.cemetery.newGreenwood-image.svg rename to public/images/cemeteries/ssm.cemetery.newGreenwood-image.svg diff --git a/public/images/maps/ssm.cemetery.newGreenwood-infantsSection.svg b/public/images/cemeteries/ssm.cemetery.newGreenwood-infantsSection.svg similarity index 100% rename from public/images/maps/ssm.cemetery.newGreenwood-infantsSection.svg rename to public/images/cemeteries/ssm.cemetery.newGreenwood-infantsSection.svg diff --git a/public/images/maps/ssm.cemetery.newGreenwood-nicheWall-1-40.svg b/public/images/cemeteries/ssm.cemetery.newGreenwood-nicheWall-1-40.svg similarity index 100% rename from public/images/maps/ssm.cemetery.newGreenwood-nicheWall-1-40.svg rename to public/images/cemeteries/ssm.cemetery.newGreenwood-nicheWall-1-40.svg diff --git a/public/images/maps/ssm.cemetery.newGreenwood-nicheWall-41-80.svg b/public/images/cemeteries/ssm.cemetery.newGreenwood-nicheWall-41-80.svg similarity index 100% rename from public/images/maps/ssm.cemetery.newGreenwood-nicheWall-41-80.svg rename to public/images/cemeteries/ssm.cemetery.newGreenwood-nicheWall-41-80.svg diff --git a/public/images/maps/ssm.cemetery.newGreenwood-nicheWall-81-106.svg b/public/images/cemeteries/ssm.cemetery.newGreenwood-nicheWall-81-106.svg similarity index 100% rename from public/images/maps/ssm.cemetery.newGreenwood-nicheWall-81-106.svg rename to public/images/cemeteries/ssm.cemetery.newGreenwood-nicheWall-81-106.svg diff --git a/public/images/maps/ssm.cemetery.newGreenwood-overview.svg b/public/images/cemeteries/ssm.cemetery.newGreenwood-overview.svg similarity index 100% rename from public/images/maps/ssm.cemetery.newGreenwood-overview.svg rename to public/images/cemeteries/ssm.cemetery.newGreenwood-overview.svg diff --git a/public/images/maps/ssm.cemetery.newGreenwood-rows-1-31-lots 3-21.svg b/public/images/cemeteries/ssm.cemetery.newGreenwood-rows-1-31-lots 3-21.svg similarity index 100% rename from public/images/maps/ssm.cemetery.newGreenwood-rows-1-31-lots 3-21.svg rename to public/images/cemeteries/ssm.cemetery.newGreenwood-rows-1-31-lots 3-21.svg diff --git a/public/images/maps/ssm.cemetery.newGreenwood-rows-1-31-lots-22-46.svg b/public/images/cemeteries/ssm.cemetery.newGreenwood-rows-1-31-lots-22-46.svg similarity index 100% rename from public/images/maps/ssm.cemetery.newGreenwood-rows-1-31-lots-22-46.svg rename to public/images/cemeteries/ssm.cemetery.newGreenwood-rows-1-31-lots-22-46.svg diff --git a/public/images/maps/ssm.cemetery.newGreenwood-rows-25-61-lots-47-59.svg b/public/images/cemeteries/ssm.cemetery.newGreenwood-rows-25-61-lots-47-59.svg similarity index 100% rename from public/images/maps/ssm.cemetery.newGreenwood-rows-25-61-lots-47-59.svg rename to public/images/cemeteries/ssm.cemetery.newGreenwood-rows-25-61-lots-47-59.svg diff --git a/public/images/maps/ssm.cemetery.newGreenwood-rows-33-60-lots-4-21A.svg b/public/images/cemeteries/ssm.cemetery.newGreenwood-rows-33-60-lots-4-21A.svg similarity index 100% rename from public/images/maps/ssm.cemetery.newGreenwood-rows-33-60-lots-4-21A.svg rename to public/images/cemeteries/ssm.cemetery.newGreenwood-rows-33-60-lots-4-21A.svg diff --git a/public/images/maps/ssm.cemetery.newGreenwood-rows-33-61-lots-22-46.svg b/public/images/cemeteries/ssm.cemetery.newGreenwood-rows-33-61-lots-22-46.svg similarity index 100% rename from public/images/maps/ssm.cemetery.newGreenwood-rows-33-61-lots-22-46.svg rename to public/images/cemeteries/ssm.cemetery.newGreenwood-rows-33-61-lots-22-46.svg diff --git a/public/images/maps/ssm.cemetery.newGreenwood-rows-63-94-lots-24-40.svg b/public/images/cemeteries/ssm.cemetery.newGreenwood-rows-63-94-lots-24-40.svg similarity index 100% rename from public/images/maps/ssm.cemetery.newGreenwood-rows-63-94-lots-24-40.svg rename to public/images/cemeteries/ssm.cemetery.newGreenwood-rows-63-94-lots-24-40.svg diff --git a/public/images/maps/ssm.cemetery.newGreenwood-rows-63-94-lots-47-59.svg b/public/images/cemeteries/ssm.cemetery.newGreenwood-rows-63-94-lots-47-59.svg similarity index 100% rename from public/images/maps/ssm.cemetery.newGreenwood-rows-63-94-lots-47-59.svg rename to public/images/cemeteries/ssm.cemetery.newGreenwood-rows-63-94-lots-47-59.svg diff --git a/public/images/maps/ssm.cemetery.newGreenwood-rows-66-95-lots-12-24.svg b/public/images/cemeteries/ssm.cemetery.newGreenwood-rows-66-95-lots-12-24.svg similarity index 100% rename from public/images/maps/ssm.cemetery.newGreenwood-rows-66-95-lots-12-24.svg rename to public/images/cemeteries/ssm.cemetery.newGreenwood-rows-66-95-lots-12-24.svg diff --git a/public/images/maps/ssm.cemetery.newGreenwood-urnGarden.svg b/public/images/cemeteries/ssm.cemetery.newGreenwood-urnGarden.svg similarity index 100% rename from public/images/maps/ssm.cemetery.newGreenwood-urnGarden.svg rename to public/images/cemeteries/ssm.cemetery.newGreenwood-urnGarden.svg diff --git a/public/images/maps/ssm.cemetery.newGreenwood-veteransSection.svg b/public/images/cemeteries/ssm.cemetery.newGreenwood-veteransSection.svg similarity index 100% rename from public/images/maps/ssm.cemetery.newGreenwood-veteransSection.svg rename to public/images/cemeteries/ssm.cemetery.newGreenwood-veteransSection.svg diff --git a/public/images/maps/ssm.cemetery.oldGreenwood-babySection.svg b/public/images/cemeteries/ssm.cemetery.oldGreenwood-babySection.svg similarity index 100% rename from public/images/maps/ssm.cemetery.oldGreenwood-babySection.svg rename to public/images/cemeteries/ssm.cemetery.oldGreenwood-babySection.svg diff --git a/public/images/maps/ssm.cemetery.oldGreenwood-eastNorth-rows-1-18-lots-1-11.svg b/public/images/cemeteries/ssm.cemetery.oldGreenwood-eastNorth-rows-1-18-lots-1-11.svg similarity index 100% rename from public/images/maps/ssm.cemetery.oldGreenwood-eastNorth-rows-1-18-lots-1-11.svg rename to public/images/cemeteries/ssm.cemetery.oldGreenwood-eastNorth-rows-1-18-lots-1-11.svg diff --git a/public/images/maps/ssm.cemetery.oldGreenwood-eastNorth-rows-1-18-lots-12-17.svg b/public/images/cemeteries/ssm.cemetery.oldGreenwood-eastNorth-rows-1-18-lots-12-17.svg similarity index 100% rename from public/images/maps/ssm.cemetery.oldGreenwood-eastNorth-rows-1-18-lots-12-17.svg rename to public/images/cemeteries/ssm.cemetery.oldGreenwood-eastNorth-rows-1-18-lots-12-17.svg diff --git a/public/images/maps/ssm.cemetery.oldGreenwood-eastNorth-rows-19-38-lots-1-11.svg b/public/images/cemeteries/ssm.cemetery.oldGreenwood-eastNorth-rows-19-38-lots-1-11.svg similarity index 100% rename from public/images/maps/ssm.cemetery.oldGreenwood-eastNorth-rows-19-38-lots-1-11.svg rename to public/images/cemeteries/ssm.cemetery.oldGreenwood-eastNorth-rows-19-38-lots-1-11.svg diff --git a/public/images/maps/ssm.cemetery.oldGreenwood-eastNorth-rows-19-38-lots-12-17.svg b/public/images/cemeteries/ssm.cemetery.oldGreenwood-eastNorth-rows-19-38-lots-12-17.svg similarity index 100% rename from public/images/maps/ssm.cemetery.oldGreenwood-eastNorth-rows-19-38-lots-12-17.svg rename to public/images/cemeteries/ssm.cemetery.oldGreenwood-eastNorth-rows-19-38-lots-12-17.svg diff --git a/public/images/maps/ssm.cemetery.oldGreenwood-eastSouthA-rows-1-18-lots 23-31.svg b/public/images/cemeteries/ssm.cemetery.oldGreenwood-eastSouthA-rows-1-18-lots 23-31.svg similarity index 100% rename from public/images/maps/ssm.cemetery.oldGreenwood-eastSouthA-rows-1-18-lots 23-31.svg rename to public/images/cemeteries/ssm.cemetery.oldGreenwood-eastSouthA-rows-1-18-lots 23-31.svg diff --git a/public/images/maps/ssm.cemetery.oldGreenwood-eastSouthA-rows-1-18-lots-1-22.svg b/public/images/cemeteries/ssm.cemetery.oldGreenwood-eastSouthA-rows-1-18-lots-1-22.svg similarity index 100% rename from public/images/maps/ssm.cemetery.oldGreenwood-eastSouthA-rows-1-18-lots-1-22.svg rename to public/images/cemeteries/ssm.cemetery.oldGreenwood-eastSouthA-rows-1-18-lots-1-22.svg diff --git a/public/images/maps/ssm.cemetery.oldGreenwood-eastSouthA-rows-19-32-lots-1-22.svg b/public/images/cemeteries/ssm.cemetery.oldGreenwood-eastSouthA-rows-19-32-lots-1-22.svg similarity index 100% rename from public/images/maps/ssm.cemetery.oldGreenwood-eastSouthA-rows-19-32-lots-1-22.svg rename to public/images/cemeteries/ssm.cemetery.oldGreenwood-eastSouthA-rows-19-32-lots-1-22.svg diff --git a/public/images/maps/ssm.cemetery.oldGreenwood-eastSouthA-rows-19-32-lots-23-31.svg b/public/images/cemeteries/ssm.cemetery.oldGreenwood-eastSouthA-rows-19-32-lots-23-31.svg similarity index 100% rename from public/images/maps/ssm.cemetery.oldGreenwood-eastSouthA-rows-19-32-lots-23-31.svg rename to public/images/cemeteries/ssm.cemetery.oldGreenwood-eastSouthA-rows-19-32-lots-23-31.svg diff --git a/public/images/maps/ssm.cemetery.oldGreenwood-eastSouthB-lots-33-45-rows-1-22.svg b/public/images/cemeteries/ssm.cemetery.oldGreenwood-eastSouthB-lots-33-45-rows-1-22.svg similarity index 100% rename from public/images/maps/ssm.cemetery.oldGreenwood-eastSouthB-lots-33-45-rows-1-22.svg rename to public/images/cemeteries/ssm.cemetery.oldGreenwood-eastSouthB-lots-33-45-rows-1-22.svg diff --git a/public/images/maps/ssm.cemetery.oldGreenwood-eastSouthB-rows-33-57-lots 23-31.svg b/public/images/cemeteries/ssm.cemetery.oldGreenwood-eastSouthB-rows-33-57-lots 23-31.svg similarity index 100% rename from public/images/maps/ssm.cemetery.oldGreenwood-eastSouthB-rows-33-57-lots 23-31.svg rename to public/images/cemeteries/ssm.cemetery.oldGreenwood-eastSouthB-rows-33-57-lots 23-31.svg diff --git a/public/images/maps/ssm.cemetery.oldGreenwood-eastSouthB-rows-46-57-lots-11-24.svg b/public/images/cemeteries/ssm.cemetery.oldGreenwood-eastSouthB-rows-46-57-lots-11-24.svg similarity index 100% rename from public/images/maps/ssm.cemetery.oldGreenwood-eastSouthB-rows-46-57-lots-11-24.svg rename to public/images/cemeteries/ssm.cemetery.oldGreenwood-eastSouthB-rows-46-57-lots-11-24.svg diff --git a/public/images/maps/ssm.cemetery.oldGreenwood-image.svg b/public/images/cemeteries/ssm.cemetery.oldGreenwood-image.svg similarity index 100% rename from public/images/maps/ssm.cemetery.oldGreenwood-image.svg rename to public/images/cemeteries/ssm.cemetery.oldGreenwood-image.svg diff --git a/public/images/maps/ssm.cemetery.oldGreenwood-overview.svg b/public/images/cemeteries/ssm.cemetery.oldGreenwood-overview.svg similarity index 100% rename from public/images/maps/ssm.cemetery.oldGreenwood-overview.svg rename to public/images/cemeteries/ssm.cemetery.oldGreenwood-overview.svg diff --git a/public/images/maps/ssm.cemetery.oldGreenwood-westSection-image.svg b/public/images/cemeteries/ssm.cemetery.oldGreenwood-westSection-image.svg similarity index 100% rename from public/images/maps/ssm.cemetery.oldGreenwood-westSection-image.svg rename to public/images/cemeteries/ssm.cemetery.oldGreenwood-westSection-image.svg diff --git a/public/images/maps/ssm.cemetery.oldGreenwood-westSection.svg b/public/images/cemeteries/ssm.cemetery.oldGreenwood-westSection.svg similarity index 100% rename from public/images/maps/ssm.cemetery.oldGreenwood-westSection.svg rename to public/images/cemeteries/ssm.cemetery.oldGreenwood-westSection.svg diff --git a/public/images/maps/ssm.cemetery.pineGrove-overview.svg b/public/images/cemeteries/ssm.cemetery.pineGrove-overview.svg similarity index 100% rename from public/images/maps/ssm.cemetery.pineGrove-overview.svg rename to public/images/cemeteries/ssm.cemetery.pineGrove-overview.svg diff --git a/public/images/maps/ssm.cemetery.westKorah-eastSection.svg b/public/images/cemeteries/ssm.cemetery.westKorah-eastSection.svg similarity index 100% rename from public/images/maps/ssm.cemetery.westKorah-eastSection.svg rename to public/images/cemeteries/ssm.cemetery.westKorah-eastSection.svg diff --git a/public/images/maps/ssm.cemetery.westKorah-northSection.svg b/public/images/cemeteries/ssm.cemetery.westKorah-northSection.svg similarity index 100% rename from public/images/maps/ssm.cemetery.westKorah-northSection.svg rename to public/images/cemeteries/ssm.cemetery.westKorah-northSection.svg diff --git a/public/images/maps/ssm.cemetery.westKorah-overview.svg b/public/images/cemeteries/ssm.cemetery.westKorah-overview.svg similarity index 100% rename from public/images/maps/ssm.cemetery.westKorah-overview.svg rename to public/images/cemeteries/ssm.cemetery.westKorah-overview.svg diff --git a/public/images/maps/ssm.cemetery.westKorah-westSection.svg b/public/images/cemeteries/ssm.cemetery.westKorah-westSection.svg similarity index 100% rename from public/images/maps/ssm.cemetery.westKorah-westSection.svg rename to public/images/cemeteries/ssm.cemetery.westKorah-westSection.svg diff --git a/routes/admin.js b/routes/admin.js index a62ef439..33ce2ab0 100644 --- a/routes/admin.js +++ b/routes/admin.js @@ -1,7 +1,7 @@ import { Router } from 'express'; +import handler_burialSiteTypes from '../handlers/admin-get/burialSiteTypes.js'; import handler_database from '../handlers/admin-get/database.js'; import handler_fees from '../handlers/admin-get/fees.js'; -import handler_lotTypes from '../handlers/admin-get/lotTypes.js'; import handler_ntfyStartup from '../handlers/admin-get/ntfyStartup.js'; import handler_occupancyTypes from '../handlers/admin-get/occupancyTypes.js'; import handler_tables from '../handlers/admin-get/tables.js'; @@ -102,7 +102,7 @@ router.post('/doDeleteOccupancyTypePrint', handler_doDeleteOccupancyTypePrint); /* * Lot Type Management */ -router.get('/lotTypes', handler_lotTypes); +router.get('/lotTypes', handler_burialSiteTypes); router.post('/doAddLotType', handler_doAddLotType); router.post('/doUpdateLotType', handler_doUpdateLotType); router.post('/doMoveLotTypeUp', handler_doMoveLotTypeUp); diff --git a/routes/admin.ts b/routes/admin.ts index 45d1ffa6..7896e4cd 100644 --- a/routes/admin.ts +++ b/routes/admin.ts @@ -1,8 +1,8 @@ import { Router } from 'express' +import handler_burialSiteTypes from '../handlers/admin-get/burialSiteTypes.js' import handler_database from '../handlers/admin-get/database.js' import handler_fees from '../handlers/admin-get/fees.js' -import handler_lotTypes from '../handlers/admin-get/lotTypes.js' import handler_ntfyStartup from '../handlers/admin-get/ntfyStartup.js' import handler_occupancyTypes from '../handlers/admin-get/occupancyTypes.js' import handler_tables from '../handlers/admin-get/tables.js' @@ -144,7 +144,7 @@ router.post('/doDeleteOccupancyTypePrint', handler_doDeleteOccupancyTypePrint) * Lot Type Management */ -router.get('/lotTypes', handler_lotTypes) +router.get('/lotTypes', handler_burialSiteTypes) router.post('/doAddLotType', handler_doAddLotType) diff --git a/routes/lotOccupancies.d.ts b/routes/burialSites.d.ts similarity index 100% rename from routes/lotOccupancies.d.ts rename to routes/burialSites.d.ts diff --git a/routes/lots.js b/routes/burialSites.js similarity index 100% rename from routes/lots.js rename to routes/burialSites.js diff --git a/routes/lots.ts b/routes/burialSites.ts similarity index 100% rename from routes/lots.ts rename to routes/burialSites.ts diff --git a/routes/lots.d.ts b/routes/cemeteries.d.ts similarity index 100% rename from routes/lots.d.ts rename to routes/cemeteries.d.ts diff --git a/routes/cemeteries.js b/routes/cemeteries.js new file mode 100644 index 00000000..1f8a6779 --- /dev/null +++ b/routes/cemeteries.js @@ -0,0 +1,22 @@ +import { Router } from 'express'; +import handler_edit from '../handlers/cemeteries-get/edit.js'; +import handler_new from '../handlers/cemeteries-get/new.js'; +import handler_next from '../handlers/cemeteries-get/next.js'; +import handler_previous from '../handlers/cemeteries-get/previous.js'; +import handler_search from '../handlers/cemeteries-get/search.js'; +import handler_view from '../handlers/cemeteries-get/view.js'; +import handler_doCreateMap from '../handlers/cemeteries-post/doCreateCemetery.js'; +import handler_doDeleteMap from '../handlers/cemeteries-post/doDeleteMap.js'; +import handler_doUpdateMap from '../handlers/cemeteries-post/doUpdateMap.js'; +import { updateGetHandler, updatePostHandler } from '../handlers/permissions.js'; +export const router = Router(); +router.get('/', handler_search); +router.get('/new', updateGetHandler, handler_new); +router.get('/:cemeteryId', handler_view); +router.get('/:cemeteryId/next', handler_next); +router.get('/:cemeteryId/previous', handler_previous); +router.get('/:cemeteryId/edit', updateGetHandler, handler_edit); +router.post('/doCreateCemetery', updatePostHandler, handler_doCreateMap); +router.post('/doUpdateCemetery', updatePostHandler, handler_doUpdateMap); +router.post('/doDeleteCemetery', updatePostHandler, handler_doDeleteMap); +export default router; diff --git a/routes/cemeteries.ts b/routes/cemeteries.ts new file mode 100644 index 00000000..11574fce --- /dev/null +++ b/routes/cemeteries.ts @@ -0,0 +1,46 @@ +import { type RequestHandler, Router } from 'express' + +import handler_edit from '../handlers/cemeteries-get/edit.js' +import handler_new from '../handlers/cemeteries-get/new.js' +import handler_next from '../handlers/cemeteries-get/next.js' +import handler_previous from '../handlers/cemeteries-get/previous.js' +import handler_search from '../handlers/cemeteries-get/search.js' +import handler_view from '../handlers/cemeteries-get/view.js' +import handler_doCreateMap from '../handlers/cemeteries-post/doCreateCemetery.js' +import handler_doDeleteMap from '../handlers/cemeteries-post/doDeleteMap.js' +import handler_doUpdateMap from '../handlers/cemeteries-post/doUpdateMap.js' +import { updateGetHandler, updatePostHandler } from '../handlers/permissions.js' + +export const router = Router() + +router.get('/', handler_search) + +router.get('/new', updateGetHandler, handler_new) + +router.get('/:cemeteryId', handler_view) + +router.get('/:cemeteryId/next', handler_next) + +router.get('/:cemeteryId/previous', handler_previous) + +router.get('/:cemeteryId/edit', updateGetHandler, handler_edit) + +router.post( + '/doCreateCemetery', + updatePostHandler, + handler_doCreateMap +) + +router.post( + '/doUpdateCemetery', + updatePostHandler, + handler_doUpdateMap +) + +router.post( + '/doDeleteCemetery', + updatePostHandler, + handler_doDeleteMap +) + +export default router diff --git a/routes/maps.d.ts b/routes/contracts.d.ts similarity index 100% rename from routes/maps.d.ts rename to routes/contracts.d.ts diff --git a/routes/lotOccupancies.js b/routes/contracts.js similarity index 98% rename from routes/lotOccupancies.js rename to routes/contracts.js index ac856039..a25e0049 100644 --- a/routes/lotOccupancies.js +++ b/routes/contracts.js @@ -26,7 +26,7 @@ import handler_doUpdateLotOccupancyFeeQuantity from '../handlers/lotOccupancies- import handler_doUpdateLotOccupancyOccupant from '../handlers/lotOccupancies-post/doUpdateLotOccupancyOccupant.js'; import handler_doUpdateLotOccupancyTransaction from '../handlers/lotOccupancies-post/doUpdateLotOccupancyTransaction.js'; import { updateGetHandler, updatePostHandler } from '../handlers/permissions.js'; -import { getConfigProperty } from '../helpers/functions.config.js'; +import { getConfigProperty } from '../helpers/config.helpers.js'; export const router = Router(); // Search router.get('/', handler_search); diff --git a/routes/lotOccupancies.ts b/routes/contracts.ts similarity index 98% rename from routes/lotOccupancies.ts rename to routes/contracts.ts index ffd59e00..a60cb4ca 100644 --- a/routes/lotOccupancies.ts +++ b/routes/contracts.ts @@ -27,7 +27,7 @@ import handler_doUpdateLotOccupancyFeeQuantity from '../handlers/lotOccupancies- import handler_doUpdateLotOccupancyOccupant from '../handlers/lotOccupancies-post/doUpdateLotOccupancyOccupant.js' import handler_doUpdateLotOccupancyTransaction from '../handlers/lotOccupancies-post/doUpdateLotOccupancyTransaction.js' import { updateGetHandler, updatePostHandler } from '../handlers/permissions.js' -import { getConfigProperty } from '../helpers/functions.config.js' +import { getConfigProperty } from '../helpers/config.helpers.js' export const router = Router() diff --git a/routes/login.js b/routes/login.js index 1bacf1d3..6f823918 100644 --- a/routes/login.js +++ b/routes/login.js @@ -1,10 +1,11 @@ import Debug from 'debug'; import { Router } from 'express'; -import { useTestDatabases } from '../data/databasePaths.js'; +import { DEBUG_NAMESPACE } from '../debug.config.js'; +import { getConfigProperty } from '../helpers/config.helpers.js'; +import { useTestDatabases } from '../helpers/database.helpers.js'; import { getApiKey } from '../helpers/functions.api.js'; import { authenticate, getSafeRedirectURL } from '../helpers/functions.authentication.js'; -import { getConfigProperty } from '../helpers/functions.config.js'; -const debug = Debug('lot-occupancy-system:login'); +const debug = Debug(`${DEBUG_NAMESPACE}:login`); export const router = Router(); function getHandler(request, response) { const sessionCookieName = getConfigProperty('session.cookieName'); diff --git a/routes/login.ts b/routes/login.ts index ffc085cd..eee9a88f 100644 --- a/routes/login.ts +++ b/routes/login.ts @@ -1,15 +1,16 @@ import Debug from 'debug' import { type Request, type Response, Router } from 'express' -import { useTestDatabases } from '../data/databasePaths.js' +import { DEBUG_NAMESPACE } from '../debug.config.js' +import { getConfigProperty } from '../helpers/config.helpers.js' +import { useTestDatabases } from '../helpers/database.helpers.js' import { getApiKey } from '../helpers/functions.api.js' import { authenticate, getSafeRedirectURL } from '../helpers/functions.authentication.js' -import { getConfigProperty } from '../helpers/functions.config.js' -const debug = Debug('lot-occupancy-system:login') +const debug = Debug(`${DEBUG_NAMESPACE}:login`) export const router = Router() diff --git a/routes/maps.js b/routes/maps.js deleted file mode 100644 index ed1711db..00000000 --- a/routes/maps.js +++ /dev/null @@ -1,22 +0,0 @@ -import { Router } from 'express'; -import handler_edit from '../handlers/maps-get/edit.js'; -import handler_new from '../handlers/maps-get/new.js'; -import handler_next from '../handlers/maps-get/next.js'; -import handler_previous from '../handlers/maps-get/previous.js'; -import handler_search from '../handlers/maps-get/search.js'; -import handler_view from '../handlers/maps-get/view.js'; -import handler_doCreateMap from '../handlers/maps-post/doCreateMap.js'; -import handler_doDeleteMap from '../handlers/maps-post/doDeleteMap.js'; -import handler_doUpdateMap from '../handlers/maps-post/doUpdateMap.js'; -import { updateGetHandler, updatePostHandler } from '../handlers/permissions.js'; -export const router = Router(); -router.get('/', handler_search); -router.get('/new', updateGetHandler, handler_new); -router.get('/:mapId', handler_view); -router.get('/:mapId/next', handler_next); -router.get('/:mapId/previous', handler_previous); -router.get('/:mapId/edit', updateGetHandler, handler_edit); -router.post('/doCreateMap', updatePostHandler, handler_doCreateMap); -router.post('/doUpdateMap', updatePostHandler, handler_doUpdateMap); -router.post('/doDeleteMap', updatePostHandler, handler_doDeleteMap); -export default router; diff --git a/routes/maps.ts b/routes/maps.ts deleted file mode 100644 index 429e53b1..00000000 --- a/routes/maps.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { type RequestHandler, Router } from 'express' - -import handler_edit from '../handlers/maps-get/edit.js' -import handler_new from '../handlers/maps-get/new.js' -import handler_next from '../handlers/maps-get/next.js' -import handler_previous from '../handlers/maps-get/previous.js' -import handler_search from '../handlers/maps-get/search.js' -import handler_view from '../handlers/maps-get/view.js' -import handler_doCreateMap from '../handlers/maps-post/doCreateMap.js' -import handler_doDeleteMap from '../handlers/maps-post/doDeleteMap.js' -import handler_doUpdateMap from '../handlers/maps-post/doUpdateMap.js' -import { updateGetHandler, updatePostHandler } from '../handlers/permissions.js' - -export const router = Router() - -router.get('/', handler_search) - -router.get('/new', updateGetHandler, handler_new) - -router.get('/:mapId', handler_view) - -router.get('/:mapId/next', handler_next) - -router.get('/:mapId/previous', handler_previous) - -router.get('/:mapId/edit', updateGetHandler, handler_edit) - -router.post( - '/doCreateMap', - updatePostHandler, - handler_doCreateMap -) - -router.post( - '/doUpdateMap', - updatePostHandler, - handler_doUpdateMap -) - -router.post( - '/doDeleteMap', - updatePostHandler, - handler_doDeleteMap -) - -export default router diff --git a/temp/legacy.importFromCSV.js b/temp/legacy.importFromCSV.js index 89aec412..71092363 100644 --- a/temp/legacy.importFromCSV.js +++ b/temp/legacy.importFromCSV.js @@ -2,7 +2,7 @@ import fs from 'node:fs'; import { dateIntegerToString, dateToString } from '@cityssm/utils-datetime'; import sqlite from 'better-sqlite3'; import papa from 'papaparse'; -import { lotOccupancyDB as databasePath } from '../data/databasePaths.js'; +import { sunriseDB as databasePath } from '../data/databasePaths.js'; import addLot from '../database/addLot.js'; import addLotOccupancy from '../database/addLotOccupancy.js'; import addLotOccupancyComment from '../database/addLotOccupancyComment.js'; @@ -301,18 +301,14 @@ async function importFromMasterCSV() { const lotOccupancyFieldValue = formatDateString(masterRow.CM_DEATH_YR, masterRow.CM_DEATH_MON, masterRow.CM_DEATH_DAY); await addOrUpdateLotOccupancyField({ lotOccupancyId: deceasedLotOccupancyId, - occupancyTypeFieldId: occupancyType.occupancyTypeFields.find((occupancyTypeField) => { - return occupancyTypeField.occupancyTypeField === 'Death Date'; - }).occupancyTypeFieldId, + occupancyTypeFieldId: occupancyType.occupancyTypeFields.find((occupancyTypeField) => occupancyTypeField.occupancyTypeField === 'Death Date').occupancyTypeFieldId, lotOccupancyFieldValue }, user); } if (masterRow.CM_AGE !== '') { await addOrUpdateLotOccupancyField({ lotOccupancyId: deceasedLotOccupancyId, - occupancyTypeFieldId: occupancyType.occupancyTypeFields.find((occupancyTypeField) => { - return occupancyTypeField.occupancyTypeField === 'Death Age'; - }).occupancyTypeFieldId, + occupancyTypeFieldId: occupancyType.occupancyTypeFields.find((occupancyTypeField) => occupancyTypeField.occupancyTypeField === 'Death Age').occupancyTypeFieldId, lotOccupancyFieldValue: masterRow.CM_AGE }, user); } @@ -320,9 +316,7 @@ async function importFromMasterCSV() { const period = importData.getDeathAgePeriod(masterRow.CM_PERIOD); await addOrUpdateLotOccupancyField({ lotOccupancyId: deceasedLotOccupancyId, - occupancyTypeFieldId: occupancyType.occupancyTypeFields.find((occupancyTypeField) => { - return (occupancyTypeField.occupancyTypeField === 'Death Age Period'); - }).occupancyTypeFieldId, + occupancyTypeFieldId: occupancyType.occupancyTypeFields.find((occupancyTypeField) => (occupancyTypeField.occupancyTypeField === 'Death Age Period')).occupancyTypeFieldId, lotOccupancyFieldValue: period }, user); } @@ -360,9 +354,7 @@ async function importFromMasterCSV() { const lotOccupancyFieldValue = formatDateString(masterRow.CM_FUNERAL_YR, masterRow.CM_FUNERAL_MON, masterRow.CM_FUNERAL_DAY); await addOrUpdateLotOccupancyField({ lotOccupancyId: deceasedLotOccupancyId, - occupancyTypeFieldId: occupancyType.occupancyTypeFields.find((occupancyTypeField) => { - return (occupancyTypeField.occupancyTypeField === 'Funeral Date'); - }).occupancyTypeFieldId, + occupancyTypeFieldId: occupancyType.occupancyTypeFields.find((occupancyTypeField) => (occupancyTypeField.occupancyTypeField === 'Funeral Date')).occupancyTypeFieldId, lotOccupancyFieldValue }, user); } @@ -370,9 +362,7 @@ async function importFromMasterCSV() { if (masterRow.CM_CONTAINER_TYPE !== '') { await addOrUpdateLotOccupancyField({ lotOccupancyId: deceasedLotOccupancyId, - occupancyTypeFieldId: occupancyType.occupancyTypeFields.find((occupancyTypeField) => { - return (occupancyTypeField.occupancyTypeField === 'Container Type'); - }).occupancyTypeFieldId, + occupancyTypeFieldId: occupancyType.occupancyTypeFields.find((occupancyTypeField) => (occupancyTypeField.occupancyTypeField === 'Container Type')).occupancyTypeFieldId, lotOccupancyFieldValue: masterRow.CM_CONTAINER_TYPE }, user); } @@ -383,9 +373,7 @@ async function importFromMasterCSV() { } await addOrUpdateLotOccupancyField({ lotOccupancyId: deceasedLotOccupancyId, - occupancyTypeFieldId: occupancyType.occupancyTypeFields.find((occupancyTypeField) => { - return (occupancyTypeField.occupancyTypeField === 'Committal Type'); - }).occupancyTypeFieldId, + occupancyTypeFieldId: occupancyType.occupancyTypeFields.find((occupancyTypeField) => (occupancyTypeField.occupancyTypeField === 'Committal Type')).occupancyTypeFieldId, lotOccupancyFieldValue: commitalType }, user); } @@ -516,14 +504,12 @@ async function importFromPrepaidCSV() { possibleLotOccupancies.lotOccupancies[0].lotOccupancyId; } } - if (!lotOccupancyId) { - lotOccupancyId = await addLotOccupancy({ - lotId: lot ? lot.lotId : '', - occupancyTypeId: importIds.preneedOccupancyType.occupancyTypeId, - occupancyStartDateString, - occupancyEndDateString: '' - }, user); - } + lotOccupancyId ||= await addLotOccupancy({ + lotId: lot ? lot.lotId : '', + occupancyTypeId: importIds.preneedOccupancyType.occupancyTypeId, + occupancyStartDateString, + occupancyEndDateString: '' + }, user); await addLotOccupancyOccupant({ lotOccupancyId, lotOccupantTypeId: importIds.preneedOwnerLotOccupantTypeId, @@ -745,9 +731,7 @@ async function importFromWorkOrderCSV() { }, user); lot = await getLot(lotId); } - const workOrderContainsLot = workOrder.workOrderLots.find((possibleLot) => { - return (possibleLot.lotId = lot.lotId); - }); + const workOrderContainsLot = workOrder.workOrderLots.find((possibleLot) => (possibleLot.lotId = lot.lotId)); if (!workOrderContainsLot) { await addWorkOrderLot({ workOrderId: workOrder.workOrderId, @@ -786,27 +770,21 @@ async function importFromWorkOrderCSV() { const lotOccupancyFieldValue = formatDateString(workOrderRow.WO_DEATH_YR, workOrderRow.WO_DEATH_MON, workOrderRow.WO_DEATH_DAY); await addOrUpdateLotOccupancyField({ lotOccupancyId, - occupancyTypeFieldId: occupancyType.occupancyTypeFields.find((occupancyTypeField) => { - return occupancyTypeField.occupancyTypeField === 'Death Date'; - }).occupancyTypeFieldId, + occupancyTypeFieldId: occupancyType.occupancyTypeFields.find((occupancyTypeField) => occupancyTypeField.occupancyTypeField === 'Death Date').occupancyTypeFieldId, lotOccupancyFieldValue }, user); } if (workOrderRow.WO_DEATH_PLACE !== '') { await addOrUpdateLotOccupancyField({ lotOccupancyId, - occupancyTypeFieldId: occupancyType.occupancyTypeFields.find((occupancyTypeField) => { - return occupancyTypeField.occupancyTypeField === 'Death Place'; - }).occupancyTypeFieldId, + occupancyTypeFieldId: occupancyType.occupancyTypeFields.find((occupancyTypeField) => occupancyTypeField.occupancyTypeField === 'Death Place').occupancyTypeFieldId, lotOccupancyFieldValue: workOrderRow.WO_DEATH_PLACE }, user); } if (workOrderRow.WO_AGE !== '') { await addOrUpdateLotOccupancyField({ lotOccupancyId, - occupancyTypeFieldId: occupancyType.occupancyTypeFields.find((occupancyTypeField) => { - return occupancyTypeField.occupancyTypeField === 'Death Age'; - }).occupancyTypeFieldId, + occupancyTypeFieldId: occupancyType.occupancyTypeFields.find((occupancyTypeField) => occupancyTypeField.occupancyTypeField === 'Death Age').occupancyTypeFieldId, lotOccupancyFieldValue: workOrderRow.WO_AGE }, user); } @@ -814,9 +792,7 @@ async function importFromWorkOrderCSV() { const period = importData.getDeathAgePeriod(workOrderRow.WO_PERIOD); await addOrUpdateLotOccupancyField({ lotOccupancyId, - occupancyTypeFieldId: occupancyType.occupancyTypeFields.find((occupancyTypeField) => { - return (occupancyTypeField.occupancyTypeField === 'Death Age Period'); - }).occupancyTypeFieldId, + occupancyTypeFieldId: occupancyType.occupancyTypeFields.find((occupancyTypeField) => (occupancyTypeField.occupancyTypeField === 'Death Age Period')).occupancyTypeFieldId, lotOccupancyFieldValue: period }, user); } @@ -852,9 +828,7 @@ async function importFromWorkOrderCSV() { const lotOccupancyFieldValue = formatDateString(workOrderRow.WO_FUNERAL_YR, workOrderRow.WO_FUNERAL_MON, workOrderRow.WO_FUNERAL_DAY); await addOrUpdateLotOccupancyField({ lotOccupancyId, - occupancyTypeFieldId: occupancyType.occupancyTypeFields.find((occupancyTypeField) => { - return occupancyTypeField.occupancyTypeField === 'Funeral Date'; - }).occupancyTypeFieldId, + occupancyTypeFieldId: occupancyType.occupancyTypeFields.find((occupancyTypeField) => occupancyTypeField.occupancyTypeField === 'Funeral Date').occupancyTypeFieldId, lotOccupancyFieldValue }, user); } @@ -862,9 +836,7 @@ async function importFromWorkOrderCSV() { if (workOrderRow.WO_CONTAINER_TYPE !== '') { await addOrUpdateLotOccupancyField({ lotOccupancyId, - occupancyTypeFieldId: occupancyType.occupancyTypeFields.find((occupancyTypeField) => { - return (occupancyTypeField.occupancyTypeField === 'Container Type'); - }).occupancyTypeFieldId, + occupancyTypeFieldId: occupancyType.occupancyTypeFields.find((occupancyTypeField) => (occupancyTypeField.occupancyTypeField === 'Container Type')).occupancyTypeFieldId, lotOccupancyFieldValue: workOrderRow.WO_CONTAINER_TYPE }, user); } @@ -875,9 +847,7 @@ async function importFromWorkOrderCSV() { } await addOrUpdateLotOccupancyField({ lotOccupancyId, - occupancyTypeFieldId: occupancyType.occupancyTypeFields.find((occupancyTypeField) => { - return (occupancyTypeField.occupancyTypeField === 'Committal Type'); - }).occupancyTypeFieldId, + occupancyTypeFieldId: occupancyType.occupancyTypeFields.find((occupancyTypeField) => (occupancyTypeField.occupancyTypeField === 'Committal Type')).occupancyTypeFieldId, lotOccupancyFieldValue: commitalType }, user); } diff --git a/temp/legacy.importFromCSV.ts b/temp/legacy.importFromCSV.ts index 2ce975fc..4cd0b63f 100644 --- a/temp/legacy.importFromCSV.ts +++ b/temp/legacy.importFromCSV.ts @@ -9,7 +9,7 @@ import { import sqlite from 'better-sqlite3' import papa from 'papaparse' -import { lotOccupancyDB as databasePath } from '../data/databasePaths.js' +import { sunriseDB as databasePath } from '../data/databasePaths.js' import addLot from '../database/addLot.js' import addLotOccupancy from '../database/addLotOccupancy.js' import addLotOccupancyComment from '../database/addLotOccupancyComment.js' @@ -31,7 +31,6 @@ import getWorkOrder, { } from '../database/getWorkOrder.js' import reopenWorkOrder from '../database/reopenWorkOrder.js' import { updateLotStatus } from '../database/updateLot.js' -// eslint-disable-next-line import/namespace import type * as recordTypes from '../types/recordTypes.js' import * as importData from './legacy.importFromCsv.data.js' @@ -600,9 +599,7 @@ async function importFromMasterCSV(): Promise { { lotOccupancyId: deceasedLotOccupancyId, occupancyTypeFieldId: occupancyType.occupancyTypeFields!.find( - (occupancyTypeField) => { - return occupancyTypeField.occupancyTypeField === 'Death Date' - } + (occupancyTypeField) => occupancyTypeField.occupancyTypeField === 'Death Date' )!.occupancyTypeFieldId!, lotOccupancyFieldValue }, @@ -615,9 +612,7 @@ async function importFromMasterCSV(): Promise { { lotOccupancyId: deceasedLotOccupancyId, occupancyTypeFieldId: occupancyType.occupancyTypeFields!.find( - (occupancyTypeField) => { - return occupancyTypeField.occupancyTypeField === 'Death Age' - } + (occupancyTypeField) => occupancyTypeField.occupancyTypeField === 'Death Age' )!.occupancyTypeFieldId!, lotOccupancyFieldValue: masterRow.CM_AGE }, @@ -632,11 +627,9 @@ async function importFromMasterCSV(): Promise { { lotOccupancyId: deceasedLotOccupancyId, occupancyTypeFieldId: occupancyType.occupancyTypeFields!.find( - (occupancyTypeField) => { - return ( + (occupancyTypeField) => ( occupancyTypeField.occupancyTypeField === 'Death Age Period' ) - } )!.occupancyTypeFieldId!, lotOccupancyFieldValue: period }, @@ -694,11 +687,9 @@ async function importFromMasterCSV(): Promise { { lotOccupancyId: deceasedLotOccupancyId, occupancyTypeFieldId: occupancyType.occupancyTypeFields!.find( - (occupancyTypeField) => { - return ( + (occupancyTypeField) => ( occupancyTypeField.occupancyTypeField === 'Funeral Date' ) - } )!.occupancyTypeFieldId!, lotOccupancyFieldValue }, @@ -712,11 +703,9 @@ async function importFromMasterCSV(): Promise { { lotOccupancyId: deceasedLotOccupancyId, occupancyTypeFieldId: occupancyType.occupancyTypeFields!.find( - (occupancyTypeField) => { - return ( + (occupancyTypeField) => ( occupancyTypeField.occupancyTypeField === 'Container Type' ) - } )!.occupancyTypeFieldId!, lotOccupancyFieldValue: masterRow.CM_CONTAINER_TYPE }, @@ -735,11 +724,9 @@ async function importFromMasterCSV(): Promise { { lotOccupancyId: deceasedLotOccupancyId, occupancyTypeFieldId: occupancyType.occupancyTypeFields!.find( - (occupancyTypeField) => { - return ( + (occupancyTypeField) => ( occupancyTypeField.occupancyTypeField === 'Committal Type' ) - } )!.occupancyTypeFieldId!, lotOccupancyFieldValue: commitalType }, @@ -921,8 +908,7 @@ async function importFromPrepaidCSV(): Promise { } } - if (!lotOccupancyId) { - lotOccupancyId = await addLotOccupancy( + lotOccupancyId ||= await addLotOccupancy( { lotId: lot ? lot.lotId : '', occupancyTypeId: importIds.preneedOccupancyType.occupancyTypeId, @@ -930,8 +916,7 @@ async function importFromPrepaidCSV(): Promise { occupancyEndDateString: '' }, user - ) - } + ); await addLotOccupancyOccupant( { @@ -1240,9 +1225,7 @@ async function importFromWorkOrderCSV(): Promise { } const workOrderContainsLot = workOrder.workOrderLots!.find( - (possibleLot) => { - return (possibleLot.lotId = lot.lotId) - } + (possibleLot) => (possibleLot.lotId = lot.lotId) ) if (!workOrderContainsLot) { @@ -1310,9 +1293,7 @@ async function importFromWorkOrderCSV(): Promise { { lotOccupancyId, occupancyTypeFieldId: occupancyType.occupancyTypeFields!.find( - (occupancyTypeField) => { - return occupancyTypeField.occupancyTypeField === 'Death Date' - } + (occupancyTypeField) => occupancyTypeField.occupancyTypeField === 'Death Date' )!.occupancyTypeFieldId!, lotOccupancyFieldValue }, @@ -1325,9 +1306,7 @@ async function importFromWorkOrderCSV(): Promise { { lotOccupancyId, occupancyTypeFieldId: occupancyType.occupancyTypeFields!.find( - (occupancyTypeField) => { - return occupancyTypeField.occupancyTypeField === 'Death Place' - } + (occupancyTypeField) => occupancyTypeField.occupancyTypeField === 'Death Place' )!.occupancyTypeFieldId!, lotOccupancyFieldValue: workOrderRow.WO_DEATH_PLACE }, @@ -1340,9 +1319,7 @@ async function importFromWorkOrderCSV(): Promise { { lotOccupancyId, occupancyTypeFieldId: occupancyType.occupancyTypeFields!.find( - (occupancyTypeField) => { - return occupancyTypeField.occupancyTypeField === 'Death Age' - } + (occupancyTypeField) => occupancyTypeField.occupancyTypeField === 'Death Age' )!.occupancyTypeFieldId!, lotOccupancyFieldValue: workOrderRow.WO_AGE }, @@ -1357,11 +1334,9 @@ async function importFromWorkOrderCSV(): Promise { { lotOccupancyId, occupancyTypeFieldId: occupancyType.occupancyTypeFields!.find( - (occupancyTypeField) => { - return ( + (occupancyTypeField) => ( occupancyTypeField.occupancyTypeField === 'Death Age Period' ) - } )!.occupancyTypeFieldId!, lotOccupancyFieldValue: period }, @@ -1417,9 +1392,7 @@ async function importFromWorkOrderCSV(): Promise { { lotOccupancyId, occupancyTypeFieldId: occupancyType.occupancyTypeFields!.find( - (occupancyTypeField) => { - return occupancyTypeField.occupancyTypeField === 'Funeral Date' - } + (occupancyTypeField) => occupancyTypeField.occupancyTypeField === 'Funeral Date' )!.occupancyTypeFieldId!, lotOccupancyFieldValue }, @@ -1433,11 +1406,9 @@ async function importFromWorkOrderCSV(): Promise { { lotOccupancyId, occupancyTypeFieldId: occupancyType.occupancyTypeFields!.find( - (occupancyTypeField) => { - return ( + (occupancyTypeField) => ( occupancyTypeField.occupancyTypeField === 'Container Type' ) - } )!.occupancyTypeFieldId!, lotOccupancyFieldValue: workOrderRow.WO_CONTAINER_TYPE }, @@ -1456,11 +1427,9 @@ async function importFromWorkOrderCSV(): Promise { { lotOccupancyId, occupancyTypeFieldId: occupancyType.occupancyTypeFields!.find( - (occupancyTypeField) => { - return ( + (occupancyTypeField) => ( occupancyTypeField.occupancyTypeField === 'Committal Type' ) - } )!.occupancyTypeFieldId!, lotOccupancyFieldValue: commitalType }, diff --git a/temp/legacy.importFromCsv.ids.d.ts b/temp/legacy.importFromCsv.ids.d.ts index cfeda03c..e77e264e 100644 --- a/temp/legacy.importFromCsv.ids.d.ts +++ b/temp/legacy.importFromCsv.ids.d.ts @@ -3,9 +3,9 @@ export declare const preneedOwnerLotOccupantTypeId: number; export declare const funeralDirectorLotOccupantTypeId: number; export declare const deceasedLotOccupantTypeId: number; export declare const purchaserLotOccupantTypeId: number; -export declare const availableLotStatusId: number; -export declare const reservedLotStatusId: number; -export declare const takenLotStatusId: number; +export declare const availableLotStatusId: any; +export declare const reservedLotStatusId: any; +export declare const takenLotStatusId: any; export declare function getLotTypeId(dataRow: { cemetery: string; }): number; diff --git a/temp/legacy.importFromCsv.ids.js b/temp/legacy.importFromCsv.ids.js index 75ca6ec4..240443ea 100644 --- a/temp/legacy.importFromCsv.ids.js +++ b/temp/legacy.importFromCsv.ids.js @@ -1,7 +1,7 @@ // eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair /* eslint-disable unicorn/no-await-expression-member */ import sqlite from 'better-sqlite3'; -import { lotOccupancyDB as databasePath } from '../data/databasePaths.js'; +import { sunriseDB as databasePath } from '../data/databasePaths.js'; import * as cacheFunctions from '../helpers/functions.cache.js'; /* * Fee IDs diff --git a/temp/legacy.importFromCsv.ids.ts b/temp/legacy.importFromCsv.ids.ts index 69ee2e2a..467bfc03 100644 --- a/temp/legacy.importFromCsv.ids.ts +++ b/temp/legacy.importFromCsv.ids.ts @@ -3,7 +3,7 @@ import sqlite from 'better-sqlite3' -import { lotOccupancyDB as databasePath } from '../data/databasePaths.js' +import { sunriseDB as databasePath } from '../data/databasePaths.js' import * as cacheFunctions from '../helpers/functions.cache.js' /* diff --git a/test/1_serverCypress.js b/test/1_serverCypress.js index be8bc7e3..d23e9e19 100644 --- a/test/1_serverCypress.js +++ b/test/1_serverCypress.js @@ -23,7 +23,7 @@ function runCypress(browser, done) { done(); }); } -describe('lot-occupancy-system', () => { +describe('sunrise-cms', () => { const httpServer = http.createServer(app); let serverStarted = false; before(() => { diff --git a/test/1_serverCypress.ts b/test/1_serverCypress.ts index 09c8f3e8..a6dbcfda 100644 --- a/test/1_serverCypress.ts +++ b/test/1_serverCypress.ts @@ -34,7 +34,7 @@ function runCypress(browser: 'chrome' | 'firefox', done: () => void): void { }) } -describe('lot-occupancy-system', () => { +describe('sunrise-cms', () => { const httpServer = http.createServer(app) let serverStarted = false diff --git a/test/functions.js b/test/functions.js index 570d3b11..46fe46f2 100644 --- a/test/functions.js +++ b/test/functions.js @@ -1,19 +1,11 @@ import assert from 'node:assert'; import fs from 'node:fs'; -import { lotNameSortNameFunction } from '../data/config.cemetery.ssm.js'; // skipcq: JS-C1003 - Testing functions import * as cacheFunctions from '../helpers/functions.cache.js'; // skipcq: JS-C1003 - Testing functions import * as sqlFilterFunctions from '../helpers/functions.sqlFilters.js'; // skipcq: JS-C1003 - Testing functions import * as userFunctions from '../helpers/functions.user.js'; -describe('config.cemetery.ssm', () => { - it('Sorts burial site names', () => { - const grave2 = 'XX-B1-G2A'; - const grave10 = 'XX-B1-G10'; - assert.ok(lotNameSortNameFunction(grave2) < lotNameSortNameFunction(grave10)); - }); -}); describe('functions.cache', () => { const badId = -3; // eslint-disable-next-line no-secrets/no-secrets diff --git a/test/functions.ts b/test/functions.ts index 51c1863c..03f6a20c 100644 --- a/test/functions.ts +++ b/test/functions.ts @@ -1,7 +1,6 @@ import assert from 'node:assert' import fs from 'node:fs' -import { lotNameSortNameFunction } from '../data/config.cemetery.ssm.js' // skipcq: JS-C1003 - Testing functions import * as cacheFunctions from '../helpers/functions.cache.js' // skipcq: JS-C1003 - Testing functions @@ -9,17 +8,6 @@ import * as sqlFilterFunctions from '../helpers/functions.sqlFilters.js' // skipcq: JS-C1003 - Testing functions import * as userFunctions from '../helpers/functions.user.js' -describe('config.cemetery.ssm', () => { - it('Sorts burial site names', () => { - const grave2 = 'XX-B1-G2A' - const grave10 = 'XX-B1-G10' - - assert.ok( - lotNameSortNameFunction(grave2) < lotNameSortNameFunction(grave10) - ) - }) -}) - describe('functions.cache', () => { const badId = -3 // eslint-disable-next-line no-secrets/no-secrets diff --git a/tsconfig.json b/tsconfig.json index 8690f26b..b0402b2c 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,8 +1,8 @@ { "compilerOptions": { - "target": "es2022", - "module": "es2022", - "moduleResolution": "Node", + "target": "ES2022", + "module": "Node16", + "moduleResolution": "Node16", "isolatedModules": false, "declaration": true, "noImplicitAny": false, diff --git a/types/applicationTypes.d.ts b/types/applicationTypes.d.ts index b904732f..e946681c 100644 --- a/types/applicationTypes.d.ts +++ b/types/applicationTypes.d.ts @@ -7,12 +7,12 @@ export interface ClearCacheWorkerMessage extends WorkerMessage { messageType: 'clearCache'; tableName: string; } -export interface CacheLotIdsWorkerMessage extends WorkerMessage { - messageType: 'cacheLotIds'; - lotId: number; - nextLotId: number; +export interface CacheBurialSiteIdsWorkerMessage extends WorkerMessage { + messageType: 'cacheBurialSiteIds'; + burialSiteId: number; + nextBurialSiteId: number; } -export interface ClearNextPreviousLotIdsCacheWorkerMessage extends WorkerMessage { - messageType: 'clearNextPreviousLotIdCache'; - lotId: number; +export interface ClearNextPreviousBurialSiteIdsCacheWorkerMessage extends WorkerMessage { + messageType: 'clearNextPreviousBurialSiteIdCache'; + burialSiteId: number; } diff --git a/types/applicationTypes.ts b/types/applicationTypes.ts index 1f379d70..95f926f3 100644 --- a/types/applicationTypes.ts +++ b/types/applicationTypes.ts @@ -9,15 +9,15 @@ export interface ClearCacheWorkerMessage extends WorkerMessage { tableName: string } -export interface CacheLotIdsWorkerMessage extends WorkerMessage { - messageType: 'cacheLotIds' - lotId: number - nextLotId: number +export interface CacheBurialSiteIdsWorkerMessage extends WorkerMessage { + messageType: 'cacheBurialSiteIds' + burialSiteId: number + nextBurialSiteId: number } -export interface ClearNextPreviousLotIdsCacheWorkerMessage +export interface ClearNextPreviousBurialSiteIdsCacheWorkerMessage extends WorkerMessage { // eslint-disable-next-line no-secrets/no-secrets - messageType: 'clearNextPreviousLotIdCache' - lotId: number + messageType: 'clearNextPreviousBurialSiteIdCache' + burialSiteId: number } diff --git a/types/configTypes.d.ts b/types/configTypes.d.ts index 74aad457..1575bb68 100644 --- a/types/configTypes.d.ts +++ b/types/configTypes.d.ts @@ -15,15 +15,6 @@ export interface Config { isAdmin?: string[]; }; aliases: { - lot?: string; - lots?: string; - map?: string; - maps?: string; - occupancy?: string; - occupancies?: string; - occupancyStartDate?: string; - occupant?: string; - occupants?: string; externalReceiptNumber?: string; workOrderOpenDate?: string; workOrderCloseDate?: string; @@ -32,20 +23,14 @@ export interface Config { fees: { taxPercentageDefault?: number; }; - map: { - mapCityDefault?: string; - mapProvinceDefault?: string; + cemeteries: { + cityDefault?: string; + provinceDefault?: string; }; - lot: { - lotNamePattern?: RegExp; - lotNameHelpText?: string; - lotNameSortNameFunction?: (lotName: string) => string; - }; - lotOccupancy: { - lotIdIsRequired?: boolean; - occupancyEndDateIsRequired?: boolean; - occupantCityDefault?: string; - occupantProvinceDefault?: string; + contracts: { + burialSiteIdIsRequired?: boolean; + cityDefault?: string; + provinceDefault?: string; prints?: string[]; }; workOrders: { diff --git a/types/configTypes.ts b/types/configTypes.ts index d4d336fc..af05ddd7 100644 --- a/types/configTypes.ts +++ b/types/configTypes.ts @@ -16,15 +16,6 @@ export interface Config { isAdmin?: string[] } aliases: { - lot?: string - lots?: string - map?: string - maps?: string - occupancy?: string - occupancies?: string - occupancyStartDate?: string - occupant?: string - occupants?: string externalReceiptNumber?: string workOrderOpenDate?: string workOrderCloseDate?: string @@ -33,20 +24,14 @@ export interface Config { fees: { taxPercentageDefault?: number } - map: { - mapCityDefault?: string - mapProvinceDefault?: string + cemeteries: { + cityDefault?: string + provinceDefault?: string } - lot: { - lotNamePattern?: RegExp - lotNameHelpText?: string - lotNameSortNameFunction?: (lotName: string) => string - } - lotOccupancy: { - lotIdIsRequired?: boolean - occupancyEndDateIsRequired?: boolean - occupantCityDefault?: string - occupantProvinceDefault?: string + contracts: { + burialSiteIdIsRequired?: boolean + cityDefault?: string + provinceDefault?: string prints?: string[] } workOrders: { diff --git a/types/recordTypes.d.ts b/types/recordTypes.d.ts index 465fc143..c59ee60e 100644 --- a/types/recordTypes.d.ts +++ b/types/recordTypes.d.ts @@ -10,77 +10,77 @@ export interface Record { recordDelete_timeMillis?: number; recordDelete_dateString?: string; } -export interface MapRecord extends Record { - mapId?: number; - mapName?: string; - mapDescription?: string; - mapLatitude?: number; - mapLongitude?: number; - mapSVG?: string; - mapAddress1?: string; - mapAddress2?: string; - mapCity?: string; - mapProvince?: string; - mapPostalCode?: string; - mapPhoneNumber?: string; - lotCount?: number; +export interface CemeteryRecord extends Record { + cemeteryId?: number; + cemeteryName?: string; + cemeteryDescription?: string; + cemeteryLatitude?: number; + cemeteryLongitude?: number; + cemeterySvg?: string; + cemeteryAddress1?: string; + cemeteryAddress2?: string; + cemeteryCity?: string; + cemeteryProvince?: string; + cemeteryPostalCode?: string; + cemeteryPhoneNumber?: string; + burialSiteCount?: number; } -export interface LotType extends Record { - lotTypeId: number; - lotType: string; +export interface BurialSiteType extends Record { + burialSiteTypeId: number; + burialSiteType: string; orderNumber?: number; - lotTypeFields?: LotTypeField[]; + burialSiteTypeFields?: BurialSiteTypeField[]; } -export interface LotTypeField extends Record { - lotTypeFieldId: number; - lotTypeField?: string; - lotTypeId?: number; - lotType: LotType; +export interface BurialSiteTypeField extends Record { + burialSiteTypeFieldId: number; + burialSiteTypeField?: string; + burialSiteTypeId?: number; + burialSiteType: BurialSiteType; fieldType: string; - lotTypeFieldValues?: string; + fieldValues?: string; isRequired?: boolean; pattern?: string; minimumLength?: number; maximumLength?: number; orderNumber?: number; } -export interface LotStatus extends Record { - lotStatusId: number; - lotStatus: string; +export interface BurialSiteStatus extends Record { + burialSiteStatusId: number; + burialSiteStatus: string; orderNumber?: number; } -export interface Lot extends Record { - lotId: number; - lotName?: string; - lotTypeId?: number; - lotType?: string; - mapId?: number; - mapName?: string; - map?: MapRecord; - mapSVG?: string; - mapKey?: string; - lotLatitude?: number; - lotLongitude?: number; - lotStatusId?: number; - lotStatus?: string; - lotFields?: LotField[]; - lotOccupancyCount?: number; - lotOccupancies?: LotOccupancy[]; - lotComments?: LotComment[]; +export interface BurialSite extends Record { + burialSiteId: number; + burialSiteName?: string; + burialSiteTypeId?: number; + burialSiteType?: string; + cemeteryId?: number; + cemeteryName?: string; + cemetery?: CemeteryRecord; + cemeterySvg?: string; + cemeterySvgId?: string; + burialSiteLatitude?: number; + burialSiteLongitude?: number; + burialSiteStatusId?: number; + burialSiteStatus?: string; + burialSiteFields?: LotField[]; + burialSiteContractCount?: number; + burialSiteContracts?: LotOccupancy[]; + burialSiteComments?: BurialSiteComment[]; } -export interface LotComment extends Record { - lotCommentId?: number; - lotId?: number; - lotCommentDate?: number; - lotCommentDateString?: string; - lotCommentTime?: number; - lotCommentTimeString?: string; - lotCommentTimePeriodString?: string; - lotComment?: string; +export interface BurialSiteComment extends Record { + burialSiteCommentId?: number; + burialSiteId?: number; + commentDate?: number; + commentDateString?: string; + commentTime?: number; + commentTimeString?: string; + commentTimePeriodString?: string; + comment?: string; } -export interface LotField extends LotTypeField, Record { - lotId?: number; - lotFieldValue?: string; +export interface LotField extends BurialSiteTypeField, Record { + burialSiteId?: number; + burialSiteFieldValue?: string; } export interface OccupancyType extends Record { occupancyTypeId: number; diff --git a/types/recordTypes.ts b/types/recordTypes.ts index 872f935a..c8d5d63d 100644 --- a/types/recordTypes.ts +++ b/types/recordTypes.ts @@ -14,44 +14,44 @@ export interface Record { } /* - * LOT OCCUPANCY DB TYPES + * SUNRISE DB TYPES */ -export interface MapRecord extends Record { - mapId?: number - mapName?: string - mapDescription?: string +export interface CemeteryRecord extends Record { + cemeteryId?: number + cemeteryName?: string + cemeteryDescription?: string - mapLatitude?: number - mapLongitude?: number - mapSVG?: string + cemeteryLatitude?: number + cemeteryLongitude?: number + cemeterySvg?: string - mapAddress1?: string - mapAddress2?: string - mapCity?: string - mapProvince?: string - mapPostalCode?: string - mapPhoneNumber?: string + cemeteryAddress1?: string + cemeteryAddress2?: string + cemeteryCity?: string + cemeteryProvince?: string + cemeteryPostalCode?: string + cemeteryPhoneNumber?: string - lotCount?: number + burialSiteCount?: number } -export interface LotType extends Record { - lotTypeId: number - lotType: string +export interface BurialSiteType extends Record { + burialSiteTypeId: number + burialSiteType: string orderNumber?: number - lotTypeFields?: LotTypeField[] + burialSiteTypeFields?: BurialSiteTypeField[] } -export interface LotTypeField extends Record { - lotTypeFieldId: number - lotTypeField?: string +export interface BurialSiteTypeField extends Record { + burialSiteTypeFieldId: number + burialSiteTypeField?: string - lotTypeId?: number - lotType: LotType + burialSiteTypeId?: number + burialSiteType: BurialSiteType fieldType: string - lotTypeFieldValues?: string + fieldValues?: string isRequired?: boolean pattern?: string minimumLength?: number @@ -60,56 +60,56 @@ export interface LotTypeField extends Record { orderNumber?: number } -export interface LotStatus extends Record { - lotStatusId: number - lotStatus: string +export interface BurialSiteStatus extends Record { + burialSiteStatusId: number + burialSiteStatus: string orderNumber?: number } -export interface Lot extends Record { - lotId: number - lotName?: string +export interface BurialSite extends Record { + burialSiteId: number + burialSiteName?: string - lotTypeId?: number - lotType?: string + burialSiteTypeId?: number + burialSiteType?: string - mapId?: number - mapName?: string - map?: MapRecord - mapSVG?: string - mapKey?: string + cemeteryId?: number + cemeteryName?: string + cemetery?: CemeteryRecord + cemeterySvg?: string + cemeterySvgId?: string - lotLatitude?: number - lotLongitude?: number + burialSiteLatitude?: number + burialSiteLongitude?: number - lotStatusId?: number - lotStatus?: string + burialSiteStatusId?: number + burialSiteStatus?: string - lotFields?: LotField[] + burialSiteFields?: LotField[] - lotOccupancyCount?: number - lotOccupancies?: LotOccupancy[] + burialSiteContractCount?: number + burialSiteContracts?: LotOccupancy[] - lotComments?: LotComment[] + burialSiteComments?: BurialSiteComment[] } -export interface LotComment extends Record { - lotCommentId?: number - lotId?: number +export interface BurialSiteComment extends Record { + burialSiteCommentId?: number + burialSiteId?: number - lotCommentDate?: number - lotCommentDateString?: string + commentDate?: number + commentDateString?: string - lotCommentTime?: number - lotCommentTimeString?: string - lotCommentTimePeriodString?: string + commentTime?: number + commentTimeString?: string + commentTimePeriodString?: string - lotComment?: string + comment?: string } -export interface LotField extends LotTypeField, Record { - lotId?: number - lotFieldValue?: string +export interface LotField extends BurialSiteTypeField, Record { + burialSiteId?: number + burialSiteFieldValue?: string } export interface OccupancyType extends Record { diff --git a/version.d.ts b/version.d.ts index 97fda101..07bdd71f 100644 --- a/version.d.ts +++ b/version.d.ts @@ -1,2 +1,2 @@ -export declare const version = "1.0.0-alpha.14"; +export declare const version = "1.0.0-dev"; export default version; diff --git a/version.js b/version.js index 1032a449..1ee79cfc 100644 --- a/version.js +++ b/version.js @@ -1,2 +1,2 @@ -export const version = '1.0.0-alpha.14'; +export const version = '1.0.0-dev'; export default version; diff --git a/version.ts b/version.ts index fe9b811a..6bd74350 100644 --- a/version.ts +++ b/version.ts @@ -1,3 +1,3 @@ -export const version = '1.0.0-alpha.14' +export const version = '1.0.0-dev' export default version diff --git a/views/_header.ejs b/views/_header.ejs index 806e4a12..2f6eea51 100644 --- a/views/_header.ejs +++ b/views/_header.ejs @@ -83,7 +83,7 @@ Reports
- diff --git a/views/_menu-workOrders.ejs b/views/_menu-workOrders.ejs index dea3b747..538af9e5 100644 --- a/views/_menu-workOrders.ejs +++ b/views/_menu-workOrders.ejs @@ -33,15 +33,4 @@ - - \ No newline at end of file diff --git a/views/dashboard.ejs b/views/dashboard.ejs index 63f431a9..408e7280 100644 --- a/views/dashboard.ejs +++ b/views/dashboard.ejs @@ -262,30 +262,12 @@
diff --git a/views/login.ejs b/views/login.ejs index 1a4fc15b..4445d2f9 100644 --- a/views/login.ejs +++ b/views/login.ejs @@ -77,11 +77,7 @@
Build <%= buildNumber %>
- - - Help - - + GitHub diff --git a/views/lot-edit.ejs b/views/lot-edit.ejs index 55db7e04..37878ca5 100644 --- a/views/lot-edit.ejs +++ b/views/lot-edit.ejs @@ -321,25 +321,19 @@
- +
- -
- -
-

- - - What is the SVG ID? - -

+ +
+ +
diff --git a/windowsService.js b/windowsService.js index 7bc8b43a..c2c0ba59 100644 --- a/windowsService.js +++ b/windowsService.js @@ -1,7 +1,7 @@ import path from 'node:path'; const _dirname = '.'; export const serviceConfig = { - name: 'Lot Occupancy Manager', - description: 'A system for managing the occupancy of lots. (i.e. Cemetery management)', + name: 'Sunrise CMS', + description: 'Sunrise Cemetery Management System, a web-based application that allows cemetery managers to manage their cemetery records.', script: path.join(_dirname, 'bin', 'www.js') }; diff --git a/windowsService.ts b/windowsService.ts index 7ec83813..816908c2 100644 --- a/windowsService.ts +++ b/windowsService.ts @@ -5,8 +5,8 @@ import type { ServiceConfig } from 'node-windows' const _dirname = '.' export const serviceConfig: ServiceConfig = { - name: 'Lot Occupancy Manager', + name: 'Sunrise CMS', description: - 'A system for managing the occupancy of lots. (i.e. Cemetery management)', + 'Sunrise Cemetery Management System, a web-based application that allows cemetery managers to manage their cemetery records.', script: path.join(_dirname, 'bin', 'www.js') }