Created
May 12, 2016 12:32
-
-
Save jnarowski/7eab1ae6569578a7920f6b12e6f565aa to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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