48 lines
1.3 KiB
Ruby
48 lines
1.3 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module Achievements
|
|
class AwardService
|
|
attr_reader :current_user, :achievement_id, :recipient_id
|
|
|
|
def initialize(current_user, achievement_id, recipient_id)
|
|
@current_user = current_user
|
|
@achievement_id = achievement_id
|
|
@recipient_id = recipient_id
|
|
end
|
|
|
|
def execute
|
|
achievement = Achievements::Achievement.find(achievement_id)
|
|
return error_no_permissions unless allowed?(achievement)
|
|
|
|
recipient = User.find(recipient_id)
|
|
|
|
user_achievement = Achievements::UserAchievement.create(
|
|
achievement: achievement,
|
|
user: recipient,
|
|
awarded_by_user: current_user)
|
|
return error_awarding(user_achievement) unless user_achievement.persisted?
|
|
|
|
ServiceResponse.success(payload: user_achievement)
|
|
rescue ActiveRecord::RecordNotFound => e
|
|
error(e.message)
|
|
end
|
|
|
|
private
|
|
|
|
def allowed?(achievement)
|
|
current_user&.can?(:award_achievement, achievement)
|
|
end
|
|
|
|
def error_no_permissions
|
|
error('You have insufficient permissions to award this achievement')
|
|
end
|
|
|
|
def error_awarding(user_achievement)
|
|
error(user_achievement&.errors&.full_messages || 'Failed to award achievement')
|
|
end
|
|
|
|
def error(message)
|
|
ServiceResponse.error(message: Array(message))
|
|
end
|
|
end
|
|
end
|