Class: Contact
- Inherits:
-
Party
- Object
- ActiveRecord::Base
- ApplicationRecord
- Party
- Contact
- Includes:
- ContactDeactivationAndDefaults, ContactDisplay, ContactQueries, Memery
- Defined in:
- app/models/contact.rb
Overview
== Schema Information
Table name: parties
Database name: primary
id :integer not null, primary key
activities_count :integer default(0)
affiliations :text default([]), is an Array
annual_revenue :integer
authorization_code_required :boolean
available_credit :decimal(14, 2) default(0.0)
banner :text
best_time_to_call :string(255)
bill_shipping_to_customer :boolean
calculate_profiling :boolean default(FALSE), not null
can_pay_by_cod_business_check :boolean
consent_preferences :jsonb
contact_roles :string(255) is an Array
creation_method :integer default("crm"), not null
credit_limit :decimal(8, 2) default(0.0)
credit_score :integer
credit_score_date :datetime
currency :string(255)
default_payment_method :string
do_not_auto_assign :boolean default(FALSE), not null
dob :date
early_payment_discount :integer
early_payment_timescale :integer
estimated_landed_cost_ptg :float
force_logout :boolean default(FALSE), not null
full_name :string(255)
full_name_tsv :tsvector
gclid :string
gender :string(1)
inactive :boolean default(FALSE), not null
job_title :string(255)
lead_time :integer
lead_time_override :integer
lead_verification_score :integer
lead_verified_at :datetime
merged_from_ids :integer is an Array
name1 :string(255)
name2 :string(255)
name3 :string(255)
number_of_employees :integer
number_of_offices :string
on_hold :boolean default(FALSE), not null
on_hold_reason :text
open_sales_activity :boolean default(FALSE), not null
ordering_instructions :text
preferred_language :string
preferred_shipping_method :string(255)
prefix :string(10)
profile_info :text
projects_per_year :string
purchase_order_required :boolean default(FALSE), not null
qc_orders :boolean default(TRUE), not null
rating :string(255)
report_grouping :string(255)
requires_rma_reference :boolean
sales_priority_index :integer default(0)
send_statement :boolean default(FALSE), not null
send_statement_reason :string(255)
shipment_instructions :text
source_info :text
spiff_enrolled :boolean
state :string(255)
state_code :string(255)
suffix :string(10)
terms :string(255)
timezone_name :string
type :string(255)
uploads_count :integer default(0)
uuid :uuid not null
verbal_po :boolean default(FALSE), not null
watch :integer
created_at :datetime
updated_at :datetime
active_spiff_enrollment_id :integer
billing_address_id :integer
bot_id :string
business_unit_id :integer
buying_group_id :integer
catalog_id :integer
company_id :integer
creator_id :integer
customer_id :integer
gl_offset_account_id :integer
ledger_detail_project_id :integer
legacy_tier2_program_pricing_id :integer
local_sales_rep_id :integer
mailing_address_id :integer
original_source_id :integer
parent_id :integer
paypal_vault_customer_id :string
paypal_vault_token_id :string
primary_sales_rep_id :integer
profile_id :integer
profile_image_id :integer
secondary_sales_rep_id :integer
service_rep_id :integer
shipping_address_id :integer
source_id :integer
spiff_address_id :integer
spiff_payable_id :integer
stripe_customer_id :string
tier2_program_pricing_id :integer
updater_id :integer
visit_id :bigint
Indexes
idx_parties_full_name_trg (full_name) USING gin
idx_party_main_address (COALESCE(shipping_address_id, billing_address_id, mailing_address_id))
idx_state_type (state,type)
idx_type_billing_address_id (type,billing_address_id)
idx_type_creation_method_state (type,creation_method,state)
idx_type_customer_id (type,customer_id)
idx_type_id_credit_limit (type,id,credit_limit)
idx_type_inactive (type,inactive)
idx_type_primary_sales_rep_id_watch (type,primary_sales_rep_id,watch)
index_parties_on_affiliations (affiliations) USING gin
index_parties_on_billing_address_id (billing_address_id)
index_parties_on_bot_id (bot_id) WHERE (bot_id IS NOT NULL)
index_parties_on_catalog_id (catalog_id)
index_parties_on_company_id (company_id)
index_parties_on_full_name_tsv (full_name_tsv) USING gin
index_parties_on_gclid (gclid) WHERE (gclid IS NOT NULL)
index_parties_on_local_sales_rep_id (local_sales_rep_id)
index_parties_on_mailing_address_id (mailing_address_id)
index_parties_on_merged_from_ids (merged_from_ids) USING gin
index_parties_on_open_sales_activity (open_sales_activity)
index_parties_on_parent_id (parent_id)
index_parties_on_primary_sales_rep_id (primary_sales_rep_id)
index_parties_on_profile_image_id (profile_image_id) USING hash
index_parties_on_report_grouping (report_grouping)
index_parties_on_secondary_sales_rep_id (secondary_sales_rep_id)
index_parties_on_service_rep_id (service_rep_id)
index_parties_on_source_id (source_id)
index_parties_on_tier2_program_pricing_id (tier2_program_pricing_id)
index_parties_on_uuid (uuid) UNIQUE
index_parties_on_visit_id (visit_id) WHERE (visit_id IS NOT NULL) USING hash
index_parties_on_watch (watch)
parties_buying_group_id_idx (buying_group_id)
parties_customer_id_index (customer_id)
parties_profile_id_idx (profile_id)
parties_shipping_address_id_idx (shipping_address_id)
parties_spiff_address_id_idx (spiff_address_id)
parties_spiff_payable_id_idx (spiff_payable_id)
Foreign Keys
fk_rails_... (profile_image_id => digital_assets.id) ON DELETE => nullify
fk_rails_... (source_id => sources.id)
fk_rails_... (visit_id => visits.id) ON DELETE => nullify
parties_billing_address_id_fk (billing_address_id => addresses.id) ON DELETE => nullify
parties_buying_group_id_fk (buying_group_id => buying_groups.id)
parties_catalog_id_fk (catalog_id => catalogs.id)
parties_company_id_fk (company_id => companies.id)
parties_customer_id_fk (customer_id => parties.id) ON DELETE => cascade
parties_mailing_address_id_fk (mailing_address_id => addresses.id) ON DELETE => nullify
parties_parent_id_fk (parent_id => parties.id) ON DELETE => nullify
parties_primary_sales_rep_id_fk (primary_sales_rep_id => parties.id) ON DELETE => nullify
parties_profile_id_fk (profile_id => profiles.id)
parties_secondary_sales_rep_id_fk (secondary_sales_rep_id => parties.id) ON DELETE => nullify
parties_shipping_address_id_fk (shipping_address_id => addresses.id) ON DELETE => nullify
parties_source_id_fk (source_id => sources.id)
parties_spiff_address_id_fk (spiff_address_id => addresses.id) ON DELETE => nullify
parties_spiff_payable_id_fk (spiff_payable_id => parties.id) ON DELETE => nullify
parties_tier2_program_pricing_id_fk (tier2_program_pricing_id => coupons.id)
Contact person (parties.type = Contact) tied to a Customer or Supplier
through customer_id. Carries CRM communications, opportunities, certifications,
and service scheduling.
Constant Summary collapse
- NAME_CANT_BE_BLANK =
"can't be blank (need at least one non-blank name)".freeze
- CONTACT_ROLES =
%w[accounting administrative decision_maker designer engineer executive human_resources information_technology installer legal logistics manager manufacturing marketing menard_associate_merchant menard_merchant menard_product_specialist sales].freeze
Constants inherited from Party
Constants included from Models::Auditable
Models::Auditable::ALWAYS_IGNORED
Instance Attribute Summary collapse
- #full_name ⇒ Object readonly
- #prefix ⇒ Object readonly
- #suffix ⇒ Object readonly
Attributes inherited from Party
Belongs to collapse
- #active_spiff_enrollment ⇒ SpiffEnrollment
-
#customer ⇒ Customer
inverse_of omitted: Party#contacts cannot name both :customer and :supplier (same FK).
- #manager ⇒ Contact
-
#original_source ⇒ Source
rubocop:enable Rails/InverseOf.
- #source ⇒ Source
- #spiff ⇒ Spiff
- #spiff_address ⇒ Address
- #supplier ⇒ Supplier
Methods inherited from Party
#catalog, #company, #gl_offset_account, #profile_image, #visit
Methods included from Models::Auditable
Has many collapse
- #accounts_payable_credit_applications ⇒ ActiveRecord::Relation<CreditApplication>
- #certifications ⇒ ActiveRecord::Relation<Certification>
- #contact_training_topics ⇒ ActiveRecord::Relation<ContactTrainingTopic>
- #course_enrollments ⇒ ActiveRecord::Relation<CourseEnrollment>
- #managed_employees ⇒ ActiveRecord::Relation<Contact>
- #opportunities ⇒ ActiveRecord::Relation<Opportunity>
- #orders ⇒ ActiveRecord::Relation<Order>
- #owner_credit_applications ⇒ ActiveRecord::Relation<CreditApplication>
- #preset_jobs ⇒ ActiveRecord::Relation<PresetJob>
- #primary_contact_credit_applications ⇒ ActiveRecord::Relation<CreditApplication>
- #purchasing_agent_credit_applications ⇒ ActiveRecord::Relation<CreditApplication>
- #quotes ⇒ ActiveRecord::Relation<Quote>
- #room_configurations ⇒ ActiveRecord::Relation<RoomConfiguration>
- #service_jobs ⇒ ActiveRecord::Relation<ServiceJob>
- #spiff_enrollments ⇒ ActiveRecord::Relation<SpiffEnrollment>
- #spiff_orders ⇒ ActiveRecord::Relation<Order>
Methods inherited from Party
#accounts, #activities, #addresses, #agreement_participants, #agreements, #assistant_conversations, #billing_credit_memos, #consignment_stores, #contact_points, #contacts, #credit_memos, #destination_call_logs, #destination_call_records, #inbound_communications, #notifications, #opportunity_participants, #origin_call_logs, #origin_call_records, #outbound_communications, #outgoing_payments, #party_topics, #purchase_orders, #queue_call_logs, #receipts, #recipient_sms_messages, #room_plans, #sender_sms_messages, #support_case_participants, #support_cases, #survey_enrollments, #uploads, #visit_events, #visits, #voucher_items, #vouchers
Delegated Instance Attributes collapse
-
#billing_address ⇒ Object
Alias for Customer#billing_address.
-
#is_homeowner? ⇒ Object
Alias for Customer#is_homeowner?.
-
#is_organization? ⇒ Object
Alias for Customer#is_organization?.
-
#primary_sales_rep ⇒ Object
Alias for Customer#primary_sales_rep.
-
#sales_rep ⇒ Object
Alias for Customer#sales_rep.
-
#store ⇒ Object
Alias for Customer#store.
Methods inherited from Party
#can?, #cannot?, #has_role?, #is_admin?, #is_document_maintainer?, #is_local_sales_rep?, #is_manager?, #is_marketing_manager?, #is_sales_manager?, #is_sales_rep?, #locale, #main_address
Class Method Summary collapse
-
.contact_roles_for_select ⇒ Array<Array(String, String)>
Options for role pickers (human label + machine value).
-
.verbal_po_contacts ⇒ ActiveRecord::Relation<Contact>
A relation of Contacts that are verbal po contacts.
Instance Method Summary collapse
-
#assign_chained_activities? ⇒ Boolean
Whether chained activities should follow this contact (active contacts only).
-
#contact_role?(roles) ⇒ Boolean
Whether this contact matches the given CRM role(s), or the check is unrestricted.
-
#resources_for_select(options = {}) ⇒ Object
Activity resources available for this contact’s customer (or self when no customer).
-
#set_owner(party) ⇒ void
rubocop:disable Naming/AccessorMethodName -- public API; assigns customer or supplier from a Party Associates this contact with the given customer or supplier (same
customer_idFK).
Methods included from ContactQueries
#all_contact_points, #all_email_contact_points, #all_emails, #all_opportunities, #all_orders, #all_related_communications, #dependents
Methods included from ContactDisplay
#all_addresses, #build_default_contact_points, #colleagues, #country, #first_address, #guest?, #last_invoice_shipping_cost, #locale, #main_address, #open_activities_counter, #options_for_reports_to, #reference_number, #shipping_amount_last_30_days, #shipping_amount_last_month, #state, #supplier_contact?, #timezone, #to_label, #to_s
Methods included from ContactDeactivationAndDefaults
#deactivate, #ok_to_delete?, #open_support_case_participant?, #reactivate, #set_default_for_opportunity, #set_default_for_order, #support_case_participant?
Methods inherited from Party
#account, #digital_assets, #linked_activities, #product_lines, #set_full_name, #set_state_code, #set_timezone
Methods included from CrmLinkable
#crm_link, #crm_link_with_host
Methods included from PartyAccount
#ability, #build_account, #create_account, #online_account_invite, #refuse_silent_account_replacement!, search_for_authenticable_linked_party_by_email
Methods included from PartyCart
#all_uploads, #cart, #cart=, #cart?, #cart_id, #cart_info, #create_activity, #create_quote_builder_project, #load_cart, #store_original_source
Methods included from PartyIdentity
#active?, #admin?, #aka, #aka=, #all_activities, #blog_admin?, #broadcast_product_interest_changed, #can_be_certified?, #can_list_all_contact_resources?, #clear_individual_names, #clear_names, #contact?, #customer?, #determine_company_id, #direct_commercial?, #direct_pro?, #employee?, #first_name, #first_name=, #guest_individual_name?, #guest_name?, #homeowner?, #id_and_name, #last_name, #last_name=, #manager?, #middle_name, #middle_name=, #name, #name=, #organization?, #person?, #primary_party, #public_facing_full_name, #public_facing_full_name=, #show_name_four, #to_s, #update_product_interests
Methods included from PartyAddresses
#addresses_options_for_select, #can_change_country?, #catalog_country, #catalog_country_iso, #catalog_country_iso3, #city, #country, #country_iso, #country_iso3, #first_address, #flag, #location_name, #most_recent_visit, #new_address, #street1, #street2, #street3, #timezone, #unique_addresses, #visit_data, #visit_location, #zip
Methods included from PartyContactInfo
#all_support_cases, #call_records?, #cell_phone, #cell_phone=, #cell_phone_formatted, #contact_point_options_for_select, #contactable?, #email, #email=, #email_options_for_select, #email_with_name, #emails, #fax, #fax=, #fax_formatted, #fax_options_for_select, #first_callable_contact_point, #first_contact_point_by_category, #phone, #phone=, #phone_formatted, #phone_options_for_select, #set_email_from_account, #set_primary_contact_point, #sms_enabled_numbers, #sms_messages, #tracking_email_address, #tracking_email_prefix, #website, #website=, #website_options_for_select
Methods included from PartySearch
active, address_search, customer_or_contact, email_search, inactive, lookup, phone_search, ransackable_scopes, searchable, with_main_address
Methods included from Models::Notable
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
Instance Attribute Details
#full_name ⇒ Object (readonly)
235 |
# File 'app/models/contact.rb', line 235 validates :full_name, presence: { message: 'must be specified for this Contact. First and last name.' } |
#prefix ⇒ Object (readonly)
237 |
# File 'app/models/contact.rb', line 237 validates :prefix, length: { maximum: 10 } |
#suffix ⇒ Object (readonly)
238 |
# File 'app/models/contact.rb', line 238 validates :suffix, length: { maximum: 10 } |
Class Method Details
.contact_roles_for_select ⇒ Array<Array(String, String)>
Options for role pickers (human label + machine value).
270 271 272 |
# File 'app/models/contact.rb', line 270 def self.contact_roles_for_select CONTACT_ROLES.map { |cr| [cr.titleize, cr] } end |
.verbal_po_contacts ⇒ ActiveRecord::Relation<Contact>
A relation of Contacts that are verbal po contacts. Active Record Scope
231 |
# File 'app/models/contact.rb', line 231 scope :verbal_po_contacts, -> { where(verbal_po: true) } |
Instance Method Details
#accounts_payable_credit_applications ⇒ ActiveRecord::Relation<CreditApplication>
221 222 |
# File 'app/models/contact.rb', line 221 has_many :accounts_payable_credit_applications, class_name: 'CreditApplication', foreign_key: :accounts_payable_contact_id, inverse_of: :accounts_payable_contact, dependent: :nullify |
#active_spiff_enrollment ⇒ SpiffEnrollment
202 |
# File 'app/models/contact.rb', line 202 belongs_to :active_spiff_enrollment, class_name: 'SpiffEnrollment', optional: true |
#assign_chained_activities? ⇒ Boolean
Whether chained activities should follow this contact (active contacts only).
296 297 298 |
# File 'app/models/contact.rb', line 296 def assign_chained_activities? !inactive end |
#billing_address ⇒ Object
Alias for Customer#billing_address
247 |
# File 'app/models/contact.rb', line 247 delegate :billing_address, to: :customer, allow_nil: true |
#certifications ⇒ ActiveRecord::Relation<Certification>
225 |
# File 'app/models/contact.rb', line 225 has_many :certifications, foreign_key: 'party_id', dependent: :destroy, inverse_of: :contact |
#contact_role?(roles) ⇒ Boolean
Whether this contact matches the given CRM role(s), or the check is unrestricted.
Returns true when contact_roles is blank, when roles is empty, or when
the intersection of stored roles and roles is non-empty.
289 290 291 |
# File 'app/models/contact.rb', line 289 def contact_role?(roles) contact_roles.blank? || roles.empty? || (contact_roles || []).intersect?([roles].flatten) end |
#contact_training_topics ⇒ ActiveRecord::Relation<ContactTrainingTopic>
217 |
# File 'app/models/contact.rb', line 217 has_many :contact_training_topics, inverse_of: :contact, foreign_key: :party_id, dependent: :destroy |
#course_enrollments ⇒ ActiveRecord::Relation<CourseEnrollment>
214 |
# File 'app/models/contact.rb', line 214 has_many :course_enrollments, foreign_key: 'party_id', dependent: :destroy, inverse_of: :party |
#customer ⇒ Customer
inverse_of omitted: Party#contacts cannot name both :customer and :supplier (same FK).
rubocop:disable Rails/InverseOf
195 |
# File 'app/models/contact.rb', line 195 belongs_to :customer, class_name: 'Customer', optional: true |
#is_homeowner? ⇒ Object
Alias for Customer#is_homeowner?
233 |
# File 'app/models/contact.rb', line 233 delegate :store, :is_homeowner?, :is_organization?, :sales_rep, :primary_sales_rep, to: :customer |
#is_organization? ⇒ Object
Alias for Customer#is_organization?
233 |
# File 'app/models/contact.rb', line 233 delegate :store, :is_homeowner?, :is_organization?, :sales_rep, :primary_sales_rep, to: :customer |
#managed_employees ⇒ ActiveRecord::Relation<Contact>
206 |
# File 'app/models/contact.rb', line 206 has_many :managed_employees, class_name: 'Contact', foreign_key: 'parent_id', dependent: :nullify, inverse_of: :manager |
#manager ⇒ Contact
201 |
# File 'app/models/contact.rb', line 201 belongs_to :manager, class_name: 'Contact', foreign_key: 'parent_id', optional: true, inverse_of: :managed_employees |
#opportunities ⇒ ActiveRecord::Relation<Opportunity>
207 208 |
# File 'app/models/contact.rb', line 207 has_many :opportunities, -> { order(:created_at).reverse_order }, inverse_of: :contact, dependent: :nullify, before_add: :set_default_for_opportunity |
#orders ⇒ ActiveRecord::Relation<Order>
211 |
# File 'app/models/contact.rb', line 211 has_many :orders, -> { order(:created_at).reverse_order }, inverse_of: :contact, dependent: :nullify, before_add: :set_default_for_order |
#original_source ⇒ Source
rubocop:enable Rails/InverseOf
199 |
# File 'app/models/contact.rb', line 199 belongs_to :original_source, class_name: 'Source', optional: true |
#owner_credit_applications ⇒ ActiveRecord::Relation<CreditApplication>
220 |
# File 'app/models/contact.rb', line 220 has_many :owner_credit_applications, class_name: 'CreditApplication', foreign_key: :owner_id, inverse_of: :owner, dependent: :nullify |
#preset_jobs ⇒ ActiveRecord::Relation<PresetJob>
215 |
# File 'app/models/contact.rb', line 215 has_many :preset_jobs, -> { order(:created_at).reverse_order }, inverse_of: :contact, dependent: :nullify |
#primary_contact_credit_applications ⇒ ActiveRecord::Relation<CreditApplication>
218 219 |
# File 'app/models/contact.rb', line 218 has_many :primary_contact_credit_applications, class_name: 'CreditApplication', foreign_key: :primary_contact_id, inverse_of: :primary_contact, dependent: :nullify |
#primary_sales_rep ⇒ Object
Alias for Customer#primary_sales_rep
233 |
# File 'app/models/contact.rb', line 233 delegate :store, :is_homeowner?, :is_organization?, :sales_rep, :primary_sales_rep, to: :customer |
#purchasing_agent_credit_applications ⇒ ActiveRecord::Relation<CreditApplication>
223 224 |
# File 'app/models/contact.rb', line 223 has_many :purchasing_agent_credit_applications, class_name: 'CreditApplication', foreign_key: :purchasing_agent_id, inverse_of: :purchasing_agent, dependent: :nullify |
#quotes ⇒ ActiveRecord::Relation<Quote>
210 |
# File 'app/models/contact.rb', line 210 has_many :quotes, through: :opportunities |
#resources_for_select(options = {}) ⇒ Object
Activity resources available for this contact’s customer (or self when no customer).
278 279 280 |
# File 'app/models/contact.rb', line 278 def resources_for_select( = {}) Activity::ResourceList.new.process(customer || self, ) end |
#room_configurations ⇒ ActiveRecord::Relation<RoomConfiguration>
209 |
# File 'app/models/contact.rb', line 209 has_many :room_configurations, through: :opportunities |
#sales_rep ⇒ Object
Alias for Customer#sales_rep
233 |
# File 'app/models/contact.rb', line 233 delegate :store, :is_homeowner?, :is_organization?, :sales_rep, :primary_sales_rep, to: :customer |
#service_jobs ⇒ ActiveRecord::Relation<ServiceJob>
216 |
# File 'app/models/contact.rb', line 216 has_many :service_jobs, -> { order(created_at: :desc) }, inverse_of: :contact, dependent: :nullify |
#set_owner(party) ⇒ void
This method returns an undefined value.
rubocop:disable Naming/AccessorMethodName -- public API; assigns customer or supplier from a Party
Associates this contact with the given customer or supplier (same customer_id FK).
258 259 260 261 262 263 264 |
# File 'app/models/contact.rb', line 258 def set_owner(party) if party.is_a?(Customer) self.customer = party elsif party.is_a?(Supplier) self.supplier = party end end |
#spiff_address ⇒ Address
203 |
# File 'app/models/contact.rb', line 203 belongs_to :spiff_address, class_name: 'Address', optional: true |
#spiff_enrollments ⇒ ActiveRecord::Relation<SpiffEnrollment>
213 |
# File 'app/models/contact.rb', line 213 has_many :spiff_enrollments, dependent: :nullify, inverse_of: :contact |
#spiff_orders ⇒ ActiveRecord::Relation<Order>
212 |
# File 'app/models/contact.rb', line 212 has_many :spiff_orders, class_name: 'Order', foreign_key: 'spiff_rep_id', dependent: :nullify, inverse_of: :spiff_rep |
#store ⇒ Object
Alias for Customer#store
233 |
# File 'app/models/contact.rb', line 233 delegate :store, :is_homeowner?, :is_organization?, :sales_rep, :primary_sales_rep, to: :customer |
#supplier ⇒ Supplier
196 |
# File 'app/models/contact.rb', line 196 belongs_to :supplier, class_name: 'Supplier', foreign_key: 'customer_id', optional: true |