Class: Customer

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)
B2B customer account (parties.type = Customer): catalog, credit, sales reps,
orders, opportunities, child contacts, and ERP financial flags.

Behaviour is composed through Customer* concerns so this class keeps associations,
enums, scopes, and glue only.

Defined Under Namespace

Classes: CustomerAnniversaryMessage, FillSalesActivity, GoogleLeadProcessor, NewCustomer, PreferredPayment, PricingProgramAssigner, PruneTouchbase, RadiantReward, ReportGrouping, ResetOpenActivityFlag, SalesPriorityCalculation, SalesRepAssigner, SalesRepChanger, SyncAddressWithTaxjar, SyncWithTaxjar, UpdateProfile, UpdateProfileStats, Watch

Constant Summary collapse

TERM_DUE =
'Due'
TERM_NET15 =
'Net 15'
TERM_NET30 =
'Net 30'
TERM_NET37 =
'Net 37'
TERM_NET45 =
'Net 45'
TERM_NET60 =
'Net 60'
TERM_NET90 =
'Net 90'
TRADE_PRO_PRODUCT_REVIEW_DELAY_MONTHS =
1
HOMEOWNER_PRODUCT_REVIEW_DELAY_MONTHS =
1
PRODUCT_REVIEW_REMINDER_DELAY_MONTHS =
1
REFERENCE_NUMBER_PATTERN =
/^CN(\d+)$/i
WATCH_STATES =
{
  'not_watched_auto' => 'Not Watched (auto/default)',
  'not_watched_forced' => 'Not Watched (forced)',
  'watch_auto' => 'Watch (auto)',
  'watch_forced' => 'Watch (forced)'
}.freeze
REJECT_ALL_BLANK =

NESTED ATTRIBUTES #

->(attrs) { attrs.all? { |_k, v| v.blank? } }
REJECT_WITHOUT_ID_AND =
->(key) { ->(attrs) { attrs['id'].blank? && attrs[key].blank? } }

Constants inherited from Party

Party::PREFERRED_LANGUAGES

Constants included from Models::Auditable

Models::Auditable::ALWAYS_IGNORED

Instance Attribute Summary collapse

Attributes included from CustomerValidations

#validate_rr

Attributes included from CustomerPricing

#propagate_discount

Attributes inherited from Party

#creation_method

Delegated Instance Attributes collapse

Methods included from CustomerDisplay

#company, #customer_service_manager

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

Belongs to collapse

Methods inherited from Party

#catalog, #company, #customer, #gl_offset_account, #profile_image, #visit

Methods included from Models::Auditable

#creator, #updater

Has one collapse

Methods inherited from Party

#account, #store

Has many collapse

Methods inherited from Party

#accounts, #activities, #addresses, #agreement_participants, #agreements, #assistant_conversations, #billing_credit_memos, #consignment_stores, #contact_points, #contacts, #course_enrollments, #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

Class Method Summary collapse

Instance Method Summary collapse

Methods included from CustomerQueries

#all_line_items, #all_opportunities, #all_orders, #all_uploads, #hold_quotes_for_transmission_default?, #next_opportunity_name, #orders?, #project_in_progress?, #quotes_complete_for_select

Methods included from CustomerDisplay

affiliations_for_select, #billing_address_attributes, #country, customer_is_real?, #locale, #main_address, #online?, options_for_terms_select, #product_review_delay_months, #reference_number, select_number_of_offices, select_projects, states_for_select, #to_label, #to_s

Methods included from CustomerContacts

#account_team, #all_addresses, #all_addresses_including_contacts, #all_contact_points, #all_emails, #all_my_active_party_ids, #all_my_party_ids, #all_notification_channels, #all_phone_numbers, #all_related_addresses, #all_related_communications, #contact_select_options, #contactable?, #contacts_and_self, #contacts_and_self_callable_contact_points, #contacts_and_self_callable_options_for_select, #contacts_and_self_contact_points_by_category, #contacts_and_self_contact_points_by_category_options_for_select, #email, #generate_guest_account, #guess_best_callable_contact_point, #guess_best_contact_point_by_category, #lead_score_pass?, #obfuscated_email, #primary_contact, #primary_rep, #secondary_rep, #self_and_contacts_party_ids_arr, #sms_enabled_numbers

