@@ -15,19 +15,63 @@ def send_workshop_attendance_reminders(workshop)
1515 end
1616 handle_asynchronously :send_workshop_attendance_reminders
1717
18- def send_workshop_emails ( workshop , audience )
18+ def send_workshop_emails ( workshop , audience , initiator_id = nil )
1919 return 'The workshop is not invitable' unless workshop . invitable?
2020
21- invite_students_to_workshop ( workshop ) if audience . in? ( %w[ students everyone ] )
22- invite_coaches_to_workshop ( workshop ) if audience . in? ( %w[ coaches everyone ] )
21+ initiator = initiator_id ? Member . find_by ( id : initiator_id ) : nil
22+ logger = initiator ? InvitationLogger . new ( workshop , initiator , audience , :invite ) : nil
23+
24+ if logger
25+ begin
26+ logger . start_batch
27+ rescue ActiveRecord ::RecordNotUnique
28+ return 'A batch is already running for this workshop and audience'
29+ end
30+ end
31+
32+ total = 0
33+ begin
34+ if audience . in? ( %w[ students everyone ] )
35+ total += invite_students_to_workshop ( workshop , logger )
36+ end
37+ if audience . in? ( %w[ coaches everyone ] )
38+ total += invite_coaches_to_workshop ( workshop , logger )
39+ end
40+ logger &.finish_batch ( total )
41+ rescue StandardError => e
42+ logger &.fail_batch ( e )
43+ raise
44+ end
2345 end
2446 handle_asynchronously :send_workshop_emails
2547
26- def send_virtual_workshop_emails ( workshop , audience )
48+ def send_virtual_workshop_emails ( workshop , audience , initiator_id = nil )
2749 return 'The workshop is not invitable' unless workshop . invitable?
2850
29- invite_students_to_virtual_workshop ( workshop ) if audience . in? ( %w[ students everyone ] )
30- invite_coaches_to_virtual_workshop ( workshop ) if audience . in? ( %w[ coaches everyone ] )
51+ initiator = initiator_id ? Member . find_by ( id : initiator_id ) : nil
52+ logger = initiator ? InvitationLogger . new ( workshop , initiator , audience , :invite ) : nil
53+
54+ if logger
55+ begin
56+ logger . start_batch
57+ rescue ActiveRecord ::RecordNotUnique
58+ return 'A batch is already running for this workshop and audience'
59+ end
60+ end
61+
62+ total = 0
63+ begin
64+ if audience . in? ( %w[ students everyone ] )
65+ total += invite_students_to_virtual_workshop ( workshop , logger )
66+ end
67+ if audience . in? ( %w[ coaches everyone ] )
68+ total += invite_coaches_to_virtual_workshop ( workshop , logger )
69+ end
70+ logger &.finish_batch ( total )
71+ rescue StandardError => e
72+ logger &.fail_batch ( e )
73+ raise
74+ end
3175 end
3276 handle_asynchronously :send_virtual_workshop_emails
3377
@@ -51,35 +95,87 @@ def send_workshop_waiting_list_reminders(workshop)
5195 private
5296
5397 def create_invitation ( workshop , member , role )
54- invitation = WorkshopInvitation . create ( workshop : workshop , member : member , role : role )
55- invitation . persisted? ? invitation : nil
98+ WorkshopInvitation . find_or_create_by ( workshop : workshop , member : member , role : role )
99+ rescue StandardError => e
100+ log_invitation_failure ( workshop , member , role , e )
101+ nil
56102 end
57103
58- def invite_coaches_to_virtual_workshop ( workshop )
104+ def log_invitation_failure ( workshop , member , role , error )
105+ Rails . logger . error (
106+ '[InvitationManager] Failed to create invitation: ' \
107+ "workshop_id=#{ workshop . id } , chapter_id=#{ workshop . chapter_id } , " \
108+ "member_id=#{ member . id } , role=#{ role } , " \
109+ "error=#{ error . class . name } : #{ error . message } "
110+ )
111+ end
112+
113+ def invite_coaches_to_virtual_workshop ( workshop , logger = nil )
114+ count = 0
59115 chapter_coaches ( workshop . chapter ) . shuffle . each do |coach |
60- invitation = create_invitation ( workshop , coach , 'Coach' ) || next
61- VirtualWorkshopInvitationMailer . invite_coach ( workshop , coach , invitation ) . deliver_now
116+ invitation = create_invitation ( workshop , coach , 'Coach' )
117+ next unless invitation
118+
119+ count += 1
120+ send_email_with_logging ( logger , coach , invitation ) do
121+ VirtualWorkshopInvitationMailer . invite_coach ( workshop , coach , invitation ) . deliver_now
122+ end
62123 end
124+ count
63125 end
64126
65- def invite_coaches_to_workshop ( workshop )
127+ def invite_coaches_to_workshop ( workshop , logger = nil )
128+ count = 0
66129 chapter_coaches ( workshop . chapter ) . shuffle . each do |coach |
67- invitation = create_invitation ( workshop , coach , 'Coach' ) || next
68- WorkshopInvitationMailer . invite_coach ( workshop , coach , invitation ) . deliver_now
130+ invitation = create_invitation ( workshop , coach , 'Coach' )
131+ next unless invitation
132+
133+ count += 1
134+ send_email_with_logging ( logger , coach , invitation ) do
135+ WorkshopInvitationMailer . invite_coach ( workshop , coach , invitation ) . deliver_now
136+ end
69137 end
138+ count
70139 end
71140
72- def invite_students_to_virtual_workshop ( workshop )
141+ def invite_students_to_virtual_workshop ( workshop , logger = nil )
142+ count = 0
73143 chapter_students ( workshop . chapter ) . shuffle . each do |student |
74- invitation = create_invitation ( workshop , student , 'Student' ) || next
75- VirtualWorkshopInvitationMailer . invite_student ( workshop , student , invitation ) . deliver_now
144+ invitation = create_invitation ( workshop , student , 'Student' )
145+ next unless invitation
146+
147+ count += 1
148+ send_email_with_logging ( logger , student , invitation ) do
149+ VirtualWorkshopInvitationMailer . invite_student ( workshop , student , invitation ) . deliver_now
150+ end
76151 end
152+ count
77153 end
78154
79- def invite_students_to_workshop ( workshop )
155+ def invite_students_to_workshop ( workshop , logger = nil )
156+ count = 0
80157 chapter_students ( workshop . chapter ) . shuffle . each do |student |
81- invitation = create_invitation ( workshop , student , 'Student' ) || next
82- WorkshopInvitationMailer . invite_student ( workshop , student , invitation ) . deliver_now
158+ invitation = create_invitation ( workshop , student , 'Student' )
159+ next unless invitation
160+
161+ count += 1
162+ send_email_with_logging ( logger , student , invitation ) do
163+ WorkshopInvitationMailer . invite_student ( workshop , student , invitation ) . deliver_now
164+ end
165+ end
166+ count
167+ end
168+
169+ def send_email_with_logging ( logger , member , invitation )
170+ if logger
171+ begin
172+ yield
173+ logger . log_success ( member , invitation )
174+ rescue StandardError => e
175+ logger . log_failure ( member , invitation , e )
176+ end
177+ else
178+ yield
83179 end
84180 end
85181
0 commit comments