sanger/sequencescape

View on GitHub
app/models/transfer/between_plates_by_submission.rb

Summary

Maintainability
A
1 hr
Test Coverage
A
100%
# frozen_string_literal: true
# This is effectively pooling: all wells that have come from the same submission will be transferred
# into the same well on the destination plate.
class Transfer::BetweenPlatesBySubmission < Transfer
  extend ::ModelExtensions::Plate::NamedScopeHelpers
  include_plate_named_scope :source
  include_plate_named_scope :destination

  include TransfersToKnownDestination
  include ControlledDestinations

  include Asset::Ownership::ChangesOwner
  set_target_for_owner(:destination)

  #--
  # Track back from the specified well to the stock plate well that has been transfered here.  Then
  # find the non-transfer request where the stock well was the source asset, and from there the submission
  # that it came from.  Hence all stock wells that are part of the same submission will be transferred to
  # the same well.
  #++
  # rubocop:todo Metrics/MethodLength
  def well_to_destination # rubocop:todo Metrics/AbcSize
    {}.tap do |sources_to_target|
      # Group the wells based on the submission
      groups = source.wells.in_column_major_order.with_pool_id.group_by(&:pool_id).delete_if { |k, _| k.nil? }.values

      # Submission group 1 will go into A1, group 2 into B1, group 3 C1, etc.
      Map.walk_plate_in_column_major_order(source.size) do |position, index|
        next unless index < groups.size

        destination_well = destination.wells.located_at(position.description).first or
          raise StandardError, "The destination does not have a well at #{position.description}"
        groups[index].each do |source|
          sources_to_target[source] = destination_well unless should_well_not_be_transferred?(source)
        end
      end
    end
  end

  # rubocop:enable Metrics/MethodLength
  private :well_to_destination

  def record_transfer(source, destination)
    self.transfers ||= {}
    self.transfers[source.map.description] = destination.map.description
  end
  private :record_transfer
end