Class: Query::CustomerFinder
- Inherits:
-
Object
- Object
- Query::CustomerFinder
- Defined in:
- app/services/query/customer_finder.rb
Instance Attribute Summary collapse
-
#customer_scope ⇒ Object
readonly
Returns the value of attribute customer_scope.
-
#search_params ⇒ Object
readonly
Returns the value of attribute search_params.
Instance Method Summary collapse
- #cell ⇒ Object
- #company_name ⇒ Object
- #coordinate ⇒ Object
- #coordinates ⇒ Object
- #email ⇒ Object
- #email2 ⇒ Object
- #exclude_customer_ids ⇒ Object
- #fax ⇒ Object
- #find_contact_points ⇒ Object
- #find_duplicates ⇒ Object
- #find_matching_customer_names ⇒ Object
- #find_matching_person_names ⇒ Object
- #find_party_nearby ⇒ Object
-
#initialize(search_params = {}) ⇒ CustomerFinder
constructor
A new instance of CustomerFinder.
- #lat ⇒ Object
- #lng ⇒ Object
- #person_first_name ⇒ Object
- #person_last_name ⇒ Object
- #person_name ⇒ Object
- #phone ⇒ Object
- #phone2 ⇒ Object
- #split_person_name ⇒ Object
Constructor Details
#initialize(search_params = {}) ⇒ CustomerFinder
Returns a new instance of CustomerFinder.
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
# File 'app/services/query/customer_finder.rb', line 5 def initialize(search_params = {}) @search_params = search_params #Extract components if customer = @search_params[:customer] @search_params[:email] = customer.all_emails @search_params[:phone] = customer.all_phone_numbers @search_params[:company_name] = customer.full_name @search_params[:person_names] = customer.contacts.active.pluck(:full_name) @search_params[:person_names] << customer.full_name if customer.is_homeowner? @search_params[:coordinates] = customer.addresses.map{|a| (a.lat.present? and a.lng.present?) ? [a.lat,a.lng] : nil }.compact.uniq @search_params[:exclude_customer_ids] = [customer.id] end @customer_scope = search_params[:customer_scope] || Customer.all @customer_scope = @customer_scope.where.not(id: exclude_customer_ids) if exclude_customer_ids.present? end |
Instance Attribute Details
#customer_scope ⇒ Object (readonly)
Returns the value of attribute customer_scope.
3 4 5 |
# File 'app/services/query/customer_finder.rb', line 3 def customer_scope @customer_scope end |
#search_params ⇒ Object (readonly)
Returns the value of attribute search_params.
3 4 5 |
# File 'app/services/query/customer_finder.rb', line 3 def search_params @search_params end |
Instance Method Details
#cell ⇒ Object
38 39 40 |
# File 'app/services/query/customer_finder.rb', line 38 def cell @search_params[:cell].presence end |
#company_name ⇒ Object
46 47 48 |
# File 'app/services/query/customer_finder.rb', line 46 def company_name @search_params[:company_name].presence end |
#coordinate ⇒ Object
71 72 73 |
# File 'app/services/query/customer_finder.rb', line 71 def coordinate ( lat.nil? or lng.nil? ) ? nil : [lat,lng] end |
#coordinates ⇒ Object
66 67 68 69 |
# File 'app/services/query/customer_finder.rb', line 66 def coordinates res = @search_params[:coordinates] || [coordinate] res.uniq.compact.select{|coord| coord.length == 2} end |
#email ⇒ Object
22 23 24 |
# File 'app/services/query/customer_finder.rb', line 22 def email @search_params[:email].presence end |
#email2 ⇒ Object
26 27 28 |
# File 'app/services/query/customer_finder.rb', line 26 def email2 @search_params[:email2].presence end |
#exclude_customer_ids ⇒ Object
75 76 77 |
# File 'app/services/query/customer_finder.rb', line 75 def exclude_customer_ids [ @search_params[:exclude_customer_ids] ].flatten.compact.uniq end |
#fax ⇒ Object
42 43 44 |
# File 'app/services/query/customer_finder.rb', line 42 def fax @search_params[:fax].presence end |
#find_contact_points ⇒ Object
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 |
# File 'app/services/query/customer_finder.rb', line 96 def find_contact_points phones = [phone, phone2, cell].flatten.map(&:presence).uniq.compact phones = phones.map{|p| PhoneNumber.parse_and_format(p) }.compact details = phones + [email, email2].flatten.map(&:presence).uniq.compact return ContactPoint.none unless details.present? contact_points = ContactPoint.belonging_to_party.where(detail: details) party_ids = [] if contact_points.present? party_ids = contact_points.pluck(:party_id) else # Try email match on domain [email,email2].compact.each do |e| domain = QuickSearch::ContactPointEmailQuickSearch.domain_scan(e) if domain domain_contact_points = ContactPoint.emails.joins(:party).where.not(Party[:inactive].eq(true)).contains("@#{domain}") party_ids += domain_contact_points.pluck(:party_id) end end end party_ids.compact.uniq end |
#find_duplicates ⇒ Object
87 88 89 90 91 92 93 94 |
# File 'app/services/query/customer_finder.rb', line 87 def find_duplicates party_ids = [find_matching_customer_names, find_matching_person_names, find_contact_points, find_party_nearby].flatten.compact.uniq customers = customer_scope.where( "parties.id IN (:party_id) or exists(select 1 from parties cnt where cnt.id IN (:party_id) and cnt.customer_id = parties.id)", party_id: party_ids ) if exclude_customer_ids.present? customers = customers.where.not(id: exclude_customer_ids) end customers end |
#find_matching_customer_names ⇒ Object
117 118 119 120 121 122 123 124 125 126 127 |
# File 'app/services/query/customer_finder.rb', line 117 def find_matching_customer_names [company_name, person_name].flatten.map(&:presence).uniq.compact.map do |customer_name| # filter out noise words search_name = customer_name.split(/[ ,\.\-\&]/).delete_if{|x| segment = x.squish.downcase; ['inc','inc','llc','ltd'].include?(segment) || segment.length <= 2 }&.join(' ') cids = [] cids += customer_scope.where(Customer[:full_name].matches("%#{search_name}%")).limit(5).pluck(:id) cids += customer_scope.lookup(search_name).limit(6).pluck(:id) # cids += customer_scope.where("full_name ILIKE ?", "%#{search_name}%").limit(2).pluck(:id) cids end.flatten.uniq end |
#find_matching_person_names ⇒ Object
129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
# File 'app/services/query/customer_finder.rb', line 129 def find_matching_person_names [person_name].flatten.map(&:presence).uniq.compact.map do |full_name| #For the purpose of finding contact matches, we will only use firstname, lastname but we will still try an exact match pnp = PersonNameParser.new( full_name ) # Only attempt match if we have first and last name or we'll have a lot of junk if pnp.first && pnp.last Contact.where(Contact[:full_name].matches("%#{pnp.simple_name}%")).where.not(customer_id: nil).limit(5).pluck(:customer_id) + Contact.lookup(pnp.full_name).limit(6).pluck(:customer_id) # Contact.where( "full_name ILIKE ?", "%#{pnp.simple_name}%").limit(2).pluck(:customer_id) else nil end end.flatten.uniq end |
#find_party_nearby ⇒ Object
144 145 146 147 148 |
# File 'app/services/query/customer_finder.rb', line 144 def find_party_nearby coordinates.map do |coord| Address.geocoded.where.not(party_id: nil).near(coord,0.1).map(&:party_id) end end |
#lat ⇒ Object
79 80 81 |
# File 'app/services/query/customer_finder.rb', line 79 def lat @search_params[:lat].presence ? @search_params[:lat].to_f : nil end |
#lng ⇒ Object
83 84 85 |
# File 'app/services/query/customer_finder.rb', line 83 def lng @search_params[:lng].presence ? @search_params[:lng].to_f : nil end |
#person_first_name ⇒ Object
54 55 56 |
# File 'app/services/query/customer_finder.rb', line 54 def person_first_name split_person_name.first end |
#person_last_name ⇒ Object
58 59 60 |
# File 'app/services/query/customer_finder.rb', line 58 def person_last_name split_person_name.last end |
#person_name ⇒ Object
50 51 52 |
# File 'app/services/query/customer_finder.rb', line 50 def person_name @search_params[:person_name].presence end |
#phone ⇒ Object
30 31 32 |
# File 'app/services/query/customer_finder.rb', line 30 def phone @search_params[:phone].presence end |
#phone2 ⇒ Object
34 35 36 |
# File 'app/services/query/customer_finder.rb', line 34 def phone2 @search_params[:phone2].presence end |
#split_person_name ⇒ Object
62 63 64 |
# File 'app/services/query/customer_finder.rb', line 62 def split_person_name @split_person_name ||= PersonNameParser.new(person_name) end |