Class: Crm::EdiCommunicationLogsController

Inherits:
CrmController show all
Includes:
Controllers::Workflowable
Defined in:
app/controllers/crm/edi_communication_logs_controller.rb

Overview

Controller: edi communication logs.

Constant Summary

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

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

#device_detector, #is_ie?

Methods included from Controllers::SubdomainDetection

#is_crm_request?, #is_www_request?, #json_request?

Methods included from Controllers::TurboSafeRedirect

#redirect_to

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

#cloneObject

Duplicates an existing EDI communication log.



73
74
75
76
77
78
79
80
81
82
83
# File 'app/controllers/crm/edi_communication_logs_controller.rb', line 73

def clone
  authorize!(:create, EdiCommunicationLog)
  existing_ecl = EdiCommunicationLog.find(params[:id])
  @edi_communication_log = existing_ecl.deep_dup
  if @edi_communication_log.save
    flash[:info] = 'Communication Log cloned'
    redirect_to_return_path_or_default url_for(action: :edit, id: @edi_communication_log.id)
  else
    render :edit, status: :unprocessable_content
  end
end

#createObject

Creates an EDI communication log.



92
93
94
95
96
97
98
99
100
101
# File 'app/controllers/crm/edi_communication_logs_controller.rb', line 92

def create
  authorize!(:create, EdiCommunicationLog)
  @edi_communication_log = EdiCommunicationLog.new(params[:edi_communication_log])
  if @edi_communication_log.save
    flash[:info] = 'Communication Log created'
    redirect_to_return_path_or_default url_for(action: :show, id: @edi_communication_log.id)
  else
    render :new, status: :unprocessable_content
  end
end

#destroyObject

Destroys the EDI communication log.



116
117
118
119
120
121
122
# File 'app/controllers/crm/edi_communication_logs_controller.rb', line 116

def destroy
  authorize!(:destroy, EdiCommunicationLog)
  @edi_communication_log = EdiCommunicationLog.find(params[:id])
  @edi_communication_log.destroy
  flash[:info] = 'Communication log deleted'
  redirect_to_return_path_or_default url_for(action: :index)
end

#discontinue_flowObject

Enqueues the discontinue EDI flow, which DELETEs pending_discontinue
listings via SP-API for the given orchestrator/partner.



219
220
221
222
223
224
# File 'app/controllers/crm/edi_communication_logs_controller.rb', line 219

def discontinue_flow
  authorize!(:manage, EdiCommunicationLog)
  EdiDiscontinueFlowWorker.perform_async(params.to_h.slice(:orchestrator_name, :partner).stringify_keys)
  flash[:info] = 'Discontinue flow queued up — will DELETE pending_discontinue listings via SP-API'
  redirect_to_return_path_or_default url_for(action: :index)
end

#do_matchObject

Matches the log's attached packing-slip upload to an order by reference
or PO number, attaches it, and releases the order.



142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
# File 'app/controllers/crm/edi_communication_logs_controller.rb', line 142

def do_match
  authorize!(:update, EdiCommunicationLog)
  @edi_communication_log = EdiCommunicationLog.find(params[:id])
  if @edi_communication_log.can_be_matched?
    # Try to match on provided order reference # or PO #
    qt = params.dig(:match, :q).presence&.squish
    order = nil
    if qt
      base_orders = @edi_communication_log.orders_for_packing_slip_matchup
      order = base_orders.where(reference_number: qt).first
      order ||= base_orders.joins(:payments).where(Payment[:po_number].eq(qt)).first
    end
    if order
      # Copy upload over to order
      u = @edi_communication_log.uploads.first
      new_u = u.clone_with_file(order)
      if new_u.save
        flash[:info] = "Packing list attached to order #{order.reference_number}"
        # link order to edi doc
        @edi_communication_log.edi_documents.create(order: order, note: 'packing list')
        @edi_communication_log.complete!
        # And try to release our order
        order.release_order
      else
        flash[:error] = "Error attaching pick slip. #{new_u.errors_to_s}"
      end
    else
      flash[:error] = "Could not find an order that matches #{qt} in reference number or po number"
    end
  else
    flash[:error] = 'EDI communication log state, type or attachment not matching criteria'
  end
  redirect_to_return_path_or_default edi_communication_log_path(@edi_communication_log)
