diff --git a/data/config.cemetery.ssm.js b/data/config.cemetery.ssm.js index c6778548..32570739 100644 --- a/data/config.cemetery.ssm.js +++ b/data/config.cemetery.ssm.js @@ -23,7 +23,7 @@ config.settings.lot.lotNameSortNameFunction = (lotName) => { return cleanLotNamePieces.join("-"); }; config.settings.lotOccupancy.occupantCityDefault = "Sault Ste. Marie"; -config.settings.lotOccupancy.prints = ["screen/lotOccupancy", "pdf/ssm.cemetery.burialPermit"]; +config.settings.lotOccupancy.prints = ["pdf/ssm.cemetery.contract", "pdf/ssm.cemetery.burialPermit"]; config.settings.map.mapCityDefault = "Sault Ste. Marie"; config.settings.workOrders.workOrderNumberLength = 6; config.settings.workOrders.workOrderMilestoneDateRecentBeforeDays = 7; diff --git a/data/config.cemetery.ssm.ts b/data/config.cemetery.ssm.ts index 2c932f14..72a03268 100644 --- a/data/config.cemetery.ssm.ts +++ b/data/config.cemetery.ssm.ts @@ -38,7 +38,7 @@ config.settings.lot.lotNameSortNameFunction = (lotName) => { }; config.settings.lotOccupancy.occupantCityDefault = "Sault Ste. Marie"; -config.settings.lotOccupancy.prints = ["screen/lotOccupancy", "pdf/ssm.cemetery.burialPermit"]; +config.settings.lotOccupancy.prints = ["pdf/ssm.cemetery.contract", "pdf/ssm.cemetery.burialPermit"]; config.settings.map.mapCityDefault = "Sault Ste. Marie"; diff --git a/helpers/functions.lotOccupancy.d.ts b/helpers/functions.lotOccupancy.d.ts index 3869a95d..07d0ab7b 100644 --- a/helpers/functions.lotOccupancy.d.ts +++ b/helpers/functions.lotOccupancy.d.ts @@ -1,3 +1,5 @@ import type * as recordTypes from "../types/recordTypes"; export declare const filterOccupantsByLotOccupantType: (lotOccupancy: recordTypes.LotOccupancy, lotOccupantType: string) => recordTypes.LotOccupancyOccupant[]; export declare const getFieldValueByOccupancyTypeField: (lotOccupancy: recordTypes.LotOccupancy, occupancyTypeField: string) => string; +export declare const getFeesByFeeCategory: (lotOccupancy: recordTypes.LotOccupancy, feeCategory: string, feeCategoryContains?: boolean) => recordTypes.LotOccupancyFee[]; +export declare const getTransactionTotal: (lotOccupancy: recordTypes.LotOccupancy) => number; diff --git a/helpers/functions.lotOccupancy.js b/helpers/functions.lotOccupancy.js index 72620d9e..b92749b2 100644 --- a/helpers/functions.lotOccupancy.js +++ b/helpers/functions.lotOccupancy.js @@ -15,3 +15,19 @@ export const getFieldValueByOccupancyTypeField = (lotOccupancy, occupancyTypeFie } return undefined; }; +export const getFeesByFeeCategory = (lotOccupancy, feeCategory, feeCategoryContains = false) => { + const feeCategoryLowerCase = feeCategory.toLowerCase(); + const fees = lotOccupancy.lotOccupancyFees.filter((possibleFee) => { + return feeCategoryContains + ? possibleFee.feeCategory.toLowerCase().includes(feeCategoryLowerCase) + : possibleFee.feeCategory.toLowerCase() === feeCategoryLowerCase; + }); + return fees; +}; +export const getTransactionTotal = (lotOccupancy) => { + let transactionTotal = 0; + for (const transaction of lotOccupancy.lotOccupancyTransactions) { + transactionTotal += transaction.transactionAmount; + } + return transactionTotal; +}; diff --git a/helpers/functions.lotOccupancy.ts b/helpers/functions.lotOccupancy.ts index b8c45036..ba189260 100644 --- a/helpers/functions.lotOccupancy.ts +++ b/helpers/functions.lotOccupancy.ts @@ -29,3 +29,29 @@ export const getFieldValueByOccupancyTypeField = ( return undefined; }; + +export const getFeesByFeeCategory = ( + lotOccupancy: recordTypes.LotOccupancy, + feeCategory: string, + feeCategoryContains = false +) => { + const feeCategoryLowerCase = feeCategory.toLowerCase(); + + const fees = lotOccupancy.lotOccupancyFees.filter((possibleFee) => { + return feeCategoryContains + ? possibleFee.feeCategory.toLowerCase().includes(feeCategoryLowerCase) + : possibleFee.feeCategory.toLowerCase() === feeCategoryLowerCase; + }); + + return fees; +}; + +export const getTransactionTotal = (lotOccupancy: recordTypes.LotOccupancy) => { + let transactionTotal = 0; + + for (const transaction of lotOccupancy.lotOccupancyTransactions) { + transactionTotal += transaction.transactionAmount; + } + + return transactionTotal; +}; \ No newline at end of file diff --git a/helpers/functions.print.js b/helpers/functions.print.js index c5dea290..1af3ef7e 100644 --- a/helpers/functions.print.js +++ b/helpers/functions.print.js @@ -26,6 +26,10 @@ const pdfPrintConfigs = { "ssm.cemetery.burialPermit": { title: "Burial Permit", params: ["lotOccupancyId"] + }, + "ssm.cemetery.contract": { + title: "Contract for Purchase of Interment Rights", + params: ["lotOccupancyId"] } }; export const getPdfPrintConfig = (printName) => { diff --git a/helpers/functions.print.ts b/helpers/functions.print.ts index 8e804381..a111fe0f 100644 --- a/helpers/functions.print.ts +++ b/helpers/functions.print.ts @@ -40,6 +40,10 @@ const pdfPrintConfigs: { [printName: string]: PrintConfig } = { "ssm.cemetery.burialPermit": { title: "Burial Permit", params: ["lotOccupancyId"] + }, + "ssm.cemetery.contract": { + title: "Contract for Purchase of Interment Rights", + params: ["lotOccupancyId"] } }; diff --git a/views/print/pdf/ssm.cemetery.contract.ejs b/views/print/pdf/ssm.cemetery.contract.ejs new file mode 100644 index 00000000..bbc40ef2 --- /dev/null +++ b/views/print/pdf/ssm.cemetery.contract.ejs @@ -0,0 +1,345 @@ +<% + const purchaserLotOccupantType = "Purchaser"; + const purchaserOccupants = lotOccupancyFunctions.filterOccupantsByLotOccupantType(lotOccupancy, purchaserLotOccupantType); + const purchaser = purchaserOccupants.length > 0 ? purchaserOccupants[0] : undefined; + + const recipientLotOccupantType = "Preneed Owner"; + const recipientOccupants = lotOccupancyFunctions.filterOccupantsByLotOccupantType(lotOccupancy, recipientLotOccupantType); + const recipient = recipientOccupants.length > 0 ? recipientOccupants[0] : undefined; + + const deathDateOccupantTypeField = "Death Date"; + const deathPlaceOccupantTypeField = "Death Place"; +%> + + + + + +

+ Contract for the Purchase of Interment Rights or
+ Cemetery Services +

+

+ in + + <%= lotOccupancy.mapName %> + + cemetery
+ operated by
+ The Corporation of the City of Sault Ste. Marie, 99 Foster Drive
+ Sault Ste. Marie Ontario   P6A 5X6 +

+

+ Contract No. +   +

+

+ Date of Purchase + +   + <% if (lotOccupancy.lotOccupancyTransactions.length > 0) { %> + <%= lotOccupancy.lotOccupancyTransactions[0].transactionDateString %> + <% } %> + +

+ + + + + + + +
+

Purchaser

+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
Name:<%= purchaser ? purchaser.occupantName : "" %>
Address:<%= purchaser ? purchaser.occupantAddress1 : "" %> 
<%= purchaser ? purchaser.occupantAddress2 : "" %> 
City:<%= purchaser ? purchaser.occupantCity : "" %> 
Province:<%= purchaser ? purchaser.occupantProvince : "" %> 
Postal Code:<%= purchaser ? purchaser.occupantPostalCode : "" %> 
Telephone:<%= purchaser ? purchaser.occupantPhoneNumber : "" %> 
E-mail<%= purchaser ? purchaser.occupantEmailAddress : "" %> 
+
+

Recipient

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Name:<%= recipient ? recipient.occupantName : "" %>
Address:<%= recipient ? recipient.occupantAddress1 : "" %> 
<%= recipient ? recipient.occupantAddress2 : "" %> 
City:<%= recipient ? recipient.occupantCity : "" %> 
Province:<%= recipient ? recipient.occupantProvince : "" %> 
Postal Code:<%= recipient ? recipient.occupantPostalCode : "" %> 
Telephone:<%= recipient ? recipient.occupantPhoneNumber : "" %> 
E-mail<%= recipient ? recipient.occupantEmailAddress : "" %> 
Date of birth 
Place of birth 
+
+

+ Purchaser's relationship to Recipient: +   +

+

+ This Contract for Purchase of Interment Rights or Cemetery Services + is between the Purchaser and The Corporation of the City of Sault Ste. Marie (Corporation) + concerning interment rights or cemetery services for the Recipient(s) + as identified in this Contract. +

+

+ The Purchaser (if different than the Recipient) + represents being legally authorized or charged with the responsibility for + the Recipient's interment rights and prepaid cemetery services + specified in this Contract. This Contract will be enforceable to + the benefit of and be binding upon the parties hereto + and their respective heirs, executors, administrators, successors, and assigns. +

+ + + + + +
+

Details

+ + <% + for (const field of lotOccupancy.lotOccupancyFields) { + if (field.lotOccupancyFieldValue) { + %> + + + + + <% + } + } + %> +
<%= field.occupancyTypeField %><%= field.lotOccupancyFieldValue %>
+
+

Interment Rights and Services

+ + + <% + let currentFeeCategory = ""; + let feeAmountTotal = 0; + let taxAmountTotal = 0; + %> + <% for (const fee of lotOccupancy.lotOccupancyFees) { %> + <% if (currentFeeCategory !== fee.feeCategory) { %> + + + + <% currentFeeCategory = fee.feeCategory; %> + <% } %> + + + + + <% + feeAmountTotal += fee.feeAmount; + taxAmountTotal += fee.taxAmount; + %> + <% } %> + + + + + + + + + + + + + + +
+ <%= fee.feeCategory %> +
+ <%= fee.feeName %> + + $<%= fee.feeAmount.toFixed(2) %> +
Sub Total + $<%= feeAmountTotal.toFixed(2) %> +
HST + $<%= taxAmountTotal.toFixed(2) %> +
Total Sale + $<%= (feeAmountTotal + taxAmountTotal).toFixed(2) %> +
Balance Owing + $<%= (feeAmountTotal + taxAmountTotal - lotOccupancyFunctions.getTransactionTotal(lotOccupancy)).toFixed(2) %> +
+
+ + + +

Contribution Levels to the Care and Maintenance Fund

+ +

Contribution Levels to the Care and Maintenance Fund - Markers

+ +

Contract Terms and Conditions

+ +
    +
  1. + The Purchaser may only cancel a contract for interment rights or cemetery services upon written notice of cancellation + to the City Clerk in accordance with the Funeral, Burial and Cremation Services Act and the terms and conditions set + out herein. +
  2. +
  3. + Where interment rights have not been exercised and none of the contracted cemetery services have been provided + and where the contract is cancelled within thirty (30) days of its execution, the Corporation shall refund the Purchaser + all moneys paid less an administrative fee as set out in the Price List. +
  4. +
  5. + Where interment rights have not been exercised and part of the contracted cemetery services have been provided, + and where the contract is cancelled within thirty (30) days of its execution, the Corporation shall refund the Purchaser + the amount described in (b) above which shall be reduced by the cost of cemetery services provided as set out in the + current Price List. +
  6. +
  7. + A contract for interment rights cannot be cancelled more than thirty (30) days after the date of execution of the + contract. +
  8. +
  9. + Where a contract for cemetery services is cancelled more than thirty (30) days after the date of execution of the + contract, the Purchaser shall be refunded the amount described in (b) and (c) above plus the amount of income + earned on that money. +
  10. +
  11. + Written consent of all surviving interment rights holder(s), if any, and any other required documentation as set out in + Cemetery By-law 2012-129 is required for: cremation, interments, disinterments, and the placement of markers, + inscriptions or photos. +
  12. +
  13. + Transfer or resale of the above listed interment rights to a third party is permitted, subject to the provisions of + Cemetery By-law 2012-129 and the Funeral, Burial and Cremation Services Act. A Certificate of Interment Rights + holder shall not resell interment rights for an amount that is greater than the price of those rights as indicated on the + current Price List, inclusive of the care and maintenance component. +
  14. +
  15. + No Certificate of Interment Rights holder(s) may subdivide and sell or transfer a portion of interment rights. +
  16. +
  17. + An Interment Rights Certificate will not be issued until this Contract has been paid in full. +
  18. +
  19. + A marker, purchased and/or installed by anyone other than the Certificate of Interment Rights holder(s) may be + removed by cemetery staff upon the written request of the Certificate of Interment Rights holder(s). +
  20. +
  21. + Dead human bodies cannot be cremated if there is a pacemaker or radioactive implant in the body or if the body is in + a container made of or containing non-flammable or hazardous material or chlorinated or fibre-reinforced plastic. +
  22. +
  23. + Dead human bodies will not be cremated unless a coroner's certificate has been provided to the operator. +
  24. +
  25. + The Corporation shall not be responsible in the event that it is unable to or prevented from carrying out this Contract + due to causes beyond its control. +
  26. +
+ + + +

Payment Terms

+

+ All pre-need interment rights and cemetery services must be paid in full at the time of ordering. +

+

+ In the case of at-need interment rights and cemetery services, the interment rights and services directly related to the + deceased will be invoiced by the Corporation and interest shall be charged at the rate determined by the Treasurer on the + unpaid balance after thirty (30) days from the date of invoice. Such services do not include interment rights in a + mausoleum. +

+

+ Any rights of cancellation of this Contract, whether within thirty (30) days or after thirty (30) days can only be exercised by + the Purchaser or his or her Estate Trustee. +

+ +

Personal Information

+ +

+ The Purchaser acknowledges and provides consent to permit the Corporation to collect, use and disclose personal + information in accordance with the requirements under the Funeral, Burial and Cremation Services Act and the + regulations made thereunder for information within the cemetery/crematorium public register. The Purchaser also + understands that the Corporation does not rent or sell personal information to third party organizations. +

+

+ All information provided by the Purchaser to the Corporation shall be held, retained, disclosed, and destroyed, as the case + may be, in accordance with the provisions of the Municipal Freedom of Information and Protection of Privacy Act. +

+ +

Consumer Information Guide and Cemetery Price List

+ +

+ By initialling below, the Purchaser acknowledges receiving a copy of the Ontario Government's Consumer Information + Guide (where made available by the Registrar) and the Cemetery Price List at the time of entering into this Contract. +

+ + + +

+ The Contract date set out below is the date on which this Contract is accepted by the Corporation. +

+ + \ No newline at end of file diff --git a/views/print/pdf/style.css b/views/print/pdf/style.css index 5894257a..c23475f3 100644 --- a/views/print/pdf/style.css +++ b/views/print/pdf/style.css @@ -32,7 +32,7 @@ body { .field { border-bottom: 1px solid black; display: inline-block; - width: 100%; + width: 100px; padding: 10px 0; } @@ -42,12 +42,14 @@ body { width: 100%; } -.data-table thead th { +.data-table thead th, +.data-table tfoot th { padding: 5px; text-align: left; } -.data-table tbody td { +.data-table tbody td, +.data-table tfoot td { padding: 5px; text-align: left; border-top: 1px solid black; @@ -59,6 +61,8 @@ body { .layout-table { width: 100%; border: 0; + margin: 0; + padding: 0; } .layout-table td { @@ -75,6 +79,10 @@ td.is-width-1 { width: 1px; } +td.has-border-bottom { + border-bottom: 1px solid black; +} + /* Padding / Margins */ .m-0 { @@ -109,6 +117,10 @@ td.is-width-1 { margin-bottom: 40px; } +.p-0 { + padding: 0; +} + .pl-1 { padding-left: 10px; } @@ -116,11 +128,19 @@ td.is-width-1 { /* Text Utilities */ .is-8pt { - font-size: 8pt; + font-size: 8pt !important; +} + +.is-10pt { + font-size: 10pt !important; +} + +.has-text-left { + text-align: left; } .has-text-right { - text-align: right; + text-align: right !important; } .has-text-centered {