Class: ActivityType

Inherits:
ApplicationRecord show all
Includes:
Memery, Models::Auditable, Models::Taggable
Defined in:
app/models/activity_type.rb

Overview

== Schema Information

Table name: activity_types
Database name: primary

id :integer not null, primary key
allow_time_lock :boolean default(FALSE), not null
autopin :boolean default(TRUE), not null
closing_instructions :text
description :string(255)
email_defer_days :integer
email_defer_tod :time
grouping :string(255)
inactive :boolean default(FALSE), not null
instructions :text
max_age_in_days :integer
next_instructions :text
notify_assigned_resource :boolean default(FALSE), not null
party_requirement :enum default("party_unrestricted"), not null
priority :integer default(2)
resource_requirement :enum default("resource_optional")
resource_restriction :string default([]), is an Array
sales_rep_as_sender :boolean default(FALSE), not null
skip_email_template_with_result :boolean default(FALSE), not null
task_type :string(255)
uniqueness :enum default("unrestricted")
created_at :datetime
updated_at :datetime
campaign_id :integer
customer_filter_id :integer
default_assignee_id :integer
email_template_id :integer
sender_party_id :integer

Indexes

activity_types_customer_filter_id_idx (customer_filter_id)
activity_types_email_template_id_idx (email_template_id)
by_id_w (id) WHERE (priority IS NOT NULL)
by_idn_w (id) WHERE (priority IS NULL)
index_activity_types_on_campaign_id (campaign_id)
index_activity_types_on_inactive_and_task_type (inactive,task_type)
index_activity_types_on_priority (priority)
index_activity_types_on_sender_party_id (sender_party_id)
index_activity_types_on_task_type (task_type)

Foreign Keys

activity_types_customer_filter_id_fk (customer_filter_id => customer_filters.id)
activity_types_email_template_id_fk (email_template_id => email_templates.id) ON DELETE => nullify
fk_rails_... (campaign_id => campaigns.id)
fk_rails_... (sender_party_id => parties.id)

Constant Summary collapse

PRIORITY_MAX =

Priority Activities always get assigned to someone

2
TOTAL_TIERS =

Total tiers.

5
TAGS_FOR_REPORTS =

Tags for reports.

[['CLOSE_THE_DEAL', 0], ['LEAD_THE_WAY', 1], ['NURTURE_ME', 2], ['MISC', 3], ['CALLBLOCK', 4], ['OTHERS', 5]].freeze

Constants included from Models::Auditable

Models::Auditable::ALWAYS_IGNORED

Constants included from Models::Schedulable

Models::Schedulable::SIMPLE_FORM_OPTIONS

Instance Attribute Summary collapse

Belongs to collapse

Methods included from Models::Auditable

#creator, #updater

Has many collapse

Methods included from Models::Taggable

#tag_records, #taggings

Has and belongs to many collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Models::Taggable

#add_tag, all_tags, #has_tag?, normalize_tag_names, not_tagged_with, #remove_tag, #tag_list, #tag_list=, #taggable_type_for_tagging, tagged_with, #tags, #tags=, tags_cloud, tags_exclude, tags_include, with_all_tags, with_any_tags, without_all_tags, without_any_tags

Methods included from Models::Auditable

#all_skipped_columns, #audit_reference_data, #should_not_save_version, #stamp_record

Methods inherited from ApplicationRecord

ransackable_associations, ransackable_attributes, ransortable_attributes, #to_relation

Methods included from Models::Schedulable

config

Methods included from Models::AfterCommittable

#after_commit

Methods included from Models::EventPublishable

#publish_event

Instance Attribute Details

#descriptionObject (readonly)

Validates task type, priority, description, party requirement, uniqueness.

Validations:



112
# File 'app/models/activity_type.rb', line 112

validates :task_type, :priority, :description, :party_requirement, :uniqueness, presence: true

#party_requirementObject (readonly)

Validates task type, priority, description, party requirement, uniqueness.

Validations:



