Class: Order

Overview

And Order is used as the main means of requesting work in Sequencescape. Its key components are: Assets/AssetGroup: The assets on which the work will be conducted Study: The study for which work is being undertaken Project: The project who will be charged for the work Request options: The parameters for the request which will be built. eg. read length Request Types: An array of request type ids which will be built by the order.

This is populated based on the submission template used.

Submission: Multiple orders may be grouped together in a submission. This

associates the two sets of requests, and is usually used to determine
what gets pooled together during multiplexing. As a result, sequencing
requests may be shared between multiple orders.

Defined Under Namespace

Modules: InstanceMethods

Constant Summary collapse

AssetTypeError =
Class.new(StandardError)
DEFAULT_ASSET_INPUT_METHODS =
['select an asset group'].freeze

Constants included from Submission::ProjectValidation

Submission::ProjectValidation::Error

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Submission::AccessionBehaviour

#can_check_data_release_and_accession?, #check_data_release_and_accession_for_submission, included, #request_types_require_accessioning?

Methods included from Submission::RequestOptionsBehaviour

included, #request_options=

Methods included from Submission::ProjectValidation

#checking_project?, #complete_building, included, #save_after_unmarshalling, #submittable?, #validating?

Methods included from Submission::AssetGroupBehaviour

#complete_building, included

Methods included from Uuid::Uuidable

included, #unsaved_uuid!, #uuid

Methods included from InstanceMethods

#complete_building

Methods inherited from ApplicationRecord

convert_labware_to_receptacle_for, find_by_id_or_name, find_by_id_or_name!

Methods included from Warren::BroadcastMessages

#broadcast, included, #queue_associated_for_broadcast, #queue_for_broadcast, #warren

Instance Attribute Details

#asset_input_methodsObject


203
204
205
# File 'app/models/order.rb', line 203

def asset_input_methods
  @asset_input_methods ||= DEFAULT_ASSET_INPUT_METHODS
end

#customize_partialObject

the name of a partial to render.


40
41
42
# File 'app/models/order.rb', line 40

def customize_partial
  @customize_partial
end

#info_differentialObject

aggrement text to display when creating a new submission


39
40
41
# File 'app/models/order.rb', line 39

def info_differential
  @info_differential
end

#input_field_infosObject

Return the list of input fields to edit when creating a new submission Unless you are doing something fancy, fall back on the defaults


217
218
219
# File 'app/models/order.rb', line 217

def input_field_infos
  @input_field_infos ||= FieldInfo.for_request_types(request_types_list.flatten)
end

#request_type_ids_listObject


199
200
201
# File 'app/models/order.rb', line 199

def request_type_ids_list
  @request_type_ids_list ||= [[]]
end

Class Method Details

.render_classObject


94
95
96
# File 'app/models/order.rb', line 94

def render_class
  Api::OrderIO
end

Instance Method Details

#add_comment(comment_str, user) ⇒ Object


240
241
242
243
244
245
246
# File 'app/models/order.rb', line 240

def add_comment(comment_str, user)
  update!(comments: [comments, comment_str].compact.join('; '))

  submission.requests.for_order_including_submission_based_requests(self).map do |request|
    request.add_comment(comment_str, user)
  end
end

#all_assetsObject


147
148
149
150
# File 'app/models/order.rb', line 147

def all_assets
  pull_assets_from_asset_group if assets.empty? && asset_group.present?
  assets
end

#all_samplesObject


142
143
144
145
# File 'app/models/order.rb', line 142

def all_samples
  # slightly less naive way
  all_assets.map(&:samples).flatten.uniq
end

#asset_uuidsObject


156
157
158
# File 'app/models/order.rb', line 156

def asset_uuids
  assets&.select(&:present?)&.map(&:uuid)
end

#building?Boolean

Are we still able to modify this instance?


227
228
229
# File 'app/models/order.rb', line 227

def building?
  submission.nil?
end

#building_submission?Boolean

We can't destroy orders once the submission has been finalized for building


108
109
110
# File 'app/models/order.rb', line 108

def building_submission?
  throw :abort unless submission.building?
end

#collect_gigabases_expected?Boolean


236
237
238
# File 'app/models/order.rb', line 236

def collect_gigabases_expected?
  input_field_infos.any? { |k| k.key == :gigabases_expected }
end

#create_request_of_type!(request_type, attributes = {}) ⇒ Object


168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
# File 'app/models/order.rb', line 168

