Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/operator documents new notifications #485

Merged
merged 7 commits into from
May 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions app/mailers/operator_document_mailer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
class OperatorDocumentMailer < ApplicationMailer
def expiring_documents(operator, user, documents)
@documents = sort_documents(documents)
@user = user
@operator = operator

mail to: user.email, subject: I18n.t("operator_document_mailer.expiring_documents.subject")
end

def expired_documents(operator, user, documents)
@documents = sort_documents(documents)
@user = user
@operator = operator

mail to: user.email, subject: I18n.t("operator_document_mailer.expired_documents.subject", count: @documents.count)
end

def document_valid(document, user)
@operator = document.operator
@document = document
@user = user
mail to: user.email, subject: I18n.t("operator_document_mailer.document_valid.subject")
end

def document_accepted_as_not_required(document, user)
@operator = document.operator
@document = document
@user = user
mail to: user.email, subject: I18n.t("operator_document_mailer.document_accepted_as_not_required.subject")
end

def document_invalid(document, user)
@operator = document.operator
@document = document
@user = user
mail to: user.email, subject: I18n.t("operator_document_mailer.document_invalid.subject")
end

private

def sort_documents(documents)
documents.sort_by { |d| [d.fmu&.name || "_", d.required_operator_document.name] }
end
end
16 changes: 0 additions & 16 deletions app/mailers/operator_mailer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,6 @@ class OperatorMailer < ApplicationMailer

helper :date

def expiring_documents(operator, user, documents)
@documents = documents.sort_by { |d| [d.fmu&.name || "_", d.required_operator_document.name] }
@user = user
@operator = operator

mail to: user.email, subject: I18n.t("operator_mailer.expiring_documents.subject")
end

def expired_documents(operator, user, documents)
@documents = documents.sort_by { |d| [d.fmu&.name || "_", d.required_operator_document.name] }
@user = user
@operator = operator

mail to: user.email, subject: I18n.t("operator_mailer.expired_documents.subject", count: @documents.count)
end

# An email that contains the a quarterly report of an operator
# It lists:
# 1. Current transparency score
Expand Down
2 changes: 1 addition & 1 deletion app/mailers/user_mailer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def generate_reset_url(user)

def generate_reset_token(user)
token, hashed = Devise.token_generator.generate(User, :reset_password_token)
user.update(reset_password_token: hashed, reset_password_sent_at: DateTime.now)
user.update!(reset_password_token: hashed, reset_password_sent_at: DateTime.now) unless user.new_record? # workaround for mailer previews
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mmm.. I didn't get this.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I had some validations errors here as in mailer's previews I'm not using persisted data, just User.new entity. I want to just get the reset token here without saving in db.

token
end
end
16 changes: 16 additions & 0 deletions app/models/operator_document.rb
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ class OperatorDocument < ApplicationRecord
after_save :recalculate_scores, if: :saved_change_to_score_related_attributes?
after_save :remove_notifications, if: :saved_change_to_expire_date?

after_commit :notify_about_changes, if: :saved_change_to_status?

scope :by_forest_types, ->(forest_type_id) { includes(:fmu).where(fmus: {forest_type: forest_type_id}) }
scope :by_country, ->(country_id) { includes(:required_operator_document).where(required_operator_documents: {country_id: country_id}) }
scope :by_required_operator_document_group, ->(required_operator_document_group_id) { includes(:required_operator_document).where(required_operator_documents: {required_operator_document_group_id: required_operator_document_group_id}) }
Expand Down Expand Up @@ -217,4 +219,18 @@ def reason_or_file
errors.add(:base, "File must be present or reason when document is non applicable")
end
end

def notify_about_changes
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mmm.. from the task in Pivotal it looks like the goal is to notify when the documents are ready to be reviewed.
Like, the operators submitted them and the admins should review them.

But here the task tells the operators that their documents were reviewed.
Maybe the description of the task in Pivotal is not very clear.

Copy link
Collaborator Author

