Class: CatalogsController

Inherits:
CrmController show all
Includes:
Controllers::Destroyable, Controllers::RequireTurboFrame, Controllers::Showable
Defined in:
app/controllers/catalogs_controller.rb

Overview

== Schema Information

Table name: catalogs

id :integer not null, primary key
name :string(255)
created_at :datetime
updated_at :datetime
currency :string(255)
currency_symbol :string(255)
store_id :integer
is_discontinued :boolean default(FALSE)
for_admin :boolean default(FALSE), not null
company_id :integer
bom_enabled :boolean default(FALSE), not null
sales_manager_employee_record_id :integer
parent_catalog_id :integer
parent_catalog_discount :decimal(5, 4)

Constant Summary collapse

TAB_ACTIONS =

Tab fragments never render standalone — non-frame hits redirect to show ?tab=.

%i[tab_overview tab_items tab_settings tab_relationships tab_images].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

Methods included from Controllers::Showable

#perform_show

Methods included from Controllers::RequireTurboFrame

require_in_pane_tab_frames, require_turbo_frame

Methods included from Controllers::Destroyable

#destroy, #perform_destroy

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

#createvoid

This method returns an undefined value.

POST /catalogs — creates a catalog.



184
185
186
187
188
189
190
191
192
# File 'app/controllers/catalogs_controller.rb', line 184

def create
  @catalog = Catalog.new(params[:catalog])
  authorize!(:create, @catalog)
  if @catalog.save
    redirect_to_return_path_or_default(catalog_path(@catalog))
  else
    render :new, status: :unprocessable_content
  end
end

#duplicatevoid

This method returns an undefined value.

POST /catalogs/:id/duplicate — deep-duplicates a catalog.



161
162
163
164
165
166
167
168
169
170
171
# File 'app/controllers/catalogs_controller.rb', line 161

def duplicate
  @original_catalog = Catalog.find(params[:id])
  authorize!(:create, Catalog)
  @new_catalog = @original_catalog.deep_dup
  if @new_catalog.save
    redirect_to edit_catalog_path(@new_catalog), notice: 'New catalog created, please update if necessary'
  else
    flash[:error] = "#{@original_catalog.name} could not be duplicated, errors reported: #{@new_catalog.errors.full_messages.to_sentence}"
    redirect_to catalog_path(@original_catalog)
  end
end

#editvoid

This method returns an undefined value.

GET /catalogs/:id/edit — edit form for an existing catalog.



176
177
178
179
# File 'app/controllers/catalogs_controller.rb', line 176

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

#indexvoid

This method returns an undefined value.

GET /catalogs — filterable, paginated catalog list.



32
33
34
35
36
37
38
39
# File 'app/controllers/catalogs_controller.rb', line 32

def index
  authorize!(:read, Catalog)
  p = params[:q].presence || {}
  p['is_discontinued_eq'] = false if p.empty?
  @q = Catalog.ransack(p)
  @q.sorts = ['parent_catalog_id desc', 'name asc'] if @q.sorts.blank?
  @pagy, @catalogs = pagy(@q.result.select_append("(select count(*) from catalog_items ci where ci.catalog_id = catalogs.id and ci.state = 'active') as active_counter"), limit: 100)
end

#newvoid

This method returns an undefined value.

GET /catalogs/new — blank catalog form, optionally scoped to a store_id.



150
151
152
153
154
155
156
# File 'app/controllers/catalogs_controller.rb', line 150

def new
  @store = Store.find(params[:store_id]) if params[:store_id]
  @catalog = (@store&.catalogs || Catalog).new(params[:catalog])
  @catalog.apply_default_locales
  @catalog.apply_default_country
  authorize!(:create, @catalog)
end

#product_line_analysisvoid

This method returns an undefined value.

GET /catalogs/:id/product_line_analysis — product-line breakdown for the
catalog's items.



212
213
214
215
216
# File 'app/controllers/catalogs_controller.rb', line 212

def product_line_analysis
  @catalog = Catalog.find(params[:id])
  @q = ProductLine.ransack(params[:q] || { id_in: @catalog.product_line_ids_for_analysis })
  @product_lines = @q.result.order(:lineage_expanded)
end

#showObject

GET /catalogs/1



42
43
44
45
# File 'app/controllers/catalogs_controller.rb', line 42

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

#sync_pricesvoid

This method returns an undefined value.

POST /catalogs/:id/sync_prices — force-syncs catalog item prices via
Catalog::SynchronizeCatalogPrices.



