Class: ArticleTechnicalsController

Inherits:
CrmController show all
Includes:
Controllers::Articlable, Controllers::ArticleRevisionEditing, Controllers::Attachable
Defined in:
app/controllers/article_technicals_controller.rb

Overview

Controller: article technicals.

Constant Summary collapse

MODEL_CLASS =

Model class.

ArticleTechnical
APPROVAL_EVENTS =

State-machine events that require Technical Article approval permission.

%w[approve_internal publish request_changes].freeze
ARTICLE_ATTRIBUTES =

Strong-parameter attributes accepted by create and update.

[
  :subject,
  :knowledge_role,
  :state_event,
  :original_author_id,
  :user_id,
  :problem_code,
  :warranty_parts,
  :warranty_labor,
  :serial_number_low_range,
  :serial_number_high_range,
  :time_required,
  :slug_custom,
  :description,
  :solution,
  { product_line_ids: [], product_category_ids: [], item_ids: [] }
].freeze
ARTICLE_FORM_ATTRIBUTES =

Form-only workflow choice. This is deliberately not an Article attribute.

[:create_revision, *ARTICLE_ATTRIBUTES].freeze

Constants included from Controllers::Attachable

Controllers::Attachable::PUBLICATIONS_PER_PAGE

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::Articlable

#convert_type, #destroy, #load_article, #show, #show_description, #show_solution

Methods included from Controllers::Attachable

#attach, #publication_modal, #remove_attachment, #search_library

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

#archivevoid

This method returns an undefined value.

Archives a Technical Article when no replacement draft is active.



138
139
140
141
142
143
144
145
146
147
148
149
150
151
# File 'app/controllers/article_technicals_controller.rb', line 138

def archive
  load_article
  authorize!(:approve, @article)
  if (replacement = @article.active_replacement_draft)
    redirect_to edit_article_technical_path(replacement),
                alert: 'Review or remove the active replacement draft before archiving its approved source.'
    return
  end

  @article.archive!
  redirect_to article_technical_path(@article), notice: 'Technical Article archived.'
rescue StateMachines::InvalidTransition => e
  redirect_to article_technical_path(@article), alert: e.message
end

#classify_knowledgevoid

This method returns an undefined value.

Classifies an article's AI corpus purpose without changing its editorial
content, lifecycle state, or replacement lineage.



157
158
159
160
161
162
163
164
165
166
# File 'app/controllers/article_technicals_controller.rb', line 157

def classify_knowledge
  load_article
  authorize!(:update, @article)

  if @article.update(knowledge_role: knowledge_role_param, updater_id: current_user.id)
    redirect_to article_technical_path(@article), notice: 'Technical Article knowledge role updated.'
  else
    redirect_to article_technical_path(@article), alert: @article.errors.full_messages.to_sentence
  end
end

#createvoid

This method returns an undefined value.

Creates a Technical Article and sends its creation notification.



82
83
84
85
86
87
88
89
90
91
92
93
# File 'app/controllers/article_technicals_controller.rb', line 82

def create
  @article = ArticleTechnical.new
  authorize!(:create, @article)
  @article.original_author_id = current_user.id

  if persist_article(article_params.except(:create_revision))
    @article.send_creation_email
    redirect_to_return_path_or_default article_technical_path(@article)
  else
    render :new, status: :unprocessable_content
  end
end

#create_replacementvoid

This method returns an undefined value.

Creates a replacement draft for an approved Technical Article.



123
124
125
126
127
128
129
130
131
132
133
# File 'app/controllers/article_technicals_controller.rb', line 123

def create_replacement
  load_article
  authorize!(:update, @article)
  authorize!(:create, ArticleTechnical)

  replacement = @article.create_replacement_draft!(author: current_user)
  redirect_to edit_article_technical_path(replacement),
              notice: "Replacement draft ##{replacement.id} is ready. The current article remains live until approval."
rescue ActiveRecord::RecordInvalid => e
  redirect_to article_technical_path(@article), alert: e.record.errors.full_messages.to_sentence
end

#editvoid

This method returns an undefined value.

Opens the Technical Article editor. Live records may optionally be saved
into the revision workflow from this same form.



74
75
76
77
# File 'app/controllers/article_technicals_controller.rb', line 74

def edit
  load_article
  authorize!(:update, @article)
end

#indexvoid

This method returns an undefined value.

Lists Technical Articles with pending reviews ahead of drafts and approved records.



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'app/controllers/article_technicals_controller.rb', line 40

def index
  authorize!(:read, Article)
  @q = ArticleTechnical.ransack(params[:q])
  explicit_sort = @q.sorts.present?
  @q.sorts = 'updated_at desc' unless explicit_sort
  review_queue_first = Arel.sql(<<~SQL.squish)
    CASE articles.state
    WHEN 'pending_review' THEN 0
    WHEN 'draft' THEN 1
    ELSE 2
    END
  SQL
  corpus_review_first = Arel::Nodes::Case.new(
    Article.arel_table[:knowledge_role]
  ).when(Article::UNREVIEWED_KNOWLEDGE_ROLE).then(0).else(1)
  scope = @q.result.includes(:original_author, :product_lines, :user, taggings: :tag)
  scope = scope.reorder(review_queue_first, corpus_review_first, updated_at: :desc) unless explicit_sort
  @pagy, @articles = pagy(scope)
  @tag_names = Tag.order(:name).pluck(:name)
  compute_stats
end

#newvoid

This method returns an undefined value.

Builds a new Technical Article attributed to the current employee.



65
66
67
68
# File 'app/controllers/article_technicals_controller.rb', line 65

def new
  @article = ArticleTechnical.new(original_author_id: current_user.id)
  authorize!(:create, @article)
end

#send_by_emailvoid

This method returns an undefined value.

Opens a new communication populated with the Technical Article.



115
116
117
118
# File 'app/controllers/article_technicals_controller.rb', line 115

def send_by_email
  load_article
  redirect_to new_communication_path(resource_id: @article.id, resource_type: 'article')
end

#updatevoid

This method returns an undefined value.

Updates an editable Technical Article and sends its update notification.



98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'app/controllers/article_technicals_controller.rb', line 98

def update
  load_article
  authorize!(:update, @article)
  permitted_params = article_params
  return save_as_revision(permitted_params) if revision_requested?(permitted_params)

  if persist_article(permitted_params.except(:create_revision))
    @article.send_update_email
    redirect_to_return_path_or_default article_technical_path(@article)
  else
    render :edit, status: :unprocessable_content
  end
end