Class: SupportCaseParticipant

Inherits:
ApplicationRecord show all
Includes:
Models::Auditable, Models::LiquidMethods
Defined in:
app/models/support_case_participant.rb

Overview

== Schema Information

Table name: support_case_participants
Database name: primary

id :integer not null, primary key
note :string(255)
notify :boolean
preferred_language :string
role :string(255)
created_at :datetime not null
updated_at :datetime not null
email_id :integer
fax_id :integer
party_id :integer
phone_id :integer
support_case_id :integer

Indexes

by_pid_scid (party_id,support_case_id)
idx_support_case_participants_unique_party (support_case_id,party_id) UNIQUE
support_case_participants_email_id_idx (email_id)
support_case_participants_fax_id_idx (fax_id)
support_case_participants_phone_id_idx (phone_id)

Foreign Keys

fk_rails_... (email_id => contact_points.id)
fk_rails_... (fax_id => contact_points.id)
fk_rails_... (party_id => parties.id) ON DELETE => cascade
fk_rails_... (phone_id => contact_points.id)
fk_rails_... (support_case_id => support_cases.id) ON DELETE => cascade

Constant Summary collapse

ROLES =
{
  'unknown' => ProfileConstants::HOMEOWNER,
  'electrician' => ProfileConstants::ELECTRICIAN,
  'installer' => ProfileConstants::INSTALLER,
  'iso' => ProfileConstants::UNKNOWN_TRADE,
  'store' => ProfileConstants::DEALER,
  'homeowner' => ProfileConstants::HOMEOWNER,
  'other trade' => ProfileConstants::UNKNOWN_TRADE
}.freeze

Constants included from Models::Auditable

Models::Auditable::ALWAYS_IGNORED

Instance Attribute Summary collapse

Belongs to collapse

Methods included from Models::Auditable

#creator, #updater

Has many collapse

Class Method Summary collapse

Instance Method Summary collapse

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, ransackable_scopes, ransortable_attributes, #to_relation

Methods included from Models::EventPublishable

#publish_event

Instance Attribute Details

#contact_nameObject

Returns the value of attribute contact_name.

Validations (if => -> { self&.party&.new_record? } ):



50
51
52
# File 'app/models/support_case_participant.rb', line 50

def contact_name
  @contact_name
end

#noteObject (readonly)



66
# File 'app/models/support_case_participant.rb', line 66

validates :note, length: { maximum: 255 }, allow_blank: true

#party_nameObject

Returns the value of attribute party_name.



50
51
52
# File 'app/models/support_case_participant.rb', line 50

def party_name
  @party_name
end

#roleObject (readonly)

validate :name_present

Validations:



65
# File 'app/models/support_case_participant.rb', line 65

validates :party, :support_case, :role, presence: true

Class Method Details

.find_participants(support_case, params = {}) ⇒ Object



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'app/models/support_case_participant.rb', line 84

def self.find_participants(support_case, params = {})
  results_array = []
  results = []
  matched_detail = nil
  raw_search_term = nil
  per_page = params[:per_page].to_i.nonzero? || 10
  page = params[:page].to_i.nonzero? || 1
  if search_term = params[:q].presence&.strip
    raw_search_term = search_term
    if cn_term = search_term.scan(Customer::REFERENCE_NUMBER_PATTERN).join.upcase.presence
      results += Customer.where(id: cn_term).to_a
      matched_detail = "CN#{cn_term}"
    elsif !search_term.match?(/[a-zA-Z]/) && (phone = PhoneNumber.parse(search_term))
      results = Party.customer_or_contact.joins(:contact_points).merge(ContactPoint.dialable.where(detail: phone.to_s)).limit(per_page).offset((page - 1) * per_page).to_a
      matched_detail = phone.format(:crm)
    elsif search_term.match?(/\A[^@\s]+@[^@\s]+\z/)
      email = search_term.downcase
      results = Party.customer_or_contact.joins(:contact_points).merge(ContactPoint.emails.contains(email)).limit(per_page).offset((page - 1) * per_page).to_a
      matched_detail = email
    else # wild card lookup
      results += Party.customer_or_contact.lookup(search_term).limit(per_page).offset((page - 1) * per_page).to_a
    end
    # If we don't have a search term but we have a party_id we can load up suggested participants
  end
  if results.blank?
    matched_detail = nil
    raw_search_term = nil
    if support_case
      results = support_case.suggested_participants
    elsif (party_id = params[:participant_id]).present?
      # Basically all contacts of the customer of that party
      party = Party.customer_or_contact.find(party_id)
      if party.customer
        results = party.customer.contacts.active.order(:full_name)
        results = results.where.not(id: params[:existing_participant_ids]) if params[:existing_participant_ids].present?
        results = results.to_a
      end
    end
  end

  if results.present?
    results_array += results.uniq.map do |party|
      entry = { text: party.to_s, id: party.id }
      if matched_detail
        entry[:text] = "#{party}#{matched_detail}"
        entry[:match] = raw_search_term
      end
      entry
    end
  end
  results_array = results_array.sort_by { |r| r[:text] }

  total_entries = results.size
  { results: results_array, total: total_entries }
end

.migrate_cpObject

TEMP METHOD



245
246
247
248
249
250
251
252
253
254
# File 'app/models/support_case_participant.rb', line 245

