Skip to content

Commit

Permalink
Added new files for email evaluators functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
edwin-jebaraj committed Dec 12, 2024
1 parent 3f4e8c1 commit 577cd5c
Show file tree
Hide file tree
Showing 14 changed files with 314 additions and 4 deletions.
99 changes: 99 additions & 0 deletions app/controllers/support/cases/email_evaluators_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
module Support
class Cases::EmailEvaluatorsController < Cases::ApplicationController
before_action :set_current_case
before_action :set_email_addresses
before_action :set_documents
before_action :current_email
before_action :set_template
before_action :category_name
before_action :organisation_name
before_action { @back_url = support_case_path(@current_case, anchor: "tasklist") }

def edit
@draft = Email::Draft.new(
default_content: default_template,
default_subject:,
template_id: @template_id,
ticket: current_case.to_model,
to_recipients: @to_recipients,
).save_draft!

@support_email_id = @draft.id
@email_evaluators = Email::Draft.find(@support_email_id)
parse_template
end

def update
@email_evaluators = Email::Draft.find(params[:id])
@email_evaluators.attributes = form_params
parse_template
if @email_evaluators.valid?(:new_message)
@email_evaluators.save_draft!
@email_evaluators.deliver_as_new_message

@current_case.update!(sent_email_to_evaluators: true)

redirect_to @back_url
else
render :edit
end
end

private

def set_current_case
@current_case = Support::Case.find(params[:case_id])
end

def category_name
@category_name = Support::Category.find(current_case.category_id).try(:title)
end

def organisation_name
@organisation_name = Support::Organisation.find(current_case.organisation_id).try(:name)
end

def set_email_addresses
@evaluators = @current_case.evaluators.all
@email_addresses = @evaluators.map(&:email)
@to_recipients = @email_addresses.to_json
end

def set_documents
@documents = @current_case.upload_documents
end

def form_params
params.require(:email_evaluators).permit(:html_content)
end

def draft_email_params
params.require(:email_evaluators).permit(:id)
end

def current_email
@current_email = current_case.email
end

def default_subject = "Case #{current_case.ref} - invitation to complete procurement evaluation"

def default_template = render_to_string(partial: "support/cases/email_evaluators/form_template")

def set_template
template = Support::EmailTemplate.find_by(title: "Invitation to complete procurement evaluation")
@template_id = template.id if template
end

def parse_template
variables = {
"organisation_name" => @organisation_name.to_s,
"sub_category" => @category_name.to_s,
"unique_case_specific_link" => "<a target='_blank' rel='noopener noreferrer' href='#{support_case_path(@current_case, anchor: 'tasklist', host: request.host)}'>unique case-specific link</a>",
"evaluation_due_date" => current_case.evaluation_due_date.strftime("%d %b %y"),
}

@parse_template = Liquid::Template.parse(@email_evaluators.body, error_mode: :strict).render(variables)
@email_evaluators.html_content = @parse_template
end
end
end
4 changes: 4 additions & 0 deletions app/models/email/template_parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ class Email::TemplateParser
def initialize(variables: {})
@variables = {
"caseworker_full_name" => Current.actor.try(:full_name),
"organisation_name" => "{{organisation_name}}",
"sub_category" => "{{sub_category}}",
"unique_case_specific_link" => "{{unique_case_specific_link}}",
"evaluation_due_date" => "{{evaluation_due_date}}",
}.merge(variables)
end

Expand Down
12 changes: 12 additions & 0 deletions app/views/support/cases/email_evaluators/_document_list.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<div class="govuk-form-group govuk-!-static-margin-bottom-8">
<h2 class="govuk-heading-m"><%= I18n.t("support.cases.email_evaluators.documents") %></h2>

<dl class="govuk-summary-list">
<% @documents.each do |document| %>
<div class="govuk-summary-list__row">
<dd class="govuk-summary-list__value"><%= link_to document.file_name, support_document_download_path(document, type: document.class), class: "govuk-link", target: "_blank" %></dd>
</div>
<% end %>
</dl>

</div>
12 changes: 12 additions & 0 deletions app/views/support/cases/email_evaluators/_email_list.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<div class="govuk-form-group govuk-!-static-margin-bottom-8">
<h2 class="govuk-heading-m"><%= I18n.t("support.cases.email_evaluators.sharing_with") %></h2>

<dl class="govuk-summary-list">
<% @evaluators.each do |item| %>
<div class="govuk-summary-list__row">
<dd class="govuk-summary-list__value"><%= item.email %></dd>
</div>
<% end %>
</dl>