Methods included from CustomerSalesMarketing

#active_sales_subscriptions, #active_subscriptions, #all_related_visits, #broadcast_customer_source_changed, #campaigns, #can_spiff?, #check_for_open_sales_activity, #company_review_url, #create_intro_activity, #human_watch_name, #last_completed_sales_activity_date, #last_meeting_activities, #last_training_activities, #local_sales_rep_name, #most_recent_attributable_visit_source, #open_activities_counter, #open_sales_activity?, #primary_sales_rep_name, #profile_name, #protected_leads, rating_options_for_select, rating_options_for_select_with_rank, #recalculate_profiling_information, #resources_for_select, #sales_manager, #sales_reps, #sales_reps_ids, #secondary_sales_rep_name, #should_broadcast_source_change?, #signup_visit, #source_for_opps_and_orders, #source_unknown?, watch_states_for_select, #watched?

Methods included from CustomerOrganization

#abbreviation_for_packing_list, #all_or_none_are_blank_in_address?, #amazon_com?, #amazon_seller_central?, #amazon_vendor_central?, #broadcast_buying_group_changed, #build_com?, #buying_group_company?, #buying_group_name, #buying_groups_options_for_select, #canadian_tire?, #certified_installer?, #company_name, #company_name=, #costco_ca?, #customer_segment, #dealer_or_trade_pro_for_locator?, #determine_company_id, #direct_buy?, #direct_buy_can?, #direct_buy_usa?, #e_commerce_misc?, #e_commerce_misc_or_direct_pro?, #effective_report_grouping, #home_depot_can?, #home_depot_usa?, #homeowner?, #houzz?, #include_po_prefix?, #organization?, #overstock_com?, #parent_organization_name, #part_of_lowes_ca?, #part_of_lowes_com?, #person?, #self_and_children_ids, #update_buying_group, #use_parent_billing_address, #use_parent_billing_address=, #walmart_ca?, #wasn4_or_wat0f?, #wayfair?, #wayfair_ca?, #wayfair_usa?, #zoro?

Methods included from CustomerShipping

#bill_shipping_to_account_number_options_for_select, #cached_active_shipping_account_numbers, #default_shipping_option_name, #default_shipping_options, #distance_from_us_warehouse, #find_or_create_canadian_tire_address_from_store_number, #jde_abn, #jde_b_ab, #jde_s_ab, #largest_shipping_cost_in_last_year, #last_invoice_shipping_cost, #shipping_account_number, #shipping_account_numbers_for_carrier, #shipping_amount_last_30_days, #shipping_amount_last_month, #spent_20_on_shipping_in_last_year?

Methods included from CustomerPricing

#apply_discount_level_to_open_children, #broadcast_discount_level_changed, #pricing_program_description, #pricing_program_discount, #pricing_program_discount_factor, #set_default_for_opportunity, #set_default_for_order

Methods included from CustomerFinancials

#account_on_hold?, #all_rmas, #all_terms, #apc_available?, #approve_credit_request, #ar_listings, #auto_increase_available_credit, #available_store_credit, #bad_debt, #billing_entity, #calculated_purchase_history, #combined_terms, #credit_limit_verification, #determine_receipt_billing_entity, duplicate_addresses, duplicate_contact_points, #locked_credit_amount, #open_amount_greater_than_a_month, #open_orders_total, #outstanding_amount, #outstanding_amount_numeric, #outstanding_ar_listings, #outstanding_balance, #overdue_balance, #payment_options, #pre_authorized_amount_numeric, #pre_authorized_payments, #preferred_payment_method, #purchase_history, #receipts_list, #request_credit, statement_of_account, #sync_credit_limit, #terms?, #terms_credit_limit, #terms_in_days

Methods included from CustomerLifecycle

#blocked_for_opportunities?, #blocked_for_orders?, #can_be_merged?, #completed_sales_orders_present?, #customer, #determine_customer_state, #exclude_manually_initiated_event?, #leadify, #ok_to_delete?, #opportunities_or_cart_present?, #reset_capabilities, #set_qc_state, #set_status, #status_should_be, #versions_for_audit_trail

Methods included from Models::SourceAttributable

#has_google_ads_attribution?, #source_locked?, #source_locked_reason, #visit_with_google_click_id?

