Class: Customer::SalesRepAssigner

Inherits:
Object
  • Object
show all
Defined in:
app/services/customer/sales_rep_assigner.rb

Overview

Service object: sales rep assigner.

Constant Summary collapse

SALES_REPS_SELF_ASSIGN_ON_CUSTOMER_CREATE_CATALOG_IDS =

Sales reps self assign on customer create catalog ids.

[1, 2].freeze

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(customer, options = nil) ⇒ SalesRepAssigner

customer - An instance of Customer
options:
skip_lead: set to true if you do not want a lead activity created
force_assign: set to true if you want to override currently assigned reps
otherwise the current rep will be left untouched.

Parameters:

  • customer (Customer)

    the customer to assign reps to

  • options (Hash, nil) (defaults to: nil)

    assignment options

Options Hash (options):

  • skip_lead (Boolean)

    do not create a lead activity

  • force_assign (Boolean)

    override currently assigned reps

  • logger (Logger)

    logger to use (defaults to Rails.logger)



18
19
20
21
22
23
24
# File 'app/services/customer/sales_rep_assigner.rb', line 18

def initialize(customer, options = nil)
  @customer = customer
  raise 'Customer Store is not set, assigner cannot be used.' if @customer.store.nil?

  @options = options || {}
  @logger = @options[:logger] || Rails.logger
end

Class Method Details

.auto_assign(customer, options = {}) ⇒ Object

class factory convenience method, see initializer for parameters

Parameters:

  • customer (Customer)

    the customer to auto-assign

  • options (Hash) (defaults to: {})

    assigner options (see #initialize)

Options Hash (options):

  • skip_lead (Boolean)

    do not create a lead activity

  • force_assign (Boolean)

    override currently assigned reps

  • logger (Logger)

    logger to use (defaults to Rails.logger)



63
64
65
66
# File 'app/services/customer/sales_rep_assigner.rb', line 63

def self.auto_assign(customer, options = {})
  assigner = new(customer, options)
  assigner.auto_assign
end

.can_self_assign?(customer, current_user) ⇒ Boolean

Condition check to determine if a rep can self assign themselves on an account on creation

Returns:

  • (Boolean)


109
110
111
# File 'app/services/customer/sales_rep_assigner.rb', line 109

def self.can_self_assign?(customer, current_user)
  (current_user.is_sales_rep? && SALES_REPS_SELF_ASSIGN_ON_CUSTOMER_CREATE_CATALOG_IDS.include?(customer.catalog_id)) || current_user.is_sales_manager?
end

.check_for_self_assign(customer, current_user) ⇒ Object

Note:

this probably could belong in a step by step wizard on customer creation where the list
of possible reps appear beforehand rather than this trickery done after the fact.

Some catalog allow for rep to self assign themselves to an account on creation (US and Canada) but others are more restrictive, this method
checks for this condition and nilify the rep in the customer if it is not self assignable.



98
99
100
101
102
103
104
105
106
# File 'app/services/customer/sales_rep_assigner.rb', line 98

def self.check_for_self_assign(customer, current_user)
  unless can_self_assign?(customer, current_user)
    # msg = "Reseting customer sales reps since current user #{current_user.id} is a sales rep, but not a sales manager, and the customer catalog is marked to not accept self assignment on customer create"
    customer.primary_sales_rep_id = nil
    customer.secondary_sales_rep_id = nil
    customer.local_sales_rep_id = nil
  end
  customer
end

Instance Method Details

#assign_reps(sales_rep_assignment_options = {}) ⇒ Object



86
87
88
89
90
91
# File 'app/services/customer/sales_rep_assigner.rb', line 86

def assign_reps(sales_rep_assignment_options = {})
  return if sales_rep_assignment_options.blank?

  sales_rep_changer = Customer::SalesRepChanger.new(@customer, skip_activity_creation: @options[:skip_lead])
  sales_rep_changer.assign_reps sales_rep_assignment_options
end

#assignment_failure_reasonString

Why #auto_assign came back empty, phrased for the person who pressed the
button. The common case is a queue whose reps are all off that day — a
staffing/config situation the user can act on, not the "contact your system
administrator" fault the UI used to report (Ferguson USA queue, 2026-07-27:
one rep on extended leave, the other on vacation).

Returns:

  • (String)


41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'app/services/customer/sales_rep_assigner.rb', line 41

def assignment_failure_reason
  return 'Auto-assignment is turned off for this account.' if @customer.do_not_auto_assign

  entry = determine_sales_rep_queue_entry
  return 'No sales rep queue entry matches this account. Set the account team manually.' if entry.nil?

  out_of_office = entry.out_of_office_rep_names
  if out_of_office.present?
    "Every sales rep in the \"#{entry.name}\" queue is out of office today " \
      "(#{out_of_office.to_sentence}). Add a rep to that queue or set the account team manually."
  else
    "No sales rep is currently available in the \"#{entry.name}\" queue. " \
      'Set the account team manually.'
  end
end

#auto_assignObject

Instance method which will look at all the sales rep entries and find the rep to assign to the
customer. Note that if any reps are present this method will do nothing unless the :force_assign option
is passed on initialization



71
72
73
74
75
76
77
78
79
80
# File 'app/services/customer/sales_rep_assigner.rb', line 71

def auto_assign
  return false if @customer.do_not_auto_assign
  return false unless @customer.sales_reps.empty? || @options[:force_assign]

  sales_rep_assignment_options = determine_sales_rep
  @logger.debug("Customer::SalesRepAssigner#assign",
                customer_id: @customer.id,
                rep_ids: sales_rep_assignment_options&.values&.flatten&.compact)
  assign_reps(sales_rep_assignment_options)
end

#determine_sales_repObject



82
83
84
# File 'app/services/customer/sales_rep_assigner.rb', line 82

def determine_sales_rep
  @customer.store.get_next_sales_rep_assignments_for_customer(@customer)
end

#determine_sales_rep_queue_entryObject



26
27
28
# File 'app/services/customer/sales_rep_assigner.rb', line 26

def determine_sales_rep_queue_entry
  @customer.store&.sales_rep_queue&.first_eligible_sales_queue_entry(@customer)
end

#effective_queue_descriptionObject



30
31
32
# File 'app/services/customer/sales_rep_assigner.rb', line 30

def effective_queue_description
  determine_sales_rep_queue_entry.try(:description) || 'No Sales Rep Queue Entry Found'
end