</div>
22 changes: 22 additions & 0 deletions app/views/support/cases/email_evaluators/_form.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<%= form_with model: @email_evaluators, scope: :email_evaluators, url: support_case_email_evaluators_path(@current_case, id: @support_email_id), method: :patch do |form| %>

<%= render "email_list" %>
<%= render "document_list"%>

<h2 class="govuk-heading-m"><%= I18n.t("support.cases.email_evaluators.preview_template") %></h2>
<%= form.govuk_text_area :html_content, label: { text: I18n.t("support.case.label.messages.reply.body"), class: "govuk-!-display-none" }, rows: 5, class: "message-reply-box",
"data-component" => "tinymce",
"data-tinymce-profile" => "basic",
"data-tinymce-selector" => ".message-reply-box",
value: form.object.body
%>

<%= form.hidden_field :to_recipients, value: @to_recipients %>
<%= form.hidden_field :id, value: @support_email_id %>

<div class="govuk-button-group flex-align-center">
<%= form.submit I18n.t("support.cases.email_evaluators.submit"), class: "govuk-button" %>
<%= link_to I18n.t("generic.button.cancel"), @back_url, class: "govuk-link govuk-link--no-visited-state" %>
</div>

<% end %>
67 changes: 67 additions & 0 deletions app/views/support/cases/email_evaluators/_form_template.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<p>{{organisation_name}} has asked you to participate in the evaluation process for a {{sub_category}} procurement. </p>

<p>Follow the steps below to complete this evaluation:</p>

<p><b>1. Complete the declaration of interest form</b></p>
<p>If you do not have a conflict of interest with any of the following suppliers, then sign the attached declaration and reply to this email with the completed declaration as an attachment.</p>

<ul>
<li>[SUPPLIER 1]</li>

<li>[SUPPLIER 2]</li>

<li>[SUPPLIER 3]</li>
</ul>


<p><b>What happens if I identify a conflict of interest?</b></p>

<p>In some situations, it is possible to mitigate a conflict of interest. When this is not possible a new evaluator can be selected. </p>

<p>Reply to this email if you have a conflict of interest so the procurement is not delayed.</p>

<p><b>2. Watch the evaluation training video (10 minutes)</b></p>
The video provides necessary knowledge for scoring and justifying your assessments. Evaluators are required to be appropriately trained to evaluate tenders in a fair, transparent, and compliant manner.  
<br />
<p>You must watch the evaluation training video before starting the evaluation process. The video link is: <a href="https://youtu.be/cbL65QlOas4?si=3fA-vKVPRGn9TEJ_">https://youtu.be/cbL65QlOas4?si=3fA-vKVPRGn9TEJ_</a> </p>
<br />

<p><b>3. Sign in to complete the evaluation</b></p>
<p>Click the {{unique_case_specific_link}} to complete your evaluation with your DfE Sign-in account. If you do not have a DfE Sign-in account, you will need to create one. </p>
<br />

<p><b>4. Complete the evaluation</b></p>
<p>Complete the tasks required by {{evaluation_due_date}} or the procurement could be delayed.</p>

<br />

<p>Help completing the evaluation</p>

<p>Bids must be evaluated using the pre-populated evaluation sheet with scores allocated using the scoring methodology and reasoning shared. Bids must be evaluated independently of each other and other evaluators. Insufficient justification for scores will result in evaluations being returned, which could delay the procurement.</p>

<p>Reply to this email if you have any questions or need help.</p>

<br />

<p><b> 5. Attend the moderation meeting</b></p>

<p>The moderation meeting is scheduled for [Day] [Date] [Time]</p>

<br>

<p> {{caseworker_full_name}} <br>
Procurement Specialist <br>
Get help buying for schools
</p>

<p>Reply to this email within 15 working days or by the date agreed. Late replies can delay the procurement process.</p>

<p>We'll close the case if we don't hear back from you. You can reopen the case at any time by replying to this email.</p>

<br>

<p><b><i>GET HELP BUYING FOR SCHOOLS SERVICE DISCLAIMER</i></b></p>

<p><b><i>Please note that the expertise and advice being provided by the Service shall not in any way affect your obligations to comply with all relevant procurement law and the Department's guidance, including but not limited to the Public Contracts Regulations, Academy Trust Handbook, ESFA Funding Agreement and the Schemes for Financing Local Authority Maintained schools.</i></b></p>