Methods inherited from Party

#digital_assets, #linked_activities, #product_lines, #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, #assign_chained_activities?, #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=, #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, #store, #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

#quick_note

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

#billing_address_idObject (readonly)



348
# File 'app/models/customer.rb', line 348

validates :billing_address_id, presence: true, if: :orders?

#catalog_idObject (readonly)



342
# File 'app/models/customer.rb', line 342

validates :catalog_id, presence: true

#checked_for_dupeObject

Returns the value of attribute checked_for_dupe.



227
228
229
# File 'app/models/customer.rb', line 227

def checked_for_dupe
  @checked_for_dupe
end

Returns the value of attribute consent_to_contact.



227
228
229
# File 'app/models/customer.rb', line 227

def consent_to_contact
  @consent_to_contact
end

#credit_scoreObject (readonly)



352
# File 'app/models/customer.rb', line 352

validates :credit_score, numericality: { greater_than: 0, less_than_or_equal_to: 100, allow_nil: true }

#early_payment_discountObject (readonly)



350
# File 'app/models/customer.rb', line 350

validates :early_payment_discount, numericality: { greater_than: 0, less_than_or_equal_to: 2, allow_nil: true }

#early_payment_timescaleObject (readonly)



351
# File 'app/models/customer.rb', line 351

validates :early_payment_timescale, numericality: { if: proc { |c| !c.early_payment_discount.nil? } }

#first_nameObject (readonly)



345
# File 'app/models/customer.rb', line 345

validates :first_name, presence: { message: "can't be blank" }, if: :homeowner?

#full_nameObject (readonly)



344
# File 'app/models/customer.rb', line 344

validates :full_name, presence: { message: "can't be blank" }, unless: :guest?

#move_contact_pointsObject

Returns the value of attribute move_contact_points.



227
228
229
# File 'app/models/customer.rb', line 227

def move_contact_points
  @move_contact_points
end

#must_have_emailObject

Returns the value of attribute must_have_email.



227
228
229
# File 'app/models/customer.rb', line 227

def must_have_email
  @must_have_email
end

#must_have_one_contactObject

Returns the value of attribute must_have_one_contact.



227
228
229
# File 'app/models/customer.rb', line 227

def must_have_one_contact
  @must_have_one_contact
end

#must_have_phoneObject

Returns the value of attribute must_have_phone.



227
228
229
# File 'app/models/customer.rb', line 227

def must_have_phone
  @must_have_phone
end

#perform_lead_verificationObject

Returns the value of attribute perform_lead_verification.



227
228
229
# File 'app/models/customer.rb', line 227

def perform_lead_verification
  @perform_lead_verification
end

#person_nameObject

Returns the value of attribute person_name.



227
228
229
# File 'app/models/customer.rb', line 227

def person_name
  @person_name
end

#prefixObject (readonly)



346
# File 'app/models/customer.rb', line 346

validates :prefix, length: { maximum: 10 }, if: :homeowner?

#profile_idObject (readonly)

VALIDATIONS #