end

#do_processObject

Runs the log's process transition.



125
126
127
128
129
130
# File 'app/controllers/crm/edi_communication_logs_controller.rb', line 125

def do_process
  authorize!(:update, EdiCommunicationLog)
  @edi_communication_log = EdiCommunicationLog.find(params[:id])
  @edi_communication_log.process
  redirect_to_return_path_or_default edi_communication_log_path(@edi_communication_log)
end

#do_statusObject

Refreshes the log's status from its source system.



133
134
135
136
137
138
# File 'app/controllers/crm/edi_communication_logs_controller.rb', line 133

def do_status
  authorize!(:update, EdiCommunicationLog)
  @edi_communication_log = EdiCommunicationLog.find(params[:id])
  @edi_communication_log.update_status
  redirect_to_return_path_or_default edi_communication_log_path(@edi_communication_log)
end

#downloadObject

Downloads the log's attached upload, or its raw data if none is attached.



56
57
58
59
60
61
62
63
64
# File 'app/controllers/crm/edi_communication_logs_controller.rb', line 56

def download
  authorize!(:read, EdiCommunicationLog)
  @edi_communication_log = EdiCommunicationLog.find(params[:id])
  if (upload = @edi_communication_log.uploads.first)
    redirect_to upload.attachment.url
  else
    send_data @edi_communication_log.data, filename: @edi_communication_log.file_name
  end
end

#editObject

Renders the form to edit an existing EDI communication log.



86
87
88
89
# File 'app/controllers/crm/edi_communication_logs_controller.rb', line 86

def edit
  authorize!(:update, EdiCommunicationLog)
  @edi_communication_log = EdiCommunicationLog.find(params[:id])
end

#indexObject

Lists EDI communication logs, ransack-filtered (hiding archived rows by
default), plus 24h activity stats.



8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'app/controllers/crm/edi_communication_logs_controller.rb', line 8

def index
  authorize!(:read, EdiCommunicationLog)
  @q = EdiCommunicationLog.ransack(params[:q])
  @q.sorts = 'created_at DESC' if @q.sorts.blank?
  # Archived is retention, not workload: everything settled for two weeks ends
  # up there (Maintenance::EdiCommunicationLogMaintenance), so showing it by
  # default would bury the operational rows under months of history. Filtering
  # State explicitly — including to `archived` — still reaches it.
  @showing_archived = @q.state_eq.present? || @q.state_in.present?
  scope = @showing_archived ? @q.result : @q.result.where.not(state: 'archived')
  @pagy, @edi_communication_logs = pagy(scope, limit: 50)

  # Pre-cast Ransack datetime string values to Time so DatetimePickerInput
  # can call strftime on them and repopulate the picker fields correctly.
  %i[created_at_gteq transmit_after_gteq].each do |cond|
    raw = @q.send(cond)
    @q.send(:"#{cond}=", raw.to_datetime) if raw.is_a?(String) && raw.present?
  rescue ArgumentError, TypeError
    nil
  end

  since_24h = 24.hours.ago
  now = Time.current
  # Run all five aggregates concurrently — Rails 7.1 async_count returns
  # an ActiveRecord::Promise that materializes when the value is read.
  promises = {
    exceptions_24h: EdiCommunicationLog.where(state: 'exception').where(created_at: since_24h..).async_count,
    processed_24h:  EdiCommunicationLog.where(state: 'processed').where(created_at: since_24h..).async_count,
    scheduled:      EdiCommunicationLog.where('transmit_after > ?', now).async_count,
    ready:          EdiCommunicationLog.where(state: 'ready').where('transmit_after IS NULL OR transmit_after <= ?', now).async_count,
    processing:     EdiCommunicationLog.where(state: 'processing').async_count
  }
  @stats = promises.transform_values(&:value)
end

#inventory_flowObject

Enqueues the inventory EDI flow for the given orchestrator/partner.



186
187
188
189
190
191
# File 'app/controllers/crm/edi_communication_logs_controller.rb', line 186