112
# File 'app/models/activity_type.rb', line 112

validates :task_type, :priority, :description, :party_requirement, :uniqueness, presence: true

#priorityObject (readonly)

Validates task type, priority, description, party requirement, uniqueness.

Validations:



112
# File 'app/models/activity_type.rb', line 112

validates :task_type, :priority, :description, :party_requirement, :uniqueness, presence: true

#task_typeObject (readonly)

Validates task type.

Validations:



109
# File 'app/models/activity_type.rb', line 109

validates :task_type, uniqueness: true

#uniquenessObject (readonly)

Validates task type, priority, description, party requirement, uniqueness.

Validations:



112
# File 'app/models/activity_type.rb', line 112

validates :task_type, :priority, :description, :party_requirement, :uniqueness, presence: true

Class Method Details

.activeActiveRecord::Relation<ActivityType>

A relation of ActivityTypes that are active. Active Record Scope

Returns:

See Also:



117
# File 'app/models/activity_type.rb', line 117

scope :active, -> { where(inactive: false) }

.condensed_options_for_selectArray<Array>

Returns [label, id] pairs for select dropdowns.

Returns:

  • (Array<Array>)

    [label, id] pairs for select dropdowns



190
191
192
# File 'app/models/activity_type.rb', line 190

def self.condensed_options_for_select
  active.sorted.map { |at| [at.task_type, at.id] }
end

.email_activitiesActiveRecord::Relation<ActivityType>

A relation of ActivityTypes that are email activities. Active Record Scope

Returns:

See Also:



125
# File 'app/models/activity_type.rb', line 125

scope :email_activities, -> { where(ActivityType[:task_type].matches('EMAIL%')) }

.meetingActiveRecord::Relation<ActivityType>

A relation of ActivityTypes that are meeting. Active Record Scope

Returns:

See Also:



122
# File 'app/models/activity_type.rb', line 122

scope :meeting, -> { where(task_type: ActivityTypeConstants::MEETING_TYPES) }

.options_for_select(options = {}) ⇒ Array

Returns activity types for use in a select list.

Parameters:

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

    selection options

Options Hash (options):

  • party (Party, nil)

    restrict the list to activity types valid for this party

  • include_activity_type_id (Integer, nil)

    always include this activity type even if inactive

  • exclude_activity_type_id (Integer, nil)

    exclude this activity type from the list

Returns:

  • (Array)

    activity type options for a select list



149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
# File 'app/models/activity_type.rb', line 149

def self.options_for_select(options = {})
  cache_key = [:activity_options_for_select]
  cache_key << (options[:party] ? options[:party].cache_key : :all_parties)
  cache_key << (options[:include_activity_type_id] || :default)
  cache_key << (options[:exclude_activity_type_id] || :default)
  cache_key << ActivityType.maximum(:updated_at).to_i
  Rails.cache.fetch(cache_key, expires_in: 15.minutes) do
    activities = ActivityType.where(ActivityType[:inactive].eq(false))
    activities = activities.where.not(id: options[:exclude_activity_type_id]) if options[:exclude_activity_type_id]
    activities = activities.or(ActivityType.where(id: options[:include_activity_type_id])) if options[:include_activity_type_id].present?
    if options[:party].present?
      # Preload customer_filter with all associations to avoid N+1 queries in valid_for_party?
      activities = activities.includes(customer_filter: %i[parties catalogs profiles buying_groups sources tier2_program_pricings])
      activities = activities.select { |at| at.id == options[:include_activity_type_id] || at.valid_for_party?(options[:party]) }
    end
    activities = activities.sort_by(&:task_type)
    activities.map { |at| [at.name, at.id] }
  end
end

.options_for_select_by_user(user, extra_at_id = nil) ⇒ Object

Options for select by user.

Parameters:

  • user (User)

    the user

  • extra_at_id (Integer) (defaults to: nil)

    the extra at id



304
305
306
307
308
309
310
311
# File 'app/models/activity_type.rb', line 304

