Class: Customer::NewCustomer
- Inherits:
-
Object
- Object
- Customer::NewCustomer
- Includes:
- ActiveModel::API, ActiveModel::Attributes, ActiveModel::Validations, ActiveModel::Validations::Callbacks, Normalizr::Concern, StripAttributes
- Defined in:
- app/services/customer/new_customer.rb
Constant Summary collapse
- REP_ASSIGN_METHODS =
{ aa: 'Auto Assign', sa: 'Self Assign', ma: 'Manually Assign', dna: 'Do Not Assign' }.with_indifferent_access
Instance Attribute Summary collapse
- #cell ⇒ Object readonly
-
#email ⇒ Object
readonly
We always validate these fields no matter what step we're in.
-
#email2 ⇒ Object
readonly
We always validate these fields no matter what step we're in.
- #fax ⇒ Object readonly
- #phone ⇒ Object readonly
- #phone2 ⇒ Object readonly
- #website ⇒ Object readonly
Delegated Instance Attributes collapse
-
#company_id ⇒ Object
Alias for Catalog#company_id.
Instance Method Summary collapse
-
#address_complete? ⇒ Boolean
Bare mininum information we need for a valid address.
-
#allow_disablement_of_address_validation? ⇒ Boolean
Accessor method to determine if we can allow disabling the address validation.
- #assignment_step? ⇒ Boolean
-
#build_address(address) ⇒ Object
Copy over address attributes.
-
#build_and_save_customer(check_for_spam: false) ⇒ Object
Builds, qualify, create lead and save customer.
-
#build_contact_points(party) ⇒ Object
Build the contact points into the party.
-
#build_customer ⇒ Object
Instantiate a new customer translating all attributes from newcustomer.
-
#buying_group ⇒ Object
Accessor method to retrieve buying group.
-
#buying_group_options_for_select ⇒ Object
Retrieves a list of buying available for the customer company.
-
#catalog ⇒ Object
Catalog is based on country in this model.
- #catalog_id ⇒ Object
- #catalog_name ⇒ Object
-
#company_name_parts ⇒ Object
Split company name in parts for highlighting on screen.
- #contact_point_details ⇒ Object
- #default_pricing_program ⇒ Object
- #default_profile ⇒ Object
- #find_duplicates ⇒ Object
- #full_address ⇒ Object
- #has_address? ⇒ Boolean
- #identify_step? ⇒ Boolean
- #is_individual? ⇒ Boolean
- #is_organization? ⇒ Boolean
- #is_spam? ⇒ Boolean
-
#name_presence ⇒ Object
Check for name presence and normalize the person name using our name parser e.g Smith, John III will be John Smith III.
- #person_first_name ⇒ Object
- #person_last_name ⇒ Object
-
#person_name_parts ⇒ Object
Split person name in parts for highlighting on screen.
-
#pricing_program_options_for_select ⇒ Object
Used in the final step to determine the pricing offered.
-
#profile ⇒ Object
Accessor method to retrieve profile.
-
#profile_collection_for_select ⇒ Object
List of profiles for selection, we assume an individual is always a homeowner only, otherwise we pull up every trade.
- #rep_assignment_method_name ⇒ Object
- #set_default_email_preferences ⇒ Object
-
#set_email_preferences ⇒ Object
Creates or updates email preferences if an email address was provided.
- #setup_or_assignment_step? ⇒ Boolean
- #setup_step? ⇒ Boolean
-
#split_person_name ⇒ Object
Calls the person name parser to split a name, returns a hash with :first_name, :last_name, :middle_name, :suffix, :prefix.
- #start_in_lead_qualify? ⇒ Boolean
- #website_url_to_base_url ⇒ Object
Instance Attribute Details
#cell ⇒ Object (readonly)
67 |
# File 'app/services/customer/new_customer.rb', line 67 validates :phone, :phone2, :cell, :fax, phone_format: true |
#email ⇒ Object (readonly)
We always validate these fields no matter what step we're in
Validations:
- Email_format
66 |
# File 'app/services/customer/new_customer.rb', line 66 validates :email, :email2, email_format: true |
#email2 ⇒ Object (readonly)
We always validate these fields no matter what step we're in
Validations:
- Email_format
66 |
# File 'app/services/customer/new_customer.rb', line 66 validates :email, :email2, email_format: true |
#fax ⇒ Object (readonly)
67 |
# File 'app/services/customer/new_customer.rb', line 67 validates :phone, :phone2, :cell, :fax, phone_format: true |
#phone ⇒ Object (readonly)
67 |
# File 'app/services/customer/new_customer.rb', line 67 validates :phone, :phone2, :cell, :fax, phone_format: true |
#phone2 ⇒ Object (readonly)
67 |
# File 'app/services/customer/new_customer.rb', line 67 validates :phone, :phone2, :cell, :fax, phone_format: true |
#website ⇒ Object (readonly)
68 |
# File 'app/services/customer/new_customer.rb', line 68 validates :website, url: { allow_nil: true, allow_blank: true } |
Instance Method Details
#address_complete? ⇒ Boolean
Bare mininum information we need for a valid address
324 325 326 |
# File 'app/services/customer/new_customer.rb', line 324 def address_complete? %i[street1 city postal_code country_iso].all? { |f| send(f).presence } end |
#allow_disablement_of_address_validation? ⇒ Boolean
Accessor method to determine if we can allow disabling the address validation
377 378 379 |
# File 'app/services/customer/new_customer.rb', line 377 def allow_disablement_of_address_validation? @address_carrier_error end |
#assignment_step? ⇒ Boolean
102 103 104 |
# File 'app/services/customer/new_customer.rb', line 102 def assignment_step? step == :assignment end |
#build_address(address) ⇒ Object
Copy over address attributes
292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 |
# File 'app/services/customer/new_customer.rb', line 292 def build_address(address) address.street1 = street1 address.street2 = street2 address.city = city address.state_code = state_code address.zip = postal_code address.country_iso3 = Country.find_by(iso: country_iso).iso3 address.is_residential = residential_address.nil? ? false : residential_address address.lat = lat address.lng = lng address.has_loading_dock = has_loading_dock address.is_construction_site = is_construction_site address.requires_inside_delivery = requires_inside_delivery address.requires_liftgate = requires_liftgate address.limited_access = limited_access address.requires_appointment = requires_appointment address.disable_address_correction = disable_address_correction.nil? ? false : disable_address_correction address end |
#build_and_save_customer(check_for_spam: false) ⇒ Object
Builds, qualify, create lead and save customer
333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 |
# File 'app/services/customer/new_customer.rb', line 333 def build_and_save_customer(check_for_spam: false) customer = build_customer if check_for_spam && is_spam? customer.errors.add(:base, 'Spam customer detected') else customer.state = 'lead_qualify' customer.state_event = :complete_qualification unless start_in_lead_qualify? if customer.save # Update the return path self.return_path = return_path && customer.id && return_path.gsub('new_party_id', customer.id.to_s) NewLead::LeadActivityAssigner.new.process(customer, notes: notes) # unless customer.primary_sales_rep_id.nil? # record email preferences set_email_preferences # Broadcast product interest if any customer.broadcast_product_interest_changed(product_line_ids_added: customer.product_line_ids) # Broadcast buying groups if any customer.(buying_group_id_added: customer.) # Queue profile image lookup (logo from Clearbit) PartyProfileImageWorker.perform_async(customer.id) end end customer end |
#build_contact_points(party) ⇒ Object
Build the contact points into the party
313 314 315 316 317 318 319 320 321 |
# File 'app/services/customer/new_customer.rb', line 313 def build_contact_points(party) party.contact_points.build(detail: phone, category: ContactPoint::PHONE) if phone.present? party.contact_points.build(detail: phone2, category: ContactPoint::PHONE) if phone2.present? party.contact_points.build(detail: cell, category: ContactPoint::CELL) if cell.present? party.contact_points.build(detail: fax, category: ContactPoint::FAX) if fax.present? party.contact_points.build(detail: email, category: ContactPoint::EMAIL) if email.present? party.contact_points.build(detail: email2, category: ContactPoint::EMAIL) if email2.present? party.contact_points.build(detail: website, category: ContactPoint::WEBSITE) if website.present? end |
#build_customer ⇒ Object
Instantiate a new customer translating all attributes from newcustomer
251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 |
# File 'app/services/customer/new_customer.rb', line 251 def build_customer cu = Customer.new cu.profile_id = profile_id cu. = cu.source_id = source_id cu.source_info = source_info.presence cu.preferred_language = preferred_language cu.catalog_id = catalog_id cu.tier2_program_pricing_id = tier2_program_pricing_id cu.gclid = gclid.presence # Split the person name, we'll reuse that later pnp = split_person_name if company_name.blank? pnp.to_party(cu) else # If not company, build a person cu.full_name = company_name if pnp.valid? # A contact is present cnt = cu.contacts.build pnp.to_party(cnt) cnt.job_title = job_title end end # Build the contact points into the contact if present otherwise customer build_contact_points(cnt || cu) cu.primary_sales_rep_id = primary_sales_rep_id cu.secondary_sales_rep_id = secondary_sales_rep_id cu.local_sales_rep_id = local_sales_rep_id cu.service_rep_id = service_rep_id cu.do_not_auto_assign = (rep_assignment_method.to_s.to_sym == :dna) cu.creation_method = creation_method # Build the address if we have all the elements if address_complete? a = build_address(cu.addresses.new) cu.shipping_address = cu.billing_address = cu.mailing_address = a end cu.product_line_ids = (product_line_ids || []).compact.uniq cu end |
#buying_group ⇒ Object
Accessor method to retrieve buying group
215 216 217 |
# File 'app/services/customer/new_customer.rb', line 215 def BuyingGroup.find(.presence) if .presence end |
#buying_group_options_for_select ⇒ Object
Retrieves a list of buying available for the customer company
220 221 222 |
# File 'app/services/customer/new_customer.rb', line 220 def BuyingGroup.(company_id: company_id) end |
#catalog ⇒ Object
Catalog is based on country in this model
225 226 227 228 |
# File 'app/services/customer/new_customer.rb', line 225 def catalog # Always return a catalog; default to US when country is not provided Catalog.default_for_country(country_iso) end |
#catalog_id ⇒ Object
230 231 232 |
# File 'app/services/customer/new_customer.rb', line 230 def catalog_id catalog.try(:id) end |
#catalog_name ⇒ Object
234 235 236 |
# File 'app/services/customer/new_customer.rb', line 234 def catalog_name catalog.try(:name) end |
#company_id ⇒ Object
Alias for Catalog#company_id
238 |
# File 'app/services/customer/new_customer.rb', line 238 delegate :company_id, to: :catalog |
#company_name_parts ⇒ Object
Split company name in parts for highlighting on screen
165 166 167 |
# File 'app/services/customer/new_customer.rb', line 165 def company_name_parts company_name.to_s.split(/[ ,\.]/).map(&:presence).compact end |
#contact_point_details ⇒ Object
155 156 157 |
# File 'app/services/customer/new_customer.rb', line 155 def contact_point_details [email, phone, fax].compact.uniq end |
#default_pricing_program ⇒ Object
177 178 179 180 181 182 183 |
# File 'app/services/customer/new_customer.rb', line 177 def default_pricing_program if is_individual? Coupon::Tier2ProgramPricing.msrp_tier2_pricing_coupon else Coupon::Tier2ProgramPricing.customer_default_trade end end |
#default_profile ⇒ Object
185 186 187 188 189 190 191 |
# File 'app/services/customer/new_customer.rb', line 185 def default_profile if is_individual? Profile.homeowner_profile else Profile.unknown_trade end end |
#find_duplicates ⇒ Object
142 143 144 145 |
# File 'app/services/customer/new_customer.rb', line 142 def find_duplicates cf = Query::CustomerFinder.new(attributes) cf.find_duplicates end |
#full_address ⇒ Object
328 329 330 |
# File 'app/services/customer/new_customer.rb', line 328 def full_address %i[street1 city postal_code country_iso].map { |f| send(f).presence }.join(' ') end |
#has_address? ⇒ Boolean
112 113 114 |
# File 'app/services/customer/new_customer.rb', line 112 def has_address? street1.present? end |
#identify_step? ⇒ Boolean
94 95 96 |
# File 'app/services/customer/new_customer.rb', line 94 def identify_step? step == :identify end |
#is_individual? ⇒ Boolean
169 170 171 |
# File 'app/services/customer/new_customer.rb', line 169 def is_individual? company_name.blank? end |
#is_organization? ⇒ Boolean
173 174 175 |
# File 'app/services/customer/new_customer.rb', line 173 def is_organization? company_name.present? end |
#is_spam? ⇒ Boolean
381 382 383 384 385 386 |
# File 'app/services/customer/new_customer.rb', line 381 def is_spam? SpamCheck.new.process( author_email: email.presence, phone_number: phone.presence || phone2.presence || cell.presence || fax.presence ) end |
#name_presence ⇒ Object
Check for name presence and normalize the person name using our name parser
e.g Smith, John III will be John Smith III
118 119 120 121 122 123 124 125 126 127 |
# File 'app/services/customer/new_customer.rb', line 118 def name_presence if person_name.present? pnp = split_person_name self.person_name = pnp.full_name end return if company_name.present? or person_name.present? errors.add :company_name, 'must be specified if no person name present' errors.add :person_name, 'must be specified if no company name present' end |
#person_first_name ⇒ Object
147 148 149 |
# File 'app/services/customer/new_customer.rb', line 147 def person_first_name pnp.first end |
#person_last_name ⇒ Object
151 152 153 |
# File 'app/services/customer/new_customer.rb', line 151 def person_last_name pnp.last end |
#person_name_parts ⇒ Object
Split person name in parts for highlighting on screen
160 161 162 |
# File 'app/services/customer/new_customer.rb', line 160 def person_name_parts person_name.to_s.scan(/(\w+)/).flatten end |
#pricing_program_options_for_select ⇒ Object
Used in the final step to determine the pricing offered
194 195 196 |
# File 'app/services/customer/new_customer.rb', line 194 def Coupon::Tier2ProgramPricing.(build_customer) end |
#profile ⇒ Object
Accessor method to retrieve profile
199 200 201 |
# File 'app/services/customer/new_customer.rb', line 199 def profile Profile.find(profile_id) if profile_id.present? end |
#profile_collection_for_select ⇒ Object
List of profiles for selection, we assume an individual is always a homeowner
only, otherwise we pull up every trade
205 206 207 208 209 210 211 212 |
# File 'app/services/customer/new_customer.rb', line 205 def profile_collection_for_select profiles = if is_individual? Profile.homeowner else Profile.trades end profiles.order(:name).pluck(:name, :id) end |
#rep_assignment_method_name ⇒ Object
90 91 92 |
# File 'app/services/customer/new_customer.rb', line 90 def rep_assignment_method_name REP_ASSIGN_METHODS[rep_assignment_method] end |
#set_default_email_preferences ⇒ Object
240 241 242 243 244 245 246 247 248 |
# File 'app/services/customer/new_customer.rb', line 240 def set_default_email_preferences # If it's for US, subscribe to everything by default # Canada will therefore be unsubscribed by default default_value = company_id == 1 %i[subscribe_to_announcements subscribe_to_events subscribe_to_newsletters subscribe_to_product_review_requests subscribe_to_promotions subscribe_to_webinars].each do |field| public_send(:"#{field}=", default_value) if public_send(field).nil? end end |
#set_email_preferences ⇒ Object
Creates or updates email preferences if an email address was provided
359 360 361 362 363 364 365 366 367 368 369 |
# File 'app/services/customer/new_customer.rb', line 359 def set_email_preferences return true if email.blank? ep = EmailPreference.find_or_initialize_by(email: email&.downcase) ep.disable_announcements = subscribe_to_announcements != true ep.disable_events = subscribe_to_events != true ep. = != true ep.disable_promotions = subscribe_to_promotions != true ep.disable_webinars = subscribe_to_webinars != true ep.save end |
#setup_or_assignment_step? ⇒ Boolean
106 107 108 |
# File 'app/services/customer/new_customer.rb', line 106 def setup_or_assignment_step? (setup_step? or assignment_step?) end |
#setup_step? ⇒ Boolean
98 99 100 |
# File 'app/services/customer/new_customer.rb', line 98 def setup_step? step == :setup end |
#split_person_name ⇒ Object
Calls the person name parser to split a name, returns a hash with :first_name, :last_name, :middle_name, :suffix, :prefix
372 373 374 |
# File 'app/services/customer/new_customer.rb', line 372 def split_person_name PersonNameParser.new(person_name) end |
#start_in_lead_qualify? ⇒ Boolean
110 |
# File 'app/services/customer/new_customer.rb', line 110 def start_in_lead_qualify? = start_in_lead_qualify |
#website_url_to_base_url ⇒ Object
129 130 131 132 133 134 135 136 137 138 139 140 |
# File 'app/services/customer/new_customer.rb', line 129 def website_url_to_base_url return unless website.present? pv = begin Addressable::URI.parse(website) rescue StandardError nil end return unless pv self.website = "#{pv.scheme || 'https'}://#{pv.host}" end |