@tsubik tsubik Apr 30, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you looked at wrong PT task. This one is "Set up email notifications to alert private sector users when their documents have been published or if they have been rejected", there is another one for notifying admins that document is ready for review (I will add a new PR today for it).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup. I probably checked the wrong task.
All good.

notify_users(operator.all_users, "document_valid") if doc_valid?
notify_users(operator.all_users, "document_accepted_as_not_required") if doc_not_required?
notify_users(operator.all_users, "document_invalid") if doc_invalid?
end

def notify_users(users, mail_template)
users.filter_actives.where.not(email: [nil, ""]).find_each do |user|
I18n.with_locale(user.locale.presence || I18n.default_locale) do
OperatorDocumentMailer.send(mail_template, self, user).deliver_later
end
end
end
end
2 changes: 1 addition & 1 deletion app/services/expiration_notifier_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ def call
operator = Operator.find(operator_id)
operator.all_users.filter_actives.each do |user|
I18n.with_locale(user.locale.presence || I18n.default_locale) do
OperatorMailer.expiring_documents(operator, user, documents).deliver_now
OperatorDocumentMailer.expiring_documents(operator, user, documents).deliver_now
end
end
end
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<p>
<%= t("mailers.greeting", name: @user.display_name, fallback: true) %>
</p>

<p>
<%= t(".paragraph1", document: @document.name_with_fmu, company: link_to(@operator.name, ENV["FRONTEND_URL"] + "/operators/"+ @operator.slug + "/documentation", target: "_blank")).html_safe %>
</p>

<p>
<%= t("mailers.salutation") %> <br/>
<%= t("mailers.signature") %>
</p>
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<%= t("mailers.greeting", name: @user.display_name, fallback: true) %>

<%= t(".paragraph1", document: @document.name_with_fmu, company: @operator.name) %>

<%= t("mailers.salutation") %>
<%= t("mailers.signature") %>
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<p>
<%= t("mailers.greeting", name: @user.display_name, fallback: true) %>
</p>

<p>
<%= t(".paragraph1") %>
</p>

<p>
<%= t("mailers.company") %>: <%= @operator.name %><br/>
<%= t("mailers.document") %>: <%= @document.name_with_fmu %><br/>
<%= OperatorDocument.human_attribute_name(:start_date) %>: <%= @document.start_date %><br/>
<%= OperatorDocument.human_attribute_name(:expire_date) %>: <%= @document.expire_date %><br/>
Link: <%= link_to nil, @document&.document_file&.attachment&.url %>
</p>

<p>
<%= t(".paragraph2") %>
</p>

<p style="background-color: #f7f6ed; padding: 20px">
<em><%= @document.admin_comment %></em>
</p>

<p>
<%= t(".paragraph3", link: link_to(nil, "#{ENV["FRONTEND_URL"]}/operators/#{@operator.slug}/documentation", target: "_blank")).html_safe %>
</p>

<p>
<%= t("mailers.salutation") %> <br/>
<%= t("mailers.signature") %>
</p>
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<%= t("mailers.greeting", name: @user.display_name, fallback: true) %>

<%= t(".paragraph1") %>

<%= t("mailers.company") %>: <%= @operator.name %>
<%= t("mailers.document") %>: <%= @document.name_with_fmu %>
<%= OperatorDocument.human_attribute_name(:start_date) %>: <%= @document.start_date %>
<%= OperatorDocument.human_attribute_name(:expire_date) %>: <%= @document.expire_date %>
Link: <%= @document&.document_file&.attachment&.url %>

<%= t(".paragraph2") %>
<%= @document.admin_comment %>

<%= t(".paragraph3", link: "#{ENV["FRONTEND_URL"]}/operators/#{@operator.slug}/documentation") %>

<%= t("mailers.salutation") %>
<%= t("mailers.signature") %>
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<p>
<%= t("mailers.greeting", name: @user.display_name, fallback: true) %>
</p>

