From b95fcaa6be4197d40465007c707cb189f4b20405 Mon Sep 17 00:00:00 2001 From: "jonathan.kerr" <3410350+jonodrew@users.noreply.github.com> Date: Sat, 23 Aug 2025 16:32:30 +0100 Subject: [PATCH] Refactor out attendance management This moves the 'attendance management' concerns into a separate object. Having it as a separate object will allow me to update things from elsewhere. While doing so I've also made a small method to tidy up a long casting. Signed-off-by: jonathan.kerr <3410350+jonodrew@users.noreply.github.com> --- .../admin/invitations_controller.rb | 66 ++----------------- app/services/managers/attendance_manager.rb | 66 +++++++++++++++++++ 2 files changed, 72 insertions(+), 60 deletions(-) create mode 100644 app/services/managers/attendance_manager.rb diff --git a/app/controllers/admin/invitations_controller.rb b/app/controllers/admin/invitations_controller.rb index 9f49d6040..af970a5b3 100644 --- a/app/controllers/admin/invitations_controller.rb +++ b/app/controllers/admin/invitations_controller.rb @@ -2,11 +2,11 @@ class Admin::InvitationsController < Admin::ApplicationController include Admin::WorkshopConcerns def update - set_and_decorate_workshop + @attendance_manager = Managers::AttendanceManager.new(params[:workshop_id], invitation_id, current_user) + @workshop = WorkshopPresenter.decorate(@attendance_manager.workshop) authorize @workshop - set_invitation - - message = update_attendance(attending: params[:attending], attended: params[:attended]) + @invitation = @attendance_manager.invitation + message = @attendance_manager.update(attending: is_attending?, attended: params[:attended]) if request.xhr? set_admin_workshop_data @@ -18,62 +18,8 @@ def update private - def update_attendance(attending:, attended:) - return update_to_attended if attended - - result = attending.eql?('true') ? update_to_attending : update_to_not_attending - message, error = result.values_at(:message, :error) - - unless error - waiting_listed = WaitingList.find_by(invitation: @invitation) - waiting_listed&.destroy - end - - message - end - - def update_to_attended - @invitation.update(attended: true) - - "You have verified #{@invitation.member.full_name}’s attendace." - end - - def update_to_attending - update_successful = @invitation.update( - attending: true, - rsvp_time: Time.zone.now, - automated_rsvp: true, - last_overridden_by_id: current_user.id - ) - - { - message: update_successful ? attending_successful : attending_failed, - error: !update_successful - } - end - - def attending_successful - @workshop.send_attending_email(@invitation) if @workshop.future? - - "You have added #{@invitation.member.full_name} to the workshop as a #{@invitation.role}." - end - - def attending_failed - "Error adding #{@invitation.member.full_name} as a #{@invitation.role}. "\ - "#{@invitation.errors.full_messages.to_sentence}." - end - - def update_to_not_attending - @invitation.update!(attending: false, last_overridden_by_id: current_user.id) - - { - message: "You have removed #{@invitation.member.full_name} from the workshop.", - error: false - } - end - - def set_invitation - @invitation = @workshop.invitations.find_by(token: invitation_id) + def is_attending? + ActiveRecord::Type::Boolean.new.cast(params[:attending]) end def invitation_id diff --git a/app/services/managers/attendance_manager.rb b/app/services/managers/attendance_manager.rb new file mode 100644 index 000000000..460c496f7 --- /dev/null +++ b/app/services/managers/attendance_manager.rb @@ -0,0 +1,66 @@ + # frozen_string_literal: true + module Managers + class AttendanceManager + attr_reader :workshop, :invitation + def initialize(workshop_id, invitation_id, current_user) + @workshop = WorkshopPresenter.decorate(Workshop.find(workshop_id)) + @invitation = @workshop.invitations.find_by(token: invitation_id) + @current_user = current_user + end + + def update(attending:, attended:) + return update_to_attended if attended + + result = attending ? update_to_attending : update_to_not_attending + message, error = result.values_at(:message, :error) + + unless error + waiting_listed = WaitingList.find_by(invitation: @invitation) + waiting_listed&.destroy! + end + + message + end + + private + def update_to_attended + @invitation.update(attended: true) + + "You have verified #{@invitation.member.full_name}’s attendance." + end + + def update_to_attending + update_successful = @invitation.update( + attending: true, + rsvp_time: Time.zone.now, + automated_rsvp: true, + last_overridden_by_id: @current_user.id + ) + + { + message: update_successful ? attending_successful : attending_failed, + error: !update_successful + } + end + + def update_to_not_attending + @invitation.update!(attending: false, last_overridden_by_id: @current_user.id) + + { + message: "You have removed #{@invitation.member.full_name} from the workshop.", + error: false + } + end + + def attending_successful + @workshop.send_attending_email(@invitation) if @workshop.future? + + "You have added #{@invitation.member.full_name} to the workshop as a #{@invitation.role}." + end + + def attending_failed + "Error adding #{@invitation.member.full_name} as a #{@invitation.role}. "\ + "#{@invitation.errors.full_messages.to_sentence}." + end + end + end