def self.options_for_select_by_user(user, extra_at_id = nil)
  rids = user..inherited_role_ids
  ActivityType.where(
    'NOT EXISTS(select 1 from activity_types_roles atr WHERE atr.activity_type_id = activity_types.id) OR EXISTS(select 1 from activity_types_roles atr WHERE atr.activity_type_id = activity_types.id AND atr.role_id IN (?)) OR activity_types.id = ?', rids, extra_at_id
  ).order('activity_types.task_type').map do |at|
    [at.name, at.id]
  end
end

.options_for_select_shortObject

Options for select short.



170
171
172
# File 'app/models/activity_type.rb', line 170

def self.options_for_select_short
  ActivityType.where.not(inactive: true).order(:task_type).pluck(:task_type, :id)
end

.party_requirement_options_for_selectArray<Array>

Returns [label, id] pairs for select dropdowns.

Returns:

  • (Array<Array>)

    [label, id] pairs for select dropdowns



185
186
187
# File 'app/models/activity_type.rb', line 185

def self.party_requirement_options_for_select
  party_requirements.map { |k, _v| [k.humanize, k] }
end

.priority_friendly_name(i) ⇒ Object

Priority friendly name.

Parameters:

  • i (Object)

    the i



201
202
203
204
205
# File 'app/models/activity_type.rb', line 201

def self.priority_friendly_name(i)
  return 'Unprioritized' unless i

  "Tier #{i} #{'(High Priority)' if i <= PRIORITY_MAX}"
end

.priority_select_optionsObject

Priority select options.



195
196
197
# File 'app/models/activity_type.rb', line 195

def self.priority_select_options
  (1...6).to_a.map { |i| [priority_friendly_name(i), i] }
end

.ransackable_scopes(_auth_object = nil) ⇒ Array<Symbol>

Returns Ransack-allowlisted scopes.

Parameters:

  • _auth_object (Object, nil) (defaults to: nil)

    the object being authorized (unused)

Returns:

  • (Array<Symbol>)

    Ransack-allowlisted scopes



138
139
140
# File 'app/models/activity_type.rb', line 138

def self.ransackable_scopes(_auth_object = nil)
  %i[tagged_with not_tagged_with tags_include]
end

.resource_requirement_options_for_selectArray<Array>

Returns [label, id] pairs for select dropdowns.

Returns:

  • (Array<Array>)

    [label, id] pairs for select dropdowns



180
181
182
# File 'app/models/activity_type.rb', line 180

def self.resource_requirement_options_for_select
  resource_requirements.map { |k, _v| [k.humanize, k] }
end

.resource_type_for_selectObject

Resource type for select.



208
209
210
# File 'app/models/activity_type.rb', line 208

def self.resource_type_for_select
  %w[ServiceJob CreditApplication Invoice SpiffEnrollment Party PurchaseOrder Delivery Opportunity SupportCaseParticipant Order CreditMemo Quote RoomConfiguration SupportCase LocatorRecord Rma].map { |v| [v.titleize.humanize, v] }
end

.sales_activitiesActiveRecord::Relation<ActivityType>

A relation of ActivityTypes that are sales activities. Active Record Scope

Returns:

See Also:



124
# File 'app/models/activity_type.rb', line 124

scope :sales_activities, -> { tagged_with('sale', 'sales-call') }

.sortedActiveRecord::Relation<ActivityType>

A relation of ActivityTypes that are sorted. Active Record Scope

Returns:

See Also:



118
# File 'app/models/activity_type.rb', line 118

scope :sorted, -> { order(:priority, :task_type) }

.trainingActiveRecord::Relation<ActivityType>

A relation of ActivityTypes that are training. Active Record Scope

Returns:

See Also:



121
# File 'app/models/activity_type.rb', line 121

scope :training, -> { where(task_type: ActivityTypeConstants::TRAINING_TYPES) }

.uniqueness_options_for_selectArray<Array>

Returns [label, id] pairs for select dropdowns.