<p>
<%= t(".paragraph1", document: @document.name_with_fmu, company: link_to(@operator.name, ENV["FRONTEND_URL"] + "/operators/"+ @operator.slug + "/documentation", target: "_blank")).html_safe %>
</p>

<p>
<%= t("mailers.salutation") %> <br/>
<%= t("mailers.signature") %>
</p>
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<%= t("mailers.greeting", name: @user.display_name, fallback: true) %>

<%= t(".paragraph1", document: @document.name_with_fmu, company: @operator.name) %>

<%= t("mailers.salutation") %>
<%= t("mailers.signature") %>
14 changes: 14 additions & 0 deletions config/locales/mailers.en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ en:
contact_us: Feel free to contact us if you have any questions.
observation_id: Observation ID
report_name: Report name
company: Company
document: Document
user_mailer:
user_acceptance:
subject: Welcome to the Open Timber Portal!
Expand Down Expand Up @@ -60,6 +62,7 @@ en:
paragraph3: "Please note that the following documents on your profile are expiring this quarter and will need to be updated:"
paragraph4: You can update these documents by logging on to your OTP profile at %{link}.
doc_expires: "%{document} expires on %{date}"
operator_document_mailer:
expiring_documents:
subject: Expiring document(s) on the Open Timber Portal
paragraph1: "The following document(s) from %{company} is/are expiring in %{days}:"
Expand All @@ -70,6 +73,17 @@ en:
other: "You have %{count} documents expired on the OTP"
paragraph1: "%{company} has %{count} document(s) that are expired:"
paragraph2: You can update these documents by logging on to your OTP profile at %{link}.
document_valid:
subject: "Open Timber Portal: new document published"
paragraph1: The document %{document} has been validated and is now published on %{company}'s profile on the Open Timber Portal.
document_accepted_as_not_required:
subject: "Open Timber Portal: updated document"
paragraph1: "The document %{document} has been approved as not required on %{company}'s profile on the Open Timber Portal."
document_invalid:
subject: "Open Timber Portal: uploaded document was not validated"
paragraph1: "The following document was reviewed and needs to be revised:"
paragraph2: "The reviewer made the following comment:"
paragraph3: "You can make edits to this document by clicking on the following link and updating it on your profile: %{link}"
system_mailer:
user_created:
subject: New account created
Expand Down
15 changes: 15 additions & 0 deletions config/locales/mailers.fr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ fr:
contact_us: N'hésitez pas à nous contacter si vous avez des questions.
observation_id: Identifiant de l’observation
report_name: Nom du rapport
company: Enterprise
document: Document
user_mailer:
user_acceptance:
subject: Bienvenue sur la plateforme Open Timber Portal
Expand Down Expand Up @@ -60,6 +62,7 @@ fr:
paragraph3: "Veuillez noter que les documents ci-dessous expirent ce trimestre et qu’il faudra les mettre à jour:"
paragraph4: "Vous pouvez actualiser ces documents directement sur votre profil, en vous connectant sur l'OTP: %{link}."
doc_expires: "%{document} expire le %{date}"
operator_document_mailer:
expiring_documents:
subject: Document(s) qui vont expirer sur l’Open Timber Portal
paragraph1: "Le(s) document(s) de %{company} ci-dessous expire(nt) dans %{days}:"
Expand All @@ -70,4 +73,16 @@ fr:
other: "Vous avez %{count} documents expiré sur l'OTP"
paragraph1: "%{company} a %{count} document(s) qui sont expiré:"
paragraph2: "Vous pouvez actualiser ces documents directement sur votre profil, en vous connectant sur l'OTP: %{link}."
document_valid:
subject: "Open Timber Portal: nouveau document publié"
paragraph1: Le document %{document} a été validé et est désormais publié sur le profil de %{company} sur l’Open Timber Portal.
document_accepted_as_not_required:
subject: "Open Timber Portal: mise à jour de votre document"
paragraph1: "Le document %{document} a été approuvé comme non requis sur le profil de %{company} sur l’Open Timber Portal."
document_invalid:
subject: "Open Timber Portal: le document téléchargé n’a pas été validé"
paragraph1: "Le document ci-dessous a été passé en revue et a besoin d’être modifié:"
paragraph2: "L'évaluateur a fait le commentaire suivant:"
paragraph3: "Vous pouvez modifier ce document en cliquant sur le lien suivant et en modifiant le document sur votre profil: %{link}"