def self.migrate_cp
  support_case_participants = SupportCaseParticipant.all.select('parties.id, party_id, phone_id, email_id, fax_id').eager_load(:party)
  support_case_participants.find_each do |scp|
    sc_cp_ids = [scp.phone_id, scp.email_id, scp.fax_id].compact.uniq
    if sc_cp_ids.present? && scp.party_id
      puts "Updating contact points #{sc_cp_ids.join(', ')} with party_id: #{scp.party_id}"
      ContactPoint.where(id: sc_cp_ids).where(party_id: nil).update_all(party_id: scp.party_id)
    end
  end
end

.rolesObject



214
215
216
# File 'app/models/support_case_participant.rb', line 214

def self.roles
  ROLES.keys
end

.with_partyActiveRecord::Relation<SupportCaseParticipant>

A relation of SupportCaseParticipants that are with party. Active Record Scope

Returns:

See Also:



60
# File 'app/models/support_case_participant.rb', line 60

scope :with_party, -> { joins(:party).eager_load(:party) }

Instance Method Details

#contact_pointsActiveRecord::Relation<ContactPoint>

Returns:

See Also:



58
# File 'app/models/support_case_participant.rb', line 58

has_many :contact_points, through: :party

#default_catalog_idObject

Best guess at what catalog this support case belongs to so we can determine the catalog id to use by default
on new participants



198
199
200
201
202
203
# File 'app/models/support_case_participant.rb', line 198

def default_catalog_id
  if pp = support_case&.primary_party && pp.respond_to?(:customer)
    cat_id = pp.customer&.catalog_id || CatalogConstants::US_CATALOG_ID
  end
  cat_id ||= CatalogConstants::US_CATALOG_ID
end

#default_source_idObject



205
206
207
208
209
210
211
212
# File 'app/models/support_case_participant.rb', line 205

def default_source_id
  case support_case&.case_type
  when 'Tech'
    1053
  when 'Ecommerce'
    853
  end
end

#emailContactPoint



54
# File 'app/models/support_case_participant.rb', line 54

belongs_to :email, class_name: 'ContactPoint', inverse_of: :email_support_case_participants, optional: true

#email_idObject



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

def email_id
  contact_points.emails.first&.id
end

#faxContactPoint



56
# File 'app/models/support_case_participant.rb', line 56

belongs_to :fax, class_name: 'ContactPoint', inverse_of: :fax_support_case_participants, optional: true

#name_presentObject



140
141
142
143
144
145
146
# File 'app/models/support_case_participant.rb', line 140

def name_present
  return if persisted? # Only check for new participants
  return if party_name.presence || contact_name.presence

  errors.add(:base, "Participant name can't be blank")
  nil
end

#new_ticket_system_codeObject



226
227
228
229
230
231
232
233
234
235
# File 'app/models/support_case_participant.rb', line 226

def new_ticket_system_code
  case support_case.case_type
  when 'Accounting'
    'ACCT_TCKT_NEW'
  when 'Ecommerce'
    'ECOM_TCKT_NEW'
  else
    'TICKET_NEW'
  end
end

#partyParty

Returns:

See Also:

Validations:



52
# File 'app/models/support_case_participant.rb', line 52

belongs_to :party, inverse_of: :support_case_participants, optional: true

#phoneContactPoint



55
# File 'app/models/support_case_participant.rb', line 55

belongs_to :phone, class_name: 'ContactPoint', inverse_of: :phone_support_case_participants, optional: true

#save_partyObject



191
192
193
194
# File 'app/models/support_case_participant.rb', line 191

def save_party
  party&.save
  true
end

#send_notification_emailObject



222
223
224
# File 'app/models/support_case_participant.rb', line 222

def send_notification_email
  CommunicationBuilder.new(resource: self, template_system_code: new_ticket_system_code, recipient_party: party, recipient_contact_point_id: email_id).create
end

#set_partyObject



148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
# File 'app/models/support_case_participant.rb', line 148

def set_party
  # Store contact points from form
  contact_points = party.contact_points.to_a if party&.new_record?
  contact_points ||= []

  customer_name = party_name.presence || contact_name.presence
  return if customer_name.blank? || role.blank? || party_id.present?

  c = Customer.new(catalog_id: default_catalog_id,
                   profile_id: ROLES[role],
                   source_id: default_source_id)
  if c.is_homeowner?
    pnp = PersonNameParser.new(customer_name)
    pnp.to_party(c)
  else
    c.full_name = customer_name
  end
  con = nil
  if c.valid?
    if contact_name.present? && contact_name != customer_name
      pnp = PersonNameParser.new(contact_name)
      con = Contact.new(customer: c)
      pnp.to_party(con)
      if con.valid?
        # Contact is the party
        self.party = con
      else
        errors.add(:contact_name, con.errors.full_messages)
      end
    else
      # Customer is the party
      self.party = c
    end
  else
    errors.add(:party_name, c.errors.full_messages)
  end

  # Carry over previously set contact points over to this new party
  return unless contact_points.present?

  contact_points.each { |cp| party.contact_points << cp unless party.contact_points.detect { |ecp| ecp == cp } }
end

#support_caseSupportCase Also known as: communication_resource

Validations:



53
# File 'app/models/support_case_participant.rb', line 53

belongs_to :support_case, inverse_of: :support_case_participants, optional: true

#to_sObject



237
238
239
240
241
242
# File 'app/models/support_case_participant.rb', line 237

def to_s
  n = []
  n << party&.customer&.full_name
  n << party&.full_name
  n.compact.join(' - ')
end