Returns:

  • (Array<Array>)

    [label, id] pairs for select dropdowns



175
176
177
# File 'app/models/activity_type.rb', line 175

def self.uniqueness_options_for_select
  uniquenesses.map { |k, _v| [k.humanize, k] }
end

.with_customer_filterActiveRecord::Relation<ActivityType>

A relation of ActivityTypes that are with customer filter. Active Record Scope

Returns:

See Also:



120
# File 'app/models/activity_type.rb', line 120

scope :with_customer_filter, -> { where.not(activity_types: { customer_filter_id: nil }) }

.with_open_counterActiveRecord::Relation<ActivityType>

A relation of ActivityTypes that are with open counter. Active Record Scope

Returns:

See Also:



119
# File 'app/models/activity_type.rb', line 119

scope :with_open_counter, -> { select('activity_types.*, (select count(a.id) from activities a where a.activity_type_id = activity_types.id and a.activity_result_type_id IS NULL) as open_counter') }

Instance Method Details

#activitiesActiveRecord::Relation<Activity>

Returns the associated activities.

Returns:

  • (ActiveRecord::Relation<Activity>)

    the associated activities



93
# File 'app/models/activity_type.rb', line 93

has_many :activities, dependent: :nullify, inverse_of: :activity_type

#activity_chain_typesActiveRecord::Relation<ActivityChainType>

Returns the associated activity chain types.

Returns:

  • (ActiveRecord::Relation<ActivityChainType>)

    the associated activity chain types



95
# File 'app/models/activity_type.rb', line 95

has_many :activity_chain_types, dependent: :destroy

#activity_chain_types_for_selectObject

Activity chain types for select.



223
224
225
# File 'app/models/activity_type.rb', line 223

def activity_chain_types_for_select
  activity_chain_types.map { |act| [act.activity_result_type.result_code, act.id] }
end

#activity_result_typesActiveRecord::Relation<ActivityResultType>

Returns the associated activity result types.

Returns:



97
# File 'app/models/activity_type.rb', line 97

has_many :activity_result_types, through: :activity_chain_types

#activity_type_assignment_queuesActiveRecord::Relation<ActivityTypeAssignmentQueue>

Returns the associated activity type assignment queues.

Returns:



99
# File 'app/models/activity_type.rb', line 99

has_many :activity_type_assignment_queues, dependent: :destroy

#activity_type_rulesActiveRecord::Relation<ActivityTypeRule>

Returns the associated activity type rules.

Returns:

  • (ActiveRecord::Relation<ActivityTypeRule>)

    the associated activity type rules



103
# File 'app/models/activity_type.rb', line 103

has_many :activity_type_rules, dependent: :destroy

#assignment_queuesActiveRecord::Relation<AssignmentQueue>

Returns the associated assignment queues.

Returns:

  • (ActiveRecord::Relation<AssignmentQueue>)

    the associated assignment queues



101
# File 'app/models/activity_type.rb', line 101

has_many :assignment_queues, through: :activity_type_assignment_queues

#auto_close_result_chainObject

Auto close result chain.



408
409
410
# File 'app/models/activity_type.rb', line 408

def auto_close_result_chain
  activity_chain_types.find { |act| !act.not_set? }
end

#campaignCampaign?

Returns the campaign this record belongs to.

Returns:

  • (Campaign, nil)

    the campaign this record belongs to



91
# File 'app/models/activity_type.rb', line 91

belongs_to :campaign, optional: true

#cancel_invalid_activities(options = {}) ⇒ String

Over time activity type rules can change.
in particular the customer state restriction
Whenever this is called all activities open with a customer state restriction
now met will be cancelled

Parameters:

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

    processing options

Options Hash (options):

  • logger (Logger, nil)

    logger to use instead of the default

  • batch_size (Integer, nil)

    limit the number of customers examined

Returns:

  • (String)

    summary message of the run



332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
# File 'app/models/activity_type.rb', line 332