222
223
224
225
226
227
228
229
230
231
232
# File 'app/controllers/catalogs_controller.rb', line 222

def sync_prices
  @catalog = Catalog.find(params[:id])
  authorize!(:update, @catalog)
  result = Catalog::SynchronizeCatalogPrices.new.process(@catalog, force_sync: true)
  if result.all_items_synchronized?
    flash[:info] = "#{result.catalog_items_updated.size} items updated"
  else
    flash[:warning] = ["#{result.catalog_items_updated.size} items updated", "#{result.catalog_items_failed.size} items failed", *result.messages]
  end
  redirect_to @catalog
end

#tab_imagesvoid

This method returns an undefined value.



86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
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
131
132
133
# File 'app/controllers/catalogs_controller.rb', line 86

def tab_images
  load_and_authorize_catalog
  @marketplace = helpers.catalog_image_profile_marketplace(@catalog)
  @marketplace_name = helpers.catalog_marketplace_name(@catalog)

  # Get active catalog items with their items, excluding publications
  non_publication_category_ids = ProductCategory.all_non_publication_goods_ids
  @active_catalog_items = @catalog.catalog_items
                                  .where(state: 'active')
                                  .joins(store_item: :item)
                                  .where(items: { product_category_id: non_publication_category_ids })

  # Calculate image statistics
  item_ids = @active_catalog_items.pluck('items.id').uniq
  @total_items = item_ids.count

  # Determine full profile count (excluding SWCH swatch)
  # AMZ has MAIN + PT01-PT11 = 12 main types
  # WAL has MAIN + AD01-AD10 = 11 types
  # WYS has MAIN + I01-I15 = 16 types
  @max_image_count = case @marketplace
                     when :AMZ then 12
                     when :WAL then 11
                     else 16
                     end

  # Count images per item
  image_counts = ImageProfile.where(item_id: item_ids)
                             .where('image_type LIKE ?', "#{@marketplace}_%")
                             .where('image_type NOT LIKE ?', '%SWCH')
                             .group(:item_id)
                             .count

  # Build distribution: how many items have exactly N images
  @image_distribution = (0..@max_image_count).map do |n|
    count = if n.zero?
              @total_items - image_counts.keys.count
            else
              image_counts.count { |_id, c| c == n }
            end
    percentage = @total_items.positive? ? (count.to_f / @total_items * 100).round(1) : 0
    { count: n, items: count, percentage: percentage }
  end
  respond_to do |format|
    format.html { render layout: should_render_layout? }
    format.turbo_stream
  end
end

#tab_itemsvoid

This method returns an undefined value.



59
60
61
62
63
64
65
# File 'app/controllers/catalogs_controller.rb', line 59

def tab_items
  load_and_authorize_catalog
  respond_to do |format|
    format.html { render layout: should_render_layout? }
    format.turbo_stream
  end
end

#tab_overviewvoid

This method returns an undefined value.

Tab actions for turbo-tabs lazy loading



50
51
52
53
54
55
56
# File 'app/controllers/catalogs_controller.rb', line 50

def tab_overview
  load_and_authorize_catalog
  respond_to do |format|
    format.html { render layout: should_render_layout? }
    format.turbo_stream
  end
end

#tab_relationshipsvoid

This method returns an undefined value.



77
78
79
80
81
82
83
# File 'app/controllers/catalogs_controller.rb', line 77

def tab_relationships
  load_and_authorize_catalog
  respond_to do |format|
    format.html { render layout: should_render_layout? }
    format.turbo_stream
  end
end

#tab_settingsvoid

This method returns an undefined value.



68
69
70
71
72
73
74
# File 'app/controllers/catalogs_controller.rb', line 68

def tab_settings
  load_and_authorize_catalog
  respond_to do |format|
    format.html { render layout: should_render_layout? }
    format.turbo_stream
  end
end

#updatevoid

This method returns an undefined value.

PATCH/PUT /catalogs/:id — updates a catalog via Catalog::UpdateCatalog.



197
198
199
200
201
202
203
204
205
206
# File 'app/controllers/catalogs_controller.rb', line 197

def update
  @catalog = Catalog.find(params[:id])
  authorize!(:update, @catalog)
  result = Catalog::UpdateCatalog.new.process(@catalog, params[:catalog])
  if result.catalog_updated?
    redirect_to_return_path_or_default(catalog_path(@catalog), notice: result.messages.join(', '))
  else
    render :edit, status: :unprocessable_content
  end
end