<p><b><i>For the avoidance of doubt, the Department shall bear no liability as a result of using our Service.</i></b></p>
14 changes: 14 additions & 0 deletions app/views/support/cases/email_evaluators/edit.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<%= render partial: "support/cases/components/case_header", locals: { current_case: @current_case } %>
<h1 class="govuk-heading-l"><%= I18n.t("support.cases.email_evaluators.header") %></h1>

<p class="govuk-body-m govuk-!-static-margin-bottom-8"><%= I18n.t("support.cases.email_evaluators.hint") %></p>

<p class="govuk-body-m"><%= I18n.t("support.cases.email_evaluators.check_list.header") %></p>

<ul class="govuk-list govuk-list--bullet govuk-!-static-margin-bottom-8">
<li><%= I18n.t("support.cases.email_evaluators.check_list.item.email_addresses") %></li>
<li><%= I18n.t("support.cases.email_evaluators.check_list.item.documents_available") %></li>
<li><%= I18n.t("support.cases.email_evaluators.check_list.item.email_template") %></li>
</ul>

<%= render "form" %>
12 changes: 10 additions & 2 deletions app/views/support/cases/show/_tasklist.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,17 @@
end

task_list.with_item(title: I18n.t("support.case.label.tasklist.item.upload_documents"), href: edit_support_case_document_uploads_path(@current_case), status: document_upload_Status)
task_list.with_item(title: I18n.t("support.case.label.tasklist.item.email_evaluators")) do | item |
item.with_status(text: I18n.t("support.case.label.tasklist.status.cannot_start"), cannot_start_yet: true)

if (@current_case.evaluators.count > 0 && @current_case.evaluation_due_date && @current_case.has_uploaded_documents && @current_case.sent_email_to_evaluators)
task_list.with_item(title: I18n.t("support.case.label.tasklist.item.email_evaluators"), href: edit_support_case_email_evaluators_path(@current_case), status: govuk_tag(text: I18n.t("support.case.label.tasklist.status.complete"), colour: "green"))
elsif (@current_case.evaluators.count > 0 && @current_case.evaluation_due_date && @current_case.has_uploaded_documents && @current_case.sent_email_to_evaluators == false)
task_list.with_item(title: I18n.t("support.case.label.tasklist.item.email_evaluators"), href: edit_support_case_email_evaluators_path(@current_case), status: govuk_tag(text: I18n.t("support.case.label.tasklist.status.to_do")))
else
task_list.with_item(title: I18n.t("support.case.label.tasklist.item.email_evaluators")) do | item |
item.with_status(text: I18n.t("support.case.label.tasklist.status.cannot_start"), cannot_start_yet: true)
end
end

task_list.with_item(title: I18n.t("support.case.label.tasklist.item.review_evaluations")) do | item |
item.with_status(text: I18n.t("support.case.label.tasklist.status.cannot_start"), cannot_start_yet: true)
end
Expand Down
13 changes: 13 additions & 0 deletions config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1795,6 +1795,19 @@ en:
destroyed: "%{name} successfully removed"
delete_confirmation: Are you sure you want to delete %{name}?
is_document_uploaded: Please select uploaded option
email_evaluators:
header: Email evaluators
hint: Check and then send the emails to notify people that the files have been shared. Files will only be accessible to email addresses added.
check_list:
header: "You should check the:"
item:
email_addresses: email addresses
documents_available: documents available to download
email_template: email template
sharing_with: Sharing with
documents: Documents
preview_template: Preview template
submit: Send email and continue
emails:
attachments:
attach_files: Attach files
Expand Down
1 change: 1 addition & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,7 @@
resources :evaluators, except: %i[show]
resource :evaluation_due_dates, only: %i[edit update]
resource :document_uploads, except: %i[show]
resource :email_evaluators, except: %i[show]
resource :email, only: %i[create] do
scope module: :emails do
resources :content, only: %i[show], param: :template
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class AddSentEmailToEvaluatorsToCase < ActiveRecord::Migration[7.2]
def change
add_column :support_cases, :sent_email_to_evaluators, :boolean, default: false
end
end
3 changes: 2 additions & 1 deletion db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema[7.2].define(version: 2024_12_09_104836) do
ActiveRecord::Schema[7.2].define(version: 2024_12_11_171744) do
create_sequence "evaluation_refs"
create_sequence "framework_refs"

