sul-dlss/argo

View on GitHub
app/controllers/apo_controller.rb

Summary

Maintainability
A
0 mins
Test Coverage
A
94%
# frozen_string_literal: true

class ApoController < ApplicationController
  include Blacklight::FacetsHelperBehavior # for facet_configuration_for_field

  load_and_authorize_resource :cocina, parent: false, class: 'Repository', only: %i[edit update]
  load_resource :cocina, parent: false, class: 'Repository', only: :delete_collection

  def new
    authorize! :create, Cocina::Models::AdminPolicy
    @form = ApoForm.new(nil, search_service:)

    render layout: 'one_column'
  end

  def edit
    @form = ApoForm.new(@cocina, search_service:)

    render layout: 'one_column'
  end

  # Draw the form controls for collection, rights and initial workflow
  def registration_options
    administrative = Repository.find(params[:id]).administrative

    # workflow_list
    @workflows = ([params[:workflow_id]] + [Settings.apo.default_workflow_option] + Array(administrative.registrationWorkflow)).compact.uniq

    access_template = administrative.accessTemplate.new({
      view: params[:view_access],
      download: params[:download_access],
      location: params[:access_location],
      controlledDigitalLending: params[:controlled_digital_lending] == 'true'
    }.compact)
    @access_template = AccessTemplate.new(access_template:, apo_defaults_template: administrative.accessTemplate)

    @collections = Array(administrative.collectionsForRegistration).filter_map do |coll_id|
      coll_title = CollectionTitleService.find(coll_id)
      unless coll_title
        Honeybadger.notify("The APO #{params[:id]} asserts that #{coll_id} is a collection for registration, but we don't find that collection in Solr")
        next
      end

      ["#{coll_title.truncate(60, separator: /\s/)} (#{coll_id.delete_prefix('druid:')})", coll_id]
    end

    # before returning the list, sort by collection title (case insensitive, dropping brackets)
    @collections.sort_by! { |collection_title| collection_title.first.downcase.delete('[]') }
  end

  def create
    authorize! :create, Cocina::Models::AdminPolicy
    @form = ApoForm.new(nil, search_service:)
    unless @form.validate(params.require(:apo).to_unsafe_h.merge(registered_by: current_user.login))
      respond_to do |format|
        format.json { render status: :bad_request, json: { errors: @form.errors } }
        format.html { render 'new', status: :unprocessable_entity }
      end
      return
    end

    @form.save

    # Index immediately, so that we have a page to send the user to. DSA indexes asynchronously.
    Dor::Services::Client.object(@form.model.externalIdentifier).reindex

    notice = "APO #{@form.model.externalIdentifier} created."

    # register a collection and make it the default if requested
    if @form.model.administrative.collectionsForRegistration.present?
      notice += " Collection #{@form.model.administrative.collectionsForRegistration.first} created."
      # Index immediately, so that we see the collection name on the page. DSA indexes asynchronously.
      Dor::Services::Client.object(@form.model.administrative.collectionsForRegistration.first).reindex
    end

    redirect_to solr_document_path(@form.model.externalIdentifier), notice:
  end

  def update
    @form = ApoForm.new(@cocina, search_service:)
    unless @form.validate(params.require(:apo).to_unsafe_h)
      respond_to do |format|
        format.json { render status: :unprocessable_entity, json: { errors: @form.errors } }
        format.html { render 'edit', status: :unprocessable_entity }
      end
      return
    end

    @form.save
    redirect_to solr_document_path(@form.model.externalIdentifier)
  end

  def delete_collection
    authorize! :update, @cocina
    collection_ids = @cocina.administrative.collectionsForRegistration - [params[:collection]]
    updated_administrative = @cocina.administrative.new(collectionsForRegistration: collection_ids)
    updated = @cocina.new(administrative: updated_administrative)
    Repository.store(updated)

    redirect_to solr_document_path(params[:id]), notice: 'APO updated.'
  end

  def spreadsheet_template
    binary_string = Faraday.get(Settings.spreadsheet_url)
    send_data(
      binary_string.body,
      filename: 'spreadsheet_template.xlsx',
      type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
    )
  end

  # Displays the turbo-frame that has a link to collections governed by this APO
  def count_collections
    query = "_query_:\"{!raw f=#{ApoConcern::FIELD_APO_ID}}info:fedora/#{params[:id]}\" AND " \
            "_query_:\"{!raw f=#{SolrDocument::FIELD_OBJECT_TYPE}}collection\""
    result = solr_conn.get('select', params: { q: query, qt: 'standard', rows: 0 })

    path_for_search = link_to_members_with_type('collection')

    render partial: 'count_collections', locals: { count: result.dig('response', 'numFound'), path_for_search: }
  end

  # Displays the turbo-frame that has a link to items governed by this APO
  def count_items
    query = "_query_:\"{!raw f=#{ApoConcern::FIELD_APO_ID}}info:fedora/#{params[:id]}\" AND " \
            "_query_:\"{!raw f=#{SolrDocument::FIELD_OBJECT_TYPE}}item\""
    result = solr_conn.get('select', params: { q: query, qt: 'standard', rows: 0 })

    path_for_search = link_to_members_with_type('item')

    render partial: 'count_items', locals: { count: result.dig('response', 'numFound'), path_for_search: }
  end

  def search_action_path(*)
    search_catalog_path(*)
  end

  private

  def search_service
    @search_service ||= Blacklight::SearchService.new(config: CatalogController.blacklight_config,
                                                      current_user:)
  end

  def link_to_members_with_type(type)
    facet_config = facet_configuration_for_field(ApoConcern::FIELD_APO_ID)
    search_state = Blacklight::SearchState.new({ f: { SolrDocument::FIELD_OBJECT_TYPE => [type] } }, blacklight_config)
    Blacklight::FacetItemPresenter.new("info:fedora/#{params[:id]}",
                                       facet_config,
                                       self,
                                       ApoConcern::FIELD_APO_ID, search_state).href
  end

  def solr_conn
    @solr_conn ||= blacklight_config.repository_class.new(blacklight_config).connection
  end
end