Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

perf/PSD-3232-SCPN-product_controler_refactoring #3498

Merged
merged 1 commit into from
Jan 6, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ class ResponsiblePersons::Notifications::ProductController < SubmitApplicationCo
add_product_image: :single_or_multi_component,
}.freeze

before_action :set_notification
before_action :set_notification_and_authorize
before_action :check_notification_submitted
meeravnagesh marked this conversation as resolved.
Show resolved Hide resolved
before_action :contains_nanomaterials_form, if: -> { step == :contains_nanomaterials }
before_action :single_or_multi_component_form, if: -> { step == :single_or_multi_component }

Expand All @@ -27,7 +28,7 @@ def show
when :completed
@notification.set_state_on_product_wizard_completed!
@continue_path = continue_path
render template: "responsible_persons/notifications/task_completed", locals: { continue_path: continue_path }
render template: "responsible_persons/notifications/task_completed", locals: { continue_path: @continue_path }
when :add_product_image
@clone_image_job = NotificationCloner::JobTracker.new(@notification.id) if @notification.cloned?
render_wizard
Expand All @@ -48,11 +49,7 @@ def update
@clone_image_job = NotificationCloner::JobTracker.new(@notification.id) if @notification.cloned?
update_add_product_image_step
else
if @notification.update_with_context(notification_params, step)
render_next_step @notification
else
rerender_current_step
end
update_column_or_fallback
end
end

Expand All @@ -62,92 +59,145 @@ def new

private

def set_notification_and_authorize
base_query = Notification
.select(selected_notification_columns + responsible_person_columns)
.joins(:responsible_person)

base_query = case step
when :contains_nanomaterials, :completed
base_query.includes(:nano_materials, :components)
when :single_or_multi_component
base_query.includes(:components)
else
base_query
end

@notification = base_query.find_by!(reference_number: params[:notification_reference_number])

@responsible_person = @notification.responsible_person

session_key = "authorized_for_notification_#{@notification.id}"
unless session[session_key]
authorized = ResponsiblePersonUser.exists?(
user_id: current_user.id,
responsible_person_id: @notification.responsible_person_id,
)
raise Pundit::NotAuthorizedError unless authorized

session[session_key] = true
end
end

def check_notification_submitted
return unless @notification.state == "notification_complete" && @notification.notification_complete_at.present?

redirect_to responsible_person_notification_path(@notification.responsible_person, @notification)
end

def continue_path
if @notification.nano_materials.present?
new_responsible_person_notification_nanomaterial_build_path(@notification.responsible_person, @notification, @notification.nano_materials.first)
elsif @notification.multi_component?
new_responsible_person_notification_product_kit_path(@notification.responsible_person, @notification)
@continue_path ||= if @notification.nano_materials.any?
new_responsible_person_notification_nanomaterial_build_path(@responsible_person, @notification, @notification.nano_materials.first)
elsif @notification.multi_component?
new_responsible_person_notification_product_kit_path(@responsible_person, @notification)
else
component = @notification.components.first || @notification.components.create!
new_responsible_person_notification_component_build_path(@responsible_person, @notification, component)
end
end

def update_with_context_and_render
if @notification.update_with_context(notification_params, step)
render_next_step @notification
else
component = @notification.components.first_or_create!
new_responsible_person_notification_component_build_path(@notification.responsible_person, @notification, component)
rerender_current_step
end
end

def update_add_internal_reference
case params.dig(:notification, :add_internal_reference)
when "yes"
model.save_routing_answer(step, "yes")
if @notification.update_with_context(notification_params, step)
render_next_step @notification
else
rerender_current_step
@notification.transaction do
model.save_routing_answer(step, "yes")
if @notification.update_with_context(notification_params, step)
render_next_step @notification
else
rerender_current_step
end
end
when "no"
model.save_routing_answer(step, "no")
@notification.industry_reference = nil
render_next_step @notification
@notification.transaction do
model.save_routing_answer(step, "no")
@notification.update_column(:industry_reference, nil)
meeravnagesh marked this conversation as resolved.
Show resolved Hide resolved
render_next_step @notification
end
else
@notification.errors.add :add_internal_reference, "Select yes to add an internal reference"
rerender_current_step
end
end