10 changes: 0 additions & 10 deletions spec/mailers/mailer_previews_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
# doing it in before all for better performance
country = create(:country)

ngo_user = create(:ngo, country: country)
create_list(:required_operator_document_country, 3, country: country)

operator = create(:operator, :with_documents, country: country)
Expand All @@ -18,15 +17,6 @@
document_file: create(:document_file), status: "doc_expired", start_date: 10.days.ago, expire_date: 2.days.ago
)
operator.operator_documents.doc_valid.first.update!(start_date: 10.days.ago, expire_date: 10.days.from_now)

# observation mailer needs observation
create(
:observation,
admin_comment: "admin comment",
monitor_comment: "monitor comment",
country: country,
modified_user: ngo_user
)
end

ActionMailer::Preview.all.each do |preview| # rubocop:disable Rails/FindEach
Expand Down
74 changes: 74 additions & 0 deletions spec/mailers/operator_document_mailer_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
require "rails_helper"

RSpec.describe OperatorDocumentMailer, type: :mailer do
include ActionView::Helpers::UrlHelper

let(:operator) { create(:operator) }
let(:user) { build(:operator_user, operator: operator) }

describe "expiring_documents" do
let(:country) { create(:country) }
let(:operator) { create(:operator, country_id: country.id) }
let(:rod1) { create(:required_operator_document_country, country_id: country.id) }
let(:rod2) { create(:required_operator_document_country, country_id: country.id) }
let(:document1) {
create(:operator_document_country, required_operator_document_id: rod1.id, operator_id: operator, expire_date: Date.tomorrow)
}
let(:document2) {
create(:operator_document_country, required_operator_document_id: rod2.id, operator_id: operator, expire_date: Date.tomorrow)
}
let(:documents) { [document1, document2] }
let(:mail) { OperatorDocumentMailer.expiring_documents(operator, user, documents) }

it "renders the headers" do
expect(mail.subject).to eq("Expiring document(s) on the Open Timber Portal")
expect(mail.to).to eq([user.email])
end

it "renders the body" do
expect(mail.body.encoded).to match(/The following document\(s\) from #{operator.name} is\/are expiring in 1 day/)
end
end

describe "document_valid" do
let(:document) { create(:operator_document_country, operator: operator, force_status: "doc_valid") }
let(:mail) { OperatorDocumentMailer.document_valid(document, user) }

it "renders the headers" do
expect(mail.subject).to eq("Open Timber Portal: new document published")
expect(mail.to).to eq([user.email])
end

it "renders the body" do
expect(mail.body.encoded).to match(/The document #{document.name_with_fmu} has been validated and is now published/)
end
end

describe "document_accepted_as_not_required" do
let(:document) { create(:operator_document_country, operator: operator, force_status: "doc_not_required") }
let(:mail) { OperatorDocumentMailer.document_accepted_as_not_required(document, user) }

it "renders the headers" do
expect(mail.subject).to eq("Open Timber Portal: updated document")
expect(mail.to).to eq([user.email])
end

it "renders the body" do
expect(mail.body.encoded).to match(/The document #{document.name_with_fmu} has been approved as not required/)
end
end

describe "document_invalid" do
let(:document) { create(:operator_document_country, operator: operator, force_status: "doc_invalid") }
let(:mail) { OperatorDocumentMailer.document_invalid(document, user) }

it "renders the headers" do
expect(mail.subject).to eq("Open Timber Portal: uploaded document was not validated")
expect(mail.to).to eq([user.email])
end

it "renders the body" do
expect(mail.body.encoded).to match(/The following document was reviewed and needs to be revised/)
end
end
end
Loading