Class: TransferRequest

Inherits:
ApplicationRecord show all
Extended by:
Request::Statemachine::ClassMethods
Includes:
AASM, AASM::Extensions, Uuid::Uuidable
Defined in:
app/models/transfer_request.rb

Overview

Note:

The setting of submission_id and outer_request is quite complicated, and depends

Every request “moving” an asset from somewhere to somewhere else without really transforming it (chemically) as, cherrypicking, pooling, spreading on the floor etc

on the exact route by which the transfer request has been created. The preferred route is by setting outer_request explicitly. However much of the historic code handles it via submission_id, either set explicitly, (eg Transfer::BetweenPlates#calculate_location_submissions) or extracted from the pool_id attribute on well, which itself is populated as part of an sql query. (See #with_pool_id on the well association in Plate)

Constant Summary collapse

ACTIVE_STATES =

States which are still considered to be processable (ie. not failed or cancelled)

%w[pending started passed qc_complete].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from AASM::Extensions

#transition_to

Methods included from Uuid::Uuidable

included, #unsaved_uuid!, #uuid

Methods inherited from ApplicationRecord

alias_association, convert_labware_to_receptacle_for, find_by_id_or_name, find_by_id_or_name!

Methods included from Squishify

extended

Instance Attribute Details

#aliquot_attributes=(value) ⇒ Object

Sets the attribute aliquot_attributes

Parameters:

  • value

    the value to set the attribute aliquot_attributes to.



21
22
23
# File 'app/models/transfer_request.rb', line 21

def aliquot_attributes=(value)
  @aliquot_attributes = value
end

#merge_equivalent_aliquotsObject

Determines if we attempt to filter out equivalent aliquots before performing transfers.



20
21
22
# File 'app/models/transfer_request.rb', line 20

def merge_equivalent_aliquots
  @merge_equivalent_aliquots
end

Instance Method Details

#outer_requestObject



157
158
159
# File 'app/models/transfer_request.rb', line 157

def outer_request
  asset.outer_request(submission_id)
end

#outer_request=(request) ⇒ Object

Note:

This is particularly important when transferring out of the initial

Set the outer request associated with this transfer request the outer request is the Request which is currently being processed, such as a LibraryCreationRequest. Setting this ensures that the transferred Aliquots are associated with the correct request, and that submission_id on transfer request is recorded correctly. Receptacle when there may be multiple active Receptacle#requests_as_source

Parameters:

  • request (Request)

    The request which is being processed



146
147
148
149
# File 'app/models/transfer_request.rb', line 146

def outer_request=(request)
  @outer_request = request
  self.submission_id = request.submission_id
end

#outer_request_candidates_lengthObject



172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
# File 'app/models/transfer_request.rb', line 172

def outer_request_candidates_length
  # Its a simple scenario, we avoid doing anything fancy and just give the thumbs up
  return true if one_or_fewer_outer_requests?

  # @todo The code below assumes that if we've got multiple outer requests then
  #       we must be at the multiplexing stage further down the pipeline. While
  #       this seems to be true in practice, it could result in some strange behaviour
  #       if triggered in other circumstances. One example was when the PacBio Library
  #       prep pipeline had multiple requests in the same submission out of each well.
  #       In this case the source aliquots didn't have a submission id set, so we couldn't
  #       find a next request to select.
  #
  #       The code currently:
  #       - For each aliquot in the receptacle detects an 'outer request' that is the next request in
  #         the submission after the request associated with the aliquot.
  #       - Ensures that this works for all aliquots in the receptacle
  #       - Creates an error for any that don't have a next request
  #
  #       In the example above, this was failing because the aliquot wasn't associated with a request,
  #       so it made no sense to find a 'next request in the submission'. It should still have failed,
  #       as the outer_request is ambiguous, but its kind of failing by accident.
  #
  #      = Fixing this
  #
  #      Firstly, I *think* this code is currently doing the right things, for the wrong reasons. So I
  #      believe it falls under general maintenance, rather than a bug fix. But all that could change.
  #
  #      This should probably be addressed as part of #3100 (https://github.com/sanger/sequencescape/issues/3100)
  #      The main aim here should probably to aim for explicitness and simplicity, rather than making
  #      this code more complicated to handle further cases.
  #
  # If we're a bit more complicated attempt to match up requests
  # This operation is a bit expensive, but needs to handle scenarios where:
  # 1) We've already done some pooling, and have multiple requests in and out
  # 2) We've got multiple aliquots from a single request, such as in Chromium
  # Failing silently at this point could result in aliquots being assigned to the wrong study
  # or the correct request information being missing downstream. (Which is then tricky to diagnose and repair)
  asset
    .aliquots
    .reduce(true) do |valid, aliquot|
      compatible = next_request_index[aliquot.id].present?
      unless compatible
        errors.add(:outer_request, "not found for aliquot #{aliquot.id} with previous request #{aliquot.request}")
      end
      valid && compatible
    end
end

#outer_request_id=(request_id) ⇒ Object

Sets the #outer_request from just a request_id

Parameters:



153
154
155
# File 'app/models/transfer_request.rb', line 153

def outer_request_id=(request_id)
  self.outer_request = Request.find(request_id)
end

#sibling_requestsObject

A sibling request is a customer request out of the same asset and in the same submission



162
163
164
165
166
167
168
169
170
# File 'app/models/transfer_request.rb', line 162

def sibling_requests # rubocop:todo Metrics/AbcSize
  if associated_requests.loaded?
    associated_requests.select { |r| r.submission_id == submission_id }
  elsif asset.requests.loaded?
    asset.requests.select { |r| r.submission_id == submission_id }
  else
    associated_requests.where(submission: submission_id)
  end
end

#source_and_target_assets_are_differentObject

validation method



130
131
132
133
134
135
136
# File 'app/models/transfer_request.rb', line 130

def source_and_target_assets_are_different
  return true unless asset_id.present? && asset_id == target_asset_id

  errors.add(:asset, 'cannot be the same as the target')
  errors.add(:target_asset, 'cannot be the same as the source')
  false
end