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

convert_labware_to_receptacle_for, find_by_id_or_name, find_by_id_or_name!

Methods included from Squishify

extended

Instance Attribute Details

#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


137
138
139
# File 'app/models/transfer_request.rb', line 137

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


126
127
128
129
# File 'app/models/transfer_request.rb', line 126

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

#outer_request_candidates_lengthObject


152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
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
# File 'app/models/transfer_request.rb', line 152

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:


133
134
135
# File 'app/models/transfer_request.rb', line 133

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


142
143
144
145
146
147
148
149
150
# File 'app/models/transfer_request.rb', line 142

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


110
111
112
113
114
115
116
# File 'app/models/transfer_request.rb', line 110

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