diff --git a/Gemfile b/Gemfile index 06b3e3f..2b41610 100644 --- a/Gemfile +++ b/Gemfile @@ -79,6 +79,7 @@ # ------------------------------------------------ # INTERNATIONALIZATION gem "i18n-js", ">= 3.0.0.rc11" #damodar added TODO: explain +gem 'gettext_i18n_rails', '~> 1.8' # ------------------------------------------------ # API diff --git a/app/admin/organisation_type.rb b/app/admin/organisation_type.rb deleted file mode 100644 index 4575f54..0000000 --- a/app/admin/organisation_type.rb +++ /dev/null @@ -1,55 +0,0 @@ -# [+Project:+] DMPRoadmap -# [+Description:+] -# -# [+Created:+] 03/09/2014 -# [+Copyright:+] Digital Curation Centre and University of California Curation Center - -ActiveAdmin.register OrganisationType do - permit_params :organisation_id, :name - - menu :priority => 4, :label => proc{I18n.t('admin.org_type')}, :parent => "Organisations management" - - index do - column I18n.t('admin.title'), :sortable => :name do |ggn| - link_to ggn.name, [:admin, ggn] - end - column I18n.t('admin.desc'), :description do |descr| - if !descr.description.nil? then - descr.description.html_safe - end - end - - actions - end - - - #show organisation type details - show do - attributes_table do - row :name - row :description do |descr| - if !descr.description.nil? then - descr.description.html_safe - end - end - row :created_at - row :updated_at - end - end - - #organisations sidebar - sidebar I18n.t('admin.orgs'), :only => :show, :if => proc { organisation_type.organisations.count >= 1} do - table_for organisation_type.organisations.order("name") do |org_list| - column I18n.t('admin.org_title'), :sortable => :name do |ggn| - link_to ggn.name, [:admin, ggn] - end - end - end - - controller do - def permitted_params - params.permit! - end - end - -end diff --git a/app/controllers/answers_controller.rb b/app/controllers/answers_controller.rb index 8b2e44a..8ef2500 100644 --- a/app/controllers/answers_controller.rb +++ b/app/controllers/answers_controller.rb @@ -21,6 +21,8 @@ authorize @answer +puts params.inspect + @answer.text = params["answer-text-#{@answer.question_id}".to_sym] #TODO: check for optimistic locking diff --git a/app/controllers/api/v0/base_controller.rb b/app/controllers/api/v0/base_controller.rb index b36bfa8..631983e 100644 --- a/app/controllers/api/v0/base_controller.rb +++ b/app/controllers/api/v0/base_controller.rb @@ -121,7 +121,7 @@ end def has_auth (auth_type) - auth = false + #auth = false # not sure if initial if is necissary, but it works with it there... refactor later? # if !TokenPermission.where(api_token: @token).nil? # TokenPermission.where(api_token: @token).find_each do |permission| @@ -131,13 +131,16 @@ # end # end # end - OrgTokenPermission.where(org_id: @user.org_id).find_each do |org_token_permission| - logger.debug "#{org_token_permission.token_permission_type.token_type}" - if org_token_permission.token_permission_type.token_type == auth_type - auth= true - end - end - return auth + + #OrgTokenPermission.where(org_id: @user.org_id).find_each do |org_token_permission| + # logger.debug "#{org_token_permission.token_permission_type.token_type}" + # if org_token_permission.token_permission_type.token_type == auth_type + # auth= true + # end + #end + #return auth + tpt = TokenPermissionType.find_by(token_type: auth) + org.token_permission_types.include?(tpt) end end diff --git a/app/controllers/api/v0/plans_controller.rb b/app/controllers/api/v0/plans_controller.rb index ad76c3d..c96d174 100644 --- a/app/controllers/api/v0/plans_controller.rb +++ b/app/controllers/api/v0/plans_controller.rb @@ -21,20 +21,20 @@ if has_auth(constant("api_endpoint_types.plans")) #params[:organization_id] = Org.where(name: params[:template][:organization]) # find_by returns nil if none found, find_by! raises an ActiveRecord error - organization = Org.find_by name: params[:template][:organisation] + org = Org.find_by name: params[:template][:organisation] # if organization exists - if !organization.nil? + if !org.nil? # if organization is funder - if organization.organisation_type == (OrganisationType.find_by(name: constant("organisation_types.funder"))) + if org.funder? # if organization has only 1 template - if organization.dmptemplates.length == 1 + if org.templates.length == 1 # set template id - dmptemplate = organization.dmptemplates.first + template = org.templates.first # else if params.template.name specified && params.template.name == one of organization's tempates - elsif !organization.dmptemplates.find_by title: params[:template][:name].nil? + elsif !org.templates.find_by title: params[:template][:name].nil? # set template id - dmptemplate = organization.templates.find_by title: params[:template][:name] + template = org.templates.find_by title: params[:template][:name] # else error: organization has more than one template and template name unspecified else render json: I18n.t("api.org_multiple_templates"), status: 400 and return @@ -73,11 +73,11 @@ end # create new project with specified parameters - @project = Project.new + @project = Plan.new @project.title = params[:project][:title] - @project.dmptemplate = dmptemplate + @project.template = template @project.slug = params[:project][:title] - @project.organisation = @user.organisations.first + #@project.organisation = @user.organisations.first @project.assign_creator(user.id) @project.guidance_groups = all_groups diff --git a/app/controllers/api/v0/statistics_controller.rb b/app/controllers/api/v0/statistics_controller.rb index f893bc5..a09bec3 100644 --- a/app/controllers/api/v0/statistics_controller.rb +++ b/app/controllers/api/v0/statistics_controller.rb @@ -9,7 +9,7 @@ # users are scoped to the organisation of the user initiating the call def users_joined if has_auth(constant("token_permission_types.statistics")) - users = restrict_date_range(@user.organisations.first.users) + users = restrict_date_range(@user.org.users) confirmed_users = [] users.each do |user| unless user.confirmed_at.blank? @@ -31,8 +31,8 @@ def using_template if has_auth(constant("token_permission_types.statistics")) template = Dmptemplate.find(params[:id]) - if template.organisation == @user.organisations.first - @template_count = restrict_date_range(template.projects).count + if template.org == @user.org + @template_count = restrict_date_range(template.plans).count respond_with @template_count else #no auth to view statistics for this template @@ -50,10 +50,10 @@ def plans_by_template if has_auth(constant("token_permission_types.statistics")) @org_projects = [] - @user.organisations.first.users.each do |user| - user.projects.each do |project| - unless @org_projects.include? project - @org_projects += [project] + @user.org.users.each do |user| + user.plans.each do |plan| + unless @org_projects.include? plan + @org_projects += [plan] end end end @@ -72,10 +72,10 @@ def plans if has_auth(constant("token_permission_types.statistics")) @org_projects = [] - @user.organisations.first.users.each do |user| - user.projects.each do |project| - unless @org_projects.include? project - @org_projects += [project] + @user.org.users.each do |user| + user.plans.each do |plan| + unless @org_projects.include? plan + @org_projects += [plan] end end end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 6564cb5..a02811c 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -17,29 +17,21 @@ redirect_to root_url, alert: I18n.t('unauthorized') end - before_filter :set_locale + before_filter :set_gettext_locale after_filter :store_location - def set_locale - # parameter from url takes precedence - # check if locale is defined - if params[:locale] # and I18n.available_locales.include? params[:locale] # throw an error if not available - # if locales data is present in the parameter from url use it - I18n.locale = params[:locale] - + def set_gettext_locale + if params[:locale] and FastGettext.default_available_locales.include?(params[:locale]) + FastGettext.locale = params[:locale] elsif user_signed_in? and !current_user[:language_id].nil? - I18n.locale = Language.find_by_id(current_user[:language_id]).abbreviation - # if user has set preferred language use it - + FastGettext.locale = Language.find_by_id(current_user[:language_id]).abbreviation #Relies on successful db call elsif user_signed_in? and current_user.org.present? and !current_user.org[:language_id].nil? - I18n.locale = Language.find_by_id(current_user.org[:language_id]).abbreviation - # use user's organization language, keep in mine the "OTHER ORG" edge case which should use default language - + FastGettext.locale = Language.find_by_id(current_user.org[:language_id]).abbreviation #Relies on successful db call else - # just use the default language, line can be commented out, included just for clarity - I18n.locale = I18n.default_locale + FastGettext.locale = FastGettext.default_locale end + puts 'FastGettext.locale = '+FastGettext.locale end # Added setting for passing local params across pages diff --git a/app/controllers/guidance_groups_controller.rb b/app/controllers/guidance_groups_controller.rb index da3e685..3729dd7 100644 --- a/app/controllers/guidance_groups_controller.rb +++ b/app/controllers/guidance_groups_controller.rb @@ -59,7 +59,7 @@ def admin_update_publish @guidance_group = GuidanceGroup.find(params[:id]) authorize @guidance_group - @guidance_group.organisation_id = current_user.organisation_id + @guidance_group.org.id = current_user.org.id @guidance_group.published = true if @guidance_group.update_attributes(params[:guidance_group]) diff --git a/app/controllers/plans_controller.rb b/app/controllers/plans_controller.rb index 0ec48ee..edae8f5 100644 --- a/app/controllers/plans_controller.rb +++ b/app/controllers/plans_controller.rb @@ -25,7 +25,7 @@ if user_signed_in? then @plan = Plan.new authorize @plan - @funders = Org.funder.all + @funders = Org.funders.all respond_to do |format| format.html # new.html.erb diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 1cb7c24..5b98dd2 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -236,7 +236,7 @@ else institution = nil end - excluded_orgs = orgs_of_type(constant("organisation_types.funder")) + orgs_of_type(constant("organisation_types.institution")) + Org.orgs_with_parent_of_type(constant("organisation_types.institution")) + excluded_orgs = Org.funders + Org.institutions guidance_groups = {} ggs = GuidanceGroup.guidance_groups_excluding(excluded_orgs) diff --git a/app/controllers/templates_controller.rb b/app/controllers/templates_controller.rb index 7de0789..50f3c60 100644 --- a/app/controllers/templates_controller.rb +++ b/app/controllers/templates_controller.rb @@ -19,18 +19,132 @@ end end @templates_own = current_templates.values - #funders templates - @templates_funders = []#Org.funders.collect{|o| o.templates } #Template.funders_templates + @other_published_version = {} + current_templates.keys.each do |dmptemplate_id| + @other_published_version[dmptemplate_id] = Template.where(org_id: current_user.org_id, dmptemplate_id: dmptemplate_id, published: true).present? + end + + # funders templates + funders_templates = {} + Org.includes(:templates).funder.each do |org| + org.templates.where(customization_of: nil, published: true).order(version: :desc).each do |temp| + if funders_templates[temp.dmptemplate_id].nil? + funders_templates[temp.dmptemplate_id] = temp + end + end + end + + @templates_funders = funders_templates.values + # are any funder templates customized + @templates_customizations = {} + Template.where(org_id: current_user.org_id, customization_of: funders_templates.keys).order(version: :desc).each do |temp| + if @templates_customizations[temp.customization_of].nil? + @templates_customizations[temp.customization_of] = {} + @templates_customizations[temp.customization_of][:temp] = temp + @templates_customizations[temp.customization_of][:published] = temp.published + else + @templates_customizations[temp.customization_of][:published] = @templates_customizations[temp.customization_of][:published] || temp.published + end + end end # GET /dmptemplates/1 def admin_template @template = Template.find(params[:id]) - authorize @template - if @template.published - # create a new template version + # check to see if this is a funder template needing customized + if @template.org_id != current_user.org_id + # definitely need to deep_copy the given template + new_customization = Template.deep_copy(@template) + new_customization.org_id = current_user.org_id + new_customization.published = false + new_customization.customization_of = @template.dmptemplate_id + # need to mark all Phases, questions, sections as not-modifiable + new_customization.phases.includes(sections: :questions).each do |phase| + phase.modifiable = false + phase.save! + phase.sections.each do |section| + section.modifiable = false + section.save! + section.questions.each do |question| + question.modifiable = false + question.save! + end + end + end + customizations = Template.includes(phases: [sections: [questions: :suggested_answers ]]).where(org_id: current_user.org_id, customization_of: @template.dmptemplate_id).order(version: :desc) + if customizations.present? + # existing customization to port over + max_version = customizations.first + new_customization.dmptemplate_id = max_version.dmptemplate_id + new_customization.version = max_version.version + 1 + # here we rip the customizations out of the old template + # First, we find any customized phases or sections + max_version.phases.each do |phase| + # check if the phase was added as a customization + if phase.modifiable + # deep copy the phase and add it to the template + phase_copy = Phase.deep_copy(phase) + phase_copy.number = new_customization.phases.length + 1 + phase_copy.template_id = new_customization.id + phase_copy.save! + else + # iterate over the sections to see if any of them are customizations + phase.sections.each do |section| + if section.modifiable + # this is a custom section + section_copy = Section.deep_copy(section) + customization_phase = new_customization.phases.includes(:sections).where(number: phase.number).first + section_copy.phase_id = customization_phase.id + # custom sections get added to the end + section_copy.number = customization_phase.sections.length + 1 + # section from phase with corresponding number in the main_template + section_copy.save! + else + # not a customized section, iterate over questions + customization_phase = new_customization.phases.includes(sections: [questions: :suggested_answers]).where(number: phase.number).first + customization_section = customization_phase.sections.where(number: section.number).first + section.questions.each do |question| + # find corresponding question in new template + customization_question = customization_section.questions.where(number: question.number).first + # apply suggested_answers + question.suggested_answers.each do |suggested_answer| + suggested_answer_copy = SuggestedAnswer.deep_copy(suggested_answer) + suggested_answer_copy.org_id = current_user.org_id + suggested_answer_copy.question_id = customization_question.id + suggested_answer_copy.save! + end + # guidance attached to a question is also a form of customization + # It will soon become an annotation of the question, and be combined with + # suggested answers + customization_question.guidance = customization_question.guidance + question.guidance + customization_question.save! + end + end + end + end + end + else + # first time customization + new_customization.version = 0 + new_customization.dmptemplate_id = loop do + random = rand 2147483647 # max int field in psql + break random unless Template.exists?(dmptemplate_id: random) + end + end + new_customization.save! + @template = new_customization end + # needed for some post-migration edge cases + # some customized templates which were edited + if @template.published + new_version = Template.deep_copy(@template) + new_version.version = @template.version + 1 + new_version.published = false + new_version.save! + @template = new_version + end + authorize @template end @@ -38,8 +152,19 @@ def admin_update @template = Template.find(params[:id]) authorize @template + if @template.published? + # published templates cannot be edited + redirect_to admin_template_template_path(@template), notice: I18n.t('org_admin.templates.read_only') and return + end @template.description = params["template-desc"] if @template.update_attributes(params[:template]) + if @template.published + # create a new template version if this template became published + new_version = Template.deep_copy(@template) + new_version.version = @template.version + 1 + new_version.published = false + new_version.save! + end redirect_to admin_index_template_path(), notice: I18n.t('org_admin.templates.updated_message') else render action: "edit" @@ -180,6 +305,7 @@ @section = Section.new(params[:section]) authorize @section.phase.template @section.description = params["section-desc"] + @section.modifiable = true if @section.save redirect_to admin_phase_template_path(id: @section.phase_id, :section_id => @section.id, edit: 'true'), notice: I18n.t('org_admin.templates.created_message') @@ -221,7 +347,7 @@ authorize @question.section.phase.template @question.guidance = params["new-question-guidance"] @question.default_value = params["new-question-default-value"] - if @question.save + if @question.save! redirect_to admin_phase_template_path(id: @question.section.phase_id, section_id: @question.section_id, question_id: @question.id, edit: 'true'), notice: I18n.t('org_admin.templates.created_message') else render action: "admin_phase" diff --git a/app/controllers/users/omniauth_callbacks_controller.rb b/app/controllers/users/omniauth_callbacks_controller.rb index 74337c0..593e146 100644 --- a/app/controllers/users/omniauth_callbacks_controller.rb +++ b/app/controllers/users/omniauth_callbacks_controller.rb @@ -19,9 +19,6 @@ # @scheme [IdentifierScheme] The IdentifierScheme for the provider # ------------------------------------------------------------- def handle_omniauth(scheme) - -puts "now weez handlin it #{scheme}" - user = User.from_omniauth(request.env["omniauth.auth"].nil? ? request.env : request.env["omniauth.auth"]) # If the user isn't logged in diff --git a/app/controllers/users/omniauth_shibboleth_request_controller.rb b/app/controllers/users/omniauth_shibboleth_request_controller.rb index 43e363d..3190c2f 100644 --- a/app/controllers/users/omniauth_shibboleth_request_controller.rb +++ b/app/controllers/users/omniauth_shibboleth_request_controller.rb @@ -2,8 +2,8 @@ before_filter :authenticate_user!, only: :associate def redirect - if !current_user.nil? && !current_user.organisation.nil? - idp = params[:idp] || current_user.organisation.wayfless_entity + if !current_user.nil? && !current_user.org.nil? + idp = params[:idp] || current_user.org.wayfless_entity else idp = params[:idp] end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 73851a3..0d8de1a 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -23,4 +23,10 @@ def hash_to_js_json_variable(obj_name, hash) "".html_safe end + + # Determines whether or not the URL path passed matches with the full path (including params) of the last URL requested. + # see http://api.rubyonrails.org/classes/ActionDispatch/Request.html#method-i-fullpath for details + def isActivePage(path) + return request.fullpath() == path + end end diff --git a/app/helpers/phases_helper.rb b/app/helpers/phases_helper.rb deleted file mode 100644 index 610c227..0000000 --- a/app/helpers/phases_helper.rb +++ /dev/null @@ -1,2 +0,0 @@ -module PhasesHelper -end diff --git a/app/helpers/plans_helper.rb b/app/helpers/plans_helper.rb new file mode 100644 index 0000000..8cdd5d9 --- /dev/null +++ b/app/helpers/plans_helper.rb @@ -0,0 +1,84 @@ +module PlansHelper + + # Build variable column headings for the project list + # -------------------------------------------------------- + def plan_list_column_heading(column) + if column.kind_of?(Array) + heading = (column.first.kind_of?(String) ? column.first : t("helpers.project.columns.unknown")) + + elsif column.kind_of?(String) + heading = column + + else + heading = t("helpers.project.columns.unknown") + end + + klass = (['name', 'description'].include?(heading) ? :dmp_th_big : :dmp_th_small) + + content_tag(:th, t("helpers.project.columns.#{heading}"), class: klass) + end + + # Populate a variable column for the project list + # -------------------------------------------------------- + def plan_list_column_body(column, plan) + + col = (column.kind_of?(Array) ? column[0] : column) + + klass, content = case col + when 'name' + [ "dmp_td_big", link_to(plan.title, plan_path(I18n.locale, plan), class: "dmp_table_link") ] + + when 'owner' + user = plan.owner + + text = if user.nil? + t("helpers.project.columns.unknown") + elsif user == current_user + t("helpers.me") + else + user.name + end + + [ "tmp_td_small", text ] + when 'shared' + shared_num = plan.users.count - 1 + text = shared_num > 0 ? (t("helpers.yes_label") + " (with #{shared_num} people) ") : t("helpers.no_label") + [ "dmp_td_small", text ] + when 'visibility' + ["dmp_td_small", (plan.visibility.nil? ? I18n.t("helpers.project.visibilities.labels.organisationally_visible") : I18n.t("helpers.project.visibilities.labels.#{plan.visibility}"))] + when 'last_edited' + [ "dmp_td_small", l(plan.latest_update.to_date, formats: :short) ] + when 'description' + [ "dmp_td_medium", (plan.try(col) || t("helpers.settings.unknown")) ] + when 'non_link_name' + [ "dmp_td_big", plan.title ] + when 'template' + ["dmp_td_big", plan.template.title] + when 'organisation' + ["dmp_td_medium", (plan.owner.org.nil? ? t("helpers.settings.unknown") : plan.owner.org.name) ] + else + [ "dmp_td_small", (plan.try(col) || t("helpers.settings.unknown")) ] + end + + content_tag(:td, content, class: klass) + end + + # Shows whether the user has default, template-default or custom settings + # for the given plan. + # -------------------------------------------------------- + def plan_settings_indicator(plan) + plan_settings = plan.super_settings(:export) + template_settings = plan.template.try(:settings, :export) + + key = if plan_settings.try(:value?) + plan_settings.formatting == template_settings.formatting ? "template_formatting" : "custom_formatting" + elsif template_settings.try(:value?) + "template_formatting" + else + "default_formatting" + end + + content_tag(:small, t("helpers.settings.plans.#{key}")) + end + +end diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb deleted file mode 100644 index 36e1c65..0000000 --- a/app/helpers/projects_helper.rb +++ /dev/null @@ -1,84 +0,0 @@ -module ProjectsHelper - - # Build variable column headings for the project list - # -------------------------------------------------------- - def project_list_column_heading(column) - if column.kind_of?(Array) - heading = (column.first.kind_of?(String) ? column.first : t("helpers.project.columns.unknown")) - - elsif column.kind_of?(String) - heading = column - - else - heading = t("helpers.project.columns.unknown") - end - - klass = (['name', 'description'].include?(heading) ? :dmp_th_big : :dmp_th_small) - - content_tag(:th, t("helpers.project.columns.#{heading}"), class: klass) - end - - # Populate a variable column for the project list - # -------------------------------------------------------- - def plan_list_column_body(column, plan) - - col = (column.kind_of?(Array) ? column[0] : column) - - klass, content = case col - when 'name' - [ "dmp_td_big", link_to(plan.title, plan_path(plan), class: "dmp_table_link") ] - - when 'owner' - user = plan.owner - - text = if user.nil? - "Unknown" - elsif user == current_user - t("helpers.me") - else - user.name - end - - [ "tmp_td_small", text ] - when 'shared' - shared_num = plan.users.count - 1 - text = shared_num > 0 ? (t("helpers.yes_label") + " (with #{shared_num} people) ") : t("helpers.no_label") - [ "dmp_td_small", text ] - when 'visibility' - ["dmp_td_small", (plan.visibility.nil? ? I18n.t("helpers.project.visibilities.labels.organisationally_visible") : I18n.t("helpers.project.visibilities.labels.#{project.visibility}"))] - when 'last_edited' - [ "dmp_td_small", l(plan.latest_update.to_date, formats: :short) ] - when 'description' - [ "dmp_td_medium", (plan.try(col) || "Unknown") ] - when 'non_link_name' - [ "dmp_td_big", plan.title ] - when 'template' - ["dmp_td_big", plan.template.title] - when 'organisation' - ["dmp_td_medium", (plan.org.nil? ? plan.owner.org.name : plan.org.name)] - else - [ "dmp_td_small", (plan.try(col) || "Unknown") ] - end - - content_tag(:td, content, class: klass) - end - - # Shows whether the user has default, template-default or custom settings - # for the given plan. - # -------------------------------------------------------- - def plan_settings_indicator(plan) - plan_settings = plan.super_settings(:export) - template_settings = plan.template.try(:settings, :export) - - key = if plan_settings.try(:value?) - plan_settings.formatting == template_settings.formatting ? "template_formatting" : "custom_formatting" - elsif template_settings.try(:value?) - "template_formatting" - else - "default_formatting" - end - - content_tag(:small, t("helpers.settings.plans.#{key}")) - end - -end diff --git a/app/models/ability.rb b/app/models/ability.rb deleted file mode 100644 index ba5e6fa..0000000 --- a/app/models/ability.rb +++ /dev/null @@ -1,38 +0,0 @@ -class Ability - include GlobalHelpers - include CanCan::Ability - - def initialize(user) - # Define abilities for the passed in user here. For example: - # - user ||= User.new # guest user (not logged in) - if user.has_role? constant("roles.super_admin") - can :manage, :all - else - can :read, :all - end - - can :manage_settings, User do |viewed_user| - viewed_user.present? && user.id == viewed_user.id - end - # - # The first argument to `can` is the action you are giving the user - # permission to do. - # If you pass :manage it will apply to every action. Other common actions - # here are :read, :create, :update and :destroy. - # - # The second argument is the resource the user can perform the action on. - # If you pass :all it will apply to every resource. Otherwise pass a Ruby - # class of the resource. - # - # The third argument is an optional hash of conditions to further filter the - # objects. - # For example, here the user can only update published articles. - # - # can :update, Article, :published => true - # - # See the wiki for details: - # https://github.com/ryanb/cancan/wiki/Defining-Abilities - - end -end diff --git a/app/models/admin_user.rb b/app/models/admin_user.rb deleted file mode 100644 index 511e649..0000000 --- a/app/models/admin_user.rb +++ /dev/null @@ -1,4 +0,0 @@ -class AdminUser < ActiveRecord::Base - devise :database_authenticatable, :recoverable, :rememberable, :trackable, :validatable - attr_accessible :email, :password, :password_confirmation, :remember_me -end diff --git a/app/models/exported_plan.rb b/app/models/exported_plan.rb index d99817f..4045298 100644 --- a/app/models/exported_plan.rb +++ b/app/models/exported_plan.rb @@ -51,27 +51,29 @@ end def funder - org = self.plan.template.try(:organisation) - org.name if org.present? && org.org.try(:name) == constant("organisation_types.funder") + org = self.plan.template.try(:org) + org.name if org.present? && org.funder? end def institution - plan.template.org.try(:name) + plan.owner.org.try(:name) end def orcid scheme = IdentifierScheme.find_by(name: 'orcid') - if self.user.nil? + if self.owner.nil? '' else - orcid = self.user.user_identifiers.where(identifier_scheme: scheme).first + orcid = self.owner.user_identifiers.where(identifier_scheme: scheme).first (orcid.nil? ? '' : orcid.identifier) end end +# TODO: This looks like it will always return an empty array as questions is undefined # sections taken from fields settings def sections - sections = self.plan.sections + # TODO: How do we know which phase to use here!? + sections = self.template.phases.first.sections return [] if questions.empty? diff --git a/app/models/guidance.rb b/app/models/guidance.rb index 31f9012..3b15e2a 100644 --- a/app/models/guidance.rb +++ b/app/models/guidance.rb @@ -15,6 +15,9 @@ belongs_to :guidance_group # belongs_to :question has_and_belongs_to_many :themes, join_table: "themes_in_guidance" +# depricated, but required for migration "single_group_for_guidance" + has_and_belongs_to_many :guidance_groups, join_table: "guidance_in_group" + diff --git a/app/models/new_plan.rb b/app/models/new_plan.rb deleted file mode 100644 index 1dac7cd..0000000 --- a/app/models/new_plan.rb +++ /dev/null @@ -1,5 +0,0 @@ -class NewPlan < ActiveRecord::Base - belongs_to :template - has_many :roles - has_many :users, through: :roles -end diff --git a/app/models/org.rb b/app/models/org.rb index 1e6764d..15dcd92 100644 --- a/app/models/org.rb +++ b/app/models/org.rb @@ -49,6 +49,7 @@ # Predefined queries for retrieving the managain organisation and funders scope :managing_orgs, -> { where(name: GlobalHelpers.constant("organisation_types.managing_organisation")) } scope :funders, -> { where(org_type: 2) } + scope :institutions, -> { where(org_type: 3) } # EVALUATE CLASS AND INSTANCE METHODS BELOW @@ -56,7 +57,11 @@ # What do they do? do they do it efficiently, and do we need them? - +# TODO: Should these be hardcoded? Also, an Org can currently be multiple org_types at one time. +# For example you can do: funder = true; project = true; school = true +# Calling type in the above scenario returns "Funder" which is a bit misleading +# Is FlagShihTzu's Bit flag the appropriate structure here or should we use an enum? +# Tests are setup currently to work with this issue. ## # returns the name of the type of the organisation as a string # defaults to none if no org type present @@ -69,7 +74,7 @@ return "Funder" elsif self.organisation? return "Organisation" - elsif @org.research_institute? + elsif self.research_institute? return "Research Institute" elsif self.project? return "Project" @@ -105,6 +110,7 @@ # # @param [String] the name of an organisation type # @return [Array] +=begin def self.orgs_with_parent_of_type(org_type) parents = OrganisationType.find_by_name(org_type).organisations children = Array.new @@ -113,7 +119,7 @@ end return children end - + ## # returns a list of all guidance groups belonging to other organisations # @@ -148,7 +154,7 @@ end return organisations_list end - + ## # returns a list of all sections of a given version from this organisation and it's parents # @@ -165,7 +171,7 @@ return sections.where("version_id = ? ", version_id).all + parent.all_sections(version_id) end end - + ## # returns the guidance groups of this organisation and all of it's children # @@ -177,7 +183,7 @@ end return ggs end - + ## # returns the highest parent organisation in the tree # @@ -189,7 +195,8 @@ return parent.root end end - +=end + ## # returns all published templates belonging to the organisation # diff --git a/app/models/org_token_permission.rb b/app/models/org_token_permission.rb deleted file mode 100644 index 894f84f..0000000 --- a/app/models/org_token_permission.rb +++ /dev/null @@ -1,11 +0,0 @@ -class OrgTokenPermission < ActiveRecord::Base - ## - # Associations - belongs_to :organisation - belongs_to :token_permission_type - - ## - # Possibly needed for active_admin - # -relies on protected_attributes gem as syntax depricated in rails 4.2 - attr_accessible :organisation_id, :token_permission_type_id, :organisation, :token_permission_type, :as => [:default, :admin] -end diff --git a/app/models/organisation_type.rb b/app/models/organisation_type.rb deleted file mode 100644 index d69aa48..0000000 --- a/app/models/organisation_type.rb +++ /dev/null @@ -1,14 +0,0 @@ -class OrganisationType < ActiveRecord::Base - ## - # Attributes - has_many :orgs - - ## - # Possibly needed for active_admin - # -relies on protected_attributes gem as syntax depricated in rails 4.2 - attr_accessible :description, :organisations, :name, :as => [:default, :admin] - - ## - # Validators - validates :name, presence: true, uniqueness: true -end diff --git a/app/models/phase.rb b/app/models/phase.rb index 15e79a1..88429fd 100644 --- a/app/models/phase.rb +++ b/app/models/phase.rb @@ -67,6 +67,7 @@ # verify if a phase has a published version or a version with one or more sections # # @return [Boolean] +=begin def has_sections versions = self.versions.where('published = ?', true).order('updated_at DESC') if versions.any? then @@ -86,7 +87,8 @@ end return has_section end - +=end + ## # deep copy the given phase and all it's associations # diff --git a/app/models/plan.rb b/app/models/plan.rb index a133d66..7f5b557 100644 --- a/app/models/plan.rb +++ b/app/models/plan.rb @@ -105,11 +105,12 @@ return answer end +# TODO: This just retrieves all of the guidance associated with the themes within the template +# so why are we transferring it here to the plan? ## # returns all of the sections for this version of the plan, and for the project's organisation # # @return [Array
,nil] either a list of sections, or nil if none were found - def set_possible_guidance_groups # find all the themes in this plan # and get the guidance groups they belong to @@ -153,17 +154,19 @@ end # add in the guidance for the user's org - unless self.owner.org.nil? then - self.owner.org.guidance_groups.each do |group| - group.guidances.each do |guidance| - common_themes = guidance.themes.all & question.themes.all - if common_themes.length > 0 - guidances << { orgname: self.template.org.name, theme: common_themes.join(','), guidance: guidance } + unless self.owner.nil? + unless self.owner.org.nil? then + self.owner.org.guidance_groups.each do |group| + group.guidances.each do |guidance| + common_themes = guidance.themes.all & question.themes.all + if common_themes.length > 0 + guidances << { orgname: self.template.org.name, theme: common_themes.join(','), guidance: guidance } + end end end end end - + # Get guidance by theme from any guidance groups currently selected self.plan_guidance_groups.where(selected: true).each do |pgg| group = pgg.guidance_group @@ -306,8 +309,8 @@ return status end - - +# TODO: Guessing this isn't in use since it still refers to Project and Version +=begin ## # defines and returns the details for the plan # details consists of a hash of: project_title, phase_title, and for each section, @@ -343,7 +346,10 @@ end return details end +=end +# TODO: commenting this old lock stuff out since PlanSection is gone and we wanted to get rid of it +=begin ## # determines wether or not a specified section of a plan is locked to a specified user and returns a status hash # @@ -436,7 +442,10 @@ lock.delete end end +=end +# TODO: Commenting out because this method appears below as well so this one is overwritten +=begin ## # returns the time of either the latest answer to any question, or the latest update to the model # @@ -453,7 +462,10 @@ return updated_at end end +=end +# TODO: Guessing this isn't in use since it still refers to Project and Version +=begin ## # returns an array of hashes. Each hash contains the question's id, the answer_id, # the answer_text, the answer_timestamp, and the answer_options @@ -488,7 +500,7 @@ end return section_questions end - +=end ## @@ -502,7 +514,9 @@ - +# TODO: commenting these out because they are overriden by private methods below, so this +# is unreachable +=begin ## # Based on the height of the text gathered so far and the available vertical # space of the pdf, estimate a percentage of how much space has been used. @@ -555,9 +569,10 @@ (num_lines * font_height) + vertical_margin + leading end +=end - - +# TODO: What are these used for? Should just be using self.org and self.org.funder? +=begin ## # sets a new funder for the project # defaults to the first dmptemplate if the current template is nill and the funder has more than one dmptemplate @@ -567,8 +582,8 @@ def funder_id=(new_funder_id) if new_funder_id != "" then new_funder = Org.find(new_funder_id); - if new_funder.dmptemplates.count >= 1 && self.dmptemplate.nil? then - self.dmptemplate = new_funder.dmptemplates.first + if new_funder.templates.count >= 1 && self.template.nil? then + self.template = new_funder.templates.first end end end @@ -583,6 +598,7 @@ end return self.template.org end +=end ## # returns the funder organisation for the project or nil if none is specified @@ -590,6 +606,10 @@ # @return [Organisation, nil] the funder for project, or nil if none exists def funder template = self.template + if template.nil? then + return nil + end + if template.customization_of return template.customization_of.org else @@ -597,6 +617,7 @@ end end +=begin ## # returns the name of the funder for the project # @@ -674,7 +695,7 @@ return organisation_id end end - +=end ## # assigns the passed user_id as an editor for the project @@ -703,6 +724,8 @@ add_user(user_id, true, true) end +# TODO: ProjectGroup doesn't exist anymore so commenting these out +=begin ## # returns the projects which the user can atleast read # @@ -735,6 +758,7 @@ return false end end +=end ## # the datetime for the latest update of this plan @@ -781,6 +805,8 @@ self.latest_update.to_date end +# TODO: These next 2 reference defunct models so commenting out +=begin ## # whether or not the plan is shared with anybody # @@ -881,6 +907,10 @@ +======= +=end + + private # reconnect the various parts of the hash so that: @@ -991,6 +1021,14 @@ role.editor= is_editor role.administrator= is_administrator role.save + + # This is necessary because we're creating the associated record but not assigning it + # to roles. Auto-saving like this may be confusing when coding upstream in a controller, + # view or api. Should probably change this to: + # self.roles << role + # and then let the save be called manually via: + # plan.save! + #self.reload end ## diff --git a/app/models/question.rb b/app/models/question.rb index c2631a5..61eddd1 100644 --- a/app/models/question.rb +++ b/app/models/question.rb @@ -59,7 +59,7 @@ end question.suggested_answers.each do |suggested_answer| suggested_answer_copy = SuggestedAnswer.deep_copy(suggested_answer) - suggested_answer_copy.quesion_id = question_copy.id + suggested_answer_copy.question_id = question_copy.id suggested_answer_copy.save! end question.themes.each do |theme| @@ -78,10 +78,12 @@ guidances = {} theme_ids = themes.collect{|t| t.id} if theme_ids.present? - GuidanceGroup.where(org_id: org.id).each do |group| + GuidanceGroup.includes(guidances: :themes).where(org_id: org.id).each do |group| group.guidances.each do |g| - g.themes.where("id IN (?)", theme_ids).each do |gg| - guidances["#{group.name} " + I18n.t('admin.guidance_lowercase_on') + " #{gg.title}"] = g + g.themes.each do |theme| + if theme_ids.include? theme.id + guidances["#{group.name} " + I18n.t('admin.guidance_lowercase_on') + " #{theme.title}"] = g + end end end end diff --git a/app/models/role.rb b/app/models/role.rb index 7bbe072..cf49c87 100644 --- a/app/models/role.rb +++ b/app/models/role.rb @@ -57,7 +57,7 @@ self.creator = true unless self.administrator? || self.editor? end - # Ensures that the access attribute is set + # Ensures that the access attribute is set (will default to creator - see logic in access_level=) def check_access_level self.access_level = self.access_level end diff --git a/app/models/section.rb b/app/models/section.rb index 710e8c7..87e98b6 100644 --- a/app/models/section.rb +++ b/app/models/section.rb @@ -10,12 +10,12 @@ accepts_nested_attributes_for :questions, :reject_if => lambda {|a| a[:text].blank? }, :allow_destroy => true # accepts_nested_attributes_for :version - attr_accessible :organisation_id, :description, :number, :title, :published, + attr_accessible :phase_id, :description, :number, :title, :published, :questions_attributes, :organisation, :phase, :modifiable, :as => [:default, :admin] - + validates :phase, :title, :number, presence: true - + ## # return the title of the section # diff --git a/app/models/settings/plan_list.rb b/app/models/settings/plan_list.rb index 812e2c8..26f6ed5 100644 --- a/app/models/settings/plan_list.rb +++ b/app/models/settings/plan_list.rb @@ -10,7 +10,7 @@ validate do cols = value["columns"] - + if cols.present? # columns can be empty, in which case they revert to defaults errors.add(:columns, I18n.t("helpers.settings.projects.errors.no_name")) unless cols.member?("name") errors.add(:columns, I18n.t("helpers.settings.projects.errors.duplicate")) unless cols.keys.uniq == cols.keys diff --git a/app/models/suggested_answer.rb b/app/models/suggested_answer.rb index 8f427c6..91ce3aa 100644 --- a/app/models/suggested_answer.rb +++ b/app/models/suggested_answer.rb @@ -12,7 +12,7 @@ :org, :question, :as => [:default, :admin] - validates :question, :org, :text, presence: true + validates :question, :org, presence: true # EVALUATE CLASS AND INSTANCE METHODS BELOW # diff --git a/app/models/template.rb b/app/models/template.rb index 87d79df..9c59637 100644 --- a/app/models/template.rb +++ b/app/models/template.rb @@ -5,7 +5,7 @@ # Associations belongs_to :org has_many :plans - has_many :phases + has_many :phases, dependent: :destroy has_many :sections, through: :phases has_many :questions, through: :sections @@ -136,6 +136,7 @@ end =end +# TODO: Why are we passing in an org and template here? ## # Verify if a template has customisation by given organisation # @@ -145,7 +146,7 @@ def has_customisations?(org_id, temp) modifiable = true phases.each do |phase| - modifiable = modifable && phase.modifiable + modifiable = modifiable && phase.modifiable end return !modifiable # if temp.org_id != org_id then diff --git a/app/models/user.rb b/app/models/user.rb index 91355df..4cf42a2 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -93,6 +93,9 @@ user_identifiers.where(identifier_scheme: scheme).first end +# TODO: Check the logic here. Its deleting the permissions if the user does not have permission +# to change orgs and either the incoming or existing org is nil. +# We should also NOT be auto-saving here!!! ## # sets a new organisation id for the user # if the user has any perms such as org_admin or admin, those are removed @@ -100,6 +103,7 @@ # # @param new_organisation_id [Integer] the id for an organisation # @return [String] the empty string as a causality of setting api_token +=begin def organisation_id=(new_organisation_id) unless self.can_change_org? || new_organisation_id.nil? || self.organisation.nil? # rip all permissions from the user @@ -119,7 +123,8 @@ def organisation=(new_organisation) organisation_id = new_organisation.id unless new_organisation.nil? end - +=end + ## # checks if the user is a super admin # if the user has any privelege which requires them to see the super admin page @@ -127,7 +132,7 @@ # # @return [Boolean] true if the user is an admin def can_super_admin? - return self.can_add_orgs? || self.can_grant_api_to_orgs? || can_change_org? + return self.can_add_orgs? || self.can_grant_api_to_orgs? || self.can_change_org? end ## @@ -137,7 +142,8 @@ # # @return [Boolean] true if the user is an organisation admin def can_org_admin? - return self.can_grant_permissions? || self.can_modify_guidance? || self.can_modify_templates? || self.can_modify_org_details? + return self.can_grant_permissions? || self.can_modify_guidance? || + self.can_modify_templates? || self.can_modify_org_details? end ## @@ -196,14 +202,6 @@ perms.include? Perm.find_by(name: constant("roles.change_org_details")) end - ## - # checks if the user can grant the api to organisations - # - # @return [Boolean] true if the user can grant api permissions to organisations - def can_grant_api_to_orgs? - perms.include? Perm.find_by(name: constant('roles.grant_api_to_orgs')) - end - ## # checks if the user can grant the api to organisations @@ -217,11 +215,13 @@ # checks what type the user's organisation is # # @return [String] the organisation type +=begin def org_type org_type = org.organisation_type return org_type end - +=end + ## # removes the api_token from the user # modifies the user model @@ -261,9 +261,11 @@ end end +# TODO: Remove this, its never called. # this generates a reset password link for a given user # which can then be sent to them with the appropriate host # prepended. +=begin def reset_password_link raw, enc = Devise.token_generator.generate(self.class, :reset_password_token) self.reset_password_token = enc @@ -272,5 +274,6 @@ edit_user_password_path + '?reset_password_token=' + raw end - +=end + end diff --git a/app/models/users_perm.rb b/app/models/users_perm.rb deleted file mode 100644 index 38a6cd3..0000000 --- a/app/models/users_perm.rb +++ /dev/null @@ -1,4 +0,0 @@ -class UsersPerm < ActiveRecord::Base - belongs_to :user - belongs_to :perm -end \ No newline at end of file diff --git a/app/policies/guidance_policy.rb b/app/policies/guidance_policy.rb index ee7be10..725326c 100644 --- a/app/policies/guidance_policy.rb +++ b/app/policies/guidance_policy.rb @@ -53,7 +53,7 @@ class Scope < Scope def resolve - scope = Guidance.includes(:guidance_group, :question, :themes).by_org(user.org_id) + scope = Guidance.includes(:guidance_group, :themes).by_org(user.org_id) end end end \ No newline at end of file diff --git a/app/views/admin/dmptemplates/settings.html.erb b/app/views/admin/dmptemplates/settings.html.erb index 171d5bc..c955083 100644 --- a/app/views/admin/dmptemplates/settings.html.erb +++ b/app/views/admin/dmptemplates/settings.html.erb @@ -4,15 +4,15 @@ <%= form_for(@settings, url: update_settings_admin_dmptemplate_path(@template), method: :put, as: 'settings[export][formatting]', html: { class: 'formtastic' }) do |f| %>
- <%= t("admin.formatting")%> + <%= _('Formatting') %>
  1. - <%= f.label(:font_face, t('helpers.settings.plans.font_face')) %> + <%= f.label(:font_face, _('Face')) %> <%= f.select(:font_face, options_for_select(Settings::Dmptemplate::VALID_FONT_FACES, @settings.formatting[:font_face]), as: 'formatting[font_face]') %> <%= f.select(:font_size, options_for_select((1..36).to_a, @settings.formatting[:font_size])) %>pt
  2. - <%= f.label(t('helpers.settings.plans.margin')) %> + <%= f.label(_('Margin')) %> <% ["top", "bottom", "left", "right"].each do |pos| %> <%= t("helpers.settings.plans.margins.#{pos}") -%> <%= select_tag("settings[export][formatting][margin][#{pos}]", options_for_select((0..100).to_a, @settings.formatting[:margin][pos])) %> @@ -22,17 +22,17 @@
