Skip to content

Commit

Permalink
feat: Author notification on proposal publication (#620)
Browse files Browse the repository at this point in the history
* add notification with eventmanager

* base to watch the CI and see files on github

* fix translation key & notififaction displaying

* add send_pubication_notification to right file

* start test rspec

* continuing rspec

* potential final test file

* fix: Merge proposal command and anonymous proposals

* fix: Change ProposalPublishedEvent to SimpleEvent

* fix: Proposal Published Event

* fix: Push FR locales

* test: Add specs for proposal_published_event

* update methode & file name

* adjust trad key

* adjust test file & update name of test file

* lint

* lint fr trad key

* lint

* update trad key order

* lint

* correct trad key link in method

* correst rspec

* fix rspec

* fix: Notification small title

* lint(rubocop): Fix offenses

* ci: Exclude BeEq Rubocop rule

* clean

* fix CI

* delete test file

* add ignore trad key in i118n-tasks.yml to fix CI

* update text syntaxe via trad key

* add '' in fr trad key

---------

Co-authored-by: Quentin Champenois <[email protected]>
  • Loading branch information
BarbaraOliveira13 and Quentinchampenois committed Nov 22, 2024
1 parent 30a47d8 commit aa3d09b
Show file tree
Hide file tree
Showing 6 changed files with 160 additions and 0 deletions.
4 changes: 4 additions & 0 deletions .rubocop_rails.yml
Original file line number Diff line number Diff line change
Expand Up @@ -109,3 +109,7 @@ RSpec/MultipleMemoizedHelpers:

RSpec/AnyInstance:
Enabled: false

RSpec/BeEq:
Exclude:
- spec/events/decidim/proposals/author_confirmation_proposal_event_spec.rb
126 changes: 126 additions & 0 deletions app/commands/decidim/proposals/publish_proposal.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
# frozen_string_literal: true

module Decidim
module Proposals
# A command with all the business logic when a user publishes a draft proposal.
class PublishProposal < Decidim::Command
include Decidim::AnonymousProposals::AnonymousBehaviorCommandsConcern

# Public: Initializes the command.
#
# proposal - The proposal to publish.
# current_user - The current user.
# override: decidim-module-anonymous_proposals/app/commands/decidim/anonymous_proposals/publish_proposal_command_overrides.rb
def initialize(proposal, current_user)
@proposal = proposal
@is_anonymous = allow_anonymous_proposals? && (current_user.blank? || proposal.authored_by?(anonymous_group))
set_current_user(current_user)
end

# Executes the command. Broadcasts these events:
#
# - :ok when everything is valid and the proposal is published.
# - :invalid if the proposal's author is not the current user.
#
# Returns nothing.
def call
return broadcast(:invalid) unless @proposal.authored_by?(@current_user)

transaction do
publish_proposal
increment_scores
send_notification
send_notification_to_participatory_space
send_publication_notification
end

broadcast(:ok, @proposal)
end

private

# This will be the PaperTrail version that is
# shown in the version control feature (1 of 1)
#
# For an attribute to appear in the new version it has to be reset
# and reassigned, as PaperTrail only keeps track of object CHANGES.
def publish_proposal
title = reset(:title)
body = reset(:body)

Decidim.traceability.perform_action!(
"publish",
@proposal,
@current_user,
visibility: "public-only"
) do
@proposal.update title: title, body: body, published_at: Time.current
end
end

# Reset the attribute to an empty string and return the old value
def reset(attribute)
attribute_value = @proposal[attribute]
PaperTrail.request(enabled: false) do
# rubocop:disable Rails/SkipsModelValidations
@proposal.update_attribute attribute, ""
# rubocop:enable Rails/SkipsModelValidations
end
attribute_value
end

def send_notification
return if @proposal.coauthorships.empty?

Decidim::EventsManager.publish(
event: "decidim.events.proposals.proposal_published",
event_class: Decidim::Proposals::PublishProposalEvent,
resource: @proposal,
followers: coauthors_followers
)
end

def send_publication_notification
Decidim::EventsManager.publish(
event: "decidim.events.proposals.author_confirmation_proposal_event",
event_class: Decidim::Proposals::AuthorConfirmationProposalEvent,
resource: @proposal,
affected_users: [@proposal.creator_identity],
extra: { force_email: true },
force_send: true
)
end

def send_notification_to_participatory_space
Decidim::EventsManager.publish(
event: "decidim.events.proposals.proposal_published",
event_class: Decidim::Proposals::PublishProposalEvent,
resource: @proposal,
followers: @proposal.participatory_space.followers - coauthors_followers,
extra: {
participatory_space: true
}
)
end

def coauthors_followers
@coauthors_followers ||= @proposal.authors.flat_map(&:followers)
end

def increment_scores
@proposal.coauthorships.find_each do |coauthorship|
if coauthorship.user_group
Decidim::Gamification.increment_score(coauthorship.user_group, :proposals)
else
Decidim::Gamification.increment_score(coauthorship.author, :proposals)
end
end
end

# override: decidim-module-anonymous_proposals/app/commands/decidim/anonymous_proposals/publish_proposal_command_overrides.rb
def component
@component ||= @proposal.component
end
end
end
end
15 changes: 15 additions & 0 deletions app/events/decidim/proposals/author_confirmation_proposal_event.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# frozen_string_literal: true

module Decidim
module Proposals
class AuthorConfirmationProposalEvent < Decidim::Events::SimpleEvent
def self.model_name
ActiveModel::Name.new(self, nil, I18n.t("decidim.events.proposals.author_confirmation_proposal_event.email_subject"))
end

def resource_title
translated_attribute(resource.title)
end
end
end
end
3 changes: 3 additions & 0 deletions config/i18n-tasks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -164,5 +164,8 @@ ignore_unused:
- decidim.newsletters.unsubscribe.error
- decidim.newsletters.unsubscribe.token_error
- decidim.half_signup.quick_auth.sms_verification.text_message
- decidim.events.proposals.author_confirmation_proposal_event.email_intro
- decidim.events.proposals.author_confirmation_proposal_event.email_outro
- decidim.events.proposals.author_confirmation_proposal_event.notification_title


6 changes: 6 additions & 0 deletions config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,12 @@ en:
email_outro: You have received this notification because you are following the initiative "%{resource_title}".
email_subject: Initiative "%{resource_title}" has been answered
notification_title: The initiative <a href="%{resource_path}">%{resource_title}</a> has been answered.
proposals:
author_confirmation_proposal_event:
email_intro: 'Your proposal " %{resource_title} " was successfully received and is now public. Thank you for participating ! You can view it here:'
email_outro: You received this notification because you are the author of the proposal. You can unfollow it by visiting the proposal page (" %{resource_title} ") and clicking on " Unfollow ".
email_subject: Your proposal has been published!
notification_title: Your proposal <a href="%{resource_path}">%{resource_title}</a> is now live.
users:
user_officialized:
email_intro: Participant %{name} (%{nickname}) has been officialized.
Expand Down
6 changes: 6 additions & 0 deletions config/locales/fr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,12 @@ fr:
email_outro: Vous avez reçu cette notification parce que vous suivez la pétition "%{resource_title}".
email_subject: La pétition "%{resource_title}" a reçu une réponse.
notification_title: La pétition <a href="%{resource_path}">%{resource_title}</a> a reçu une réponse.
proposals:
author_confirmation_proposal_event:
email_intro: 'Votre proposition « %{resource_title} » a été reçue avec succès et est maintenant publique. Merci pour votre participation ! Vous pouvez la consulter ici :'
email_outro: Vous recevez cette notification car vous êtes l’auteur de la proposition. Vous pouvez vous désabonner en visitant la page de la proposition (« %{resource_title} ») et en cliquant sur « Ne plus suivre ».
email_subject: Votre proposition a été publiée !
notification_title: Votre proposition <a href="%{resource_path}">%{resource_title}</a> est maintenant en ligne.
users:
user_officialized:
email_intro: Le participant %{name} (%{nickname}) a été officialisé.
Expand Down

0 comments on commit aa3d09b

Please sign in to comment.