class ProtocolsController < ApplicationController include RenamingUtil include ProtocolsImporter include ProtocolsExporter before_action :check_create_permissions, only: [ :create_new_modal, :create ] before_action :check_clone_permissions, only: [ :clone ] before_action :check_view_permissions, only: [ :protocol_status_bar, :updated_at_label, :linked_children, :linked_children_datatable ] before_action :check_edit_permissions, only: [ :edit, :update_metadata, :update_keywords, :edit_name_modal, :edit_keywords_modal, :edit_authors_modal, :edit_description_modal ] before_action :check_view_all_permissions, only: [ :index, :datatable ] before_action :check_unlink_permissions, only: [ :unlink, :unlink_modal ] before_action :check_revert_permissions, only: [ :revert, :revert_modal ] before_action :check_update_parent_permissions, only: [ :update_parent, :update_parent_modal ] before_action :check_update_from_parent_permissions, only: [ :update_from_parent, :update_from_parent_modal ] before_action :check_load_from_repository_views_permissions, only: [ :load_from_repository_modal, :load_from_repository_datatable ] before_action :check_load_from_repository_permissions, only: [ :load_from_repository ] before_action :check_load_from_file_permissions, only: [ :load_from_file ] before_action :check_copy_to_repository_permissions, only: [ :copy_to_repository, :copy_to_repository_modal ] before_action :check_make_private_permissions, only: [ :make_private ] before_action :check_publish_permissions, only: [ :publish ] before_action :check_archive_permissions, only: [ :archive ] before_action :check_restore_permissions, only: [ :restore ] before_action :check_import_permissions, only: [ :import ] before_action :check_export_permissions, only: [ :export ] def index end def datatable respond_to do |format| format.json { render json: ::ProtocolsDatatable.new( view_context, @current_organization, @type, current_user ) } end end def linked_children respond_to do |format| format.json { render json: { title: I18n.t("protocols.index.linked_children.title", protocol: @protocol.name), html: render_to_string({ partial: "protocols/index/linked_children_modal_body.html.erb", locals: { protocol: @protocol } }) } } end end def linked_children_datatable respond_to do |format| format.json { render json: ::ProtocolLinkedChildrenDatatable.new( view_context, @protocol, current_user, self ) } end end def make_private move_protocol("make_private") end def publish move_protocol("publish") end def archive move_protocol("archive") end def restore move_protocol("restore") end def edit end def update_metadata @protocol.record_timestamps = false @protocol.assign_attributes(metadata_params) respond_to do |format| if @protocol.save format.json { render json: { updated_at_label: render_to_string( partial: "protocols/header/updated_at_label.html.erb" ), name_label: render_to_string( partial: "protocols/header/name_label.html.erb" ), authors_label: render_to_string( partial: "protocols/header/authors_label.html.erb" ), description_label: render_to_string( partial: "protocols/header/description_label.html.erb" ) } } else format.json { render json: @protocol.errors, status: :unprocessable_entity } end end end def update_keywords respond_to do |format| if @protocol.update_keywords(params[:keywords]) format.json { render json: { updated_at_label: render_to_string( partial: "protocols/header/updated_at_label.html.erb" ), keywords_label: render_to_string( partial: "protocols/header/keywords_label.html.erb" ) } } else format.json { render json: {}, status: :unprocessable_entity } end end end def create @protocol = Protocol.new( organization: @current_organization, protocol_type: Protocol.protocol_types[@type == :public ? :in_repository_public : :in_repository_private], added_by: current_user ) @protocol.assign_attributes(create_params) ts = Time.now @protocol.record_timestamps = false @protocol.created_at = ts @protocol.updated_at = ts if @type == :public @protocol.published_on = ts end respond_to do |format| if @protocol.save format.json { render json: { url: edit_protocol_path( @protocol, organization: @current_organization, type: @type ) } } else format.json { render json: @protocol.errors, status: :unprocessable_entity } end end end def clone cloned = nil Protocol.transaction do begin cloned = @original.deep_clone_repository(current_user) rescue Exception raise ActiveRecord:: Rollback end end respond_to do |format| if cloned != nil flash[:success] = t( "protocols.index.clone.success_flash", original: @original.name, new: cloned.name ) flash.keep(:success) format.json { render json: {}, status: :ok } else flash[:error] = t( "protocols.index.clone.error_flash", original: @original.name ) flash.keep(:error) format.json { render json: {}, status: :bad_request } end end end def copy_to_repository link_protocols = can_link_copied_protocol_in_repository(@protocol) && params[:link] respond_to do |format| transaction_error = false Protocol.transaction do begin @new = @protocol.copy_to_repository( copy_to_repository_params[:name], copy_to_repository_params[:protocol_type], link_protocols, current_user ) rescue Exception transaction_error = true raise ActiveRecord:: Rollback end end if transaction_error # Bad request error format.json { render json: { message: t("my_modules.protocols.copy_to_repository_modal.error_400") }, status: :bad_request } elsif @new.invalid? # Render errors format.json { render json: @new.errors, status: :unprocessable_entity } else # Everything good, render 200 format.json { render json: { refresh: link_protocols }, status: :ok } end end end def unlink respond_to do |format| transaction_error = false Protocol.transaction do begin @protocol.unlink rescue Exception transaction_error = true raise ActiveRecord:: Rollback end end if transaction_error # Bad request error format.json { render json: { message: t("my_modules.protocols.unlink_error") }, status: :bad_request } else # Everything good, display flash & render 200 flash[:success] = t( "my_modules.protocols.unlink_flash", ) flash.keep(:success) format.json { render json: {}, status: :ok } end end end def revert respond_to do |format| if @protocol.can_destroy? transaction_error = false Protocol.transaction do begin # Revert is basically update from parent @protocol.update_from_parent(current_user) rescue Exception transaction_error = true raise ActiveRecord:: Rollback end end if transaction_error # Bad request error format.json do render json: { message: t('my_modules.protocols.revert_error') }, status: :bad_request end else # Everything good, display flash & render 200 flash[:success] = t( 'my_modules.protocols.revert_flash' ) flash.keep(:success) format.json { render json: {}, status: :ok } end else format.json do render json: { message: t('my_modules.protocols.revert_error_locked') }, status: :bad_request end end end end def update_parent respond_to do |format| if @protocol.parent.can_destroy? transaction_error = false Protocol.transaction do begin @protocol.update_parent(current_user) rescue Exception transaction_error = true raise ActiveRecord:: Rollback end end if transaction_error # Bad request error format.json { render json: { message: t("my_modules.protocols.update_parent_error") }, status: :bad_request } else # Everything good, display flash & render 200 flash[:success] = t( "my_modules.protocols.update_parent_flash", ) flash.keep(:success) format.json { render json: {}, status: :ok } end else format.json do render json: { message: t('my_modules.protocols.update_parent_error_locked') }, status: :bad_request end end end end def update_from_parent respond_to do |format| if @protocol.can_destroy? transaction_error = false Protocol.transaction do begin @protocol.update_from_parent(current_user) rescue Exception transaction_error = true raise ActiveRecord:: Rollback end end if transaction_error # Bad request error format.json { render json: { message: t("my_modules.protocols.update_from_parent_error") }, status: :bad_request } else # Everything good, display flash & render 200 flash[:success] = t( "my_modules.protocols.update_from_parent_flash", ) flash.keep(:success) format.json { render json: {}, status: :ok } end else format.json do render json: { message: t('my_modules.protocols.update_from_parent_error_locked') }, status: :bad_request end end end end def load_from_repository respond_to do |format| if @protocol.can_destroy? transaction_error = false Protocol.transaction do begin @protocol.load_from_repository(@source, current_user) rescue Exception transaction_error = true raise ActiveRecord:: Rollback end end if transaction_error # Bad request error format.json { render json: { message: t("my_modules.protocols.load_from_repository_error") }, status: :bad_request } else # Everything good, display flash & render 200 flash[:success] = t( "my_modules.protocols.load_from_repository_flash", ) flash.keep(:success) format.json { render json: {}, status: :ok } end else format.json do render json: { message: t('my_modules.protocols.load_from_repository_error_locked') }, status: :bad_request end end end end def load_from_file # This is actually very similar to import respond_to do |format| if @protocol.can_destroy? transaction_error = false Protocol.transaction do begin import_into_existing(@protocol, @protocol_json, current_user) rescue Exception transaction_error = true raise ActiveRecord:: Rollback end end if transaction_error format.json { render json: { status: :error }, status: :bad_request } else # Everything good, display flash & render 200 flash[:success] = t( "my_modules.protocols.load_from_file_flash", ) flash.keep(:success) format.json { render json: { status: :ok }, status: :ok } end else format.json do render json: { status: :locked }, status: :bad_request end end end end def import protocol = nil respond_to do |format| transaction_error = false Protocol.transaction do begin protocol = import_new_protocol(@protocol_json, @organization, @type, current_user) rescue Exception transaction_error = true raise ActiveRecord:: Rollback end end p_name = ( @protocol_json["name"].present? && !@protocol_json["name"].empty? ) ? @protocol_json["name"] : t("protocols.index.no_protocol_name") if transaction_error format.json { render json: { name: p_name, status: :bad_request }, status: :bad_request } else format.json { render json: { name: p_name, new_name: protocol.name, status: :ok }, status: :ok } end end end def export respond_to do |format| format.json { render json: { protocols: export_protocols(@protocols) }, status: :ok } end end def unlink_modal respond_to do |format| format.json { render json: { title: t("my_modules.protocols.confirm_link_update_modal.unlink_title"), message: t("my_modules.protocols.confirm_link_update_modal.unlink_message"), btn_text: t("my_modules.protocols.confirm_link_update_modal.unlink_btn_text"), url: unlink_protocol_path(@protocol) } } end end def revert_modal respond_to do |format| format.json { render json: { title: t("my_modules.protocols.confirm_link_update_modal.revert_title"), message: t("my_modules.protocols.confirm_link_update_modal.revert_message"), btn_text: t("my_modules.protocols.confirm_link_update_modal.revert_btn_text"), url: revert_protocol_path(@protocol) } } end end def update_parent_modal respond_to do |format| format.json { render json: { title: t("my_modules.protocols.confirm_link_update_modal.update_parent_title"), message: t("my_modules.protocols.confirm_link_update_modal.update_parent_message"), btn_text: t("general.update"), url: update_parent_protocol_path(@protocol) } } end end def update_from_parent_modal respond_to do |format| format.json { render json: { title: t("my_modules.protocols.confirm_link_update_modal.update_self_title"), message: t("my_modules.protocols.confirm_link_update_modal.update_self_message"), btn_text: t("general.update"), url: update_from_parent_protocol_path(@protocol) } } end end def load_from_repository_datatable @protocol = Protocol.find_by_id(params[:id]) @type = (params[:type] || "public").to_sym respond_to do |format| format.json { render json: ::LoadFromRepositoryProtocolsDatatable.new( view_context, @protocol.organization, @type, current_user ) } end end def load_from_repository_modal @protocol = Protocol.find_by_id(params[:id]) respond_to do |format| format.json { render json: { html: render_to_string({ partial: "my_modules/protocols/load_from_repository_modal_body.html.erb" }) } } end end def copy_to_repository_modal @new = Protocol.new @original = Protocol.find(params[:id]) respond_to do |format| format.json { render json: { html: render_to_string({ partial: "my_modules/protocols/copy_to_repository_modal_body.html.erb" }) } } end end def protocol_status_bar respond_to do |format| format.json { render json: { html: render_to_string({ partial: "my_modules/protocols/protocol_status_bar.html.erb" }) } } end end def updated_at_label respond_to do |format| format.json { render json: { html: render_to_string({ partial: "protocols/header/updated_at_label.html.erb" }) } } end end def create_new_modal @new_protocol = Protocol.new respond_to do |format| format.json { render json: { html: render_to_string({ partial: "protocols/index/create_new_modal_body.html.erb" }) } } end end def edit_name_modal respond_to do |format| format.json { render json: { title: I18n.t("protocols.header.edit_name_modal.title", protocol: @protocol.name), html: render_to_string({ partial: "protocols/header/edit_name_modal_body.html.erb" }) } } end end def edit_keywords_modal respond_to do |format| format.json { render json: { title: I18n.t("protocols.header.edit_keywords_modal.title", protocol: @protocol.name), html: render_to_string({ partial: "protocols/header/edit_keywords_modal_body.html.erb" }), keywords: @protocol.organization.protocol_keywords_list } } end end def edit_authors_modal respond_to do |format| format.json { render json: { title: I18n.t("protocols.header.edit_authors_modal.title", protocol: @protocol.name), html: render_to_string({ partial: "protocols/header/edit_authors_modal_body.html.erb" }) } } end end def edit_description_modal respond_to do |format| format.json { render json: { title: I18n.t("protocols.header.edit_description_modal.title", protocol: @protocol.name), html: render_to_string({ partial: "protocols/header/edit_description_modal_body.html.erb" }) } } end end private def move_protocol(action) rollbacked = false results = [] begin Protocol.transaction do @protocols.find_each do |protocol| result = { name: protocol.name } success = protocol.method(action).call(current_user) # Try renaming protocol unless success rename_record(protocol, :name) success = protocol.method(action).call(current_user) end result[:new_name] = protocol.name result[:type] = protocol.protocol_type result[:success] = success results << result end end rescue rollbacked = true end respond_to do |format| unless rollbacked format.json { render json: { html: render_to_string({ partial: "protocols/index/results_modal_body.html.erb", locals: { results: results, en_action: "#{action}_results" } }) } } else format.json { render json: {}, status: :bad_request } end end end def load_organization_and_type @organizations = current_user.organizations.order(name: :asc) @current_organization = @organizations.select{ |org| org.id == params[:organization].to_i }.first @current_organization ||= @organizations.first # :public, :private or :archive @type = (params[:type] || "public").to_sym end def check_view_all_permissions load_organization_and_type unless can_view_organization_protocols(@current_organization) render_403 end end def check_view_permissions @protocol = Protocol.find_by_id(params[:id]) if @protocol.blank? || !can_view_protocol(@protocol) respond_to { |f| f.json { render json: {}, status: :unauthorized } } end end def check_create_permissions load_organization_and_type if !can_create_new_protocol(@current_organization) || @type == :archive render_403 end end def check_clone_permissions load_organization_and_type @original = Protocol.find_by_id(params[:id]) if @original.blank? || !can_clone_protocol(@original) || @type == :archive render_403 end end def check_edit_permissions load_organization_and_type @protocol = Protocol.find_by_id(params[:id]) unless can_edit_protocol(@protocol) render_403 end end def check_unlink_permissions @protocol = Protocol.find_by_id(params[:id]) if @protocol.blank? || !can_unlink_protocol(@protocol) render_403 end end def check_revert_permissions @protocol = Protocol.find_by_id(params[:id]) if @protocol.blank? || !can_revert_protocol(@protocol) render_403 end end def check_update_parent_permissions @protocol = Protocol.find_by_id(params[:id]) if @protocol.blank? || !can_update_parent_protocol(@protocol) render_403 end end def check_update_from_parent_permissions @protocol = Protocol.find_by_id(params[:id]) if @protocol.blank? || !can_update_protocol_from_parent(@protocol) render_403 end end def check_load_from_repository_views_permissions @protocol = Protocol.find_by_id(params[:id]) if @protocol.blank? || !can_view_protocol(@protocol) render_403 end end def check_load_from_repository_permissions @protocol = Protocol.find_by_id(params[:id]) @source = Protocol.find_by_id(params[:source_id]) if @protocol.blank? || @source.blank? || !can_load_protocol_from_repository(@protocol, @source) render_403 end end def check_load_from_file_permissions @protocol_json = params[:protocol] @protocol = Protocol.find_by_id(params[:id]) @my_module = @protocol.my_module if @protocol_json.blank? || @protocol.blank? || @my_module.blank? || !can_load_protocol_into_module(@my_module) render_403 end end def check_copy_to_repository_permissions @protocol = Protocol.find_by_id(params[:id]) @my_module = @protocol.my_module if @my_module.blank? or !can_copy_protocol_to_repository(@my_module) render_403 end end def check_make_private_permissions @protocols = Protocol.where(id: params[:protocol_ids]) @protocols.find_each do |protocol| unless can_make_protocol_private(protocol) then respond_to { |f| f.json { render json: {}, status: :unauthorized } } return end end end def check_publish_permissions @protocols = Protocol.where(id: params[:protocol_ids]) @protocols.find_each do |protocol| unless can_publish_protocol(protocol) then respond_to { |f| f.json { render json: {}, status: :unauthorized } } return end end end def check_archive_permissions @protocols = Protocol.where(id: params[:protocol_ids]) @protocols.find_each do |protocol| unless can_archive_protocol(protocol) then respond_to { |f| f.json { render json: {}, status: :unauthorized } } return end end end def check_restore_permissions @protocols = Protocol.where(id: params[:protocol_ids]) @protocols.find_each do |protocol| unless can_restore_protocol(protocol) then respond_to { |f| f.json { render json: {}, status: :unauthorized } } return end end end def check_import_permissions @protocol_json = params[:protocol] @organization = Organization.find(params[:organization_id]) @type = params[:type] ? params[:type].to_sym : nil if !( @protocol_json.present? && @organization.present? && (@type == :public || @type == :private) && can_import_protocols(@organization) ) render_403 end end def check_export_permissions @protocols = Protocol.where(id: params[:protocol_ids]) if @protocols.blank? || @protocols.any? { |p| !can_export_protocol(p) } render_403 end end def copy_to_repository_params params.require(:protocol).permit(:name, :protocol_type) end def create_params params.require(:protocol).permit(:name) end def metadata_params params.require(:protocol).permit(:name, :authors, :description) end end