Class: Party

Inherits:
ApplicationRecord show all
Includes:
ActionView::Helpers::NumberHelper, CrmLinkable, Models::Auditable, Models::LiquidMethods, Models::Notable, PartyAccount, PartyAddresses, PartyCart, PartyContactInfo, PartyIdentity, PartySearch, PgSearch::Model
Defined in:
app/models/party.rb

Overview

Single-table inheritance (STI) base for every CRM party row in parties
(customers, contacts, employees, suppliers, buying-group rows, and similar roles).

Shared persistence (addresses, reps, consent JSON, catalog links) lives on this model;
subtype behaviour is composed through subclasses and Party*, Customer*, and Contact*
concerns.

Direct Known Subclasses

Contact, Customer, Employee, GroupAssociation, Supplier

Defined Under Namespace

Classes: ExistingAccountError, RecordTimezone

Constant Summary collapse

PREFERRED_LANGUAGES =
%w[French Spanish].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 one collapse

Has many collapse

Has and belongs to many collapse

Delegated Instance Attributes collapse

Instance Method Summary collapse

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, #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

#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

#creation_methodObject (readonly)



311
# File 'app/models/party.rb', line 311

validates :creation_method, inclusion: { in: creation_methods.keys }

Instance Method Details

#accountAccount

NOTE: this is a documentation-only association used as a convenience
accessor. Use accounts (has_many below) for collection access. We keep
dependent: :destroy so that destroying a party still cleans up its sole
account row; the truly dangerous primitive (auto-destroying an existing
account when assigning a new one) is intercepted by the build_account
override below.

Returns:

See Also:



245
# File 'app/models/party.rb', line 245

has_one :account, dependent: :destroy

#accountsActiveRecord::Relation<Account>

Returns:

  • (ActiveRecord::Relation<Account>)

See Also:



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

has_many :accounts, dependent: :destroy

#activitiesActiveRecord::Relation<Activity>

rubocop:enable Rails/InverseOf

Returns:

See Also:



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

has_many :activities, dependent: :destroy

#addressesActiveRecord::Relation<Address>

Returns:

  • (ActiveRecord::Relation<Address>)

See Also:



246
247
248
249
250
251
252
# File 'app/models/party.rb', line 246

has_many :addresses, dependent: :nullify, inverse_of: :party do
  def main_address
    find_by(id: [proxy_association.owner.mailing_address_id,
                 proxy_association.owner.billing_address_id,
                 proxy_association.owner.shipping_address_id]) || first
  end
end

#agreement_participantsActiveRecord::Relation<AgreementParticipant>

Returns:

See Also:



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

has_many :agreement_participants, dependent: :destroy

#agreementsActiveRecord::Relation<Agreement>

Returns:

See Also:



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

has_many :agreements, through: :agreement_participants

#assistant_conversationsActiveRecord::Relation<AssistantConversation>

Returns:

See Also:



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

has_many :assistant_conversations, foreign_key: :user_id, dependent: :destroy, inverse_of: :user

#billing_credit_memosActiveRecord::Relation<CreditMemo>

Returns:

See Also:



278
279
# File 'app/models/party.rb', line 278

has_many :billing_credit_memos, class_name: 'CreditMemo', foreign_key: 'billing_customer_id', dependent: :nullify,
inverse_of: :billing_customer

#can?Object

Alias for Ability#can?

Returns:

  • (Object)

    Ability#can?

See Also:



304
# File 'app/models/party.rb', line 304

delegate :can?, :cannot?, to: :ability

#cannot?Object

Alias for Ability#cannot?

Returns:

  • (Object)

    Ability#cannot?

See Also:



304
# File 'app/models/party.rb', line 304

delegate :can?, :cannot?, to: :ability

#catalogCatalog

Returns:

See Also:



232
# File 'app/models/party.rb', line 232

belongs_to :catalog, optional: true

#companyCompany

Returns:

See Also:

Validations:



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

belongs_to :company, optional: true

#consignment_storesActiveRecord::Relation<Store>

Returns:

  • (ActiveRecord::Relation<Store>)

See Also:



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