- <%= t("admin.max_pages")%> + <%= _('Max Pages')%>
  1. - <%= label_tag('settings_export_max_pages', t('helpers.settings.plans.max_pages')) %> + <%= label_tag('settings_export_max_pages', _('Maximum number of pages')) %> <%= select_tag('settings[export][max_pages]', options_for_select((1..10).to_a, @settings.max_pages)) %>
- <%= submit_tag(t('helpers.save'), class: 'btn btn-primary') %> - <%= submit_tag(t('helpers.settings.plans.reset'), class: 'btn btn-primary') %> + <%= submit_tag(_('Save'), class: 'btn btn-primary') %> + <%= submit_tag(_('Reset'), class: 'btn btn-primary') %>
<% end %> diff --git a/app/views/api/v0/statistics/plans.json.jbuilder b/app/views/api/v0/statistics/plans.json.jbuilder index 1a05c9b..fe85ca8 100644 --- a/app/views/api/v0/statistics/plans.json.jbuilder +++ b/app/views/api/v0/statistics/plans.json.jbuilder @@ -1,25 +1,25 @@ json.prettify! -json.plans @org_projects.each do |project| - json.id project.id - json.grant_number project.grant_number - json.org_id project.organisation_id +json.plans @org_projects.each do |plan| + json.id plan.id + json.grant_number plan.grant_number + json.org_id plan.creator.org.id json.template do - json.title project.dmptemplate.title - json.id project.dmptemplate.id + json.title plan.template.title + json.id plan.template.id end json.project do - json.title project.title + json.title plan.title end json.funder do - json.name project.funder_name + json.name (plan.template.org.funder? ? plan.org.name : '') end json.principal_investigator do - json.name project.principal_investigator + json.name plan.principal_investigator end json.data_contact do - json.info project.data_contact + json.info plan.data_contact end - json.description project.description + json.description plan.description end \ No newline at end of file diff --git a/app/views/api/v0/statistics/plans_by_template.json.jbuilder b/app/views/api/v0/statistics/plans_by_template.json.jbuilder index 155bbba..d8d5485 100644 --- a/app/views/api/v0/statistics/plans_by_template.json.jbuilder +++ b/app/views/api/v0/statistics/plans_by_template.json.jbuilder @@ -1,14 +1,14 @@ json.prettify! templates = {} -@org_projects.each do |project| +@org_projects.each do |plan| # if hash exists - if templates[project.dmptemplate.title].blank? - templates[project.dmptemplate.title] = {} - templates[project.dmptemplate.title][:title] = project.dmptemplate.title - templates[project.dmptemplate.title][:id] = project.dmptemplate.id - templates[project.dmptemplate.title][:uses] = 1 + if templates[plan.template.title].blank? + templates[plan.template.title] = {} + templates[plan.template.title][:title] = plan.template.title + templates[plan.template.title][:id] = plan.template.id + templates[plan.template.title][:uses] = 1 else - templates[project.dmptemplate.title][:uses] += 1 + templates[plan.template.title][:uses] += 1 end end diff --git a/app/views/home/index.html.erb b/app/views/home/index.html.erb index 4c03d50..40441b0 100644 --- a/app/views/home/index.html.erb +++ b/app/views/home/index.html.erb @@ -2,13 +2,10 @@
-

