91 lines
2.9 KiB
Ruby
91 lines
2.9 KiB
Ruby
|
# frozen_string_literal: true
|
||
|
|
||
|
module Issues
|
||
|
class SetCrmContactsService < ::BaseProjectService
|
||
|
attr_accessor :issue, :errors
|
||
|
|
||
|
MAX_ADDITIONAL_CONTACTS = 6
|
||
|
|
||
|
def execute(issue)
|
||
|
@issue = issue
|
||
|
@errors = []
|
||
|
|
||
|
return error_no_permissions unless allowed?
|
||
|
return error_invalid_params unless valid_params?
|
||
|
|
||
|
determine_changes if params[:crm_contact_ids]
|
||
|
|
||
|
return error_too_many if too_many?
|
||
|
|
||
|
add_contacts if params[:add_crm_contact_ids]
|
||
|
remove_contacts if params[:remove_crm_contact_ids]
|
||
|
|
||
|
if issue.valid?
|
||
|
ServiceResponse.success(payload: issue)
|
||
|
else
|
||
|
# The default error isn't very helpful: "Issue customer relations contacts is invalid"
|
||
|
issue.errors.delete(:issue_customer_relations_contacts)
|
||
|
issue.errors.add(:issue_customer_relations_contacts, errors.to_sentence)
|
||
|
ServiceResponse.error(payload: issue, message: issue.errors.full_messages)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
private
|
||
|
|
||
|
def determine_changes
|
||
|
existing_contact_ids = issue.issue_customer_relations_contacts.map(&:contact_id)
|
||
|
params[:add_crm_contact_ids] = params[:crm_contact_ids] - existing_contact_ids
|
||
|
params[:remove_crm_contact_ids] = existing_contact_ids - params[:crm_contact_ids]
|
||
|
end
|
||
|
|
||
|
def add_contacts
|
||
|
params[:add_crm_contact_ids].uniq.each do |contact_id|
|
||
|
issue_contact = issue.issue_customer_relations_contacts.create(contact_id: contact_id)
|
||
|
|
||
|
unless issue_contact.persisted?
|
||
|
# The validation ensures that the id exists and the user has permission
|
||
|
errors << "#{contact_id}: The resource that you are attempting to access does not exist or you don't have permission to perform this action"
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
def remove_contacts
|
||
|
issue.issue_customer_relations_contacts
|
||
|
.where(contact_id: params[:remove_crm_contact_ids]) # rubocop: disable CodeReuse/ActiveRecord
|
||
|
.delete_all
|
||
|
end
|
||
|
|
||
|
def allowed?
|
||
|
current_user&.can?(:set_issue_crm_contacts, issue)
|
||
|
end
|
||
|
|
||
|
def valid_params?
|
||
|
set_present? ^ add_or_remove_present?
|
||
|
end
|
||
|
|
||
|
def set_present?
|
||
|
params[:crm_contact_ids].present?
|
||
|
end
|
||
|
|
||
|
def add_or_remove_present?
|
||
|
params[:add_crm_contact_ids].present? || params[:remove_crm_contact_ids].present?
|
||
|
end
|
||
|
|
||
|
def too_many?
|
||
|
params[:add_crm_contact_ids] && params[:add_crm_contact_ids].length > MAX_ADDITIONAL_CONTACTS
|
||
|
end
|
||
|
|
||
|
def error_no_permissions
|
||
|
ServiceResponse.error(message: ['You have insufficient permissions to set customer relations contacts for this issue'])
|
||
|
end
|
||
|
|
||
|
def error_invalid_params
|
||
|
ServiceResponse.error(message: ['You cannot combine crm_contact_ids with add_crm_contact_ids or remove_crm_contact_ids'])
|
||
|
end
|
||
|
|
||
|
def error_too_many
|
||
|
ServiceResponse.error(payload: issue, message: ["You can only add up to #{MAX_ADDITIONAL_CONTACTS} contacts at one time"])
|
||
|
end
|
||
|
end
|
||
|
end
|