Class: CustomerSearch
- Inherits:
-
Search
- Object
- ActiveRecord::Base
- ApplicationRecord
- Search
- CustomerSearch
- Defined in:
- app/models/customer_search.rb
Overview
== Schema Information
Table name: searches
Database name: primary
id :integer not null, primary key
name :string(255)
persist :boolean default(FALSE)
pinned :boolean default(FALSE), not null
query_params :jsonb
result_set_size :integer default(0)
selected_columns :string is an Array
set_limit :integer default(25)
sort_column :string(255)
sort_columns :string default([]), not null, is an Array
sort_direction :string(255) default("ASC")
type :string(255) not null
created_at :datetime
updated_at :datetime
employee_id :integer
Indexes
employee_id_pinned (employee_id,pinned)
employee_id_type (employee_id,type)
Saved advanced-search query for CRM Customers — a Search STI subclass.
Its +query_params+ drive Ransack for the expressible predicates and the
non-Ransack filters in Models::CustomerSearchCriteria (has-ordered EXISTS,
ltree product containment, campaign membership, drop events, profile,
certified installer). It also exposes the CRM customer mass-actions, each of
which enqueues a +MassSearch::*+ worker over the search's selected records.
Constant Summary collapse
- CUSTOM_CRITERIA_KEYS =
Keys consumed by apply_custom_criteria — excluded from the Ransack strict probe
so we don't get false-positive InvalidSearchError reports in AppSignal. %w[ has_ordered_item_id has_ordered_product_category_id has_ordered_product_line_id has_ordered_days has_ordered_days_time_range_gteq has_ordered_days_time_range_lteq minimum_number_of_orders has_ordered_type has_not_ordered_days has_not_quoted_days campaign_id_in campaign_id_not_in has_campaign_activity_status custom_drop_reason_codes custom_drop_rep_ids profile_in profile_not_in is_certified_installer ].freeze
Constants inherited from Search
Constants included from Models::Schedulable
Models::Schedulable::SIMPLE_FORM_OPTIONS
Instance Attribute Summary
Attributes inherited from Search
#composite_columns, #pagy_count, #pagy_limit, #pagy_page, #sql_select_columns
Class Method Summary collapse
-
.custom_criteria_keys ⇒ Array<String>
+query_params+ keys handled outside Ransack (by Models::CustomerSearchCriteria), excluded from the strict Ransack probe.
-
.scope_options_for_mass_schedule_activity ⇒ Array<Array(String, String)>
+[label, value]+ scope options for the schedule-activity mass action.
-
.select_options_for_profile ⇒ Array<Array(String, String)>
Profile select options, prefixed with the "Any Organization" ('ORG') and "All Trade" ('TRADE') sentinels.
Instance Method Summary collapse
-
#address_id_fields ⇒ Array<Array(String, String)>
+[label, address-id column]+ pairs for the address-based mass-action target selector.
-
#drop_action_reps_for_select ⇒ Array<Array>
Sales-rep select options scoped to the customers currently in the search's result set.
-
#mass_assign_reps(params, cur_user = nil) ⇒ Hash
Enqueues rep assignment (with an optional logged activity) over the selected customers.
-
#mass_assign_source(params, cur_user = nil) ⇒ Hash
Enqueues a source-id update over the selected customers.
-
#mass_assign_to_audience(params, cur_user = nil) ⇒ Hash
Enqueues assignment of the selected customers to an existing audience.
-
#mass_assign_to_campaign(params, cur_user = nil) ⇒ Hash
Enqueues assignment of the selected customers to an existing or newly-named campaign.
-
#mass_auto_assign_sales_rep(params, cur_user = nil) ⇒ Hash
Enqueues automatic sales-rep assignment over the selected customers.
-
#mass_create_audience(params, cur_user = nil) ⇒ Hash
Enqueues creation of an audience from the selected customers.
-
#mass_delete_on_lead_qualify_and_guest_state(_params, cur_user = nil) ⇒ Hash
Enqueues deletion of the selected customers that are in lead-qualify or guest state.
-
#mass_drop_sales_rep(params, cur_user) ⇒ Hash
Enqueues dropping a sales rep from the selected customers, recording a reason.
-
#mass_locator_blacklist(params, cur_user) ⇒ Hash
Enqueues locator blacklisting of the selected customers.
-
#mass_locator_unblacklist(params, cur_user) ⇒ Hash
Enqueues removal of locator blacklisting from the selected customers.
-
#mass_locator_unwhitelist(_params, cur_user) ⇒ Hash
Enqueues removal of locator whitelisting from the selected customers.
-
#mass_locator_whitelist(params, cur_user) ⇒ Hash
Enqueues locator whitelisting of the selected customers.
-
#mass_online_account_invite(_params, cur_user = nil) ⇒ Hash
Enqueues online-account invitations to the selected customers.
-
#mass_schedule_activity(params, cur_user = nil) ⇒ Hash
Enqueues scheduling of an activity over the selected customers, optionally scoped to contacts and/or tied to a campaign.
-
#mass_switch_rep_roles(_params, cur_user = nil) ⇒ Hash
Enqueues swapping of primary/secondary rep roles over the selected customers.
-
#set_defaults ⇒ void
Default new customer searches to every state except guest.
Methods included from Models::CustomerSearchCriteria
Methods included from Models::SearchAddressable
Methods inherited from Search
#all_composite_columns, allowed_role_ids, #append_custom_column, #append_ouput_column, #append_to_sql_select_columns, #applicable_sort_terms, #apply_array_match, #apply_criteria, #apply_customer_cross_reference, #apply_distance_search, #apply_select, #apply_sort, #available_events, available_output_columns, #available_output_columns, base_search_class_name, #cleanup_search_results, composite_column, #composite_column, database_columns, default_columns, default_sort, #discard_excess, #effective_name, #effective_short_name, #employee, #enqueue_navbar_pinned_refresh, #fast_count, favorites, friendly_column_name, #get_pinned_results, #get_sort_term, global_favorite, has_role_for_search?, #human_query_params, instantiate_query_template, #instantiate_resource_updater, #limit_options, main_resource_class, main_resource_table, mass_actions_for_select, #mass_export, maximum_unpersisted_queries, #normalize_for_mass_update, options, options_classes, #output_columns_for_select, #pagy_from_search, #perform, #perform_selected, #pinned_query, #prepend_custom_column, #prepend_output_column, query_favorites_templates, #ransack_probe_params, recent_searches_for_employee_id, #record_list, #refresh_pinned_results, #remove_other_pins, search_name, #search_name, #search_results, search_type, search_type_humanized, select_sort_columns, #select_sort_columns, #select_statement, #set_sort_term, #sort_column1, #sort_column1=, #sort_column2, #sort_column2=, #sort_column3, #sort_column3=, #sort_columns_for_select, #sort_columns_to_hash, #sortable_column?, #target_geocoding, unpersisted_queries_quote_reached?, #unrecord_list, #validated_selected_columns, view_resource_class, view_resource_klass, #view_resource_klass, view_resource_table, visible?, with_search_results
Methods inherited from ApplicationRecord
ransackable_associations, ransackable_attributes, ransackable_scopes, ransortable_attributes, #to_relation
Methods included from Models::Schedulable
Methods included from Models::AfterCommittable
Methods included from Models::EventPublishable
Class Method Details
.custom_criteria_keys ⇒ Array<String>
Returns +query_params+ keys handled outside Ransack (by
Models::CustomerSearchCriteria), excluded from the strict Ransack probe.
109 110 111 |
# File 'app/models/customer_search.rb', line 109 def self.custom_criteria_keys CUSTOM_CRITERIA_KEYS end |
.scope_options_for_mass_schedule_activity ⇒ Array<Array(String, String)>
Returns +[label, value]+ scope options for the
schedule-activity mass action.
298 299 300 |
# File 'app/models/customer_search.rb', line 298 def self. [['Customer Only', 'customer_only'], ['Primary Contact', 'primary_contact'], ['All Active Contacts', 'all_active_contacts']] end |
.select_options_for_profile ⇒ Array<Array(String, String)>
Returns profile select options, prefixed with
the "Any Organization" ('ORG') and "All Trade" ('TRADE') sentinels.
400 401 402 |
# File 'app/models/customer_search.rb', line 400 def self. [['Any Organization', 'ORG'], ['All Trade', 'TRADE']] + Profile.(false) end |
Instance Method Details
#address_id_fields ⇒ Array<Array(String, String)>
Returns +[label, address-id column]+ pairs for
the address-based mass-action target selector.
394 395 396 |
# File 'app/models/customer_search.rb', line 394 def address_id_fields [%w[Shipping shipping_address_id], %w[Billing billing_address_id], %w[Mailing mailing_address_id]] end |
#drop_action_reps_for_select ⇒ Array<Array>
Sales-rep select options scoped to the customers currently in the search's
result set.
138 139 140 141 |
# File 'app/models/customer_search.rb', line 138 def drop_action_reps_for_select selected_customer_ids = search_results.pluck(:resource_id) Employee.(customer_ids: selected_customer_ids) end |
#mass_assign_reps(params, cur_user = nil) ⇒ Hash
Enqueues rep assignment (with an optional logged activity) over the selected customers.
148 149 150 151 152 153 154 155 156 |
# File 'app/models/customer_search.rb', line 148 def mass_assign_reps(params, cur_user = nil) jid = MassSearch::CustomerAssignRepsWorker.perform_async( 'search_id' => id, 'action_params' => { 'resource_params' => (params[:resource] || {}).to_h, 'activity' => (params[:activity] || {}).to_h }, 'user_id' => cur_user&.id, 'locale' => I18n.locale.to_s ) { status: :ok, job_id: jid } end |
#mass_assign_source(params, cur_user = nil) ⇒ Hash
Enqueues a source-id update over the selected customers.
182 183 184 185 186 187 188 189 190 |
# File 'app/models/customer_search.rb', line 182 def mass_assign_source(params, cur_user = nil) jid = ::SearchResourceUpdateWorker.perform_async( 'search_id' => id, 'action_params' => { 'resource_params' => { 'source_id' => params[:source_id] } }, 'user_id' => cur_user&.id, 'locale' => I18n.locale.to_s ) { status: :ok, job_id: jid } end |
#mass_assign_to_audience(params, cur_user = nil) ⇒ Hash
Enqueues assignment of the selected customers to an existing audience.
215 216 217 218 219 220 221 222 223 224 225 |
# File 'app/models/customer_search.rb', line 215 def mass_assign_to_audience(params, cur_user = nil) return { status: :error, message: 'You must specify an audience' } if params[:audience_id].blank? jid = MassSearch::CustomerAssignToAudienceWorker.perform_async( 'search_id' => id, 'action_params' => { 'audience_id' => params[:audience_id] }, 'user_id' => cur_user&.id, 'locale' => I18n.locale.to_s ) { status: :ok, job_id: jid } end |
#mass_assign_to_campaign(params, cur_user = nil) ⇒ Hash
Enqueues assignment of the selected customers to an existing or newly-named campaign.
233 234 235 236 237 238 239 240 241 242 243 244 |
# File 'app/models/customer_search.rb', line 233 def mass_assign_to_campaign(params, cur_user = nil) campaign_params = params[:campaign] || {} return { status: :error, message: 'You must specify an existing campaign or enter a name for a new campaign' } if campaign_params[:campaign_id].blank? && campaign_params[:new_campaign_name].blank? jid = MassSearch::CustomerAssignToCampaignWorker.perform_async( 'search_id' => id, 'action_params' => { 'campaign' => campaign_params.to_h }, 'user_id' => cur_user&.id, 'locale' => I18n.locale.to_s ) { status: :ok, job_id: jid } end |
#mass_auto_assign_sales_rep(params, cur_user = nil) ⇒ Hash
Enqueues automatic sales-rep assignment over the selected customers.
163 164 165 166 167 168 169 170 171 172 173 174 175 |
# File 'app/models/customer_search.rb', line 163 def mass_auto_assign_sales_rep(params, cur_user = nil) jid = MassSearch::CustomerAutoAssignSalesRepWorker.perform_async( 'search_id' => id, 'action_params' => { 'remove_existing_reps' => params[:remove_existing_reps], 'skip_lead_assignment' => params[:skip_lead_assignment], 'activity' => (params[:activity] || {}).to_h }, 'user_id' => cur_user&.id, 'locale' => I18n.locale.to_s ) { status: :ok, job_id: jid } end |
#mass_create_audience(params, cur_user = nil) ⇒ Hash
Enqueues creation of an audience from the selected customers.
197 198 199 200 201 202 203 204 205 206 207 208 |
# File 'app/models/customer_search.rb', line 197 def mass_create_audience(params, cur_user = nil) audience_params = (params[:audience] || {}).to_h return { status: :error, message: 'You must specify a name and type for the audience' } if audience_params[:audience_name].blank? || audience_params[:audience_type].blank? jid = MassSearch::CustomerCreateAudienceWorker.perform_async( 'search_id' => id, 'action_params' => { 'audience' => audience_params }, 'user_id' => cur_user&.id, 'locale' => I18n.locale.to_s ) { status: :ok, job_id: jid } end |
#mass_delete_on_lead_qualify_and_guest_state(_params, cur_user = nil) ⇒ Hash
Enqueues deletion of the selected customers that are in lead-qualify or guest state.
266 267 268 269 270 271 272 273 274 |
# File 'app/models/customer_search.rb', line 266 def mass_delete_on_lead_qualify_and_guest_state(_params, cur_user = nil) jid = MassSearch::CustomerDeleteLeadsWorker.perform_async( 'search_id' => id, 'action_params' => {}, 'user_id' => cur_user&.id, 'locale' => I18n.locale.to_s ) { status: :ok, job_id: jid } end |
#mass_drop_sales_rep(params, cur_user) ⇒ Hash
Enqueues dropping a sales rep from the selected customers, recording a reason.
307 308 309 310 311 312 313 314 315 |
# File 'app/models/customer_search.rb', line 307 def mass_drop_sales_rep(params, cur_user) jid = MassSearch::CustomerDropSalesRepWorker.perform_async( 'search_id' => id, 'action_params' => { 'sales_rep_id' => params[:sales_rep_id], 'reason_code' => params[:reason_code], 'comment' => params[:comment] }, 'user_id' => cur_user&.id, 'locale' => I18n.locale.to_s ) { status: :ok, job_id: jid } end |
#mass_locator_blacklist(params, cur_user) ⇒ Hash
Enqueues locator blacklisting of the selected customers.
337 338 339 340 341 342 343 344 345 |
# File 'app/models/customer_search.rb', line 337 def mass_locator_blacklist(params, cur_user) jid = MassSearch::CustomerLocatorBlacklistWorker.perform_async( 'search_id' => id, 'action_params' => { 'reason' => params[:reason] }, 'user_id' => cur_user&.id, 'locale' => I18n.locale.to_s ) { status: :ok, job_id: jid } end |
#mass_locator_unblacklist(params, cur_user) ⇒ Hash
Enqueues removal of locator blacklisting from the selected customers.
367 368 369 370 371 372 373 374 375 |
# File 'app/models/customer_search.rb', line 367 def mass_locator_unblacklist(params, cur_user) jid = MassSearch::CustomerLocatorUnblacklistWorker.perform_async( 'search_id' => id, 'action_params' => { 'inform_customer' => params[:inform_customer] }, 'user_id' => cur_user&.id, 'locale' => I18n.locale.to_s ) { status: :ok, job_id: jid } end |
#mass_locator_unwhitelist(_params, cur_user) ⇒ Hash
Enqueues removal of locator whitelisting from the selected customers.
352 353 354 355 356 357 358 359 360 |
# File 'app/models/customer_search.rb', line 352 def mass_locator_unwhitelist(_params, cur_user) jid = MassSearch::CustomerLocatorUnwhitelistWorker.perform_async( 'search_id' => id, 'action_params' => {}, 'user_id' => cur_user&.id, 'locale' => I18n.locale.to_s ) { status: :ok, job_id: jid } end |
#mass_locator_whitelist(params, cur_user) ⇒ Hash
Enqueues locator whitelisting of the selected customers.
322 323 324 325 326 327 328 329 330 |
# File 'app/models/customer_search.rb', line 322 def mass_locator_whitelist(params, cur_user) jid = MassSearch::CustomerLocatorWhitelistWorker.perform_async( 'search_id' => id, 'action_params' => { 'reason' => params[:reason] }, 'user_id' => cur_user&.id, 'locale' => I18n.locale.to_s ) { status: :ok, job_id: jid } end |
#mass_online_account_invite(_params, cur_user = nil) ⇒ Hash
Enqueues online-account invitations to the selected customers.
382 383 384 385 386 387 388 389 390 |
# File 'app/models/customer_search.rb', line 382 def mass_online_account_invite(_params, cur_user = nil) jid = MassSearch::CustomerOnlineAccountInviteWorker.perform_async( 'search_id' => id, 'action_params' => {}, 'user_id' => cur_user&.id, 'locale' => I18n.locale.to_s ) { status: :ok, job_id: jid } end |
#mass_schedule_activity(params, cur_user = nil) ⇒ Hash
Enqueues scheduling of an activity over the selected customers, optionally
scoped to contacts and/or tied to a campaign.
282 283 284 285 286 287 288 289 290 291 292 293 294 |
# File 'app/models/customer_search.rb', line 282 def mass_schedule_activity(params, cur_user = nil) activity_params = (params[:activity] || {}).to_h apply_scope = activity_params.delete('apply_scope') campaign_id = activity_params.delete('campaign_id') jid = MassSearch::CustomerScheduleActivityWorker.perform_async( 'search_id' => id, 'action_params' => { 'activity' => activity_params, 'apply_scope' => apply_scope, 'campaign_id' => campaign_id }, 'user_id' => cur_user&.id, 'locale' => I18n.locale.to_s ) { status: :ok, job_id: jid } end |
#mass_switch_rep_roles(_params, cur_user = nil) ⇒ Hash
Enqueues swapping of primary/secondary rep roles over the selected customers.
251 252 253 254 255 256 257 258 259 |
# File 'app/models/customer_search.rb', line 251 def mass_switch_rep_roles(_params, cur_user = nil) jid = MassSearch::CustomerSwitchRepRolesWorker.perform_async( 'search_id' => id, 'action_params' => {}, 'user_id' => cur_user&.id, 'locale' => I18n.locale.to_s ) { status: :ok, job_id: jid } end |
#set_defaults ⇒ void
This method returns an undefined value.
Default new customer searches to every state except guest. Expressed as
state_in (positive list) rather than state_not_in: ['guest'] so the
Status filter renders as "is any of" with the included states visible —
clearer to users than an exclusion they have to mentally invert.
119 120 121 122 123 124 125 126 127 128 |
# File 'app/models/customer_search.rb', line 119 def set_defaults super return unless new_record? qp = (query_params || {}).with_indifferent_access return if qp[:state_in].present? || qp[:state_not_in].present? non_guest_states = Customer.states_for_select.map(&:last) - ['guest'] self.query_params = (query_params || {}).merge('state_in' => non_guest_states) end |