def cancel_invalid_activities(options = {})
  return unless customer_filter

  logr = options[:logger] || logger
  logr.info "ActivityType#cancel_invalid_activities for Activity Type id (#{id}/#{task_type}), looking for activities scheduled on customer not matching filter #{customer_filter}"
  counts = { cancelled: 0, skipped: 0 }
  error_msg = []
  protect_lead_activities = has_tag?(NewLead::ActivityAgendaReconciler::LEAD_ACTIVITY_TAG)
  invalid_activities(options).find_each do |activity|
    logr.info "Invalidating activity id #{activity.id}"
    protection = NewLead::ProtectLastOpenLeadActivity.call(activity:, activity_type: self) if protect_lead_activities
    if protection&.skip_cancellation?
      counts[:skipped] += 1
    elsif protection&.cancelled? || (!protection && invalidate_activity(activity, options))
      counts[:cancelled] += 1
    else
      err_msg = "Activity id #{activity.id} #{activity.errors_to_s}"
      logr.error err_msg
      error_msg << err_msg
    end
  end
  msg = "Cancelled invalid activities completed, cancelled: #{counts[:cancelled]} activities, skipped: #{counts[:skipped]} activities"
  logr.info msg
  msg += ", errors: \n#{error_msg.join(",\n")}" if error_msg.present?
  msg
end

#customer_filterCustomerFilter?

Returns the customer filter this record belongs to.

Returns:

  • (CustomerFilter, nil)

    the customer filter this record belongs to



89
# File 'app/models/activity_type.rb', line 89

belongs_to :customer_filter, optional: true

#deep_dupObject

Returns a deep-copied, unsaved duplicate of the record.

Returns:

  • (Object)

    a deep-copied, unsaved duplicate of the record



68
69
70
71
72
# File 'app/models/activity_type.rb', line 68

def deep_dup
  deep_clone(include: %i[activity_chain_types activity_type_assignment_queues]) do |original, copy|
    copy.task_type = "#{original.task_type}_COPY" if copy.is_a?(ActivityType)
  end
end

#default_assigneeEmployee?

Returns the default assignee this record belongs to.

Returns:

  • (Employee, nil)

    the default assignee this record belongs to



83
# File 'app/models/activity_type.rb', line 83

belongs_to :default_assignee, class_name: 'Employee', optional: true

#determine_assigned_resource(party, cur_user_id = nil, target_date = nil, resource = nil, options = {}) ⇒ Employee?

Determines the employee resource to assign for the given party.

Parameters:

  • party (Party)

    the customer, contact, or supplier

  • cur_user_id (Integer, nil) (defaults to: nil)

    the current user id

  • target_date (Date, Time, nil) (defaults to: nil)

    the intended target date for the activity

  • resource (Object, nil) (defaults to: nil)

    the activity resource

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

    assignment options, passed through to the assignment queue

Options Hash (options):

  • ignore_target_date (Boolean)

    skip the rep availability check for the target date

Returns:

  • (Employee, nil)

    the determined resource



251
252
253
254
255
256
# File 'app/models/activity_type.rb', line 251

def determine_assigned_resource(party, cur_user_id = nil, target_date = nil, resource = nil, options = {})
  rep = nil
  rep_id = determine_assigned_resource_id(party, cur_user_id, target_date, resource, options)
  rep = Employee.find(rep_id) if rep_id
  rep
end

#determine_assigned_resource_id(party, cur_user_id = nil, target_date = nil, resource = nil, options = {}) ⇒ Integer?

For a given customer (which is handled by a specific wy company) this method will determine
the resource to assign to the activity
party : the customer object, contact, or supplier
cur_user_id : the current user
target_date : the intended target date for the activity, this is used to determine the individual resource when a
group type assignment is desired and we need to determine the least busy agent.

Parameters:

  • party (Party)

    the customer, contact, or supplier

  • cur_user_id (Integer, nil) (defaults to: nil)

    the current user id

  • target_date (Date, Time, nil) (defaults to: nil)

    the intended target date for the activity

  • resource (Object, nil) (defaults to: nil)

    the activity resource

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

    assignment options, passed through to the assignment queue