has_many :consignment_stores, class_name: 'Store', foreign_key: :consignee_party_id, dependent: :nullify, inverse_of: :consignee_party

#contact_pointsActiveRecord::Relation<ContactPoint>

Returns:

See Also:



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

has_many :contact_points, -> { order(:position) }, dependent: :nullify, inverse_of: :party

#contactsActiveRecord::Relation<Contact>

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

Returns:

  • (ActiveRecord::Relation<Contact>)

See Also:

Validations (if => #must_have_one_contact ):



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

has_many :contacts, foreign_key: 'customer_id', dependent: :destroy

#course_enrollmentsActiveRecord::Relation<CourseEnrollment>

Returns:

See Also:



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

has_many :course_enrollments, dependent: :destroy, inverse_of: :party

#credit_memosActiveRecord::Relation<CreditMemo>

owner of the credit memo

Returns:

See Also:



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

has_many :credit_memos, foreign_key: 'customer_id', dependent: :nullify, inverse_of: :customer

#customerCustomer

WHEN CREATING A NEW ASSOCIATION FOR YOUR PARTY, CUSTOMER OR CONTACT
DO NOT FORGET TO HANDLE THEM IN MERGE OPERATIONS
IMPLEMENT THIS IN customer_merger.rb or contact_merger.rb

Returns:

See Also:



231
# File 'app/models/party.rb', line 231

belongs_to :customer, optional: true

#destination_call_logsActiveRecord::Relation<CallLog>

Returns:

  • (ActiveRecord::Relation<CallLog>)

See Also:



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

has_many :destination_call_logs, class_name: 'CallLog', foreign_key: 'to_party_id', dependent: :nullify, inverse_of: :to_party

#destination_call_recordsActiveRecord::Relation<CallRecord>

Returns:

See Also:



260
261
# File 'app/models/party.rb', line 260

has_many :destination_call_records, class_name: 'CallRecord', foreign_key: 'destination_party_id', dependent: :nullify,
inverse_of: :destination_party

#digital_assetsActiveRecord::Relation<DigitalAsset>

Returns:

See Also:



301
# File 'app/models/party.rb', line 301

has_and_belongs_to_many :digital_assets

#gl_offset_accountLedgerAccount



235
# File 'app/models/party.rb', line 235

belongs_to :gl_offset_account, class_name: 'LedgerAccount', optional: true

#has_role?Object

Alias for Account#has_role?

Returns:

  • (Object)

    Account#has_role?

See Also:



305
# File 'app/models/party.rb', line 305

delegate :has_role?, :is_admin?, :is_manager?, :is_sales_manager?, :is_sales_rep?, :is_local_sales_rep?, :is_marketing_manager?, :is_document_maintainer?, to: :account

#inbound_communicationsActiveRecord::Relation<Communication>

Returns:

See Also:



269
270
# File 'app/models/party.rb', line 269

has_many :inbound_communications, class_name: 'Communication', foreign_key: 'recipient_party_id', dependent: :nullify,
inverse_of: :recipient_party

#is_admin?Object

Alias for Account#is_admin?

Returns:

  • (Object)

    Account#is_admin?

See Also:



305
# File 'app/models/party.rb', line 305

delegate :has_role?, :is_admin?, :is_manager?, :is_sales_manager?, :is_sales_rep?, :is_local_sales_rep?, :is_marketing_manager?, :is_document_maintainer?, to: :account

#is_document_maintainer?Object

Alias for Account#is_document_maintainer?

Returns:

  • (Object)

    Account#is_document_maintainer?

See Also:



305
# File 'app/models/party.rb', line 305

delegate :has_role?, :is_admin?, :is_manager?, :is_sales_manager?, :is_sales_rep?, :is_local_sales_rep?, :is_marketing_manager?, :is_document_maintainer?, to: :account

#is_local_sales_rep?Object

Alias for Account#is_local_sales_rep?

Returns:

  • (Object)

    Account#is_local_sales_rep?

See Also:



305
# File 'app/models/party.rb', line 305

delegate :has_role?, :is_admin?, :is_manager?, :is_sales_manager?, :is_sales_rep?, :is_local_sales_rep?, :is_marketing_manager?, :is_document_maintainer?, to: :account

#is_manager?Object

Alias for Account#is_manager?

Returns:

  • (Object)

    Account#is_manager?

See Also:



305
# File 'app/models/party.rb', line 305

delegate :has_role?, :is_admin?, :is_manager?, :is_sales_manager?, :is_sales_rep?, :is_local_sales_rep?, :is_marketing_manager?, :is_document_maintainer?, to: :account

#is_marketing_manager?Object

Alias for Account#is_marketing_manager?

Returns:

  • (Object)

    Account#is_marketing_manager?

See Also:



305
# File 'app/models/party.rb', line 305

delegate :has_role?, :is_admin?, :is_manager?, :is_sales_manager?, :is_sales_rep?, :is_local_sales_rep?, :is_marketing_manager?, :is_document_maintainer?, to: :account

#is_sales_manager?Object

Alias for Account#is_sales_manager?

Returns:

  • (Object)

    Account#is_sales_manager?

See Also:



305
# File 'app/models/party.rb', line 305

delegate :has_role?, :is_admin?, :is_manager?, :is_sales_manager?, :is_sales_rep?, :is_local_sales_rep?, :is_marketing_manager?, :is_document_maintainer?, to: :account

#is_sales_rep?Object

Alias for Account#is_sales_rep?

Returns:

  • (Object)

    Account#is_sales_rep?

See Also:



305
# File 'app/models/party.rb', line 305

delegate :has_role?, :is_admin?, :is_manager?, :is_sales_manager?, :is_sales_rep?, :is_local_sales_rep?, :is_marketing_manager?, :is_document_maintainer?, to: :account

#linked_activitiesActiveRecord::Relation<Activity>

Returns:

See Also:



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

has_and_belongs_to_many :linked_activities, class_name: 'Activity'

#localeObject

Alias for I18n#locale

Returns:

  • (Object)

    I18n#locale

See Also:



325
# File 'app/models/party.rb', line 325

delegate :locale, to: :I18n

#main_addressObject

Alias for Addresses#main_address

Returns:

  • (Object)

    Addresses#main_address

See Also:



306
# File 'app/models/party.rb', line 306

delegate :main_address, to: :addresses

#notificationsActiveRecord::Relation<Noticed::Notification>

Returns:

  • (ActiveRecord::Relation<Noticed::Notification>)

See Also:



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

has_many :notifications, as: :recipient, dependent: :destroy, class_name: 'Noticed::Notification'

#opportunity_participantsActiveRecord::Relation<OpportunityParticipant>

Returns:

See Also:



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

has_many :opportunity_participants, inverse_of: :party, dependent: :destroy

#origin_call_logsActiveRecord::Relation<CallLog>

Returns:

  • (ActiveRecord::Relation<CallLog>)

See Also:



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

has_many :origin_call_logs, class_name: 'CallLog', foreign_key: 'from_party_id', dependent: :nullify, inverse_of: :from_party

#origin_call_recordsActiveRecord::Relation<CallRecord>

Returns:

See Also:



259
# File 'app/models/party.rb', line 259

has_many :origin_call_records, class_name: 'CallRecord', foreign_key: 'origin_party_id', dependent: :nullify, inverse_of: :origin_party

#outbound_communicationsActiveRecord::Relation<Communication>

Returns:

See Also:



267
268
# File 'app/models/party.rb', line 267

has_many :outbound_communications, class_name: 'Communication', foreign_key: 'sender_party_id', dependent: :nullify,
inverse_of: :sender_party

#outgoing_paymentsActiveRecord::Relation<OutgoingPayment>

Returns:

See Also:



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

has_many :outgoing_payments, foreign_key: 'supplier_id', dependent: :nullify, inverse_of: :supplier

#party_topicsActiveRecord::Relation<PartyTopic>

Returns:

See Also:



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

has_many :party_topics, inverse_of: :party, dependent: :destroy

#product_linesActiveRecord::Relation<ProductLine>

rubocop:disable Rails/HasAndBelongsToMany -- legacy join tables; migrating to has_many :through is a separate effort

Returns:

See Also:



299
# File 'app/models/party.rb', line 299

has_and_belongs_to_many :product_lines

#profile_imageImage

Returns:

See Also:



236
# File 'app/models/party.rb', line 236

belongs_to :profile_image, class_name: 'Image', dependent: :destroy, optional: true

#purchase_ordersActiveRecord::Relation<PurchaseOrder>

Returns:

See Also:



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

has_many :purchase_orders, foreign_key: :supplier_id, dependent: :nullify, inverse_of: :supplier

#queue_call_logsActiveRecord::Relation<QueueCallLog>

Returns:

See Also:



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

has_many :queue_call_logs, class_name: 'QueueCallLog', foreign_key: 'caller_party_id', dependent: :nullify, inverse_of: :caller_party

#receiptsActiveRecord::Relation<Receipt>

Returns:

  • (ActiveRecord::Relation<Receipt>)

See Also:



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

has_many :receipts, foreign_key: 'customer_id', dependent: :nullify, inverse_of: :customer

#recipient_sms_messagesActiveRecord::Relation<SmsMessage>

Returns:

See Also:



293
294
# File 'app/models/party.rb', line 293

has_many :recipient_sms_messages, class_name: 'SmsMessage', foreign_key: :recipient_party_id, dependent: :nullify,
inverse_of: :recipient_party

#room_plansActiveRecord::Relation<RoomPlan>

Returns:

See Also:



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

has_many :room_plans, inverse_of: :party, dependent: :destroy

#sender_sms_messagesActiveRecord::Relation<SmsMessage>

Returns:

See Also:



291
292
# File 'app/models/party.rb', line 291

has_many :sender_sms_messages, class_name: 'SmsMessage', foreign_key: :sender_party_id, dependent: :nullify,
inverse_of: :sender_party

#set_full_nameObject (protected)



339
340
341
342
343
# File 'app/models/party.rb', line 339

protected def set_full_name
  existing_full_name = full_name
  apply_full_name_for_party_type!(existing_full_name)
  self.full_name ||= existing_full_name
end

#set_state_codeObject (protected)



327
328
329
330
# File 'app/models/party.rb', line 327

protected def set_state_code
  self.state_code = main_address&.state_code
  self.state_code ||= visit_data(:state_code)
end

#set_timezoneObject (protected)



332
333
334
335
336
337
# File 'app/models/party.rb', line 332

protected def set_timezone
  return if timezone_name.present?
  return if state == 'guest' # Ignore guests

  Party::RecordTimezone.new.process(self, save_directly: true)
end

#storeStore

Returns:

See Also:



238
# File 'app/models/party.rb', line 238

has_one :store, through: :catalog

#support_case_participantsActiveRecord::Relation<SupportCaseParticipant>

Returns:

See Also:



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

has_many :support_case_participants, dependent: :destroy

#support_casesActiveRecord::Relation<SupportCase>

Returns:

See Also:



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

has_many :support_cases, through: :support_case_participants

#survey_enrollmentsActiveRecord::Relation<SurveyEnrollment>

Returns:

See Also:



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

has_many :survey_enrollments, dependent: :destroy, inverse_of: :party

#uploadsActiveRecord::Relation<Upload>

Returns:

  • (ActiveRecord::Relation<Upload>)

See Also:



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

has_many :uploads, as: :resource, dependent: :destroy

#visitVisit

Returns:

See Also:



234
# File 'app/models/party.rb', line 234

belongs_to :visit, inverse_of: :party, optional: true

#visit_eventsActiveRecord::Relation<VisitEvent>

Returns:

See Also:



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

has_many :visit_events, through: :visits

#visitsActiveRecord::Relation<Visit>

Returns:

  • (ActiveRecord::Relation<Visit>)

See Also:



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

has_many :visits, foreign_key: :user_id, dependent: :nullify, inverse_of: :user

#voucher_itemsActiveRecord::Relation<VoucherItem>

Returns:

See Also:



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

has_many :voucher_items, through: :vouchers

#vouchersActiveRecord::Relation<Voucher>

Returns:

  • (ActiveRecord::Relation<Voucher>)

See Also:



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

has_many :vouchers, foreign_key: 'supplier_id', dependent: :nullify, inverse_of: :supplier