Class: Order
Overview
An 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.
Constant Summary
collapse
- AssetTypeError =
Ensure order methods behave correctly
Class.new(StandardError)
- DEFAULT_ASSET_INPUT_METHODS =
['select an asset group'].freeze
Submission::ProjectValidation::Error
Instance Attribute Summary collapse
Class Method Summary
collapse
Instance Method Summary
collapse
#can_check_data_release_and_accession?, #check_data_release_and_accession_for_submission, included, #request_types_require_accessioning?
included, #request_options=
#checking_project?, included, #save_after_unmarshalling, #submittable?, #validating?
#complete_building_asset_group, included
included, #unsaved_uuid!, #uuid
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
#info_differential=(value) ⇒ Object
Unused. Maintained because some submission templates attempt to set the info
36
37
38
|
# File 'app/models/order.rb', line 36
def info_differential=(value)
@info_differential = value
end
|
Return the list of input fields to edit when creating a new submission Unless you are doing something fancy, fall back on the defaults
248
249
250
|
# File 'app/models/order.rb', line 248
def input_field_infos
@input_field_infos ||= FieldInfo.for_request_types(request_types_list.flatten)
end
|
#request_type_ids_list ⇒ Object
213
214
215
|
# File 'app/models/order.rb', line 213
def request_type_ids_list
@request_type_ids_list ||= [[]]
end
|
Class Method Details
.render_class ⇒ Object
96
97
98
|
# File 'app/models/order.rb', line 96
def render_class
Api::OrderIo
end
|
Instance Method Details
271
272
273
274
275
276
277
278
|
# File 'app/models/order.rb', line 271
def (, user)
update!(comments: [, ].compact.join('; '))
submission
.requests
.for_order_including_submission_based_requests(self)
.map { |request| request.(, user) }
end
|
#all_assets ⇒ Object
154
155
156
157
|
# File 'app/models/order.rb', line 154
def all_assets
pull_assets_from_asset_group if assets.empty? && asset_group.present?
assets
end
|
#all_samples ⇒ Object
149
150
151
152
|
# File 'app/models/order.rb', line 149
def all_samples
all_assets.map(&:samples).flatten.uniq
end
|
#asset_uuids ⇒ Object
163
164
165
|
# File 'app/models/order.rb', line 163
def asset_uuids
assets&.select(&:present?)&.map(&:uuid)
end
|
#assets=(assets_to_add) ⇒ Object
110
111
112
|
# File 'app/models/order.rb', line 110
def assets=(assets_to_add)
super(assets_to_add.map { |a| a.is_a?(Receptacle) ? a : a.receptacle })
end
|
#autodetection_default ⇒ Object
101
102
103
|
# File 'app/models/order.rb', line 101
def autodetection_default
false
end
|
#building? ⇒ Boolean
Are we still able to modify this instance?
258
259
260
|
# File 'app/models/order.rb', line 258
def building?
submission.nil?
end
|
#building_submission? ⇒ Boolean
We can’t destroy orders once the submission has been finalized for building
115
116
117
|
# File 'app/models/order.rb', line 115
def building_submission?
throw :abort unless submission.building?
end
|
#collect_gigabases_expected? ⇒ Boolean
267
268
269
|
# File 'app/models/order.rb', line 267
def collect_gigabases_expected?
input_field_infos.any? { |k| k.key == :gigabases_expected }
end
|
#complete_building ⇒ Object
105
106
107
108
|
# File 'app/models/order.rb', line 105
def complete_building
check_project_details!
complete_building_asset_group
end
|
#create_request_of_type!(request_type, attributes = {}) ⇒ Object
rubocop:todo Metrics/MethodLength
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
|
# File 'app/models/order.rb', line 176
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.request_metadata_attributes = em
request.state = request_type.initial_state
request.order = self
if request.asset.present?
unless asset_applicable_to_type?(request_type, request.asset)
raise AssetTypeError, 'Asset type does not match that expected by request type.'
end
end
end
end
|
#cross_compatible? ⇒ Boolean
138
139
140
|
# File 'app/models/order.rb', line 138
def cross_compatible?
false
end
|
#cross_project_allowed ⇒ Object
134
135
136
|
# File 'app/models/order.rb', line 134
def cross_project_allowed
false
end
|
#cross_study_allowed ⇒ Object
130
131
132
|
# File 'app/models/order.rb', line 130
def cross_study_allowed
false
end
|
#duplicates_within(timespan) {|matching_samples, matching_orders, matching_submissions| ... } ⇒ Object
rubocop:enable Metrics/MethodLength
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
|
# File 'app/models/order.rb', line 197
def duplicates_within(timespan) matching_orders =
Order
.containing_samples(all_samples)
.where(template_name:)
.includes(:submission, assets: :samples)
.where.not(orders: { 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_type ⇒ Object
242
243
244
|
# File 'app/models/order.rb', line 242
def first_request_type
@first_request_type ||= RequestType.find(request_types.first)
end
|
#friendly_name ⇒ Object
280
281
282
|
# File 'app/models/order.rb', line 280
def friendly_name
asset_group.try(:name) || asset_group_name || id
end
|
#generate_broadcast_event ⇒ Object
288
289
290
|
# File 'app/models/order.rb', line 288
def generate_broadcast_event
BroadcastEvent::OrderMade.create!(seed: self, user: user)
end
|
#json_root ⇒ Object
159
160
161
|
# File 'app/models/order.rb', line 159
def json_root
'order'
end
|
#multiplexed? ⇒ Boolean
167
168
169
|
# File 'app/models/order.rb', line 167
def multiplexed?
RequestType.where(id: request_types).for_multiplexing.exists?
end
|
#multiplier_for(request_type_id) ⇒ Object
171
172
173
|
# File 'app/models/order.rb', line 171
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
252
253
254
255
|
# File 'app/models/order.rb', line 252
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_samples ⇒ Object
returns an array of samples, that potentially can not be included in submission
297
298
299
|
# File 'app/models/order.rb', line 297
def not_ready_samples
all_samples.reject(&:can_be_included_in_submission?)
end
|
#on_delete_destroy_submission ⇒ Object
119
120
121
122
123
124
125
126
127
128
|
# File 'app/models/order.rb', line 119
def on_delete_destroy_submission
if building_submission?
orders = submission.orders
submission.destroy unless orders.size > 1
return true
end
false
end
|
#request_types_list ⇒ Object
request_type_ids_list is set for orders created by submission templates It is used by the input_field_infos section, which controls rendering form fields appropriate to each request type in the submission interface request_type_ids is calculated from this in the various sub-classes and gets persisted to the database, and used for the actual construction. TODO: Simplify this - There are a few attributes which all refer to loosely the same thing, a list of request type ids: * request_type_ids_list - Set by submission templates, but also recalculated on the fly and used in various methods * request_types_ids - Setter on order subclasses. * request_types - Serialized version on order, persisted in the database - The request_types on the database should become the authoritative source. - request_type_ids_list should just be a setter, which populates request_types. It may need to transform the input slightly. Ideally we eliminate this entirely, and be consistent between templates and orders - There appear to be several methods which essentially do the same thing. They should be unified. - I’m not even 100% how request_types_ids factors in.
238
239
240
|
# File 'app/models/order.rb', line 238
def request_types_list
request_type_ids_list.map { |ids| RequestType.find(ids) }
end
|
#samples ⇒ Object
TODO: Figure out why eager loading aliquots/samples returns [] even when we limit order_assets to receptacles.
144
145
146
147
|
# File 'app/models/order.rb', line 144
def samples
assets.map(&:samples).flatten.uniq
end
|
#sequencing_order? ⇒ Boolean
Returns true if this is an order for sequencing
263
264
265
|
# File 'app/models/order.rb', line 263
def sequencing_order?
RequestType.find(request_types).any?(&:sequencing?)
end
|
#study_is_active ⇒ Object
292
293
294
|
# File 'app/models/order.rb', line 292
def study_is_active
errors.add(:study, 'is not active') if study.present? && !study.active?
end
|
#subject_type ⇒ Object
284
285
286
|
# File 'app/models/order.rb', line 284
def subject_type
'order'
end
|