Options Hash (options):

  • ignore_target_date (Boolean)

    skip the rep availability check for the target date

Returns:

  • (Integer, nil)

    the id of the determined resource



285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
# File 'app/models/activity_type.rb', line 285

def determine_assigned_resource_id(party, cur_user_id = nil, target_date = nil, resource = nil, options = {})
  assigned_resource_id = nil
  company_id = party&.determine_company_id || Company::USA
  customer = party&.customer

  begin
    if (ataq = activity_type_assignment_queues.find { |ataq| ataq.company_id == company_id })
      assigned_resource_id = ataq.get_first_resource(customer, cur_user_id, target_date, priority, nil, resource, options)
    end
  rescue AssignmentQueue::UnassignableActivity
    logger.error "Could not determine an assignable rep for activity type #{id} on party_id #{party.id}"
  end
  assigned_resource_id ||= cur_user_id
  assigned_resource_id
end

#email_templateEmailTemplate?

Returns the email template this record belongs to.

Returns:

  • (EmailTemplate, nil)

    the email template this record belongs to



87
# File 'app/models/activity_type.rb', line 87

belongs_to :email_template, optional: true

#email_template_descriptionObject

Email template description.



413
414
415
416
417
418
419
420
# File 'app/models/activity_type.rb', line 413

def email_template_description
  s = []
  s << email_template.description
  s << "[#{email_template.category}]" if email_template.category.present?
  s << "+#{email_defer_days}d" if email_defer_days.present?
  s << "@#{email_defer_tod.strftime('%I:%M %p')}" if email_defer_tod.present?
  s.join(' ')
end

#email_transmit_at_timeObject

Calculates the date/time when the creation email for this activity
should be transmitted. It will transmit immediately by default. If the
activity type has configured email deferral rules, it will apply those
by adding a number of days or setting the time of day to transmit.



426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
# File 'app/models/activity_type.rb', line 426

def email_transmit_at_time
  # Determine here if we send immediately or schedule the email
  return unless email_defer_days&.positive? || email_defer_tod.present?

  transmit_at = Time.current
  if email_defer_days&.positive?
    # Add this number of days to the current time
    transmit_at += email_defer_days.days
  end
  if email_defer_tod
    # If email has a deferal rule for a specific time of the day
    transmit_at = email_defer_tod.on(transmit_at)
    # But if the time of day has passed already we advance to the next day
    transmit_at += 1.day if transmit_at < Time.current
  end
  transmit_at
end

#invalid_activities(options = {}) ⇒ ActiveRecord::Relation

Returns open activities whose customer no longer matches the customer filter.

Parameters:

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

    processing options

Options Hash (options):

  • batch_size (Integer, nil)

    limit the number of customers examined

Returns:

  • (ActiveRecord::Relation)

    the invalid activities



380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
# File 'app/models/activity_type.rb', line 380

def invalid_activities(options = {})
  res = Activity.none
  return res unless customer_filter

  logger.info "ActivityType#cancel_invalid_activities : Hunting for customers with a filter that does not match #{customer_filter}"
  invalid_customer_ids = []
  customers = Customer.joins(:linked_activities).merge(activities.open_activities)
  customers = customers.limit(options[:batch_size]) if options[:batch_size].present?
  customers.find_each do |customer|
    invalid_customer_ids << customer.id unless valid_for_party?(customer)
  end
  invalid_customer_ids = invalid_customer_ids.compact.uniq
  res = activities.open_activities.where(customer_id: invalid_customer_ids).select('activities.*') if invalid_customer_ids.present?
  res
end

#invalidate_activity(a, _options = {}) ⇒ Object

Invalidate activity.

Parameters:

  • a (Object)

    the a

  • _options (Object) (defaults to: {})

    the options



