Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save jnarowski/7eab1ae6569578a7920f6b12e6f565aa to your computer and use it in GitHub Desktop.
Save jnarowski/7eab1ae6569578a7920f6b12e6f565aa to your computer and use it in GitHub Desktop.
class ReadModel::ContactsSource
include Common::HasAccessor
inject :config
inject :contacts_authorization
inject :history_source
CONTACT_FIELDS = [
:leads__id, :first_name, :last_name, :position, :cached_tag_list, :lead_status_id,
:lead_process_id, :user_id, :leads__created_at, :leads__updated_at,
:referral_source_id, :background, :leads__private, :avatar_file_name, :company_id,
:created_by_id, :group_id, :note_last_added_at, :private_notes,
:department, :prefix, :note_last_added_id, :industry_id, :organization_id
]
def get_contact(contact_id)
contact = DB[:leads].where(id: contact_id).first || (raise Common::Errors::RecordNotFound)
ReadModel::Support::Avatars.add_contact_avatar_url!(contact, config)
contact[:contact_buckets] = DB[:lead_buckets].select(:id, :bucket_id).where(lead_id: contact[:id]).all
contact[:company] = DB[:companies].select(:id, :name).where(id: contact[:company_id]).first if contact[:company_id]
contact[:emails] = DB[:secondary_emails].where(lead_id: contact_id).all
contact[:websites] = DB[:secondary_websites].where(lead_id: contact_id).all
contact[:phone_numbers] = DB[:phone_numbers].where(record_id: contact_id, record_type: 'Contact').all
contact[:addresses] = DB[:addresses].where(record_id: contact_id, record_type: 'Contact').all
contact[:social_accounts] = DB[:social_accounts].where(record_id: contact_id, record_type: 'Contact').all
contact[:permissions] = DB[:permissions].where(record_id: contact_id, record_type: 'Contact').all
contact[:field_values] = DB[:field_values].where(fielder_id: contact_id, fielder_type: 'Contact').all
contact[:important_dates] = DB[:important_dates].where(dater_id: contact_id, dater_type: 'Contact').all
contact[:google_contact_sync] = DB[:leads_syncs].where(lead_id: contact_id, sync_type: 'google_contacts').order(:id).last
contact[:permission] = contacts_authorization.can_update_read_model?(contact) ? 1 : 0
ReadModel::Support::Attachments.add_attachments!([contact], 'Contact', [contact_id], config)
ReadModel::Support::Relationships.add_entity_relationships!(contact, 'Contact', config)
ReadModel::Support::Attachments.add_v2_fields!(contact[:attachments], accessor) if contact[:attachments]
contact
end
def get_contacts(options)
dataset = DB[:leads].select(*CONTACT_FIELDS).where(leads__organization_id: accessor.organization_id).order(:leads__id)
unless accessor.admin?
dataset = ReadModel::Support::Scopes.add_permission_scope(dataset, 'Contact', accessor.id, accessor.group_ids)
end
if since = options[:since]
dataset = dataset.where{ leads__updated_at >= since }
end
if options[:filters]
if options[:filters][:bucket_id]
dataset = dataset.
left_join(:lead_buckets, lead_id: :leads__id).
where(:lead_buckets__bucket_id => options[:filters][:bucket_id])
end
end
contacts = ReadModel::Support::Paginator.paginate(dataset, options[:page], options[:per_page] || accessor.per_page)
return contacts if contacts.empty?
contact_ids = contacts.map { |c| c[:id] }
companies = DB[:companies].where(id: contacts.map {|c| c[:company_id] }).all
companies_hash = Utils::Hash.hash_from_array(companies, :id)
contacts.each do |contact|
if company_id = contact[:company_id]
contact[:company] = companies_hash[company_id].try(:first)
end
if contact[:avatar_file_name]
avatar_file_name = contact[:avatar_file_name].gsub(' ', '_')
contact[:avatar_url] = config.s3_assets.contact_thumb % {
organization_id: contact[:organization_id], id: contact[:id], file_name: avatar_file_name
}
else
contact[:avatar_url] = config.s3_assets.contact_default_thumb
end
end
emails = DB[:secondary_emails].where(lead_id: contact_ids).all
add_associated_entities!(contacts, emails, :emails, :lead_id)
websites = DB[:secondary_websites].where(lead_id: contact_ids).all
add_associated_entities!(contacts, websites, :websites, :lead_id)
phone_numbers = DB[:phone_numbers].where(record_id: contact_ids, record_type: 'Contact').all
add_associated_entities!(contacts, phone_numbers, :phone_numbers, :record_id)
addresses = DB[:addresses].where(record_id: contact_ids, record_type: 'Contact').all
add_associated_entities!(contacts, addresses, :addresses, :record_id)
social_accounts = DB[:social_accounts].where(record_id: contact_ids, record_type: 'Contact').all
add_associated_entities!(contacts, social_accounts, :social_accounts, :record_id)
permissions = DB[:permissions].where(record_id: contact_ids, record_type: 'Contact').all
add_associated_entities!(contacts, permissions, :permissions, :record_id)
field_values = DB[:field_values].where(fielder_id: contact_ids, fielder_type: 'Contact').all
add_associated_entities!(contacts, field_values, :field_values, :fielder_id)
important_dates = DB[:important_dates].where(dater_id: contact_ids, dater_type: 'Contact').all
add_associated_entities!(contacts, important_dates, :important_dates, :dater_id)
relationship_fields = [
:relationships__id, :relationships__relater_id, :relationships__relatee_id, :relationships__relatee_type, :relationships__category,
:relationships__role, :relationships__relationship_type_id, :relationships__primary_item,
:companies__name___company_name, :leads__first_name, :leads__last_name, :proposals__name___deal_name,
:cases__subject___case_name,
]
relationships = DB[:relationships].select(*relationship_fields).
left_join(:leads, id: :relationships__relatee_id, 'Contact' => :relationships__relatee_type).
left_join(:companies, id: :relationships__relatee_id, 'Company' => :relationships__relatee_type).
left_join(:proposals, id: :relationships__relatee_id, 'Deal' => :relationships__relatee_type).
left_join(:cases, id: :relationships__relatee_id, 'Case' => :relationships__relatee_type).
where(relater_id: contact_ids, relater_type: 'Contact').all
add_associated_relationships!(contacts, relationships)
contacts
end
def get_bucket_contacts(options = {})
dataset = DB[:leads].select(*CONTACT_FIELDS).where(leads__organization_id: accessor.organization_id).order(:leads__id)
unless accessor.admin?
dataset = ReadModel::Support::Scopes.add_permission_scope(dataset, 'Contact', accessor.id, accessor.group_ids)
end
if options[:filters]
if options[:filters][:bucket_id]
dataset = dataset.
left_join(:lead_buckets, lead_id: :leads__id).
where(:lead_buckets__bucket_id => options[:filters][:bucket_id])
end
end
contacts = ReadModel::Support::Paginator.paginate(dataset, options[:page], options[:per_page] || accessor.per_page)
return contacts if contacts.empty?
contact_ids = contacts.map { |c| c[:id] }
companies = DB[:companies].where(id: contacts.map {|c| c[:company_id] }).all
companies_hash = Utils::Hash.hash_from_array(companies, :id)
contacts.each do |contact|
if company_id = contact[:company_id]
contact[:company] = companies_hash[company_id].try(:first)
end
if contact[:avatar_file_name]
avatar_file_name = contact[:avatar_file_name].gsub(' ', '_')
contact[:avatar_url] = config.s3_assets.contact_thumb % {
organization_id: contact[:organization_id], id: contact[:id], file_name: avatar_file_name
}
else
contact[:avatar_url] = config.s3_assets.contact_default_thumb
end
end
buckets = DB[:lead_buckets].where(lead_id: contact_ids).all
add_associated_buckets!(contacts, buckets)
# emails = DB[:secondary_emails].where(lead_id: contact_ids).all
# add_associated_entities!(contacts, emails, :emails, :lead_id)
#
# websites = DB[:secondary_websites].where(lead_id: contact_ids).all
# add_associated_entities!(contacts, websites, :websites, :lead_id)
#
# phone_numbers = DB[:phone_numbers].where(record_id: contact_ids, record_type: 'Contact').all
# add_associated_entities!(contacts, phone_numbers, :phone_numbers, :record_id)
#
# addresses = DB[:addresses].where(record_id: contact_ids, record_type: 'Contact').all
# add_associated_entities!(contacts, addresses, :addresses, :record_id)
#
# social_accounts = DB[:social_accounts].where(record_id: contact_ids, record_type: 'Contact').all
# add_associated_entities!(contacts, social_accounts, :social_accounts, :record_id)
#
# permissions = DB[:permissions].where(record_id: contact_ids, record_type: 'Contact').all
# add_associated_entities!(contacts, permissions, :permissions, :record_id)
#
# field_values = DB[:field_values].where(fielder_id: contact_ids, fielder_type: 'Contact').all
# add_associated_entities!(contacts, field_values, :field_values, :fielder_id)
#
# important_dates = DB[:important_dates].where(dater_id: contact_ids, dater_type: 'Contact').all
# add_associated_entities!(contacts, important_dates, :important_dates, :dater_id)
#
# relationship_fields = [
# :relationships__id, :relationships__relater_id, :relationships__relatee_id, :relationships__relatee_type, :relationships__category,
# :relationships__role, :relationships__relationship_type_id, :relationships__primary_item,
# :companies__name___company_name, :leads__first_name, :leads__last_name, :proposals__name___deal_name,
# :cases__subject___case_name,
# ]
# relationships = DB[:relationships].select(*relationship_fields).
# left_join(:leads, id: :relationships__relatee_id, 'Contact' => :relationships__relatee_type).
# left_join(:companies, id: :relationships__relatee_id, 'Company' => :relationships__relatee_type).
# left_join(:proposals, id: :relationships__relatee_id, 'Deal' => :relationships__relatee_type).
# left_join(:cases, id: :relationships__relatee_id, 'Case' => :relationships__relatee_type).
# where(relater_id: contact_ids, relater_type: 'Contact').all
# add_associated_relationships!(contacts, relationships)
contacts
end
def get_contacts_without_buckets(options = {})
dataset = DB[:leads].select(*CONTACT_FIELDS).where(leads__organization_id: accessor.organization_id).order(:leads__id)
unless accessor.admin?
dataset = ReadModel::Support::Scopes.add_permission_scope(dataset, 'Contact', accessor.id, accessor.group_ids)
end
dataset = dataset.where("(SELECT COUNT(lead_buckets.id) FROM lead_buckets WHERE leads.id = lead_buckets.lead_id) = 0")
if options[:filters]
if user_id = options[:filters][:user_id]
if user_id == 'mine'
dataset = dataset.where(user_id: accessor.id)
end
end
end
contacts = ReadModel::Support::Paginator.paginate(dataset, options[:page], options[:per_page] || accessor.per_page)
return contacts if contacts.empty?
contact_ids = contacts.map { |c| c[:id] }
companies = DB[:companies].where(id: contacts.map {|c| c[:company_id] }).all
companies_hash = Utils::Hash.hash_from_array(companies, :id)
contacts.each do |contact|
if company_id = contact[:company_id]
contact[:company] = companies_hash[company_id].try(:first)
end
if contact[:avatar_file_name]
avatar_file_name = contact[:avatar_file_name].gsub(' ', '_')
contact[:avatar_url] = config.s3_assets.contact_thumb % {
organization_id: contact[:organization_id], id: contact[:id], file_name: avatar_file_name
}
else
contact[:avatar_url] = config.s3_assets.contact_default_thumb
end
end
add_recent_notes!(contacts)
add_note_count!(contacts)
contacts
end
def get_removed_contacts(options)
dataset = DB[:removed_entities].where(organization_id: accessor.organization_id, entity_type: 'Contact')
dataset = dataset.where{ removed_at > options[:since] } if options[:since]
dataset.all
end
def get_entities_by_ids(contact_ids, options = {})
contact_fields = [:leads__id, :leads__organization_id, :first_name, :last_name, :leads__position, :cached_tag_list___tags, :lead_statuses__name___status,
:lead_processes__name___stage, :leads__created_at, :referral_sources__name___referral_source,
:background, :avatar_file_name, :company_id, :private_notes, :note_last_added_at,
:department, :industries__name___industry]
dataset = DB[:leads].select(*contact_fields).where(leads__id: contact_ids).order(:leads__id).
left_join(:lead_statuses, id: :leads__lead_status_id).
left_join(:lead_processes, id: :leads__lead_process_id).
left_join(:referral_sources, id: :leads__referral_source_id).
left_join(:industries, id: :leads__industry_id)
unless accessor.admin?
dataset = ReadModel::Support::Scopes.add_permission_scope(dataset, 'Contact', accessor.id, accessor.group_ids)
end
contacts = dataset.all
contact_ids = contacts.map { |c| c[:id] }
companies = DB[:companies].where(id: contacts.map {|c| c[:company_id] }).all
companies_hash = companies.index_by { |c| c[:id] }
contacts.each do |contact|
if company_id = contact[:company_id]
contact[:company] = companies_hash[company_id]
end
if contact[:avatar_file_name]
avatar_file_name = contact[:avatar_file_name].gsub(' ', '_')
contact[:avatar_url] = config.s3_assets.contact_thumb % {
organization_id: contact[:organization_id], id: contact[:id], file_name: avatar_file_name
}
else
contact[:avatar_url] = config.s3_assets.contact_default_thumb
end
end
emails = DB[:secondary_emails].where(lead_id: contact_ids).all
add_associated_entities!(contacts, emails, :emails, :lead_id)
websites = DB[:secondary_websites].where(lead_id: contact_ids).all
add_associated_entities!(contacts, websites, :websites, :lead_id)
phone_numbers = DB[:phone_numbers].where(record_id: contact_ids, record_type: 'Contact').all
add_associated_entities!(contacts, phone_numbers, :phone_numbers, :record_id)
addresses = DB[:addresses].where(record_id: contact_ids, record_type: 'Contact').all
add_associated_entities!(contacts, addresses, :addresses, :record_id)
social_accounts = DB[:social_accounts].where(record_id: contact_ids, record_type: 'Contact').all
add_associated_entities!(contacts, social_accounts, :social_accounts, :record_id)
buckets = DB[:lead_buckets].where(lead_id: contact_ids).all
add_associated_buckets!(contacts, buckets)
if options[:recent_notes]
add_recent_notes!(contacts)
end
contacts
end
def get_email_participants(ids)
contacts = DB[:leads].select(:id, :first_name, :last_name).where(id: ids).all
emails = DB[:secondary_emails].select(:lead_id, :email).where(lead_id: ids).all
emails_group = emails.group_by { |e| e[:lead_id] }
contacts.inject([]) do |result, contact|
if emails = emails_group[contact[:id]]
email_address = (emails.first || {})[:email]
result << {
id: contact[:id],
type: 'Contact',
label: "#{contact[:first_name]} #{contact[:last_name]}".strip,
email: email_address,
}
end
result
end
end
private
def add_note_count!(entities)
entities.each do |entity|
entity[:note_count] = 5
end
end
def add_recent_notes!(entities)
record_ids = entities.map{|e| e[:id] }
histories = history_source.get_related_histories({
record_type: 'Contact',
record_id: record_ids
})
entities.each do |entity|
contact_histories = histories.select{|h| h[:history_record_id] == entity[:id] && h[:external_type] == 'Note' }
entity[:recent_notes] = contact_histories[0..1]
end
end
def add_associated_buckets!(entities, lead_buckets)
entities.each do |entity|
entity[:bucket_ids] = lead_buckets.select{|lb| lb[:lead_id] == entity[:id] }.map {|b| b[:bucket_id]}
end
end
def add_associated_relationships!(entities, relationships)
entities_hash = Utils::Hash.hash_from_array(relationships, :relater_id)
entities.each do |entity|
entity[:relationships] = entities_hash[entity[:id].to_s]
end
end
def add_associated_entities!(entities, associated_entities, association_name, key)
entities_hash = Utils::Hash.hash_from_array(associated_entities, key)
entities.each do |entity|
entity[association_name] = entities_hash[entity[:id]]
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment