diff --git a/CHANGELOG.md b/CHANGELOG.md index b5637083df..aea55c771e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ # Changelog +## Unreleased +- Add complete plan flag to V2 API [#3595](https://github.com/DMPRoadmap/roadmap/pull/3595) + ## v5.0.2 - Bump Ruby to v3.1.4 and use `.ruby-version` in CI - [#3566](https://github.com/DMPRoadmap/roadmap/pull/3566) diff --git a/app/controllers/api/v2/plans_controller.rb b/app/controllers/api/v2/plans_controller.rb index 7714e9c892..a12635c585 100644 --- a/app/controllers/api/v2/plans_controller.rb +++ b/app/controllers/api/v2/plans_controller.rb @@ -4,12 +4,13 @@ module Api module V2 class PlansController < BaseApiController # rubocop:todo Style/Documentation respond_to :json + before_action :set_complete_param, only: %i[show index] # GET /api/v2/plans/:id def show raise Pundit::NotAuthorizedError unless @scopes.include?('read') - @plan = Plan.find_by(id: params[:id]) + @plan = Plan.includes(roles: :user).find_by(id: params[:id]) raise Pundit::NotAuthorizedError unless @plan.present? @@ -25,9 +26,17 @@ def index raise Pundit::NotAuthorizedError unless @scopes.include?('read') @plans = PlansPolicy::Scope.new(@resource_owner).resolve + @plans = @plans.includes(answers: { question: :section }) if @complete @items = paginate_response(results: @plans) render '/api/v2/plans/index', status: :ok end + + private + + # GET /api/v2/plans?complete=true and /api/v2/plans/:id?complete=true + def set_complete_param + @complete = params[:complete].to_s.downcase == 'true' + end end end end diff --git a/app/presenters/api/v2/plan_presenter.rb b/app/presenters/api/v2/plan_presenter.rb index c841844c6c..4e37a45111 100644 --- a/app/presenters/api/v2/plan_presenter.rb +++ b/app/presenters/api/v2/plan_presenter.rb @@ -4,9 +4,9 @@ module Api module V2 # Helper class for the API V2 project / DMP class PlanPresenter - attr_reader :data_contact, :contributors, :costs + attr_reader :data_contact, :contributors, :costs, :complete_plan_data - def initialize(plan:) + def initialize(plan:, complete: false) @contributors = [] return unless plan.present? @@ -22,6 +22,8 @@ def initialize(plan:) end @costs = plan_costs(plan: @plan) + + @complete_plan_data = fetch_all_q_and_a if complete end # Extract the ARK or DOI for the DMP OR use its URL if none exists @@ -55,6 +57,25 @@ def plan_costs(plan:) currency_code: 'usd', value: answer.text } end end + + # Fetch all questions and answers from a plan, regardless of theme + def fetch_all_q_and_a + answers = @plan.answers + return [] unless answers.present? + + answers.filter_map do |answer| + q = answer.question + next unless q.present? + + { + id: q.id, + title: "Question #{q.number || q.id}", + section: q.section&.title, + question: q.text.to_s, + answer: answer.text.to_s + } + end + end end end end diff --git a/app/views/api/v2/plans/_show.json.jbuilder b/app/views/api/v2/plans/_show.json.jbuilder index 0de52775a3..4b752b15e1 100644 --- a/app/views/api/v2/plans/_show.json.jbuilder +++ b/app/views/api/v2/plans/_show.json.jbuilder @@ -4,7 +4,7 @@ json.schema 'https://github.com/RDA-DMP-Common/RDA-DMP-Common-Standard/tree/master/examples/JSON/JSON-schema/1.0' -presenter = Api::V2::PlanPresenter.new(plan: plan) +presenter = Api::V2::PlanPresenter.new(plan: plan, complete: @complete) # Note the symbol of the dmproadmap json object # nested in extensions which is the container for the json template object, etc. @@ -68,5 +68,20 @@ unless @minimal json.title template.title end end + + if @complete + json.complete_plan do + q_and_a = presenter.complete_plan_data + next if q_and_a.blank? + + json.array! q_and_a do |item| + json.question_id item[:id] + json.title item[:title] + json.section item[:section] + json.question item[:question] + json.answer item[:answer] + end + end + end end end