def create_request_of_type!(request_type, attributes = {})
  em = request_type.(request_options)
  request_type.create!(attributes) do |request|
    request.submission_id               = submission_id
    request.study                       = study
    request.initial_project             = project
    request.user                        = user
    request. = em
    request.state                       = request_type.initial_state
    request.order                       = self

    if request.asset.present?
      raise AssetTypeError, 'Asset type does not match that expected by request type.' unless asset_applicable_to_type?(request_type, request.asset)
    end
  end
end

#cross_compatible?Boolean


131
132
133
# File 'app/models/order.rb', line 131

def cross_compatible?
  false
end

#cross_project_allowedObject


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

def cross_project_allowed
  false
end

#cross_study_allowedObject


123
124
125
# File 'app/models/order.rb', line 123

def cross_study_allowed
  false
end

#duplicates_within(timespan) {|matching_samples, matching_orders, matching_submissions| ... } ⇒ Object

Yields:

  • (matching_samples, matching_orders, matching_submissions)

185
186
187
188
189
190
191
192
193
194
195
196
197
# File 'app/models/order.rb', line 185

def duplicates_within(timespan)
  matching_orders = Order.containing_samples(all_samples)
                         .where(template_name: template_name)
                         .includes(:submission, assets: :samples)
                         .where.not(orders: { id: id })
                         .where('orders.created_at > ?', Time.current - timespan)
  return false if matching_orders.empty?

  matching_samples = matching_orders.map(&:samples).flatten & all_samples
  matching_submissions = matching_orders.map(&:submission).uniq
  yield matching_samples, matching_orders, matching_submissions if block_given?
  true
end

#first_request_typeObject


211
212
213
# File 'app/models/order.rb', line 211

def first_request_type
  RequestType.find(request_types.first)
end

#friendly_nameObject


248
249
250
# File 'app/models/order.rb', line 248

def friendly_name
  asset_group.try(:name) || asset_group_name || id
end

#generate_broadcast_eventObject


256
257
258
# File 'app/models/order.rb', line 256

def generate_broadcast_event
  BroadcastEvent::OrderMade.create!(seed: self, user: user)
end

#json_rootObject


152
153
154
# File 'app/models/order.rb', line 152

def json_root
  'order'
end

#multiplexed?Boolean


160
161
162
# File 'app/models/order.rb', line 160

def multiplexed?
  RequestType.where(id: request_types).for_multiplexing.exists?
end

#multiplier_for(request_type_id) ⇒ Object


164
165
166
# File 'app/models/order.rb', line 164

def multiplier_for(request_type_id)
  (request_options.dig(:multiplier, request_type_id.to_s) || 1).to_i
end

#next_request_type_id(request_type_id) ⇒ Object


221
222
223
224
# File 'app/models/order.rb', line 221

def next_request_type_id(request_type_id)
  request_type_ids = request_types.map(&:to_i)
  request_type_ids[request_type_ids.index(request_type_id) + 1]
end

#not_ready_samplesObject

returns an array of samples, that potentially can not be included in submission


265
266
267
# File 'app/models/order.rb', line 265

def not_ready_samples
  all_samples.reject(&:can_be_included_in_submission?)
end

#on_delete_destroy_submissionObject


112
113
114
115
116
117
118
119
120
121
# File 'app/models/order.rb', line 112

def on_delete_destroy_submission
  if building_submission?
    # After destroying an order, if it is the last order on it's submission
    # destroy the submission too.
    orders = submission.orders
    submission.destroy unless orders.size > 1
    return true
  end
  false
end

#request_types_listObject


207
208
209
# File 'app/models/order.rb', line 207

def request_types_list
  request_type_ids_list.map { |ids| RequestType.find(ids) }
end

#samplesObject

TODO: Figure out why eager loading aliquots/samples returns [] even when we limit order_assets to receptacles.


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

def samples
  # naive way
  assets.map(&:samples).flatten.uniq
end

#sequencing_order?Boolean

Returns true if this is an order for sequencing


232
233
234
# File 'app/models/order.rb', line 232

def sequencing_order?
  RequestType.find(request_types).any?(&:sequencing?)
end

#study_is_activeObject


260
261
262
# File 'app/models/order.rb', line 260

def study_is_active
  errors.add(:study, 'is not active') if study.present? && !study.active?
end

#subject_typeObject


252
253
254
# File 'app/models/order.rb', line 252

def subject_type
  'order'
end