Validations (if => CustomerOrganization#organization? ):



341
# File 'app/models/customer.rb', line 341

validates :profile_id, presence: true, if: :organization?

#record_parent_billing_addressObject

Returns the value of attribute record_parent_billing_address.



227
228
229
# File 'app/models/customer.rb', line 227

def record_parent_billing_address
  @record_parent_billing_address
end

#suffixObject (readonly)



347
# File 'app/models/customer.rb', line 347

validates :suffix, length: { maximum: 10 }, if: :homeowner?

Class Method Details

.by_repActiveRecord::Relation<Customer>

A relation of Customers that are by rep. Active Record Scope

Returns:

See Also:



363
# File 'app/models/customer.rb', line 363

scope :by_rep, ->(rep) { where('parties.primary_sales_rep_id = :rep_id or parties.secondary_sales_rep_id = :rep_id or parties.local_sales_rep_id = :rep_id', rep_id: rep.id) }

.homeownersActiveRecord::Relation<Customer>

A relation of Customers that are homeowners. Active Record Scope

Returns:

See Also:



366
# File 'app/models/customer.rb', line 366

scope :homeowners, -> { where(profile_id: ProfileConstants::HOMEOWNER) }

.locator_eligibleActiveRecord::Relation<Customer>

A relation of Customers that are locator eligible. Active Record Scope

Returns:

See Also:



374
375
376
377
378
379
380
381
382
383
384
# File 'app/models/customer.rb', line 374

scope :locator_eligible, -> {
  without_locator_record
    .non_guests
    .joins(:profile)
    .joins(:customer_record)
    .where(Profile[:locator_eligible].eq(true))
    .where(Customer[:created_at].lt(1.month.ago))
    .where.not('exists(select 1 from locator_black_list_parties lblp where lblp.customer_id = parties.id)')
    .where('exists(select 1 from addresses a where a.party_id = parties.id)')
    .where('(customer_records.trailing_twelve_months_number_of_orders >= 1 and customer_records.trailing_twelve_months_revenue >= 200.0) or customer_records.trailing_twelve_months_number_of_opportunities >= 1')
}

.locator_expiredActiveRecord::Relation<Customer>

A relation of Customers that are locator expired. Active Record Scope

Returns:

See Also:



385
386
387
388
389
390
391
392
# File 'app/models/customer.rb', line 385

scope :locator_expired, -> {
  with_locator_record
    .joins(:locator_record)
    .joins(:customer_record)
    .where(LocatorRecord[:confirmed_at].lt(1.year.ago))
    .where(LocatorRecord[:last_confirmed_at].lt(1.year.ago))
    .where('(customer_records.trailing_twelve_months_number_of_orders < 1 or customer_records.trailing_twelve_months_revenue < 200.0) and customer_records.trailing_twelve_months_number_of_opportunities < 1')
}

.non_guestsActiveRecord::Relation<Customer>

A relation of Customers that are non guests. Active Record Scope

Returns:

See Also:



365
# File 'app/models/customer.rb', line 365

scope :non_guests, -> { where.not(state: 'guest') }

.not_locator_blackistedActiveRecord::Relation<Customer>

A relation of Customers that are not locator blackisted. Active Record Scope

Returns:

See Also:



372
# File 'app/models/customer.rb', line 372

scope :not_locator_blackisted, -> { where_not_exists(:locator_black_listing) }

.organizationsActiveRecord::Relation<Customer>

A relation of Customers that are organizations. Active Record Scope

Returns:

See Also:



367
# File 'app/models/customer.rb', line 367

scope :organizations, -> { where.not(profile_id: ProfileConstants::HOMEOWNER) }

.protected_byActiveRecord::Relation<Customer>

A relation of Customers that are protected by. Active Record Scope

Returns:

See Also:



369
# File 'app/models/customer.rb', line 369

scope :protected_by, ->(customer_id) { Customer.joins(:customer_record).where('customer_records.lead_protector_id' => customer_id) }

.valid_parentsActiveRecord::Relation<Customer>

A relation of Customers that are valid parents. Active Record Scope

Returns:

See Also:



364
# File 'app/models/customer.rb', line 364

scope :valid_parents, -> { where.not(profile_id: nil).where.not(profile_id: ProfileConstants::BUYING_GROUP) }

.watchedActiveRecord::Relation<Customer>

A relation of Customers that are watched. Active Record Scope

Returns:

See Also:



373
# File 'app/models/customer.rb', line 373

scope :watched, -> { where(watch: %w[watch_auto watch_forced]) }

.with_locator_recordActiveRecord::Relation<Customer>

A relation of Customers that are with locator record. Active Record Scope

Returns:

See Also:



371
# File 'app/models/customer.rb', line 371

scope :with_locator_record, -> { non_guests.where_exists(:locator_record) }

.with_won_opportunities_sinceActiveRecord::Relation<Customer>

A relation of Customers that are with won opportunities since. Active Record Scope

Returns:

See Also:



368
# File 'app/models/customer.rb', line 368

scope :with_won_opportunities_since, ->(date) { non_guests.where("(select count(id) from opportunities o where o.state = 'won' and o.customer_id = parties.id and o.created_at >= ?) > 1", date) }

.without_contact_pointsActiveRecord::Relation<Customer>

A relation of Customers that are without contact points. Active Record Scope

Returns:

See Also:



393
394
395
396
# File 'app/models/customer.rb', line 393

scope :without_contact_points, -> {
  where('not exists(select 1 from contact_points cp where cp.party_id = parties.id)')
    .where("not exists(select 1 from contact_points cp inner join parties cnt on cp.party_id = cnt.id where cnt.type = 'Contact' and cnt.customer_id = parties.id )")
}

.without_locator_recordActiveRecord::Relation<Customer>

A relation of Customers that are without locator record. Active Record Scope

Returns:

See Also:



370
# File 'app/models/customer.rb', line 370

scope :without_locator_record, -> { non_guests.where_not_exists(:locator_record) }

Instance Method Details

#billing_addressAddress

Returns:

See Also:



263
# File 'app/models/customer.rb', line 263

belongs_to :billing_address, class_name: 'Address', optional: true

#buying_groupBuyingGroup



257
# File 'app/models/customer.rb', line 257

belongs_to :buying_group, optional: true

#certificationsActiveRecord::Relation<Certification>

rubocop:disable Rails/InverseOf -- Contact shares customer_id FK; see Contact model

Returns:

See Also:



300
# File 'app/models/customer.rb', line 300

has_many :certifications, foreign_key: 'party_id', dependent: :destroy

#change_catalog(new_catalog) ⇒ void

This method returns an undefined value.

Reassigns the customer to another catalog via the catalog assigner service.

Parameters:

  • new_catalog (Catalog)

    target catalog



420
421
422
# File 'app/models/customer.rb', line 420

def change_catalog(new_catalog)
  Catalog::AssignCatalogToCustomer.new.process(self, new_catalog)
end

#child_organizationsActiveRecord::Relation<Customer>

Returns:

See Also:



271
# File 'app/models/customer.rb', line 271

has_many :child_organizations, class_name: 'Customer', foreign_key: 'parent_id', dependent: :nullify, inverse_of: :parent_organization

#credit_applicationsActiveRecord::Relation<CreditApplication>

Returns:

See Also:



292
# File 'app/models/customer.rb', line 292

has_many :credit_applications, dependent: :destroy

#credit_card_vaultsActiveRecord::Relation<CreditCardVault>

Returns:

See Also:



281
# File 'app/models/customer.rb', line 281

has_many :credit_card_vaults, dependent: :destroy

#customer_drop_eventsActiveRecord::Relation<CustomerDropEvent>

Returns:

See Also:



282
# File 'app/models/customer.rb', line 282

has_many :customer_drop_events, dependent: :destroy

#customer_recordCustomerRecord



267
# File 'app/models/customer.rb', line 267

has_one :customer_record, dependent: :destroy, inverse_of: :party, foreign_key: 'party_id'

#data_import_rowDataImportRow



266
# File 'app/models/customer.rb', line 266

has_one :data_import_row, dependent: :nullify, inverse_of: :customer

#direct_shipmentsActiveRecord::Relation<DirectShipment>

Returns:

  • (ActiveRecord::Relation<DirectShipment>)

See Also:



293
# File 'app/models/customer.rb', line 293

has_many :direct_shipments, through: :orders

#edi_orchestratorEdi::BaseOrchestrator?

Returns the EDI orchestrator for this customer when persisted.

Returns:



410
411
412
413
414
# File 'app/models/customer.rb', line 410

def edi_orchestrator
  return unless persisted?

  Edi::BaseOrchestrator.orchestrator_for_customer_id(id)
end

#exported_catalog_item_packetsActiveRecord::Relation<ExportedCatalogItemPacket>

Returns:

See Also:



294
# File 'app/models/customer.rb', line 294

has_many :exported_catalog_item_packets, dependent: :nullify

#feedsActiveRecord::Relation<Feed>

Returns:

  • (ActiveRecord::Relation<Feed>)

See Also:



289
# File 'app/models/customer.rb', line 289

has_many :feeds, dependent: :destroy, inverse_of: :customer

#home_stateState

rubocop:disable Rails/InverseOf -- State is a lookup table by code; parties reference it, not the inverse

Returns:

See Also:



260
# File 'app/models/customer.rb', line 260

belongs_to :home_state, class_name: 'State', foreign_key: 'state_code', primary_key: 'code', optional: true

#identification_numbersActiveRecord::Relation<IdentificationNumber>

Returns:

See Also:



279
# File 'app/models/customer.rb', line 279

has_many :identification_numbers, dependent: :destroy

#invoicesActiveRecord::Relation<Invoice>

Returns:

  • (ActiveRecord::Relation<Invoice>)

See Also:



283
# File 'app/models/customer.rb', line 283

has_many :invoices, dependent: :nullify, inverse_of: :customer

#ledger_detail_projectLedgerProject



265
# File 'app/models/customer.rb', line 265

belongs_to :ledger_detail_project, class_name: 'LedgerProject', optional: true

#legacy_pricing_programPricingProgram

Returns:

  • (PricingProgram)

See Also:



255
# File 'app/models/customer.rb', line 255

belongs_to :legacy_pricing_program, class_name: 'PricingProgram', optional: true

#liability_insurancesActiveRecord::Relation<LiabilityInsurance>

Returns:

See Also:



277
# File 'app/models/customer.rb', line 277

has_many :liability_insurances, dependent: :destroy

#local_sales_repEmployee

Returns:

See Also:



252
# File 'app/models/customer.rb', line 252

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

#locator_black_listingLocatorBlackListParty



270
# File 'app/models/customer.rb', line 270

has_one :locator_black_listing, class_name: 'LocatorBlackListParty', dependent: :destroy, inverse_of: :customer

#locator_recordLocatorRecord



268
# File 'app/models/customer.rb', line 268

has_one :locator_record, dependent: :destroy, inverse_of: :customer

#locator_white_listingLocatorWhiteListParty



269
# File 'app/models/customer.rb', line 269

has_one :locator_white_listing, class_name: 'LocatorWhiteListParty', dependent: :destroy, inverse_of: :customer

#mailing_addressAddress

Returns:

See Also:



264
# File 'app/models/customer.rb', line 264

belongs_to :mailing_address, class_name: 'Address', optional: true

#marketplace_invoice_formatObject

Alias for Customer_record#marketplace_invoice_format

Returns:

  • (Object)

    Customer_record#marketplace_invoice_format

See Also:



233
# File 'app/models/customer.rb', line 233

delegate :marketplace_invoice_format, to: :customer_record, allow_nil: true

#notification_channelsActiveRecord::Relation<NotificationChannel>

Returns:

See Also:



280
# File 'app/models/customer.rb', line 280

has_many :notification_channels, dependent: :destroy

#opportunitiesActiveRecord::Relation<Opportunity>

Returns:

See Also:



272
# File 'app/models/customer.rb', line 272

has_many :opportunities, dependent: :destroy, before_add: :set_default_for_opportunity, inverse_of: :customer

#order_rmasActiveRecord::Relation<OrderRma>

Returns:

  • (ActiveRecord::Relation<OrderRma>)

See Also:



286
# File 'app/models/customer.rb', line 286

has_many :order_rmas, through: :orders, source: :rmas

#ordersActiveRecord::Relation<Order>

Returns:

  • (ActiveRecord::Relation<Order>)

See Also:



274
# File 'app/models/customer.rb', line 274

has_many :orders, -> { order(:created_at).reverse_order }, dependent: :destroy, before_add: :set_default_for_order, inverse_of: :customer

#original_sourceSource

Returns:

See Also:



249
# File 'app/models/customer.rb', line 249

belongs_to :original_source, class_name: 'Source', optional: true

#parent_organizationCustomer

Returns:

See Also:



258
# File 'app/models/customer.rb', line 258

belongs_to :parent_organization, class_name: 'Customer', foreign_key: 'parent_id', optional: true, inverse_of: :child_organizations

#paymentsActiveRecord::Relation<Payment>

Returns:

  • (ActiveRecord::Relation<Payment>)

See Also:



284
# File 'app/models/customer.rb', line 284

has_many :payments, dependent: :nullify

#preset_jobsActiveRecord::Relation<PresetJob>

Returns:

See Also:



288
# File 'app/models/customer.rb', line 288

has_many :preset_jobs, -> { order(:created_at).reverse_order }, dependent: :destroy, inverse_of: :customer

#primary_sales_repEmployee

Returns:

See Also:



250
# File 'app/models/customer.rb', line 250

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

#profileProfile

Returns:

See Also:



254
# File 'app/models/customer.rb', line 254

belongs_to :profile, optional: true

#quick_estimatorsActiveRecord::Relation<QuickEstimator>

Returns:

See Also:



287
# File 'app/models/customer.rb', line 287

has_many :quick_estimators, dependent: :destroy

#quotesActiveRecord::Relation<Quote>

Returns:

  • (ActiveRecord::Relation<Quote>)

See Also:



275
# File 'app/models/customer.rb', line 275

has_many :quotes, -> { order(:created_at).reverse_order }, through: :opportunities

Returns:

See Also:



291
# File 'app/models/customer.rb', line 291

has_many :related_activities, class_name: 'Activity', dependent: :nullify, inverse_of: :customer

#rmasActiveRecord::Relation<Rma>

Returns:

  • (ActiveRecord::Relation<Rma>)

See Also:



285
# File 'app/models/customer.rb', line 285

has_many :rmas, dependent: :nullify

#room_configurationsActiveRecord::Relation<RoomConfiguration>

Returns:

  • (ActiveRecord::Relation<RoomConfiguration>)

See Also:



273
# File 'app/models/customer.rb', line 273

has_many :room_configurations, through: :opportunities

#search_resultsActiveRecord::Relation<SearchResult>

Returns:

See Also:



290
# File 'app/models/customer.rb', line 290

has_many :search_results, as: :resource, dependent: :destroy

#secondary_sales_repEmployee

Returns:

See Also:



251
# File 'app/models/customer.rb', line 251

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

#service_jobsActiveRecord::Relation<ServiceJob>

Returns:

See Also:



295
# File 'app/models/customer.rb', line 295

has_many :service_jobs, dependent: :destroy

#service_repEmployee

Returns:

See Also:



253
# File 'app/models/customer.rb', line 253

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

#set_full_nameObject (protected)

rubocop:disable Metrics/AbcSize, Naming/PredicateMethod -- Party STI callback; trailing true satisfies callback contract



425
426
427
428
429
430
431
432
433
434
435
# File 'app/models/customer.rb', line 425

protected def set_full_name
  pn = [prefix, first_name, middle_name, last_name, suffix].filter_map { |np| np.to_s.squish.presence }.join(' ')
  pn = full_name if full_name.present? && pn.blank?
  if homeowner? && pn.present?
    self.full_name = pn
    PersonNameParser.new(pn).to_party(self)
  else
    self.full_name ||= pn
  end
  true
end

#shipping_account_numbersActiveRecord::Relation<ShippingAccountNumber>

Returns:

See Also:



278
# File 'app/models/customer.rb', line 278

has_many :shipping_account_numbers, dependent: :destroy

#shipping_addressAddress

rubocop:enable Rails/InverseOf

Returns:

See Also:



262
# File 'app/models/customer.rb', line 262

belongs_to :shipping_address, class_name: 'Address', optional: true

#showcasesActiveRecord::Relation<Showcase>

Returns:

See Also:



296
# File 'app/models/customer.rb', line 296

has_many :showcases, class_name: 'Showcase', dependent: :nullify

#sourceSource

ASSOCIATIONS #

Returns:

See Also:



248
# File 'app/models/customer.rb', line 248

belongs_to :source, optional: true

#statement_of_accountsActiveRecord::Relation<StatementOfAccount>

Returns:

See Also:



297
# File 'app/models/customer.rb', line 297

has_many :statement_of_accounts, dependent: :destroy

#subscribersActiveRecord::Relation<Subscriber>

Returns:

See Also:



298
# File 'app/models/customer.rb', line 298

has_many :subscribers, dependent: :destroy

#tax_exemptionsActiveRecord::Relation<TaxExemption>

Returns:

See Also:



276
# File 'app/models/customer.rb', line 276

has_many :tax_exemptions, dependent: :destroy

#tier2_program_pricingCoupon::Tier2ProgramPricing

Validations:



256
# File 'app/models/customer.rb', line 256

belongs_to :tier2_program_pricing, class_name: 'Coupon::Tier2ProgramPricing', optional: true

#votesActiveRecord::Relation<Vote>

rubocop:enable Rails/InverseOf

Returns:

  • (ActiveRecord::Relation<Vote>)

See Also:



302
# File 'app/models/customer.rb', line 302

has_many :votes, dependent: :destroy