def inventory_flow
  authorize!(:manage, EdiCommunicationLog)
  EdiInventoryFlowWorker.perform_async(params.to_h.slice(:orchestrator_name, :partner).stringify_keys)
  flash[:info] = 'Inventory flow queued up, refresh this page to check status'
  redirect_to_return_path_or_default url_for(action: :index)
end

#listing_message_feed_flowObject

Enqueues the listing-message-feed EDI flow for the given orchestrator/partner.



210
211
212
213
214
215
# File 'app/controllers/crm/edi_communication_logs_controller.rb', line 210

def listing_message_feed_flow
  authorize!(:manage, EdiCommunicationLog)
  EdiListingMessageFeedFlowWorker.perform_async(params.to_h.slice(:orchestrator_name, :partner).stringify_keys)
  flash[:info] = 'Listing Message Feed flow queued up, refresh this page to check status'
  redirect_to_return_path_or_default url_for(action: :index)
end

#newObject

Renders the form for a new EDI communication log.



67
68
69
70
# File 'app/controllers/crm/edi_communication_logs_controller.rb', line 67

def new
  authorize!(:create, EdiCommunicationLog)
  @edi_communication_log = EdiCommunicationLog.new
end

#orchestratorsObject

Lists every EDI orchestrator class and the individual orchestrators it runs.



44
45
46
47
# File 'app/controllers/crm/edi_communication_logs_controller.rb', line 44

def orchestrators
  authorize!(:manage, EdiCommunicationLog)
  @orchestrators_by_class = Edi::BaseOrchestrator.all_orchestrators_class.index_with(&:orchestrators)
end

#order_flowObject

Enqueues the order EDI flow for the given orchestrator/partner.



178
179
180
181
182
183
# File 'app/controllers/crm/edi_communication_logs_controller.rb', line 178

def order_flow
  authorize!(:manage, EdiCommunicationLog)
  EdiOrderFlowWorker.perform_async(params.to_h.slice(:orchestrator_name, :partner).stringify_keys)
  flash[:info] = 'Order flow queued up, refresh this page to check status'
  redirect_to_return_path_or_default url_for(action: :index)
end

#price_flowObject

Enqueues the price EDI flow for the given orchestrator/partner.



202
203
204
205
206
207
# File 'app/controllers/crm/edi_communication_logs_controller.rb', line 202

def price_flow
  authorize!(:manage, EdiCommunicationLog)
  EdiPriceFlowWorker.perform_async(params.to_h.slice(:orchestrator_name, :partner).stringify_keys)
  flash[:info] = 'Price flow queued up, refresh this page to check status'
  redirect_to_return_path_or_default url_for(action: :index)
end

#product_data_flowObject

Enqueues the product data EDI flow for the given orchestrator/partner.



194
195
196
197
198
199
# File 'app/controllers/crm/edi_communication_logs_controller.rb', line 194

def product_data_flow
  authorize!(:manage, EdiCommunicationLog)
  EdiProductDataFlowWorker.perform_async(params.to_h.slice(:orchestrator_name, :partner).stringify_keys)
  flash[:info] = 'Product Data flow queued up, refresh this page to check status'
  redirect_to_return_path_or_default url_for(action: :index)
end

#showObject

Shows a single EDI communication log.



50
51
52
53
# File 'app/controllers/crm/edi_communication_logs_controller.rb', line 50

def show
  authorize!(:read, EdiCommunicationLog)
  @edi_communication_log = EdiCommunicationLog.find(params[:id])
end

#updateObject

Updates the EDI communication log.



104
105
106
107
108
109
110
111
112
113
# File 'app/controllers/crm/edi_communication_logs_controller.rb', line 104

def update
  authorize!(:update, EdiCommunicationLog)
  @edi_communication_log = EdiCommunicationLog.find(params[:id])
  if @edi_communication_log.update(params[:edi_communication_log])
    flash[:info] = 'Communication Log updated'
    redirect_to_return_path_or_default url_for(action: :show, id: @edi_communication_log.id)
  else
    render :edit, status: :unprocessable_content
  end
end