Class: CustomersController
- Inherits:
-
CrmController
- Object
- ActionController::Base
- ApplicationController
- CrmController
- CustomersController
- Includes:
- Controllers::ActivitiesTab, Controllers::CommunicationsTab, Controllers::DigitalAssetLinkable, Controllers::OpportunitiesTab, Controllers::OrdersTab, Controllers::RequireTurboFrame, Controllers::SmsTab, Controllers::UploadsTab, Controllers::Workflowable
- Defined in:
- app/controllers/customers_controller.rb
Overview
Controller: customers.
Constant Summary collapse
- TAB_ACTIONS =
Tab fragments never render standalone — non-frame hits redirect to show ?tab=.
%i[tab_digital_assets tab_attachments tab_communications tab_sms tab_activities tab_opportunities tab_orders tab_accounting tab_addresses tab_certifications tab_contacts tab_lead_protections tab_main_profile tab_marketing tab_product_reviews tab_warranty tab_profiling tab_receipts tab_showcases tab_stats tab_subsidiaries tab_tickets tab_training tab_outlet_purchases].freeze
Constants included from Controllers::ReferenceFindable
Controllers::ReferenceFindable::ID_EMBEDDED_PATTERNS
Constants included from Controllers::AnalyticsEvents
Controllers::AnalyticsEvents::MAX_QUEUED_EVENTS, Controllers::AnalyticsEvents::SESSION_KEY
Constants included from Controllers::ErrorRendering
Controllers::ErrorRendering::NON_CONTENT_PATH_PREFIXES
Instance Method Summary collapse
-
#accounting_action ⇒ void
Dispatches accounting-tab actions: create receipt, record payment, or transmit documents (invoices / credit memos / statements) via a new communication.
-
#add_to_campaign ⇒ void
Subscribes the customer to the selected marketing campaign.
-
#auto_increase_available_credit ⇒ void
Attempts an automatic available-credit increase (terms customers only), falling back to an Accounting approval request.
-
#available_credit ⇒ void
Renders the available-credit page.
-
#check_credit_limit ⇒ void
Renders the credit-limit check result for a quoted or entered order amount.
-
#closed ⇒ void
Starts the close-customer flow (drop event) when the customer can be closed.
-
#confirm_account_team ⇒ void
Saves the account team via
Customer::SalesRepAssigner. -
#confirm_lead_protection ⇒ void
Saves lead-protection changes.
-
#confirm_notification_channels ⇒ void
Saves notification-channel changes, surfacing duplicate-channel errors.
-
#confirm_pricing ⇒ void
Saves the pricing selection.
-
#confirm_profile ⇒ void
Saves profile changes; reassigns the pricing program when the profile changed.
-
#confirm_structure ⇒ void
Saves the parent-organization change.
-
#create ⇒ void
Legacy action — always raises; customers are created via customer_identify.
-
#create_iq_accessory_preference ⇒ void
Creates an IQ accessory filter for the customer from an item or exclusive item group.
-
#create_topic_follow_up ⇒ void
Creates a topic follow-up communication for the customer and opens it for editing.
-
#delete_iq_accessory_preference ⇒ void
Deletes an IQ accessory preference.
-
#destroy ⇒ Object
DELETE /customers/1.
-
#do_auto_assign_sales_rep ⇒ void
Force-runs automatic sales-rep assignment for the customer.
-
#do_merge ⇒ void
Enqueues the customer-merge background job and redirects to the job page.
-
#drop_events ⇒ void
Renders the drop-events page.
-
#duplicates ⇒ void
(also: #complete_qualification)
Lists possible duplicate customers for merging, preemptively allocating a sales rep when qualification can complete.
-
#edit ⇒ Object
GET /customers/1/edit.
-
#edit_account_team ⇒ void
Renders the account-team editor.
-
#edit_accounting_information ⇒ void
Renders the accounting-information editor (read-only fallback when the user lacks permission).
-
#edit_catalog ⇒ void
Renders the catalog-change form for the customer.
-
#edit_default_address ⇒ void
Renders the default-address editor.
-
#edit_iq_accessory_preference ⇒ void
Renders the edit form for an IQ accessory preference.
-
#edit_lead_protection ⇒ void
Renders the lead-protection editor.
-
#edit_notification_channels ⇒ void
Renders the notification-channels editor.
-
#edit_pricing ⇒ void
Renders the pricing editor.
-
#edit_profile ⇒ void
Renders the profile editor.
-
#edit_shipping_preferences ⇒ void
Renders the shipping-preferences editor.
-
#edit_structure ⇒ void
Renders the structure (parent organization) editor.
-
#index ⇒ Object
GET /customers.
-
#iq_accessory_preferences ⇒ void
Lists the customer's auto-generated IQ accessory filters.
-
#lookup_emails ⇒ void
JSON autocomplete of the customer's (and contacts') email addresses.
-
#lookup_faxes ⇒ void
JSON autocomplete of the customer's (and contacts') fax numbers.
-
#lookup_phones ⇒ void
JSON autocomplete of the customer's (and contacts') phone numbers.
-
#marketing ⇒ void
Renders the marketing page (campaign memberships).
-
#merge ⇒ void
Renders the merge comparison screen for two customers, listing blocking errors (orders under shipping) for each side.
-
#merge_addresses ⇒ void
Runs the address-duplicate merger for the customer's addresses.
-
#merge_contact_points ⇒ void
Runs the contact-point merger for the customer's contact points.
-
#new ⇒ Object
GET /customers/new.
-
#new_iq_accessory_preference ⇒ void
Renders the new IQ accessory preference form.
-
#promotions ⇒ void
Renders the promotions list: active tier-3 coupons targeting the customer.
-
#radiant_rewards ⇒ void
Renders the Radiant Rewards page.
-
#recalculate_profiling_information ⇒ void
Recomputes the customer's profiling information.
-
#release_from_lead_qualification ⇒ void
Completes lead qualification for the customer, optionally pre-assigning a primary sales rep, and warns about held orders.
-
#sales_priority_index_analysis ⇒ void
Renders the sales-priority-index score breakdown for the customer.
-
#show ⇒ void
Shows the customer's details.
-
#show_accounting_information ⇒ void
Renders the read-only accounting-information view.
-
#statement_pdf ⇒ void
Generates the statement-of-account PDF and routes to a new communication carrying it (or back to the customer when there are no open documents).
-
#sync_credit ⇒ void
Re-synchronizes the customer's credit limit with the accounting system.
-
#tab_accounting ⇒ void
Renders the accounting tab: paginated AR listings plus per-currency open totals.
-
#tab_activities ⇒ void
Renders the activities tab fragment.
-
#tab_addresses ⇒ void
Renders the addresses tab fragment.
-
#tab_attachments ⇒ void
Renders the attachments (uploads) tab fragment.
-
#tab_certifications ⇒ void
Renders the certifications tab fragment.
-
#tab_communications ⇒ void
Renders the communications tab fragment.
-
#tab_contacts ⇒ void
Renders the contacts tab fragment.
-
#tab_digital_assets ⇒ void
Renders the digital-assets tab fragment.
-
#tab_lead_protections ⇒ void
Renders the lead-protections tab: customers this customer protects.
-
#tab_main_profile ⇒ void
Renders the main-profile tab fragment.
-
#tab_marketing ⇒ void
Renders the marketing tab fragment.
-
#tab_opportunities ⇒ void
Renders the opportunities tab fragment.
-
#tab_orders ⇒ void
Renders the orders tab fragment.
-
#tab_outlet_purchases ⇒ Object
Every retailer purchase we know this customer made, whether or not it ties to a project.
-
#tab_product_reviews ⇒ void
Renders the product-reviews tab: Reviews.io reviews plus the company review link.
-
#tab_profiling ⇒ void
Renders the profiling tab fragment.
-
#tab_receipts ⇒ void
Renders the receipts tab fragment.
-
#tab_showcases ⇒ void
Renders the showcases tab fragment.
-
#tab_sms ⇒ void
Renders the SMS tab fragment.
-
#tab_stats ⇒ void
Renders the stats tab fragment.
-
#tab_subsidiaries ⇒ void
Renders the subsidiaries tab fragment.
-
#tab_tickets ⇒ void
Renders the tickets tab fragment.
-
#tab_training ⇒ void
Renders the training tab: the customer's contacts' training topics grouped by topic category.
-
#tab_warranty ⇒ void
Renders the warranty tab fragment, loading the customer's warranties.
-
#update ⇒ Object
PUT /customers/1.
-
#update_accounting_information ⇒ void
Saves accounting information; restricted to admin and accounting_rep roles.
-
#update_catalog ⇒ void
Assigns the customer to a new catalog, converting orders, quotes, and rooms.
-
#update_default_address ⇒ void
Saves the customer's default address selection.
-
#update_iq_accessory_preference ⇒ void
Saves changes to an IQ accessory preference.
-
#update_shipping_preferences ⇒ void
Saves the customer's shipping preferences.
Methods included from Controllers::DigitalAssetLinkable
Methods included from Controllers::RequireTurboFrame
require_in_pane_tab_frames, require_turbo_frame
Methods included from Controllers::Workflowable
#render_workflow_error_stream, #render_workflow_success_stream, #workflow_action, #workflow_action_complete
Methods inherited from CrmController
#access_denied, #context_id, #context_object, #crm_home_path, #current_ability, #default_url_options, #download_temp, #get_tempfile_path_for_download, #init_status_job_collector, #initialize_crm_lazy_chunks, #persist_enqueued_status_jobs, #record_not_found, #redirect_to_job_or_fallback, #render_edit_action, #set_context, #set_download_path, #stash_file_for_temp_download, #sync_admin_presence_cookie, #touch_employee_last_seen
Methods inherited from ApplicationController
#account_impersonated?, #add_to_flash, #after_sign_in_path_for, #bypass_forgery_protection?, #chat_enabled?, #cloudflare_cleared?, #default_catalog, #default_url_options, #enable_turbo_frames, #find_publication, #fix_invalid_accept_header, #init_js_utils, #is_globals_call?, #layout_by_resource, #locale_store, #redirect_to, #require_employee_for_crm, #set_base_host, #set_real_ip, #set_report_errors_for, #should_render_layout?, #skip_layout_for_turbo_frame?, #stamp_impersonation_context, #tab_frame_breakout_request?, #warmlyyours_canada_ip?, #warmlyyours_ip?, #y
Methods included from Controllers::ReturnPathHandling
#check_for_return_path, #redirect_to_return_path_or_default
Methods included from Controllers::AnalyticsEvents
#consume_queued_analytics_events, #registration_lead_type, #track_event
Methods included from Controllers::DeviceDetection
Methods included from Controllers::SubdomainDetection
#is_crm_request?, #is_www_request?, #json_request?
Methods included from Controllers::TurboSafeRedirect
Methods included from Controllers::TrackingDetection
#bot_request?, #gdpr_country?, #gdpr_country_data, #prevent_bots, #set_tracking_cookie, #track_visitor?
Methods included from Controllers::AcceleratedFileSending
#send_file_accelerated, #send_upload_accelerated
Methods included from Controllers::ErrorRendering
#excp_string, #mail_to_for_error_reporting, #render_400, #render_404, #render_406, #render_410, #render_500, #render_invalid_authenticity_token, #render_ip_spoof_error, #render_unpermitted_parameters, #safe_referer_or_fallback
Methods included from Controllers::TurnstileVerification
#load_turnstile_script_tag, #turnstile_lazy_widget, #turnstile_script_tag, #turnstile_widget, #validate_turnstile!
Methods included from Controllers::CloudflareCaching
edge_cached, #edge_cached_action?, #reset_cloudflare_cache, #set_cloudflare_cache, #skip_edge_cache!, #skip_session
Methods included from Controllers::Webpackable
#preload_webpack_fonts, #webpack_css_include, #webpack_css_url, #webpack_js_include, #wpd_is_running?
Methods included from Controllers::Localizable
#cloudflare_country_locale, #determine_request_locale, #geocoder_locale, #guest_user_locale_check, #locale_optional_www_auth_path?, #param_locale, #set_locale, #set_request_locale, #skip_localization?, #warmlyyours_ip_locale
Methods included from Controllers::Authenticable
#access_denied, #authenticate_account, #authenticate_account!, #authenticate_account_from_login_token!, #check_is_a_manager, #check_is_a_sales_manager, #check_is_an_admin, #check_is_an_employee, #check_party, #clear_mismatched_guest_user, #create_guest_user, #credentials?, #current_or_guest_user, #current_or_guest_user_id_read_only, #current_user, #devise_mapping, #fully_logged_in?, #generate_bot_id, #guest_user, #identifiable?, #init_current_user, #initialize_guest, #load_context_user, #logging_in, #resource, #resource_name, #restrict_access_for_non_employees, #scrubbed_request_path, #user_object, #warn_on_session_guest_id_leak
Methods included from UrlsHelper
#catalog_breadcrumb_links, #catalog_link, #catalog_link_for_product_line, #catalog_link_for_sku, #cms_link, #delocalized_path, #path_to_sales_product_sku, #path_to_sales_product_sku_for_product_line, #path_to_sales_product_sku_for_product_line_slug, #product_line_from_catalog_link, #protocol_neutral_url, #sanitize_external_url, #valid_external_url?
Instance Method Details
#accounting_action ⇒ void
This method returns an undefined value.
Dispatches accounting-tab actions: create receipt, record payment, or
transmit documents (invoices / credit memos / statements) via a new
communication.
659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 |
# File 'app/controllers/customers_controller.rb', line 659 def accounting_action form_action, template_id = params[:transmit_instructions]&.split('|') case form_action when 'receipt' redirect_to new_receipt_path('credit_memos' => params['credit_memos'], 'invoices' => params['invoices']) when 'payment' redirect_to new_payment_receipts_path('customer_id' => @customer.id, 'invoices' => params['invoices'], 'credit_memos' => params['credit_memos'], :return_path => customer_path(@customer)) when 'transmit' if params[:invoices].blank? && params[:credit_memos].blank? && params[:soas].blank? flash[:error] = 'Please select documents to transmit' redirect_to customer_path(@customer, tab: 'accounting') else begin adt = AccountingDocumentTransmitter.new( { INV: params['invoices'], CM: params['credit_memos'], SOA: params['soas'] }, customer: @customer, template_id: template_id ) co = adt.build_communication if co.save redirect_to edit_communication_path(co.id) else flash[:error] = "Problem creating communication. #{co.errors_to_s}" redirect_to customer_path(@customer, tab: 'accounting') end rescue Dragonfly::Job::Fetch::NotFound => e flash[:error] = "One or more document PDFs could not be found. The invoice PDF may need to be regenerated. (#{e.})" redirect_to customer_path(@customer, tab: 'accounting') end end else flash[:error] = 'Unrecognized or unspecified action' redirect_to customer_path(@customer, tab: 'accounting') end end |
#add_to_campaign ⇒ void
This method returns an undefined value.
Subscribes the customer to the selected marketing campaign.
158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 |
# File 'app/controllers/customers_controller.rb', line 158 def add_to_campaign campaign_id = params.dig(:new_campaign, :campaign_id) if campaign_id.blank? flash[:error] = 'You must select a campaign' else campaign = Campaign.find(campaign_id) res = campaign.add_customer(@customer) if res.subscribed? flash[:info] = "Customer added to #{campaign.name}" else flash[:error] = "Customer not added to #{campaign.name}, error: #{res.}" end end redirect_to marketing_customer_path(@customer) end |
#auto_increase_available_credit ⇒ void
This method returns an undefined value.
Attempts an automatic available-credit increase (terms customers only),
falling back to an Accounting approval request.
835 836 837 838 839 840 841 842 843 844 845 |
# File 'app/controllers/customers_controller.rb', line 835 def auto_increase_available_credit order = params[:order_id].nil? ? nil : Order.find(params[:order_id]) if !@customer.has_terms? flash[:error] = 'Credit limit increase only available to customers with terms' elsif @customer.auto_increase_available_credit(params[:amount].to_d, order) flash[:info] = "Request approved. Available credit increased to #{number_to_currency(@customer.available_credit)}" else flash[:info] = 'Unable to automatically increase customer credit as some criteria were not met. Request has been sent to Accounting for approval.' end redirect_to_return_path_or_default(customer_path(@customer)) end |
#available_credit ⇒ void
This method returns an undefined value.
Renders the available-credit page.
285 |
# File 'app/controllers/customers_controller.rb', line 285 def available_credit; end |
#check_credit_limit ⇒ void
This method returns an undefined value.
Renders the credit-limit check result for a quoted or entered order
amount.
850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 |
# File 'app/controllers/customers_controller.rb', line 850 def check_credit_limit params[:check_credit_limit_params] ||= { order_amount: '' } @check_credit_limit_params = OpenStruct.new(params[:check_credit_limit_params]) @customer = Customer.find(params[:id]) quote = Quote.find(params[:check_credit_limit_params][:quote_id]) if params[:check_credit_limit_params][:quote_id].present? order_amount = params[:check_credit_limit_params][:order_amount] @amount = if quote.present? quote.total else (order_amount.present? ? order_amount.to_f : 0) end @result = {} @result = @customer.request_credit(@amount) if @amount.positive? end |
#closed ⇒ void
This method returns an undefined value.
Starts the close-customer flow (drop event) when the customer can be
closed.
823 824 825 826 827 828 829 830 |
# File 'app/controllers/customers_controller.rb', line 823 def closed if @customer.sales_reps_ids.present? || @customer.can_closed? redirect_to new_customer_customer_drop_event_path(customer_id: @customer.id) else flash[:info] = 'Customer is not in a state that can be closed' redirect_to customer_path(@customer) end end |
#confirm_account_team ⇒ void
This method returns an undefined value.
Saves the account team via Customer::SalesRepAssigner.
751 752 753 754 755 756 757 758 |
# File 'app/controllers/customers_controller.rb', line 751 def confirm_account_team rep_assigner = Customer::SalesRepAssigner.new(@customer) if rep_assigner.assign_reps(customer_account_team_params) redirect_to @customer, notice: 'Account Team Saved' else render :edit_account_team, status: :unprocessable_content end end |
#confirm_lead_protection ⇒ void
This method returns an undefined value.
Saves lead-protection changes.
797 798 799 800 801 802 803 |
# File 'app/controllers/customers_controller.rb', line 797 def confirm_lead_protection if @customer.update(params[:customer] || {}) redirect_to @customer, notice: 'Lead Protection Saved' else render :edit_lead_protection, status: :unprocessable_content end end |
#confirm_notification_channels ⇒ void
This method returns an undefined value.
Saves notification-channel changes, surfacing duplicate-channel errors.
780 781 782 783 784 785 786 787 788 789 |
# File 'app/controllers/customers_controller.rb', line 780 def confirm_notification_channels if @customer.update(params[:customer] || {}) redirect_to @customer, notice: 'Notification Channels Saved' else render :edit_notification_channels, status: :unprocessable_content end rescue ActiveRecord::RecordNotUnique @customer.errors.add(:base, 'A duplicate notification channel already exists. Please refresh and try again.') render :edit_notification_channels, status: :unprocessable_content end |
#confirm_pricing ⇒ void
This method returns an undefined value.
Saves the pricing selection.
736 737 738 739 740 741 742 743 |
# File 'app/controllers/customers_controller.rb', line 736 def confirm_pricing if @customer.update(customer_pricing_params) redirect_to @customer, notice: 'Pricing Selection Saved' else set_program_pricings render :edit_pricing, status: :unprocessable_content end end |
#confirm_profile ⇒ void
This method returns an undefined value.
Saves profile changes; reassigns the pricing program when the profile
changed.
715 716 717 718 719 720 721 722 723 724 725 726 |
# File 'app/controllers/customers_controller.rb', line 715 def confirm_profile res = Customer::UpdateProfile.new.process(@customer, customer_profile_params) if res.success if res.profile_changed Customer::PricingProgramAssigner.new(customer_id: @customer.id).update_customer # redirect_to questions_customer_pricing_program_assigner_path(@customer), notice: 'Profile updated, please confirm pricing' end redirect_to @customer else render :edit_profile, status: :unprocessable_content end end |
#confirm_structure ⇒ void
This method returns an undefined value.
Saves the parent-organization change.
766 767 768 769 770 771 772 |
# File 'app/controllers/customers_controller.rb', line 766 def confirm_structure if @customer.update(params[:customer] || {}) redirect_to @customer, notice: 'Parent Org Saved' else render :edit_parent_org, status: :unprocessable_content end end |
#create ⇒ void
This method returns an undefined value.
Legacy action — always raises; customers are created via customer_identify.
80 81 82 |
# File 'app/controllers/customers_controller.rb', line 80 def create raise 'Legacy Method, should not be used' end |
#create_iq_accessory_preference ⇒ void
This method returns an undefined value.
Creates an IQ accessory filter for the customer from an item or exclusive
item group.
374 375 376 377 378 379 380 381 382 383 384 385 386 |
# File 'app/controllers/customers_controller.rb', line 374 def create_iq_accessory_preference item = exclusive_item_group = nil item = Item.find(params[:iq_accessory_filter][:item_id]) if params[:iq_accessory_filter][:item_id].present? exclusive_item_group = ExclusiveItemGroup.find(params[:iq_accessory_filter][:exclusive_item_group_id]) if params[:iq_accessory_filter][:exclusive_item_group_id].present? item_or_exclusive_item_group = item || exclusive_item_group @iq_accessory_filter = IqAccessoryFilter.create_single_customer_iq_accessory_filter(@customer, item_or_exclusive_item_group, params[:iq_accessory_filter][:comment]) if item_or_exclusive_item_group if @iq_accessory_filter redirect_to(iq_accessory_preferences_customer_path(@customer)) else @iq_accessory_filter ||= IqAccessoryFilter.new(params[:iq_accessory_filter]) render action: 'new_iq_accessory_preference', status: :unprocessable_content end end |
#create_topic_follow_up ⇒ void
This method returns an undefined value.
Creates a topic follow-up communication for the customer and opens it for
editing.
698 699 700 701 702 703 704 705 706 |
# File 'app/controllers/customers_controller.rb', line 698 def create_topic_follow_up com = CustomerTopic.create_communication(@customer, current_user) if com.persisted? redirect_to edit_communication_path(com) else flash[:error] = "There was a problem creating the communication. #{com.errors_to_s}" redirect_to customer_path(@customer, tab: 'topics') end end |
#delete_iq_accessory_preference ⇒ void
This method returns an undefined value.
Deletes an IQ accessory preference.
407 408 409 410 411 |
# File 'app/controllers/customers_controller.rb', line 407 def delete_iq_accessory_preference @iq_accessory_filter = IqAccessoryFilter.for_customer(@customer).is_auto_generated_only.find(params[:iq_accessory_filter_id]) @iq_accessory_filter&.destroy redirect_to(iq_accessory_preferences_customer_path(@customer)) end |
#destroy ⇒ Object
DELETE /customers/1
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
# File 'app/controllers/customers_controller.rb', line 105 def destroy if @customer.ok_to_delete? @customer.destroy redirect_to(customers_url) else deps = +'' @customer.opportunities.each do |o| break if deps.length > 200 deps << "<a href='#{opportunity_path(o)}'>opportunity: #{o.name}</a> " end @customer.quotes.each do |q| break if deps.length > 200 deps << "<a href='#{quote_path(q)}'>quote: #{q.reference_number}</a> " end @customer.orders.each do |o| break if deps.length > 200 deps << "<a href='#{order_path(o)}'>order: #{o.reference_number}</a> " end deps << '...' if deps.length > 200 flash[:error] = "Customer cannot be deleted because it is referenced by: #{deps}" redirect_to customer_path(@customer) end end |
#do_auto_assign_sales_rep ⇒ void
This method returns an undefined value.
Force-runs automatic sales-rep assignment for the customer.
807 808 809 810 811 812 813 814 815 816 817 818 |
# File 'app/controllers/customers_controller.rb', line 807 def do_auto_assign_sales_rep # Remove the do not assign flag if this action is explicitely called @customer.do_not_auto_assign = false rep_assigner = Customer::SalesRepAssigner.new(@customer, force_assign: true) if rep_assigner.auto_assign flash[:info] = 'Account team assigned' redirect_to customer_path(@customer) else flash[:error] = rep_assigner.assignment_failure_reason redirect_to edit_account_team_customer_path(@customer) end end |
#do_merge ⇒ void
This method returns an undefined value.
Enqueues the customer-merge background job and redirects to the job page.
220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 |
# File 'app/controllers/customers_controller.rb', line 220 def do_merge load_customers || return = { customer_ids: [@survivor.id, @duplicate.id], notify_email: current_user.email }.stringify_keys job_id = CustomerMergeWorker.perform_async() if job_id.blank? if (job_id = BackgroundJobStatus.search(worker_klass: 'CustomerMergeWorker', args: ).first&.dig(:job_id)) flash[:warning] = 'A similar job was already enqueued, watching status of that job now' end end if job_id.present? redirect_to job_path(job_id) else flash[:warning] = 'There was a problem queuing the job' redirect_to_return_path_or_default customer_path(@survivor.id) end end |
#drop_events ⇒ void
This method returns an undefined value.
Renders the drop-events page.
305 |
# File 'app/controllers/customers_controller.rb', line 305 def drop_events; end |
#duplicates ⇒ void Also known as: complete_qualification
This method returns an undefined value.
Lists possible duplicate customers for merging, preemptively allocating a
sales rep when qualification can complete.
621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 |
# File 'app/controllers/customers_controller.rb', line 621 def duplicates if params[:customer_id].present? @possible_duplicates = Customer.where(id: params[:customer_id]) flash[:error] = "Cannot merge into itself. This is the same customer you're giving me." if @possible_duplicates.first == @customer else @possible_duplicates = Query::CustomerFinder.new(customer: @customer).find_duplicates end if @customer.can_complete_qualification? || @customer.primary_sales_rep_id.nil? # Preemptive allocation of sales rep, takes a slot but that's how we go = Customer::SalesRepAssigner.new(@customer).determine_sales_rep @customer.primary_sales_rep_id = [:primary_sales_rep_id] if .present? end if request.xhr? render partial: 'duplicates' else render :duplicates end end |
#edit ⇒ Object
GET /customers/1/edit
66 67 68 69 70 71 72 73 74 75 |
# File 'app/controllers/customers_controller.rb', line 66 def edit if @customer @source_id = @customer.source_id set_edit_variables render_edit_action(status: :ok) else flash[:error] = 'Customer does not exist.' redirect_to customers_path end end |
#edit_account_team ⇒ void
This method returns an undefined value.
Renders the account-team editor.
747 |
# File 'app/controllers/customers_controller.rb', line 747 def edit_account_team; end |
#edit_accounting_information ⇒ void
This method returns an undefined value.
Renders the accounting-information editor (read-only fallback when the
user lacks permission).
314 315 316 317 318 319 320 321 322 323 |
# File 'app/controllers/customers_controller.rb', line 314 def edit_accounting_information @tax_exemptions = @customer.tax_exemptions respond_to do |format| if can? :edit_accounting_info, Customer format.html else format.html { render action: 'show_accounting_information' } end end end |
#edit_catalog ⇒ void
This method returns an undefined value.
Renders the catalog-change form for the customer.
438 439 440 441 |
# File 'app/controllers/customers_controller.rb', line 438 def edit_catalog @new_catalog = Catalog.find(params[:new_catalog_id]) if params[:new_catalog_id] @customer.catalog = @new_catalog end |
#edit_default_address ⇒ void
This method returns an undefined value.
Renders the default-address editor.
537 538 539 |
# File 'app/controllers/customers_controller.rb', line 537 def edit_default_address (:update, @customer) end |
#edit_iq_accessory_preference ⇒ void
This method returns an undefined value.
Renders the edit form for an IQ accessory preference.
390 391 392 |
# File 'app/controllers/customers_controller.rb', line 390 def edit_iq_accessory_preference @iq_accessory_filter = IqAccessoryFilter.for_customer(@customer).is_auto_generated_only.find(params[:iq_accessory_filter_id]) end |
#edit_lead_protection ⇒ void
This method returns an undefined value.
Renders the lead-protection editor.
793 |
# File 'app/controllers/customers_controller.rb', line 793 def edit_lead_protection; end |
#edit_notification_channels ⇒ void
This method returns an undefined value.
Renders the notification-channels editor.
776 |
# File 'app/controllers/customers_controller.rb', line 776 def edit_notification_channels; end |
#edit_pricing ⇒ void
This method returns an undefined value.
Renders the pricing editor.
730 731 732 |
# File 'app/controllers/customers_controller.rb', line 730 def edit_pricing set_program_pricings end |
#edit_profile ⇒ void
This method returns an undefined value.
Renders the profile editor.
710 |
# File 'app/controllers/customers_controller.rb', line 710 def edit_profile; end |
#edit_shipping_preferences ⇒ void
This method returns an undefined value.
Renders the shipping-preferences editor.
347 |
# File 'app/controllers/customers_controller.rb', line 347 def edit_shipping_preferences; end |
#edit_structure ⇒ void
This method returns an undefined value.
Renders the structure (parent organization) editor.
762 |
# File 'app/controllers/customers_controller.rb', line 762 def edit_structure; end |
#index ⇒ Object
GET /customers
26 27 28 |
# File 'app/controllers/customers_controller.rb', line 26 def index redirect_to employee_dashboard_path(current_user) end |
#iq_accessory_preferences ⇒ void
This method returns an undefined value.
Lists the customer's auto-generated IQ accessory filters.
361 362 363 |
# File 'app/controllers/customers_controller.rb', line 361 def iq_accessory_preferences @iq_accessory_filters = IqAccessoryFilter.for_customer(@customer).is_auto_generated_only end |
#lookup_emails ⇒ void
This method returns an undefined value.
JSON autocomplete of the customer's (and contacts') email addresses.
491 492 493 494 495 |
# File 'app/controllers/customers_controller.rb', line 491 def lookup_emails @customer = Customer.find(params[:customer_id]) results = @customer.contacts_and_self_contact_points_by_category(ContactPoint::EMAIL).distinct.order(:detail).pluck(:detail) render json: TomSelect.format_json_results(self, results, params[:page], params[:per_page]) end |
#lookup_faxes ⇒ void
This method returns an undefined value.
JSON autocomplete of the customer's (and contacts') fax numbers.
507 508 509 510 511 |
# File 'app/controllers/customers_controller.rb', line 507 def lookup_faxes @customer = Customer.find(params[:customer_id]) results = @customer.contacts_and_self_contact_points_by_category(ContactPoint::FAX).distinct.order(:detail).pluck(:detail) render json: TomSelect.format_json_results(self, results, params[:page], params[:per_page]) end |
#lookup_phones ⇒ void
This method returns an undefined value.
JSON autocomplete of the customer's (and contacts') phone numbers.
499 500 501 502 503 |
# File 'app/controllers/customers_controller.rb', line 499 def lookup_phones @customer = Customer.find(params[:customer_id]) results = @customer.contacts_and_self_contact_points_by_category([ContactPoint::PHONE, ContactPoint::CELL]).distinct.order(:detail).pluck(:detail) render json: TomSelect.format_json_results(self, results, params[:page], params[:per_page]) end |
#marketing ⇒ void
This method returns an undefined value.
Renders the marketing page (campaign memberships).
301 |
# File 'app/controllers/customers_controller.rb', line 301 def marketing; end |
#merge ⇒ void
This method returns an undefined value.
Renders the merge comparison screen for two customers, listing blocking
errors (orders under shipping) for each side.
177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 |
# File 'app/controllers/customers_controller.rb', line 177 def merge @error_count = 0 first_customer_id = params.dig(:merge, :first_customer_id) || params.dig(:first_customer_id) second_customer_id = params.dig(:merge, :second_customer_id) || params.dig(:second_customer_id) @customer1 = Customer.find(first_customer_id) @customer2 = Customer.find(second_customer_id) if @customer1.catalog_id == @customer2.catalog_id @customer1_inventory = Merger::CustomerMerger.inventory(@customer1) @customer1_errors = [] @customer1.orders.all_awaiting_deliveries.each do |order| @customer1_errors << { record_type: order.class.name, record_id: order.id, record_description: order.state, errors: ['Order is under shipping states'], record: order } end # @customer1_inventory.each do |r| # @customer1_errors += 1 unless r.valid? # end @customer2_inventory = Merger::CustomerMerger.inventory(@customer2) @customer2_errors = [] @customer2.orders.all_awaiting_deliveries.each do |order| @customer2_errors << { record_type: order.class.name, record_id: order.id, record_description: order.state, errors: ['Order is under shipping states'], record: order } end # @customer2_inventory.each do |r| # @customer2_errors += 1 unless r.valid? # end @error_count = @customer1_errors.size + @customer2_errors.size if params[:survivor_customer_id].present? @customer1_selected = params[:survivor_customer_id] == @customer1.id @customer2_selected = params[:survivor_customer_id] == @customer2.id elsif @customer1.created_at < @customer2.created_at @customer1_selected = true else @customer2_selected = true end else flash[:error] = 'Customer master and duplicate have different catalogs, resolve catalog discrepancy first' redirect_to_return_path_or_default customer_path(@customer1) end end |
#merge_addresses ⇒ void
This method returns an undefined value.
Runs the address-duplicate merger for the customer's addresses.
259 260 261 262 263 264 265 266 267 268 |
# File 'app/controllers/customers_controller.rb', line 259 def merge_addresses am = Merger::AddressMerger.new(@customer.id) begin am.perform_merge! flash[:info] = 'Merge check completed.' rescue StandardError => e flash[:error] = "Merge could not be completed. #{e.}" end redirect_to_return_path_or_default customer_addresses_path(@customer) end |
#merge_contact_points ⇒ void
This method returns an undefined value.
Runs the contact-point merger for the customer's contact points.
272 273 274 275 276 277 278 279 280 281 |
# File 'app/controllers/customers_controller.rb', line 272 def merge_contact_points cpm = Merger::ContactPointMerge.new(@customer.id) begin cpm.perform_merge! flash[:info] = 'Merge check completed.' rescue StandardError => e flash[:error] = "Merge could not be completed. #{e.}" end redirect_to_return_path_or_default customer_contacts_path(@customer) end |
#new ⇒ Object
GET /customers/new
61 62 63 |
# File 'app/controllers/customers_controller.rb', line 61 def new redirect_to new_customer_identify_path end |
#new_iq_accessory_preference ⇒ void
This method returns an undefined value.
Renders the new IQ accessory preference form.
367 368 369 |
# File 'app/controllers/customers_controller.rb', line 367 def new_iq_accessory_preference @iq_accessory_filter = IqAccessoryFilter.new end |
#promotions ⇒ void
This method returns an undefined value.
Renders the promotions list: active tier-3 coupons targeting the customer.
566 567 568 569 570 |
# File 'app/controllers/customers_controller.rb', line 566 def promotions qb = Coupon::QueryBuilder.new(Coupon.active.tier3) @coupons = qb.for_specific_customer(@customer).query.order('coupons.expiration_date desc') render layout: false end |
#radiant_rewards ⇒ void
This method returns an undefined value.
Renders the Radiant Rewards page.
459 |
# File 'app/controllers/customers_controller.rb', line 459 def radiant_rewards; end |
#recalculate_profiling_information ⇒ void
This method returns an undefined value.
Recomputes the customer's profiling information.
415 416 417 |
# File 'app/controllers/customers_controller.rb', line 415 def recalculate_profiling_information @customer.recalculate_profiling_information end |
#release_from_lead_qualification ⇒ void
This method returns an undefined value.
Completes lead qualification for the customer, optionally pre-assigning a
primary sales rep, and warns about held orders.
240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 |
# File 'app/controllers/customers_controller.rb', line 240 def release_from_lead_qualification if @customer.can_complete_qualification? if (psr_id = params.dig(:customer, :primary_sales_rep_id)) # preassign rep Customer::SalesRepAssigner.new(@customer).assign_reps(primary_sales_rep_id: psr_id) end res = @customer.complete_qualification # this will allow the updating if res flash[:info] = +'Customer was released from lead qualification stage. ' flash[:info] << "#{@customer.orders.held.length} order(s) are currently on hold, please review them for correctness and release." if @customer.orders.held.present? else flash[:error] = "Customer was not released from lead qualification stage. #{@customer.errors_to_s}" end end redirect_to customer_path(@customer) end |
#sales_priority_index_analysis ⇒ void
This method returns an undefined value.
Renders the sales-priority-index score breakdown for the customer.
463 464 465 466 |
# File 'app/controllers/customers_controller.rb', line 463 def sales_priority_index_analysis @results = Customer::SalesPriorityCalculation.score_single_customer(@customer.id) render layout: 'crm/crm' end |
#show ⇒ void
This method returns an undefined value.
Shows the customer's details.
For HTML: preloads key associations, loads the customer's active contacts with contact points, and enqueues a profile-image lookup.
For JSON: renders the customer as JSON.
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
# File 'app/controllers/customers_controller.rb', line 36 def show raise ActiveRecord::RecordNotFound if @customer.nil? respond_to do |format| format.html do ActiveRecord::Associations::Preloader.new( records: [@customer], associations: [ { primary_sales_rep: %i[profile_image employee_phone_status] }, :profile, :buying_group, :source, :profile_image, :parent_organization, :customer_record, { catalog: :store }, { addresses: :country } ] ).call @contacts = @customer.contacts.active.includes(:contact_points).order(Contact[:full_name]) enqueue_profile_image_lookup(@customer) end format.json do render json: @customer.to_json end end end |
#show_accounting_information ⇒ void
This method returns an undefined value.
Renders the read-only accounting-information view.
309 |
# File 'app/controllers/customers_controller.rb', line 309 def show_accounting_information; end |
#statement_pdf ⇒ void
This method returns an undefined value.
Generates the statement-of-account PDF and routes to a new communication
carrying it (or back to the customer when there are no open documents).
422 423 424 425 426 427 428 429 430 431 432 433 434 |
# File 'app/controllers/customers_controller.rb', line 422 def statement_pdf @soa = StatementOfAccount.generate_pdf(@customer, params[:per_currency].present? || false) if @soa.nil? redirect_to customer_path(@customer.id) flash[:info] = 'Unable to generate statement, customer has no open documents.' else recipient_contact_point_id = @soa.primary_transmission_contact_point_id redirect_to new_communication_path(upload_ids: @soa.uploads.map(&:id), recipient_party_id: @customer.id, recipient_contact_point_id: recipient_contact_point_id, template_system_code: 'STATEMENTOFACCOUNT') end end |
#sync_credit ⇒ void
This method returns an undefined value.
Re-synchronizes the customer's credit limit with the accounting system.
289 290 291 292 293 294 295 296 297 |
# File 'app/controllers/customers_controller.rb', line 289 def sync_credit res = @customer.sync_credit_limit if res[:ok] flash[:info] = 'Credit Limits Synchronized' else flash[:error] = "Error while synchronizing credit limits. #{res[:message]}" end redirect_to_return_path_or_default available_credit_customer_path(@customer) end |
#tab_accounting ⇒ void
This method returns an undefined value.
Renders the accounting tab: paginated AR listings plus per-currency open
totals.
471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 |
# File 'app/controllers/customers_controller.rb', line 471 def tab_accounting ar_scope = @customer.ar_listings(show_open_only: params[:show_open_only]) # countless skips the pagy COUNT(*) — view_ar_listings can't prune its correlated # subqueries from a COUNT projection across UNION ALL, so the count costs ~100ms # for high-AR customers (AppSignal #393). Prev/next nav is sufficient for this listing. @pagy_ar, @ar_listings = pagy(:countless, ar_scope, limit: 50, page: params[:page]) # Calculate currency totals using database-level aggregation instead of Ruby iteration # Use reorder(nil) to remove inherited ORDER BY which causes GROUP BY errors @grouped_ar_listings = ar_scope.reorder(nil).where.not(currency: [nil, 'ALL']).group(:currency).sum(:open_amount_calc).sort respond_to do |format| format.html { render layout: false } format.turbo_stream do render turbo_stream: turbo_stream.replace('ar-listings-frame', partial: 'ar_listings', locals: { show_customer: false, show_check: true }) end end end |
#tab_activities ⇒ void
This method returns an undefined value.
Renders the activities tab fragment.
912 913 914 915 916 917 918 919 |
# File 'app/controllers/customers_controller.rb', line 912 def tab_activities (:read, @customer) build_activities_tab_data(@customer) respond_to do |format| format.html { render layout: should_render_layout? } format.turbo_stream end end |
#tab_addresses ⇒ void
This method returns an undefined value.
Renders the addresses tab fragment.
531 532 533 |
# File 'app/controllers/customers_controller.rb', line 531 def tab_addresses render layout: false end |
#tab_attachments ⇒ void
This method returns an undefined value.
Renders the attachments (uploads) tab fragment.
879 880 881 882 883 884 885 886 |
# File 'app/controllers/customers_controller.rb', line 879 def (:read, @customer) build_uploads_tab_data(@customer) respond_to do |format| format.html { render layout: should_render_layout? } format.turbo_stream end end |
#tab_certifications ⇒ void
This method returns an undefined value.
Renders the certifications tab fragment.
150 151 152 153 154 |
# File 'app/controllers/customers_controller.rb', line 150 def tab_certifications # @certifications = @customer.certifications # @course_enrollments = @customer.course_enrollments render layout: false end |
#tab_communications ⇒ void
This method returns an undefined value.
Renders the communications tab fragment.
890 891 892 893 894 895 896 897 |
# File 'app/controllers/customers_controller.rb', line 890 def tab_communications (:read, @customer) build_communications_tab_data(@customer) respond_to do |format| format.html { render layout: should_render_layout? } format.turbo_stream end end |
#tab_contacts ⇒ void
This method returns an undefined value.
Renders the contacts tab fragment.
515 516 517 518 519 520 521 |
# File 'app/controllers/customers_controller.rb', line 515 def tab_contacts @show_inactive = params[:show_inactive] == 'true' respond_to do |format| format.html { render layout: false } format.turbo_stream end end |
#tab_digital_assets ⇒ void
This method returns an undefined value.
Renders the digital-assets tab fragment.
869 870 871 872 873 874 875 |
# File 'app/controllers/customers_controller.rb', line 869 def tab_digital_assets (:read, @customer) respond_to do |format| format.html { render layout: should_render_layout? } format.turbo_stream end end |
#tab_lead_protections ⇒ void
This method returns an undefined value.
Renders the lead-protections tab: customers this customer protects.
587 588 589 590 |
# File 'app/controllers/customers_controller.rb', line 587 def tab_lead_protections @lead_protections = Customer.joins(:customer_record).where('customer_records.lead_protector_id' => @customer.id) render layout: false end |
#tab_main_profile ⇒ void
This method returns an undefined value.
Renders the main-profile tab fragment.
574 575 576 |
# File 'app/controllers/customers_controller.rb', line 574 def tab_main_profile render layout: false end |
#tab_marketing ⇒ void
This method returns an undefined value.
Renders the marketing tab fragment.
560 561 562 |
# File 'app/controllers/customers_controller.rb', line 560 def tab_marketing render layout: false end |
#tab_opportunities ⇒ void
This method returns an undefined value.
Renders the opportunities tab fragment.
938 939 940 941 942 943 944 945 |
# File 'app/controllers/customers_controller.rb', line 938 def tab_opportunities (:read, @customer) build_opportunities_tab_data(@customer) respond_to do |format| format.html { render layout: should_render_layout? } format.turbo_stream end end |
#tab_orders ⇒ void
This method returns an undefined value.
Renders the orders tab fragment.
949 950 951 952 953 954 955 956 |
# File 'app/controllers/customers_controller.rb', line 949 def tab_orders (:read, @customer) build_orders_tab_data(@customer) respond_to do |format| format.html { render layout: should_render_layout? } format.turbo_stream end end |
#tab_outlet_purchases ⇒ Object
Every retailer purchase we know this customer made, whether or not it ties
to a project. Unlike the opportunity tab, this includes customer-level links
— purchases that share no product line with any quote.
See doc/tasks/202608081330_OUTLET_PURCHASE_ATTRIBUTION.md.
925 926 927 928 929 930 931 932 933 934 |
# File 'app/controllers/customers_controller.rb', line 925 def tab_outlet_purchases (:read, @customer) @outlet_purchases = @customer.outlet_purchases .includes(:verified_by, :opportunity, invoice: { customer: :catalog }) .order(created_at: :desc) respond_to do |format| format.html { render layout: should_render_layout? } format.turbo_stream end end |
#tab_product_reviews ⇒ void
This method returns an undefined value.
Renders the product-reviews tab: Reviews.io reviews plus the company
review link.
595 596 597 598 599 |
# File 'app/controllers/customers_controller.rb', line 595 def tab_product_reviews @reviews_io_reviews = fetch_reviews_io_reviews @company_review_link_data = prepare_company_review_link render layout: false end |
#tab_profiling ⇒ void
This method returns an undefined value.
Renders the profiling tab fragment.
525 526 527 |
# File 'app/controllers/customers_controller.rb', line 525 def tab_profiling render layout: false end |
#tab_receipts ⇒ void
This method returns an undefined value.
Renders the receipts tab fragment.
651 652 653 |
# File 'app/controllers/customers_controller.rb', line 651 def tab_receipts render layout: false end |
#tab_showcases ⇒ void
This method returns an undefined value.
Renders the showcases tab fragment.
613 614 615 616 |
# File 'app/controllers/customers_controller.rb', line 613 def tab_showcases # Render showcases tab content only for AJAX tabs to avoid full-page reload loops render layout: false end |
#tab_sms ⇒ void
This method returns an undefined value.
Renders the SMS tab fragment.
901 902 903 904 905 906 907 908 |
# File 'app/controllers/customers_controller.rb', line 901 def tab_sms (:read, @customer) build_sms_tab_data(@customer) respond_to do |format| format.html { render layout: should_render_layout? } format.turbo_stream end end |
#tab_stats ⇒ void
This method returns an undefined value.
Renders the stats tab fragment.
554 555 556 |
# File 'app/controllers/customers_controller.rb', line 554 def tab_stats render layout: false end |
#tab_subsidiaries ⇒ void
This method returns an undefined value.
Renders the subsidiaries tab fragment.
580 581 582 583 |
# File 'app/controllers/customers_controller.rb', line 580 def tab_subsidiaries @child_organizations = @customer.child_organizations unless @customer.child_organizations.empty? render layout: false end |
#tab_tickets ⇒ void
This method returns an undefined value.
Renders the tickets tab fragment.
645 646 647 |
# File 'app/controllers/customers_controller.rb', line 645 def tab_tickets render layout: false end |
#tab_training ⇒ void
This method returns an undefined value.
Renders the training tab: the customer's contacts' training topics grouped
by topic category.
135 136 137 138 139 140 141 142 143 144 145 146 |
# File 'app/controllers/customers_controller.rb', line 135 def tab_training params[:q] = { state_in: %w[assigned requested certified] } if params[:q].blank? @q = ContactTrainingTopic.joins(:contact, { topic: :topic_category }) .merge(@customer.contacts) .merge(Topic.sorted).ransack(params[:q]) @contact_training_topics = @q.result @contact_training_topics_grouped = @contact_training_topics.group_by { |pt| pt.topic.topic_category } respond_to do |format| format.html { render layout: false } format.turbo_stream end end |
#tab_warranty ⇒ void
This method returns an undefined value.
Renders the warranty tab fragment, loading the customer's warranties.
603 604 605 606 607 608 609 |
# File 'app/controllers/customers_controller.rb', line 603 def tab_warranty (:read, @customer) @warranties = @customer.warranties .includes(:order, :created_by, :products, :uploads) .order(submitted_at: :desc) render layout: false end |
#update ⇒ Object
PUT /customers/1
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'app/controllers/customers_controller.rb', line 85 def update if @customer.update(params[:customer] || {}) @customer.qualify_lead if @customer.guest? PartyRecordTimezone.new.process(@customer) redirect_to_return_path_or_default(customer_path(@customer)) else set_edit_variables render_edit_action(status: :unprocessable_content) end rescue ActiveRecord::RecordNotSaved => e ErrorReporting.from_controller(self).informational( 'Customer update failed: RecordNotSaved', customer_id: @customer.id, error: e. ) @customer.errors.add(:base, 'Could not save the customer record. Please try again or contact support.') set_edit_variables render_edit_action(status: :unprocessable_content) end |
#update_accounting_information ⇒ void
This method returns an undefined value.
Saves accounting information; restricted to admin and accounting_rep roles.
327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 |
# File 'app/controllers/customers_controller.rb', line 327 def update_accounting_information @can_update = current_account.has_role?('admin') || current_account.has_role?('accounting_rep') unless @can_update redirect_to customer_path(@customer), alert: 'You are not authorized to update accounting information.' return end respond_to do |format| if @customer.update(params[:customer] || {}) format.html { redirect_to(customer_path(@customer)) } format.xml { head :ok } else set_edit_variables format.html { render action: 'edit_accounting_information', status: :unprocessable_content } format.xml { render xml: @document.errors, status: :unprocessable_content } end end end |
#update_catalog ⇒ void
This method returns an undefined value.
Assigns the customer to a new catalog, converting orders, quotes, and
rooms.
446 447 448 449 450 451 452 453 454 455 |
# File 'app/controllers/customers_controller.rb', line 446 def update_catalog new_catalog = Catalog.find(params[:customer][:catalog_id]) result = Catalog::AssignCatalogToCustomer.new.process(@customer, new_catalog) if result.catalog_assigned? flash[:info] = "Catalog changed to #{new_catalog.name} and all orders, quotes and rooms converted successfully. #{result..join}".first(500) else flash[:error] = result..to_sentence.first(500) end redirect_to_return_path_or_default customer_path(@customer) end |
#update_default_address ⇒ void
This method returns an undefined value.
Saves the customer's default address selection.
543 544 545 546 547 548 549 550 |
# File 'app/controllers/customers_controller.rb', line 543 def update_default_address (:update, @customer) if @customer.update(params[:customer]) redirect_to_return_path_or_default customer_path(@customer, tab: 'addresses') else render :edit_default_address, status: :unprocessable_content end end |
#update_iq_accessory_preference ⇒ void
This method returns an undefined value.
Saves changes to an IQ accessory preference.
396 397 398 399 400 401 402 403 |
# File 'app/controllers/customers_controller.rb', line 396 def update_iq_accessory_preference @iq_accessory_filter = IqAccessoryFilter.for_customer(@customer).is_auto_generated_only.find(params[:iq_accessory_filter_id]) if @iq_accessory_filter.update(params[:iq_accessory_filter]) redirect_to(iq_accessory_preferences_customer_path(@customer)) else render action: 'edit_iq_accessory_preference', status: :unprocessable_content end end |
#update_shipping_preferences ⇒ void
This method returns an undefined value.
Saves the customer's shipping preferences.
351 352 353 354 355 356 357 |
# File 'app/controllers/customers_controller.rb', line 351 def update_shipping_preferences if @customer.update(params[:customer] || {}) redirect_to_return_path_or_default customer_path(@customer, tab: 'addresses') else render action: 'edit_shipping_preferences', status: :unprocessable_content end end |