362
363
364
365
366
367
368
369
370
371
372
373
# File 'app/models/activity_type.rb', line 362

def invalidate_activity(a, _options = {})
  a.new_note = 'Cancelled after customer state change no longer meets criteria established for this activity type.'
  a.activity_result_type_id = ActivityResultTypeConstants::CANCEL
  a.completion_datetime = Time.current
  res = a.save
  if res
    logger.info(" * cancelled activity id #{a.id}")
  else
    logger.error(" * could not cancel activity id #{a.id}")
  end
  res
end

#is_a_quote_follow_up?Boolean

Returns whether the record is a quote follow up.

Returns:

  • (Boolean)

    whether the record is a quote follow up



233
234
235
# File 'app/models/activity_type.rb', line 233

def is_a_quote_follow_up?
  ActivityTypeConstants::QUOFUS_IDS.include?(id)
end

#is_email?Boolean

Returns whether the record is email.

Returns:

  • (Boolean)

    whether the record is email



238
239
240
# File 'app/models/activity_type.rb', line 238

def is_email?
  task_type.match?(/^EMAIL/)
end

#nameString

Returns the name of the record.

Returns:

  • (String)

    the name of the record



314
315
316
# File 'app/models/activity_type.rb', line 314

def name
  "#{task_type} - #{description}"
end

#priority_friendly_nameObject

Priority friendly name.



319
320
321
# File 'app/models/activity_type.rb', line 319

def priority_friendly_name
  self.class.priority_friendly_name(priority)
end

#priority_tier?Boolean

Returns whether the record priority tier.

Returns:

  • (Boolean)

    whether the record priority tier



228
229
230
# File 'app/models/activity_type.rb', line 228

def priority_tier?
  priority && priority <= PRIORITY_MAX
end

#result_options_for_selectArray<Array>

Returns [label, id] pairs for select dropdowns.

Returns:

  • (Array<Array>)

    [label, id] pairs for select dropdowns



259
260
261
262
263
264
265
266
267
268
269
# File 'app/models/activity_type.rb', line 259

def result_options_for_select
  # Use includes instead of joins to preload activity_result_type and avoid N+1
  chains = activity_chain_types.includes(:activity_result_type, :email_template)
  chains.map do |c|
    # "CODE - description [Email: …]" — the option-buttons Stimulus controller
    # shows the code as the button label and the full text as its tooltip.
    display = [c.activity_result_type.result_code, c.activity_result_type.description].select(&:present?).join(' - ')
    display += " [Email: #{c.email_template.description}]" if c.email_template
    [display, c.activity_result_type_id]
  end.uniq
end

#rolesActiveRecord::Relation<Role>

Returns the associated roles.

Returns:

  • (ActiveRecord::Relation<Role>)

    the associated roles



106
# File 'app/models/activity_type.rb', line 106

has_and_belongs_to_many :roles

#sales_activityObject

Sales activity.



218
219
220
# File 'app/models/activity_type.rb', line 218

def sales_activity
  has_tag?('sale')
end

#sender_partyEmployee?

Returns the sender party this record belongs to.

Returns:

  • (Employee, nil)

    the sender party this record belongs to



85
# File 'app/models/activity_type.rb', line 85

belongs_to :sender_party, class_name: 'Employee', optional: true

#to_sString

Returns string representation of the record.

Returns:

  • (String)

    string representation of the record



213
214
215
# File 'app/models/activity_type.rb', line 213

def to_s
  "#{task_type} [#{id}]"
end

#valid_for_party?(party) ⇒ Boolean

Returns whether the record valid for party.

Parameters:

  • party (Object)

    the party

Returns:

  • (Boolean)

    whether the record valid for party



398
399
400
401
402
403
404
405
# File 'app/models/activity_type.rb', line 398

def valid_for_party?(party)
  return true unless party
  return true unless customer_filter
  return true unless (customer = party.try(:customer))
  return true unless customer.is_a?(Customer) # Now we have suppliers

  customer_filter.applies_to_customer?(customer)
end