# Run this step only when notification doesn't already have nanomaterials
def update_contains_nanomaterials
return render_next_step @notification if @notification.nano_materials.any?
return render_next_step @notification if @notification.nano_materials.loaded? ? @notification.nano_materials.any? : @notification.nano_materials.exists?

form = contains_nanomaterials_form
return rerender_current_step unless form.valid?

model.save_routing_answer(step, form.contains_nanomaterials)
@notification.make_ready_for_nanomaterials!(form.nanomaterials_count.to_i)
render_next_step @notification
@notification.transaction do
meeravnagesh marked this conversation as resolved.
Show resolved Hide resolved
model.save_routing_answer(step, form.contains_nanomaterials)
@notification.make_ready_for_nanomaterials!(form.nanomaterials_count.to_i)
render_next_step @notification
end
end

# Run this step only when notifications does not have multiple components
def update_single_or_multi_component_step
return render_next_step @notification if @notification.multi_component?

form = single_or_multi_component_form
return rerender_current_step unless form.valid?

@notification.make_single_ready_for_components!(form.components_count.to_i)
render_next_step @notification
@notification.transaction do
meeravnagesh marked this conversation as resolved.
Show resolved Hide resolved
@notification.make_single_ready_for_components!(form.components_count.to_i)
render_next_step @notification
end
end

def update_add_product_image_step
if params[:image_upload].present?
params[:image_upload].each { |img| @notification.add_image(img) }
return rerender_current_step if @notification.errors.present?

@notification.save
if params[:back_to_edit] == "true"
redirect_to edit_responsible_person_notification_path(@notification.responsible_person, @notification)
elsif params[:after_save] == "upload_another"
rerender_current_step
else
render_next_step @notification
end
@notification.save!
handle_existing_image_uploads
elsif @notification.image_uploads.present?
if params[:back_to_edit] == "true"
redirect_to edit_responsible_person_notification_path(@notification.responsible_person, @notification)
elsif params[:after_save] == "upload_another"
rerender_current_step
else
render_next_step @notification
end
handle_existing_image_uploads
else
@notification.errors.add :image_uploads, "Select an image"
rerender_current_step
end
end

def handle_existing_image_uploads
if params[:back_to_edit] == "true"
redirect_to edit_responsible_person_notification_path(@notification.responsible_person, @notification)
elsif params[:after_save] == "upload_another"
rerender_current_step
else
render_next_step @notification
end
end

def notification_params
params.fetch(:notification, {})
.permit(
:product_name,
:industry_reference,
:under_three_years,
:still_on_the_market,
:shades,
:import_country,
:cpnp_notification_date,
:was_notified_before_eu_exit,
image_uploads_attributes: [file: []],
)
end
Expand Down Expand Up @@ -191,4 +241,81 @@ def single_or_multi_component_values
def model
@notification
end

def rerender_current_step
render step
end

def selected_notification_columns
%i[
id
reference_number
product_name
state
notification_complete_at
responsible_person_id
industry_reference
under_three_years
components_are_mixed
previous_state
routing_questions_answers
cpnp_reference
source_notification_id
archive_reason
import_country
shades
cpnp_notification_date
was_notified_before_eu_exit
still_on_the_market
ph_min_value
ph_max_value
csv_cache
deleted_at
]
end

def responsible_person_columns
[
Arel.sql("responsible_persons.id as responsible_person_id"),
Arel.sql("responsible_persons.name as responsible_person_name"),
]
end

def update_column_or_fallback
direct_update_columns = {
product_name: true,
under_three_years: true,
industry_reference: ->(_params) { step != :add_internal_reference },
still_on_the_market: true,
shades: true,
import_country: true,
cpnp_notification_date: true,
was_notified_before_eu_exit: true,
}

direct_update_columns.each do |column, condition|
next unless notification_params.key?(column)
next unless condition.is_a?(Proc) ? condition.call(notification_params) : condition

return perform_direct_column_update(column)
end

@notification.transaction do
if @notification.update_with_context(notification_params, step)
render_next_step @notification
else
rerender_current_step
end
end
end

def perform_direct_column_update(column)
column_updated = @notification.update_column(column, notification_params[column])
if column_updated
render_next_step(@notification)
else
@notification.errors.add(column, "could not be updated")
rerender_current_step
end
end
end
Loading
Loading