scinote-web/app/controllers/samples_controller.rb
2017-04-06 15:26:24 +02:00

362 lines
9.9 KiB
Ruby

class SamplesController < ApplicationController
include InputSanitizeHelper
include ActionView::Helpers::TextHelper
include ApplicationHelper
before_action :load_vars, only: [:edit, :update, :destroy, :show]
before_action :load_vars_nested, only: [:new, :create]
before_action :check_edit_permissions, only: :edit
before_action :check_destroy_permissions, only: :destroy
def new
respond_to do |format|
format.html
if can_create_samples(@team)
groups = @team.sample_groups.map do |g|
{ id: g.id, name: sanitize_input(g.name), color: g.color }
end
types = @team.sample_types.map do |t|
{ id: t.id, name: sanitize_input(t.name) }
end
format.json do
render json: {
sample_groups: groups.as_json,
sample_types: types.as_json
}
end
else
format.json { render json: {}, status: :unauthorized }
end
end
end
def create
sample = Sample.new(
user: current_user,
team: @team
)
sample.last_modified_by = current_user
errors = {
init_fields: [],
custom_fields: []
};
respond_to do |format|
if can_create_samples(@team)
if params[:sample]
# Sample name
if params[:sample][:name]
sample.name = params[:sample][:name]
end
# Sample type
if params[:sample][:sample_type_id] != "-1"
sample_type = SampleType.find_by_id(params[:sample][:sample_type_id])
if sample_type
sample.sample_type_id = params[:sample][:sample_type_id]
end
end
# Sample group
if params[:sample][:sample_group_id] != "-1"
sample_group = SampleGroup.find_by_id(params[:sample][:sample_group_id])
if sample_group
sample.sample_group_id = params[:sample][:sample_group_id]
end
end
end
if !sample.save
errors[:init_fields] = sample.errors.messages
else
# Sample was saved, we can add all newly added sample fields
params[:custom_fields].to_a.each do |id, val|
scf = SampleCustomField.new(
custom_field_id: id,
sample_id: sample.id,
value: val
)
if !scf.save
errors[:custom_fields] << {
"#{id}": scf.errors.messages
}
else
sample_annotation_notification(sample, scf)
end
end
end
errors.delete_if { |k, v| v.blank? }
if errors.empty?
format.json do
render json: {
id: sample.id,
flash: t(
'samples.create.success_flash',
sample: escape_input(sample.name),
team: escape_input(@team.name)
)
},
status: :ok
end
else
format.json { render json: errors, status: :bad_request }
end
else
format.json { render json: {}, status: :unauthorized }
end
end
end
def show
respond_to do |format|
format.json do
render json: {
html: render_to_string(
partial: 'info_sample_modal.html.erb'
)
}
end
end
end
def edit
json = {
sample: {
name: escape_input(@sample.name),
sample_type: @sample.sample_type.nil? ? "" : @sample.sample_type.id,
sample_group: @sample.sample_group.nil? ? "" : @sample.sample_group.id,
custom_fields: {}
},
sample_groups: @team.sample_groups.map do |g|
{ id: g.id, name: sanitize_input(g.name), color: g.color }
end,
sample_types: @team.sample_types.map do |t|
{ id: t.id, name: sanitize_input(t.name) }
end
}
# Add custom fields ids as key (easier lookup on js side)
@sample.sample_custom_fields.each do |scf|
json[:sample][:custom_fields][scf.custom_field_id] = {
sample_custom_field_id: scf.id,
value: escape_input(scf.value)
}
end
respond_to do |format|
format.html
format.json {
render json: json
}
end
end
def update
sample = Sample.find_by_id(params[:sample_id])
sample.last_modified_by = current_user
errors = {
init_fields: [],
sample_custom_fields: [],
custom_fields: []
};
respond_to do |format|
if sample
if can_edit_sample(sample)
if params[:sample]
if params[:sample][:name]
sample.name = params[:sample][:name]
end
# Check if user selected empty sample type
if params[:sample][:sample_type_id] == "-1"
sample.sample_type_id = nil
elsif params[:sample][:sample_type_id]
sample_type = SampleType.find_by_id(params[:sample][:sample_type_id])
if sample_type
sample.sample_type_id = params[:sample][:sample_type_id]
end
end
# Check if user selected empty sample type
if params[:sample][:sample_group_id] == "-1"
sample.sample_group_id = nil
elsif params[:sample][:sample_group_id]
sample_group = SampleGroup.find_by_id(params[:sample][:sample_group_id])
if sample_group
sample.sample_group_id = params[:sample][:sample_group_id]
end
end
end
# Add all newly added sample fields
params[:custom_fields].to_a.each do |id, val|
# Check if client is lying (SCF shouldn't exist)
scf = SampleCustomField.where("custom_field_id = ? AND sample_id = ?", id, sample.id).take
if scf
old_text = scf.value
# Well, client was naughty, no XMAS for him this year, update
# existing SCF instead of creating new one
scf.value = val
if !scf.save
# This client needs some lessons
errors[:custom_fields] << {
"#{id}": scf.errors.messages
}
else
sample_annotation_notification(sample, scf, old_text)
end
else
# SCF doesn't exist, create it
scf = SampleCustomField.new(
custom_field_id: id,
sample_id: sample.id,
value: val
)
if !scf.save
errors[:custom_fields] << {
"#{id}": scf.errors.messages
}
else
sample_annotation_notification(sample, scf)
end
end
end
scf_to_delete = []
# Update all existing custom values
params[:sample_custom_fields].to_a.each do |id, val|
scf = SampleCustomField.find_by_id(id)
if scf
# SCF exists, but value is empty, add scf to queue to be deleted
# (if everything is correct)
if val.empty?
scf_to_delete << scf
else
old_text = scf.value
# SCF exists, update away
scf.value = val
if !scf.save
errors[:sample_custom_fields] << {
"#{id}": scf.errors.messages
}
else
sample_annotation_notification(sample, scf, old_text)
end
end
else
# SCF doesn't exist, we can't do much but yield error
errors[:sample_custom_fields] << {
"#{id}": I18n.t("samples.edit.scf_does_not_exist")
}
end
end
if !sample.save
errors[:init_fields] = sample.errors.messages
end
errors.delete_if { |k, v| v.blank? }
if errors.empty?
# Now we can destroy empty scfs
scf_to_delete.map(&:destroy)
format.json do
render json: {
id: sample.id,
flash: t(
'samples.update.success_flash',
sample: escape_input(sample.name),
team: escape_input(@team.name)
)
},
status: :ok
end
else
format.json { render json: errors, status: :bad_request }
end
else
format.json { render json: {}, status: :unauthorized }
end
else
format.json { render json: {}, status: :not_found }
end
end
end
def destroy
end
private
def load_vars
@sample = Sample.find_by_id(params[:id])
@team = current_team
unless @sample
render_404
end
end
def load_vars_nested
@team = Team.find_by_id(params[:team_id])
unless @team
render_404
end
end
def check_create_permissions
unless can_create_samples(@team)
render_403
end
end
def check_edit_permissions
unless can_edit_sample(@sample)
render_403
end
end
def check_destroy_permissions
unless can_delete_samples(@team)
render_403
end
end
def sample_params
params.require(:sample).permit(
:name,
:sample_type_id,
:sample_group_id
)
end
def sample_annotation_notification(sample, scf, old_text = nil)
table_url = params.fetch(:request_url) { :request_url_must_be_present }
smart_annotation_notification(
old_text: (old_text if old_text),
new_text: scf.value,
title: t('notifications.sample_annotation_title',
user: current_user.full_name,
column: scf.custom_field.name,
sample: sample.name),
message: t('notifications.sample_annotation_message_html',
sample: link_to(sample.name, table_url),
column: link_to(scf.custom_field.name, table_url))
)
end
end