Expand Down Expand Up @@ -637,6 +637,7 @@
t.boolean "is_evaluator", default: false
t.date "evaluation_due_date"
t.boolean "has_uploaded_documents"
t.boolean "sent_email_to_evaluators", default: false
t.index ["category_id"], name: "index_support_cases_on_category_id"
t.index ["existing_contract_id"], name: "index_support_cases_on_existing_contract_id"
t.index ["new_contract_id"], name: "index_support_cases_on_new_contract_id"
Expand Down
52 changes: 52 additions & 0 deletions spec/features/support/agent_can_email_to_evaluators_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
require "rails_helper"

describe "Agent can email to evaluators", :js, :with_csrf_protection do
include_context "with an agent"

let(:support_case) { create(:support_case) }
let(:file_1) { fixture_file_upload(Rails.root.join("spec/fixtures/support/text-file.txt"), "text/plain") }
let(:file_2) { fixture_file_upload(Rails.root.join("spec/fixtures/support/another-text-file.txt"), "text/plain") }
let(:document_uploader) { support_case.document_uploader(files: [file_1, file_2]) }

specify "When add evaluators, set due date and upload documents status are not complete" do
visit support_case_path(support_case, anchor: "tasklist")

expect(find("#complete-evaluation-1-status")).to have_text("To do")
expect(find("#complete-evaluation-2-status")).to have_text("To do")
expect(find("#complete-evaluation-3-status")).to have_text("To do")
expect(find("#complete-evaluation-4-status")).to have_text("Cannot start")
end

specify "When add evaluators or set due date or upload documents status are not complete" do
support_case.update!(evaluation_due_date: Date.tomorrow)
visit support_case_path(support_case, anchor: "tasklist")

expect(find("#complete-evaluation-1-status")).to have_text("To do")
expect(find("#complete-evaluation-2-status")).to have_text("Complete")
expect(find("#complete-evaluation-3-status")).to have_text("To do")
expect(find("#complete-evaluation-4-status")).to have_text("Cannot start")
end

specify "When add evaluators, set due date and upload documents status are complete" do
support_case.update!(evaluation_due_date: Date.tomorrow, has_uploaded_documents: true)
support_case.evaluators.create!(first_name: "Momo", last_name: "Taro", email: "email@address")
document_uploader.save!
create(:support_email_template, title: "Invitation to complete procurement evaluation", subject: "about energy", body: "energy body")
support_case.reload

visit support_case_path(support_case, anchor: "tasklist")

expect(find("#complete-evaluation-4-status")).to have_text("To do")

visit edit_support_case_email_evaluators_path(support_case)

expect(page).to have_content("Email evaluators")

create(:support_email, :inbox, ticket: support_case, outlook_conversation_id: "OCID1", subject: "Email Vealuators", recipients: [{ "name" => "Test 1", "address" => "[email protected]" }], unique_body: "Email 1", is_read: false)
support_case.update!(sent_email_to_evaluators: true)

visit support_case_path(support_case, anchor: "tasklist")

expect(find("#complete-evaluation-4-status")).to have_text("Complete")
end
end
2 changes: 1 addition & 1 deletion spec/models/support/case_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
describe "#to_csv" do
it "includes headers" do
expect(described_class.to_csv).to eql(
"id,ref,category_id,request_text,support_level,status,state,created_at,updated_at,agent_id,first_name,last_name,email,phone_number,source,organisation_id,existing_contract_id,new_contract_id,procurement_id,savings_status,savings_estimate_method,savings_actual_method,savings_estimate,savings_actual,action_required,organisation_type,value,closure_reason,extension_number,other_category,other_query,procurement_amount,confidence_level,special_requirements,query_id,exit_survey_sent,detected_category_id,creation_source,user_selected_category,created_by_id,procurement_stage_id,initial_request_text,with_school,next_key_date,next_key_date_description,discovery_method,discovery_method_other_text,project,other_school_urns,is_evaluator,evaluation_due_date,has_uploaded_documents\n",
"id,ref,category_id,request_text,support_level,status,state,created_at,updated_at,agent_id,first_name,last_name,email,phone_number,source,organisation_id,existing_contract_id,new_contract_id,procurement_id,savings_status,savings_estimate_method,savings_actual_method,savings_estimate,savings_actual,action_required,organisation_type,value,closure_reason,extension_number,other_category,other_query,procurement_amount,confidence_level,special_requirements,query_id,exit_survey_sent,detected_category_id,creation_source,user_selected_category,created_by_id,procurement_stage_id,initial_request_text,with_school,next_key_date,next_key_date_description,discovery_method,discovery_method_other_text,project,other_school_urns,is_evaluator,evaluation_due_date,has_uploaded_documents,sent_email_to_evaluators\n",
)
end
end
Expand Down

0 comments on commit 577cd5c

Please sign in to comment.