Skip to content

Commit

Permalink
Add various emails to send out manually to participants (#1571)
Browse files Browse the repository at this point in the history
* Add various emails to send out manually to participants (#1571)

* Make reminder mail manually sendable too

---------

Co-authored-by: Nils Rauch <[email protected]>
  • Loading branch information
njaeggi and TheWalkingLeek authored Feb 11, 2025
1 parent 0bfb1b4 commit 0743bf0
Show file tree
Hide file tree
Showing 6 changed files with 299 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# frozen_string_literal: true

# Copyright (c) 2024, Schweizer Alpen-Club. This file is part of
# hitobito_sac_cas and licensed under the Affero General Public License version 3
# or later. See the COPYING file at the top-level directory or at
# https://github.com/hitobito/hitobito_sac_cas

module SacCas::Event::Participations::MailDispatchesController
extend ActiveSupport::Concern

prepended do
def mail_type_valid?
if (participation.roles.map(&:type) & Event::Course::LEADER_ROLES).any?
Event::Participation::MANUALLY_SENDABLE_LEADERSHIP_MAILS.include?(mail_type)
else
Event::Participation::MANUALLY_SENDABLE_PARTICIPANT_MAILS.include?(mail_type)
end
end
end

private

def send_event_participation_canceled_mail = Event::ParticipationCanceledMailer.confirmation(participation).deliver_later

def send_event_canceled_no_leader_mail = Event::CanceledMailer.no_leader(participation).deliver_later

def send_event_canceled_minimum_participants_mail = Event::CanceledMailer.minimum_participants(participation).deliver_later

def send_event_canceled_weather_mail = Event::CanceledMailer.weather(participation).deliver_later

def send_event_participation_summon_mail = Event::ParticipationMailer.summon(participation).deliver_later

def send_course_application_confirmation_assigned_mail = Event::ApplicationConfirmationMailer.confirmation(participation, mail_type).deliver_later

def send_event_participation_reject_rejected_mail = Event::ParticipationMailer.reject_rejected(participation).deliver_later

def send_event_participation_reject_applied_mail = Event::ParticipationMailer.reject_applied(participation).deliver_later

def send_event_survey_mail = Event::SurveyMailer.survey(participation).deliver_later

def send_course_application_confirmation_unconfirmed_mail = Event::ApplicationConfirmationMailer.confirmation(participation, mail_type).deliver_later

def send_course_application_confirmation_applied_mail = Event::ApplicationConfirmationMailer.confirmation(participation, mail_type).deliver_later

def send_event_participant_reminder_mail = Event::ParticipantReminderMailer.reminder(participation).deliver_later

def send_event_published_notice_mail = Event::PublishedMailer.notice(event, participation.person).deliver_later

def send_event_leader_reminder_next_week_mail = Event::LeaderReminderMailer.reminder(participation, mail_type).deliver_later

def send_event_leader_reminder_8_weeks_mail = Event::LeaderReminderMailer.reminder(participation, mail_type).deliver_later
end
20 changes: 20 additions & 0 deletions app/helpers/sac_cas/dropdown/event/participation/mail_dispatch.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# frozen_string_literal: true

# Copyright (c) 2024, Schweizer Alpen-Club. This file is part of
# hitobito_sac_cas and licensed under the Affero General Public License version 3
# or later. See the COPYING file at the top-level directory or at
# https://github.com/hitobito/hitobito_sac_cas

module SacCas::Dropdown::Event::Participation::MailDispatch
def init_items
if (participation.roles.map(&:type) & Event::Course::LEADER_ROLES).any?
Event::Participation::MANUALLY_SENDABLE_LEADERSHIP_MAILS.each do |type|
add_mail_item(type)
end
else
Event::Participation::MANUALLY_SENDABLE_PARTICIPANT_MAILS.each do |type|
add_mail_item(type)
end
end
end
end
21 changes: 21 additions & 0 deletions app/models/sac_cas/event/participation.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,28 @@
module SacCas::Event::Participation
extend ActiveSupport::Concern

MANUALLY_SENDABLE_LEADERSHIP_MAILS = [
Event::PublishedMailer::NOTICE,
Event::LeaderReminderMailer::REMINDER_NEXT_WEEK,
Event::LeaderReminderMailer::REMINDER_8_WEEKS
]

prepended do
self::MANUALLY_SENDABLE_PARTICIPANT_MAILS = [
Event::ParticipationCanceledMailer::CONFIRMATION,
Event::CanceledMailer::NO_LEADER,
Event::CanceledMailer::MINIMUM_PARTICIPANTS,
Event::CanceledMailer::WEATHER,
Event::ParticipationMailer::SUMMONED_PARTICIPATION,
Event::ApplicationConfirmationMailer::ASSIGNED,
Event::ParticipationMailer::REJECT_REJECTED_PARTICIPATION,
Event::ParticipationMailer::REJECT_APPLIED_PARTICIPATION,
Event::ParticipantReminderMailer::REMINDER,
Event::SurveyMailer::SURVEY,
Event::ApplicationConfirmationMailer::UNCONFIRMED,
Event::ApplicationConfirmationMailer::APPLIED
]

include I18nEnums
include CapitalizedDependentErrors

Expand Down
4 changes: 3 additions & 1 deletion lib/hitobito_sac_cas/wagon.rb
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,11 @@ class Wagon < Rails::Engine
Event::Kind.prepend SacCas::Event::Kind
Event::Course.prepend SacCas::Event::Course
Event::KindCategory.prepend SacCas::Event::KindCategory
Event::Participation.prepend SacCas::Event::Participation
Event::ParticipationBanner.prepend SacCas::Event::ParticipationBanner
Event::ParticipationContactData.prepend SacCas::Event::ParticipationContactData
Event::Participatable.prepend SacCas::Event::Participatable
Event::ParticipationMailer.prepend SacCas::Event::ParticipationMailer
Event::Participation.prepend SacCas::Event::Participation
Event::Answer.include SacCas::Event::Answer
Group.include SacCas::Group
Household.prepend SacCas::Household
Expand Down Expand Up @@ -148,6 +148,7 @@ class Wagon < Rails::Engine
MountedAttrs::EnumSelect.prepend SacCas::MountedAttrs::EnumSelect
Dropdown::PeopleExport.prepend SacCas::Dropdown::PeopleExport
Dropdown::GroupEdit.prepend SacCas::Dropdown::GroupEdit
Dropdown::Event::Participation::MailDispatch.prepend SacCas::Dropdown::Event::Participation::MailDispatch
Event::ParticipationButtons.prepend SacCas::Event::ParticipationButtons
Sheet::Person.prepend SacCas::Sheet::Person
StandardFormBuilder.prepend SacCas::StandardFormBuilder
Expand All @@ -165,6 +166,7 @@ class Wagon < Rails::Engine
Event::KindsController.prepend SacCas::Event::KindsController
Event::KindCategoriesController.prepend SacCas::Event::KindCategoriesController
Event::ParticipationsController.prepend SacCas::Event::ParticipationsController
Event::Participations::MailDispatchesController.prepend SacCas::Event::Participations::MailDispatchesController
Event::RegisterController.prepend SacCas::Event::RegisterController
Event::RolesController.prepend SacCas::Event::RolesController
GroupsController.permitted_attrs << :mitglied_termination_by_section_only
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
# frozen_string_literal: true

# Copyright (c) 2024, Schweizer Alpen-Club. This file is part of
# hitobito_sac_cas and licensed under the Affero General Public License version 3
# or later. See the COPYING file at the top-level directory or at
# https://github.com/hitobito/hitobito_sac_cas.

require "spec_helper"

describe Event::Participations::MailDispatchesController do
include ActiveJob::TestHelper

let(:course) do
Fabricate(:sac_course, kind: event_kinds(:ski_course), link_survey: "bitte-bitte-umfrage-ausfüllen.ch", language: "de")
end
let(:participation) do
Event::Participation.create!(event: course, person: people(:mitglied))
end
let(:group) { course.groups.first }

before { sign_in(user) }

describe "POST #create" do
context "as member" do
let(:user) { people(:mitglied) }

it "unauthorized" do
expect do
post :create, params: {group_id: group, event_id: course, participation_id: participation, mail_type: :leader_reminder}
end.to raise_error(CanCan::AccessDenied)
end
end

context "as admin" do
let(:user) { people(:admin) }

it "raises if trying to send participant email to leader" do
Event::Course::Role::Leader.create!(participation: participation)
expect do
post :create, params: {group_id: group, event_id: course, participation_id: participation, mail_type: :event_participation_canceled}
end.to raise_error("Invalid mail type")
end

it "raises if trying to send leader email to participant" do
expect do
post :create, params: {group_id: group, event_id: course, participation_id: participation, mail_type: :event_published_notice}
end.to raise_error("Invalid mail type")
end

it "sends participation canceled email" do
expect do
post :create, params: {group_id: group, event_id: course, participation_id: participation, mail_type: :event_participation_canceled}
end.to have_enqueued_mail(Event::ParticipationCanceledMailer, :confirmation).exactly(1).times
expect(flash[:notice]).to eq("Es wurde eine E-Mail verschickt.")
end

it "sends canceled no leader email" do
expect do
post :create, params: {group_id: group, event_id: course, participation_id: participation, mail_type: :event_canceled_no_leader}
end.to have_enqueued_mail(Event::CanceledMailer, :no_leader).exactly(1).times
expect(flash[:notice]).to eq("Es wurde eine E-Mail verschickt.")
end

it "sends canceled minimum participants email" do
expect do
post :create, params: {group_id: group, event_id: course, participation_id: participation, mail_type: :event_canceled_minimum_participants}
end.to have_enqueued_mail(Event::CanceledMailer, :minimum_participants).exactly(1).times
expect(flash[:notice]).to eq("Es wurde eine E-Mail verschickt.")
end

it "sends canceled weather email" do
expect do
post :create, params: {group_id: group, event_id: course, participation_id: participation, mail_type: :event_canceled_weather}
end.to have_enqueued_mail(Event::CanceledMailer, :weather).exactly(1).times
expect(flash[:notice]).to eq("Es wurde eine E-Mail verschickt.")
end

it "sends participation summon email" do
expect do
post :create, params: {group_id: group, event_id: course, participation_id: participation, mail_type: :event_participation_summon}
end.to have_enqueued_mail(Event::ParticipationMailer, :summon).exactly(1).times
expect(flash[:notice]).to eq("Es wurde eine E-Mail verschickt.")
end

it "sends application confirmation assigned email" do
expect do
post :create, params: {group_id: group, event_id: course, participation_id: participation, mail_type: :course_application_confirmation_assigned}
end.to have_enqueued_mail(Event::ApplicationConfirmationMailer, :confirmation).with(participation, "course_application_confirmation_assigned").exactly(1).times
expect(flash[:notice]).to eq("Es wurde eine E-Mail verschickt.")
end

it "sends participation reject rejected email" do
expect do
post :create, params: {group_id: group, event_id: course, participation_id: participation, mail_type: :event_participation_reject_rejected}
end.to have_enqueued_mail(Event::ParticipationMailer, :reject_rejected).exactly(1).times
expect(flash[:notice]).to eq("Es wurde eine E-Mail verschickt.")
end

it "sends participation reject applied email" do
expect do
post :create, params: {group_id: group, event_id: course, participation_id: participation, mail_type: :event_participation_reject_applied}
end.to have_enqueued_mail(Event::ParticipationMailer, :reject_applied).exactly(1).times
expect(flash[:notice]).to eq("Es wurde eine E-Mail verschickt.")
end

it "sends survey email" do
expect do
post :create, params: {group_id: group, event_id: course, participation_id: participation, mail_type: :event_survey}
end.to have_enqueued_mail(Event::SurveyMailer, :survey).exactly(1).times
expect(flash[:notice]).to eq("Es wurde eine E-Mail verschickt.")
end

it "sends application confirmation unconfirmed email" do
expect do
post :create, params: {group_id: group, event_id: course, participation_id: participation, mail_type: :course_application_confirmation_unconfirmed}
end.to have_enqueued_mail(Event::ApplicationConfirmationMailer, :confirmation).with(participation, "course_application_confirmation_unconfirmed").exactly(1).times
expect(flash[:notice]).to eq("Es wurde eine E-Mail verschickt.")
end

it "sends application confirmation applied email" do
expect do
post :create, params: {group_id: group, event_id: course, participation_id: participation, mail_type: :course_application_confirmation_applied}
end.to have_enqueued_mail(Event::ApplicationConfirmationMailer, :confirmation).with(participation, "course_application_confirmation_applied").exactly(1).times
expect(flash[:notice]).to eq("Es wurde eine E-Mail verschickt.")
end

it "sends participation reminder email" do
expect do
post :create, params: {group_id: group, event_id: course, participation_id: participation, mail_type: :event_participant_reminder}
end.to have_enqueued_mail(Event::ParticipantReminderMailer, :reminder).with(participation).exactly(1).times
expect(flash[:notice]).to eq("Es wurde eine E-Mail verschickt.")
end

it "sends application published notice email" do
Event::Course::Role::Leader.create!(participation: participation)
expect do
post :create, params: {group_id: group, event_id: course, participation_id: participation, mail_type: :event_published_notice}
end.to have_enqueued_mail(Event::PublishedMailer, :notice).exactly(1).times
expect(flash[:notice]).to eq("Es wurde eine E-Mail verschickt.")
end

it "sends leader reminder next week email" do
Event::Course::Role::Leader.create!(participation: participation)
expect do
post :create, params: {group_id: group, event_id: course, participation_id: participation, mail_type: :event_leader_reminder_next_week}
end.to have_enqueued_mail(Event::LeaderReminderMailer, :reminder).with(participation, "event_leader_reminder_next_week").exactly(1).times
expect(flash[:notice]).to eq("Es wurde eine E-Mail verschickt.")
end

it "sends leader reminder 8 weeks email" do
Event::Course::Role::Leader.create!(participation: participation)
expect do
post :create, params: {group_id: group, event_id: course, participation_id: participation, mail_type: :event_leader_reminder_8_weeks}
end.to have_enqueued_mail(Event::LeaderReminderMailer, :reminder).with(participation, "event_leader_reminder_8_weeks")
expect(flash[:notice]).to eq("Es wurde eine E-Mail verschickt.")
end
end
end
end
44 changes: 44 additions & 0 deletions spec/helpers/dropdown/event/participation/mail_dispatch_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# frozen_string_literal: true

# Copyright (c) 2024, Schweizer Alpen-Club. This file is part of
# hitobito_sac_cas and licensed under the Affero General Public License version 3
# or later. See the COPYING file at the top-level directory or at
# https://github.com/hitobito/hitobito_sac_cas

require "spec_helper"

describe Dropdown::Event::Participation::MailDispatch do
include Rails.application.routes.url_helpers
include FormatHelper
include LayoutHelper
include UtilityHelper

let(:user) { people(:admin) }
let(:course) { events(:top_course) }
let(:group) { groups(:root) }
let(:participation) do
Event::Participation.create!(event: course, person: people(:abonnent))
end
let(:dropdown) do
described_class.new(self, course, group, participation)
end

subject { Capybara.string(dropdown.to_s) }

def menu = subject.find(".btn-group > ul.dropdown-menu")

it "only renders leader options for leader" do
Event::Course::Role::Leader.create!(participation: participation)
is_expected.to have_content "E-Mail senden"

expect(menu).to have_link "Kurs: E-Mail Reminder Kursleitung"
expect(menu).not_to have_link "Kurs: E-Mail Abmeldung"
end

it "only renders participant options for participant" do
is_expected.to have_content "E-Mail senden"

expect(menu).not_to have_link "Kurs: E-Mail Reminder Kursleitung"
expect(menu).to have_link "Kurs: E-Mail Abmeldung"
end
end

0 comments on commit 0743bf0

Please sign in to comment.