55 lines
1.7 KiB
Ruby
55 lines
1.7 KiB
Ruby
|
# frozen_string_literal: true
|
||
|
|
||
|
module Members
|
||
|
class InvitationReminderEmailService
|
||
|
include Gitlab::Utils::StrongMemoize
|
||
|
|
||
|
attr_reader :invitation
|
||
|
|
||
|
MAX_INVITATION_LIFESPAN = 14.0
|
||
|
REMINDER_RATIO = [2, 5, 10].freeze
|
||
|
|
||
|
def initialize(invitation)
|
||
|
@invitation = invitation
|
||
|
end
|
||
|
|
||
|
def execute
|
||
|
return unless experiment_enabled?
|
||
|
|
||
|
reminder_index = days_on_which_to_send_reminders.index(days_after_invitation_sent)
|
||
|
return unless reminder_index
|
||
|
|
||
|
invitation.send_invitation_reminder(reminder_index)
|
||
|
end
|
||
|
|
||
|
private
|
||
|
|
||
|
def experiment_enabled?
|
||
|
Gitlab::Experimentation.enabled_for_attribute?(:invitation_reminders, invitation.invite_email)
|
||
|
end
|
||
|
|
||
|
def days_after_invitation_sent
|
||
|
(Date.today - invitation.created_at.to_date).to_i
|
||
|
end
|
||
|
|
||
|
def days_on_which_to_send_reminders
|
||
|
# Don't send any reminders if the invitation has expired or expires today
|
||
|
return [] if invitation.expires_at && invitation.expires_at <= Date.today
|
||
|
|
||
|
# Calculate the number of days on which to send reminders based on the MAX_INVITATION_LIFESPAN and the REMINDER_RATIO
|
||
|
REMINDER_RATIO.map { |number_of_days| ((number_of_days * invitation_lifespan_in_days) / MAX_INVITATION_LIFESPAN).ceil }.uniq
|
||
|
end
|
||
|
|
||
|
def invitation_lifespan_in_days
|
||
|
# When the invitation lifespan is more than 14 days or does not expire, send the reminders within 14 days
|
||
|
strong_memoize(:invitation_lifespan_in_days) do
|
||
|
if invitation.expires_at
|
||
|
[(invitation.expires_at - invitation.created_at.to_date).to_i, MAX_INVITATION_LIFESPAN].min
|
||
|
else
|
||
|
MAX_INVITATION_LIFESPAN
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|