diff --git a/forms-flow-web/src/components/FOI/customComponents/ContactApplicant/util.tsx b/forms-flow-web/src/components/FOI/customComponents/ContactApplicant/util.tsx index 8dddb35d1..1d997bd19 100644 --- a/forms-flow-web/src/components/FOI/customComponents/ContactApplicant/util.tsx +++ b/forms-flow-web/src/components/FOI/customComponents/ContactApplicant/util.tsx @@ -1,3 +1,5 @@ +import { any } from "prop-types"; + export const renderTemplate = (template: string, content: string, params: Array) => { let newTemplate = template.replace("{{content}}", content); return applyVariables(newTemplate, params); @@ -18,15 +20,20 @@ export const getExtensiondetails = (requestExtensions:any, type: string) => { if (recentExtension["extensiontype"] === "Public Body" && recentExtension["extensionstatus"] == "Approved") { return [recentExtension["extendedduedays"], recentExtension["extendedduedate"], recentExtension["extensionreson"]] } else if (recentExtension["extensiontype"] === "OIPC" && recentExtension["extensionstatus"] == "Approved") { - return [recentExtension["approvednoofdays"], recentExtension["extendedduedate"], recentExtension["extensionreson"]] + return [recentExtension["approvednoofdays"], recentExtension["extendedduedate"], recentExtension["extensionreson"], recentExtension["created_at"], recentExtension["extensionreasonid"], recentExtension["decisiondate"] + ] } } - return ["","",""] + return ["","","","","",""] } export const getTemplateVariables = (requestDetails: any, requestExtensions:any, templateInfo: any) => { let oipcExtension = getExtensiondetails(requestExtensions, "OIPC"); let pbExtension = getExtensiondetails(requestExtensions, "Public Body"); + + // Find the record that matches the criteria for already taken a time extension under section 10(1), excluding the most recent record + const filteredOutLatestExtensions = findLatestMatchingTimeExtension(requestExtensions, reasonsToCheck); + return [ {name: "{{axisRequestId}}", value: requestDetails.axisRequestId}, {name: "{{title}}", value: templateInfo?.label || ""}, @@ -43,6 +50,18 @@ export const getTemplateVariables = (requestDetails: any, requestExtensions:any, {name: "{{pbExtensionDueDate}}", value: pbExtension[1]}, {name: "{{pbExtensionReason}}", value: pbExtension[2]}, {name: "{{pbExtensionBody}}", value: "public body"}, + {name: "{{oipcExtensionDueDays}}", value: oipcExtension[0]}, + {name: "{{oipcExtensionDueDates}}", value: oipcExtension[1]}, + {name: "{{oipcExtensionReason}}", value: oipcExtension[2]}, + {name: "{{oipcExtensionNotiDate}}", value: oipcExtension[5]}, + {name: "{{oipcOriginalReceivedDate}}", value: requestDetails.receivedDate}, + {name: "{{oipcOriginalDueDate}}", value: requestDetails.originalDueDate}, + {name: "{{sectionID}}", value: mapSectionWithExtensionReasonId(oipcExtension[4])}, + {name: "{{takenExtensionStatus}}", value: isAlreadyTakenTimeExtension(filteredOutLatestExtensions)}, + {name: "{{filteredExtensionDate}}", value: filteredOutLatestExtensions ? filteredOutLatestExtensions.extendedduedate : ""}, + {name: "{{filteredExtensionDueDays}}", value: filteredOutLatestExtensions ? filteredOutLatestExtensions.extendedduedays : ""}, + {name: "{{oipcComplaintStatus}}", value: oipcComplaintCheck(requestDetails.oipcdetails)}, + ]; } @@ -55,3 +74,44 @@ export const isTemplateDisabled = (currentCFRForm: any, template: any) => { } return false } + +// Function to map extension reason id to its textual representation +const mapSectionWithExtensionReasonId = (extensionReasonId: number) => { + switch (extensionReasonId) { + case 6: + return "10(1)(d)"; // 10(1)(d) = Applicant Consent + case 7: + return "10(1)(c)"; // 10(1)(c) = Consultation + case 8: + return "10(1)(a)"; // 10(1)(a) = Further detail from applicant required + case 9: + return "10(1)(b)"; // 10(1)(b) = Large Volume and/or Volume of Search + default: + return ""; + } +}; + +// List of reasons to check already taken a time extension under section 10(1) +const reasonsToCheck = [ + "OIPC - Applicant Consent", + "OIPC - Consultation", + "OIPC - Further Detail from Applicant Required", + "OIPC - Large Volume and/or Volume of Search" +]; + +// Find the record that matches the criteria for already taken a time extension under section 10(1), excluding the most recent record. +const findLatestMatchingTimeExtension = (requestExtensions: any[], reasonsToCheck: string[]): any | null => { + const foundObject = requestExtensions + .filter(extension => extension.extensiontype === "OIPC" && reasonsToCheck.includes(extension.extensionreson) && extension !== requestExtensions[0]) + .find(extension => reasonsToCheck.includes(extension.extensionreson)) || null; + + return foundObject; +}; + +// Function to check and return "Yes" or "No" +const isAlreadyTakenTimeExtension = (result: any | null): string => { + return result === null ? "No" : "Yes"; +}; + +// Check if there are any OIPC details. +const oipcComplaintCheck = (oipcdetails: any): string => oipcdetails && oipcdetails.length > 0 ? "Yes" : "No"; diff --git a/request-management-api/migrations/versions/8487688c2e35_add_applicantCorrespondenceTemplates.py b/request-management-api/migrations/versions/8487688c2e35_add_applicantCorrespondenceTemplates.py new file mode 100644 index 000000000..c8474b75c --- /dev/null +++ b/request-management-api/migrations/versions/8487688c2e35_add_applicantCorrespondenceTemplates.py @@ -0,0 +1,68 @@ +"""empty message + +Revision ID: 8487688c2e35 +Revises: c3e447d3d94d +Create Date: 2024-06-20 17:16:09.447577 + +""" +from alembic import op +from datetime import datetime +import sqlalchemy as sa +from sqlalchemy.sql import column, table +from sqlalchemy.sql.sqltypes import Boolean, String,Text,Integer,DateTime + + +# revision identifiers, used by Alembic. +revision = '8487688c2e35' +down_revision = 'c3e447d3d94d' +branch_labels = None +depends_on = None + + +def upgrade(): + applicant_correspondence_templates = table('ApplicantCorrespondenceTemplates', + column('name',String), + column('documenturipath',Text), + column('description',String), + column('active',Boolean), + column('display',Boolean), + column('version',Integer), + column('created_at',DateTime), + column('createdby',String), + ) + op.bulk_insert( + applicant_correspondence_templates, + [{'name': 'OIPCAPPLICANTCONSENTEXTENSION', + 'description': 'OIPC Applicant Consent Time Extension', + 'active': True, + 'display': True, + 'version': 1, + 'documenturipath': '/TEMPLATES/EMAILS/oipc_applicant_consent_time_extension.html', + 'created_at': datetime.now(), + 'createdby': 'system'}, + {'name': 'OIPCFIRSTTIMEEXTENSION', + 'description': 'OIPC Applicant First Time Extension', + 'active': True, + 'display': True, + 'version': 1, + 'documenturipath': '/TEMPLATES/EMAILS/oipc_first_time_extension.html', + 'created_at': datetime.now(), + 'createdby': 'system'}, + {'name': 'OIPCSUBSEQUENTTIMEEXTENSION', + 'description': 'OIPC Subsequent Time Extension', + 'active': True, + 'display': True, + 'version': 1, + 'documenturipath': '/TEMPLATES/EMAILS/oipc_subsequent_time_extension.html', + 'created_at': datetime.now(), + 'createdby': 'system'}] + ) + + +def downgrade(): + op.execute( + """ + DELETE FROM "ApplicantCorrespondenceTemplates" + WHERE name IN ('OIPCAPPLICANTCONSENTEXTENSION', 'OIPCFIRSTTIMEEXTENSION', 'OIPCSUBSEQUENTTIMEEXTENSION') + """ + ) diff --git a/request-management-api/request_api/email_templates/oipc_applicant_consent_time_extension.html b/request-management-api/request_api/email_templates/oipc_applicant_consent_time_extension.html new file mode 100644 index 000000000..0130b0f73 --- /dev/null +++ b/request-management-api/request_api/email_templates/oipc_applicant_consent_time_extension.html @@ -0,0 +1,172 @@ + + + + + + + + + + + + + +
+
+
+

NoteThis form is for any time extension application under section 10(2)(a) based on: 

+
+
+

 

+
+
+
    +
  • +

    section 10(1)(d) consent 

    +
  • +
+
+
+

 

+
+
+

Please attach written proof of the applicant’s consent. 

+
+
+

 

+
+
+

Please submit this form at least 3 business days before the due date and ensure that all information is complete and accurate. 

+
+
+

Shape 

+
+
+

Section 1 – Public body background (required: all fields) 

+
+
+

OIPC file # of previous extension (if applicable):  XXX 

+
+
+

Shape 

+
+
+

Public body (full name):  {{selectedMinistry}} 

+
+
+

Public body File #:  {{axisRequestId}} 

+
+
+

Public body Contact Name:  {{assignedToFirstName}}  {{assignedToLastName}} 

+
+ +
+

Contact Email Address:  {{assignedGroupEmail}} 

+
+
+

Shape 

+
+
+
+

Please provide a brief description of the original request: 

+
+
+

{{description}} 

+
+
+

Shape 

+
+
+

Date request for records received:  {{oipcOriginalReceivedDate}} 

+
+
+

Original due date of request:  {{oipcOriginalDueDate}} 

+
+
+

 

+
+
+

Was a fee estimate sent?    Yes        No 

+
+
+

Date fee estimate sent:  Date 

+
+
+

Date deposit or full fee paid:   

+
+
+

Date of fee waiver decision:  Date 

+
+
+

 

+
+
+

Current request due date:  {{oipcOriginalDueDate}} 

+
+
+

Number of business days requested for this extension:  {{oipcExtensionDueDays}} 

+
+
+

Proposed Due Date:  {{oipcOriginalDueDate}} 

+
+
+

Shape 

+
+
+

Has the public body already taken a time extension under section 10(1)? 

+
+
+

+ {{takenExtensionStatus}}    +

+
+
+

If so, please indicate: 

+
+
+

Date of time extension:  {{filteredExtensionDate}} 

+
+
+

Number of days extended:  {{filteredExtensionDueDays}} 

+
+
+

 

+
+
+

Basis for time extension: 

+
+
+

{{sectionID}}        

+
+
+

Date of letter notifying applicant of the extension:  {{oipcExtensionNotiDate}} 

+
+
+

Has the applicant complained to the OIPC about this time extension? 

+
+
+

{{oipcComplaintStatus}} 

+
+
+

Shape 

+
+
+

Section 2 – Proof of applicant consent (required: attachment) 

+
+
+

Please attach written proof of the applicant’s consent to the time extension. Emails are an acceptable form of proof. 

+
+
+

Forms missing proof of applicant’s consent will not be processed. 

+
+
+

(Please refer to page 9 of the Time extension guidelines for public bodies for more information.) 

+
+
+

+ + + + \ No newline at end of file diff --git a/request-management-api/request_api/email_templates/oipc_first_time_extension.html b/request-management-api/request_api/email_templates/oipc_first_time_extension.html new file mode 100644 index 000000000..cfb42f329 --- /dev/null +++ b/request-management-api/request_api/email_templates/oipc_first_time_extension.html @@ -0,0 +1,377 @@ +
+
+

Note: This form is for time extension applications: 

+
+
+

 

+
+
+
    +
  • +

    Under section 10(2)(a) based on: 

    +
  • +
+
+
+
    +
  • +

    section 10(1)(a) insufficient detail 

    +
  • +
+
+
+
    +
  • +

    section 10(1)(b) large volume 

    +
  • +
+
+
+
    +
  • +

    section 10(1)(c) consultation 

    +
  • +
+
+
+

 

+
+
+
    +
  • +

    Under section 10(2)(b): 

    +
  • +
+
+
+
    +
  • +

    if the commissioner otherwise considers that it is fair and reasonable to extend the time for responding 

    +
  • +
+
+
+

 

+
+
+

Do not use this form for applications based on section 10(1)(d) consent. 

+
+
+

 

+
+
+

Please submit this form at least 3 business days before the due date and ensure that all information is complete and accurate. 

+
+
+

Shape 

+
+
+

Section 1 – Public body background (required: all fields) 

+
+
+

 

+
+
+

Public body (full name):  {{selectedMinistry}} 

+
+
+
+

Public body File #:  {{axisRequestId}} 

+
+
+

Public body Contact Name:  {{assignedToFirstName}}  {{assignedToLastName}} 

+
+ +
+

Contact Email Address:  {{assignedGroupEmail}} 

+
+
+

Shape 

+
+
+

Please provide a brief description of the original request: 

+
+
+

{{description}} 

+
+
+

Shape 

+
+
+

Date request for records received:  {{oipcOriginalReceivedDate}} 

+
+
+

Original due date of request:  {{oipcOriginalDueDate}} 

+
+
+

 

+
+
+

Was a fee estimate sent?    Yes        No 

+
+
+

Date fee estimate sent:  Date 

+
+
+

Date deposit or full fee paid:   

+
+
+

Date of fee waiver decision:  Date 

+
+
+

 

+
+
+

Current request due date:  {{oipcOriginalDueDate}} 

+
+
+

Number of business days requested for this extension:  XXX 

+
+
+

Proposed Due Date:   

+
+
+

 

+
+
+

Shape 

+
+
+

Has the public body already taken a time extension under section 10(1)? 

+
+
+

{{takenExtensionStatus}}   

+
+
+

If so, please indicate: 

+
+
+

Date of time extension:  {{filteredExtensionDate}} 

+
+
+

Number of days extended:  {{filteredExtensionDueDays}} 

+
+
+

Basis for previous time extension: {{sectionID}} 

+
+
+

Number of days extended:  {{filteredExtensionDueDays}} 

+
+
+

Date of letter notifying applicant of the extension:  {{oipcExtensionNotiDate}} 

+
+
+

Has the applicant complained to the OIPC about this time extension? 

+
+
+

{{oipcComplaintStatus}}    

+
+
+

Shape 

+
+
+

Section 2 - Grounds for Current Extension Application (choose all that apply) 

+
+
+

  Section 10(2)(a) 

+
+
+

   {{sectionID}} 

+
+
+

   

+
+
+

   

+
+
+

  Section 10(2)(b) 

+
+
+

 

+
+
+

Shape 

+
+
+
+

Section 3 – Additional information (required for each selection made in section 2) 

+
+
+

 

+
+
+

10(1)(a) Insufficient detail (required: all fields) 

+
+
+

Please include the following with your submission: 

+
+
+
    +
  • +

    A complete copy of the original request. 

    +
  • +
+
+
+

 

+
+
+

Explain how the original request does not provide sufficient detail: 

+
+
+

XXXX 

+
+
+

 

+
+
+

Explain why satisfactory clarification from the applicant was not obtained within 60 business days (or 30 business days if the public body’s own time extension was not taken): 

+
+
+

XXXX 

+
+
+

Shape 

+
+
+

10(1)(b) Volume of records (required: either volume of records requested, or volume of records searched or both, and an explanation regarding unreasonable interference). 

+
+
+

 

+
+
+

Large volume of records requested 

+
+
+

 

+
+
+

Approximate number of pages of responsive records:  XXXXX 

+
+
+

 

+
+
+

Large volume of records searched  

+
+
+

 

+
+
+
+

Number of pages searched:  XXXXX 

+
+
+

Number of program areas searched:  XXXXX 

+
+
+

Total amount of time spent performing search:  XXXXX 

+
+
+

 

+
+
+

Unreasonable interference with the operations of the public body 

+
+
+

Explain how meeting the time limit would unreasonably interfere with the operations of the public body. 

+
+
+

XXXX 

+
+
+

 

+
+
+

Current status 

+
+
+

Please describe the current status of processing this request and any other relevant information: 

+
+
+

XXXX 

+
+
+

Shape 

+
+
+

10(1)(c) Time for consultation (required: all fields, for each public body/third party consulted) 

+
+
+

(Please refer to page 8 of the Time extension guidelines for public bodies for more information) 

+
+
+

 

+
+
+

Full name of the public body or third party: XXXX 

+
+
+

Number of pages sent or to be sent for consultation:  XXXX 

+
+
+

Date consultation was sent or will be sent:  XXXX 

+
+
+

 

+
+
+

Why is consultation necessary to make a decision about access? 

+
+
+

XXXX 

+
+
+

What is the third party or public body’s interest in the record? 

+
+
+

XXXX 

+
+
+

 

+
+
+

Current status of the consultation, including efforts made to obtain a response to the consultation and expected return date: 

+
+
+

XXXX 

+
+
+

Shape 

+
+
+

 

+
+
+

10(2)(b)  (required: circumstances and explanation) 

+
+
+

Please note the need for exceptional circumstances, such as forest fires, flooding, court involvement, and unforeseeable issues. See pages 9-10 of the time extension guidelines. 

+
+
+

 

+
+
+

Explain why it would be fair and reasonable for the Commissioner to grant a time extension. Include a chronology of the processing of the request and an explanation for any delays: 

+
+
+

XXXX  

+
+
+

Shape 

+
+
+

 

+
+
+

Section 4 – Additional comments 

+
+
+

Please provide any additional comments or details that will assist in the decision on this request: 

+
+
+

XXXX 

+
\ No newline at end of file diff --git a/request-management-api/request_api/email_templates/oipc_subsequent_time_extension.html b/request-management-api/request_api/email_templates/oipc_subsequent_time_extension.html new file mode 100644 index 000000000..f8da88a26 --- /dev/null +++ b/request-management-api/request_api/email_templates/oipc_subsequent_time_extension.html @@ -0,0 +1,227 @@ +
+
+

Note: This form is for subsequent time extension applications (after the first OIPC-approved extension): 

+
+
+

 

+
+
+
    +
  • +

    Under section 10(2)(a) based on: 

    +
  • +
+
+
+
    +
  • +

    section 10(1)(a) insufficient detail 

    +
  • +
+
+
+
    +
  • +

    section 10(1)(b) large volume 

    +
  • +
+
+
+
    +
  • +

    section 10(1)(c) consultation 

    +
  • +
+
+
+

 

+
+
+
    +
  • +

    Under section 10(2)(b): 

    +
  • +
+
+
+
    +
  • +

    if the commissioner otherwise considers that it is fair and reasonable to extend the time for responding 

    +
  • +
+
+
+

 

+
+
+

Do not use this form for applications based on section 10(1)(d) consent. 

+
+
+

 

+
+
+

Please submit this form at least 5 business days before the due date and ensure that all information is complete and accurate. 

+
+
+

Shape 

+
+
+

Section 1 – Public body background (required: all fields) 

+
+
+

OIPC file # of previous extension (if applicable):  XXX 

+
+
+

Shape 

+
+
+
+

Public body (full name):  {{selectedMinistry}} 

+
+
+

Public body File #:  {{axisRequestId}} 

+
+
+

Public body Contact Name:  {{assignedToFirstName}}  {{assignedToLastName}} 

+
+ +
+

Contact Email Address:  {{assignedGroupEmail}} 

+
+
+

ShapeFOI applicant (full name):  {{assignedToFirstName}}  {{assignedToLastName}} 

+
+
+

Applicant email address:  {{assignedGroupEmail}}  

+
+ +
+

Shape 

+
+
+

Please provide a brief description of the original request: 

+
+
+

{{description}} 

+
+
+

Shape 

+
+
+

Date request for records received:  {{oipcOriginalReceivedDate}} 

+
+
+

Original due date of request:  {{oipcOriginalDueDate}} 

+
+
+

Current request due date:  {{oipcOriginalDueDate}} 

+
+
+

Number of business days requested for this extension:  {{oipcExtensionDueDays}} 

+
+
+

Proposed Due Date:   

+
+
+

Shape 

+
+
+

Section 2 - Grounds for Current Extension Application (required: choose all that apply) 

+
+
+

 

+
+
+

  Section 10(2)(a) 

+
+
+

{{sectionID}}    

+
+
+

    

+
+
+

   

+
+
+

 

+
+
+

  Section 10(2)(b) Please note the need for exceptional circumstances, such as forest fires, flooding, court involvement, and unforeseeable issues. See pages 9-10 of the time extension guidelines. 

+
+
+

 

+
+
+

Shape 

+
+
+

Section 3 – Additional information (required: all fields) 

+
+
+

 

+
+
+

Basis for previous time extension: 

+
+
+

{{sectionID}}   

+
+
+

    

+
+
+

   

+
+
+

   

+
+
+

 

+
+
+

Number of days previously extended: XXX 

+
+
+

 

+
+
+

Please explain why the previous time extension was not sufficient to complete the request: 

+
+
+

XXX 

+
+
+

 

+
+
+

Describe any changes since the previous time extension was granted: 

+
+
+

XXX 

+
+
+

 

+
+
+

Describe the progress made on this file since the previous time extension was granted: 

+
+
+

XXX 

+
+
+

 

+
+
+

Have any records been released to the applicant?  No    

+
+
+

 

+
+
+

Will there be a phased release of records?   No 

+
\ No newline at end of file diff --git a/request-management-api/request_api/services/email/templates/templateconfig.py b/request-management-api/request_api/services/email/templates/templateconfig.py index b307a2cfe..7c0f14992 100644 --- a/request-management-api/request_api/services/email/templates/templateconfig.py +++ b/request-management-api/request_api/services/email/templates/templateconfig.py @@ -16,6 +16,12 @@ def gettemplatename(self, key): return "fee_estimate_notification_outstanding.html" elif key == "PAYOUTSTANDINGFULLPAYMENT": return "fee_payment_confirmation_outstanding.html" + elif key == "OIPCAPPLICANTCONSENTEXTENSION": + return "oipc_applicant_consent_time_extension.html" + elif key == "OIPCFIRSTTIMEEXTENSION": + return "oipc_first_time_extension.html" + elif key == "OIPCSUBSEQUENTTIMEEXTENSION": + return "oipc_subsequent_time_extension.html" else: logging.info("Unknown key") return None