<%= raw t('welcome_title')%>

- <%= raw t('welcome_text', - application_name: Rails.configuration.branding[:application][:name], - organisation_name: Rails.configuration.branding[:organisation][:name])%> - +

<%= _('Welcome.')%>

+ <%= raw _('

%{application_name} has been jointly developed by the %{organisation_name} to help you write data management plans.

') % {:application_name => Rails.configuration.branding[:application][:name], :organisation_name => Rails.configuration.branding[:organisation][:name]} %>
-

<%= t('screencast_text', application_name: Rails.configuration.branding[:application][:name]) %>

+

<%= _('Screencast on how to use %{application_name}') % {:application_name => Rails.configuration.branding[:application][:name]} %>

@@ -30,7 +27,7 @@
- <%= t('helpers.sign_in')%> + <%= _('Sign in')%>
@@ -41,9 +38,9 @@
- <%= t('helpers.sign_up') %> + <%= _('Sign up') %>

- <%= t('helpers.sign_up_text', application_name: Rails.configuration.branding[:application][:name])%> + <%= _('New to %{application_name}? Sign up today.') % {:application_name => Rails.configuration.branding[:application][:name]} %>

diff --git a/app/views/layouts/_footer.html.erb b/app/views/layouts/_footer.html.erb index f8728e7..897d824 100644 --- a/app/views/layouts/_footer.html.erb +++ b/app/views/layouts/_footer.html.erb @@ -3,9 +3,9 @@