Class: Query::CustomerRelatedCommunications

Inherits:
Object
  • Object
show all
Defined in:
app/services/query/customer_related_communications.rb

Overview

Builds the seven-way Communication union for a Customer.

Returns a Communication relation usable in further .where / .order /
pagination calls; callers can treat it like any other AR relation rooted on
Communication. Mirrors the shape of Query::ContactRelatedCommunications,
which uses the same from(... UNION ...) pattern.

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(customer) ⇒ CustomerRelatedCommunications

Returns a new instance of CustomerRelatedCommunications.

Parameters:

  • customer (Customer)

    customer whose communication graph to assemble.



18
19
20
# File 'app/services/query/customer_related_communications.rb', line 18

def initialize(customer)
  @customer = customer
end

Class Method Details

.call(customer) ⇒ ActiveRecord::Relation<Communication>

Returns union of every
communication associated with this customer's relationship graph.

Parameters:

Returns:

  • (ActiveRecord::Relation<Communication>)

    union of every
    communication associated with this customer's relationship graph.



13
14
15
# File 'app/services/query/customer_related_communications.rb', line 13

def self.call(customer)
  new(customer).call
end

Instance Method Details

#callActiveRecord::Relation<Communication>

Build the union of every communication associated with the customer.

Logic Details

The seven branches each pick out communications related to the customer
through a different relationship:

  1. recipient_party_id ∈ (customer.id + active_contact_ids) — the
    customer or one of its contacts received the communication.
  2. sender_party_id ∈ same set — sent by the customer or a contact.
  3. CommunicationRecipient via contact_points whose party_id is in
    the same set — communications addressed by email/phone to a contact
    point owned by the scope (handles the email-thread case where the
    recipient_party_id is unset but the contact_point ties back).
    4-6. resource_type/resource_id matches one of the customer's
    quotes, orders, or opportunities — communications about a record
    in the customer's transaction history.
  4. resource_type='Customer' + resource_id=customer.id — communications
    threaded against the customer record itself.

Branches are merged with SQL UNION (deduplication baked in — a
communication sent by the customer about their own order shows up once,
not three times). The result is wrapped in Communication.from(...) so
downstream .where / .order see a relation whose model is Communication.

Returns:

  • (ActiveRecord::Relation<Communication>)

    relation rooted on
    Communication.from("(<UNION sql>) AS communications") — the seven
    branches' results merged via SQL UNION, wrapped in a derived table
    so further .where / .order chain naturally.



51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'app/services/query/customer_related_communications.rb', line 51

def call
  party_ids = @customer.self_and_contacts_party_ids_arr
  branches = [
    Communication.where(recipient_party_id: party_ids),
    Communication.where(sender_party_id: party_ids),
    via_contact_points(party_ids),
    Communication.where(resource_type: 'Quote', resource_id: @customer.quotes.select(:id)),
    Communication.where(resource_type: 'Order', resource_id: @customer.orders.select(:id)),
    Communication.where(resource_type: 'Opportunity', resource_id: @customer.opportunities.select(:id)),
    Communication.where(resource_type: 'Customer', resource_id: @customer.id)
  ]
  Communication.from("(#{branches.map(&:to_sql).join(' UNION ')}) AS communications")
end