Class: SampleManifestExcel::Upload::Base

Inherits:
Object
  • Object
show all
Includes:
AccessionHelper, ActiveModel::Model
Defined in:
app/sample_manifest_excel/sample_manifest_excel/upload/base.rb

Overview

An upload will Find the start row based on the Sanger Sample Id column header cell Create a Data object based on the file. Extract the columns based on the headings in the spreadsheet Find the sanger sample id column Create some Rows Retrieve the sample manifest *Create a processor based on the sample manifest The Upload is only valid if the file, columns, sample manifest and processor are valid.

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from AccessionHelper

#accessioning_enabled?, #permitted_to_accession?

Constructor Details

#initialize(attributes = {}) ⇒ Base

rubocop:todo Metrics/AbcSize



41
42
43
44
45
46
47
48
49
50
51
52
# File 'app/sample_manifest_excel/sample_manifest_excel/upload/base.rb', line 41

def initialize(attributes = {}) # rubocop:todo Metrics/AbcSize
  super
  @data = Upload::Data.new(file)
  @start_row = @data.start_row
  @columns = column_list.extract(data.header_row.reject(&:blank?) || [])
  @sanger_sample_id_column = columns.find_by(:name, :sanger_sample_id)
  @cache = Cache.new(self)
  @rows = Upload::Rows.new(data, columns, @cache)
  @sample_manifest = derive_sample_manifest
  @override = override || false
  @processor = create_processor
end

Instance Attribute Details

#cacheObject (readonly)

rubocop:todo Layout/LineLength



25
26
27
# File 'app/sample_manifest_excel/sample_manifest_excel/upload/base.rb', line 25

def cache
  @cache
end

#column_listObject

Returns the value of attribute column_list.



22
23
24
# File 'app/sample_manifest_excel/sample_manifest_excel/upload/base.rb', line 22

def column_list
  @column_list
end

#columnsObject (readonly)

rubocop:todo Layout/LineLength



25
26
27
# File 'app/sample_manifest_excel/sample_manifest_excel/upload/base.rb', line 25

def columns
  @columns
end

#dataObject (readonly)

rubocop:todo Layout/LineLength



25
26
27
# File 'app/sample_manifest_excel/sample_manifest_excel/upload/base.rb', line 25

def data
  @data
end

#fileObject

Returns the value of attribute file.



22
23
24
# File 'app/sample_manifest_excel/sample_manifest_excel/upload/base.rb', line 22

def file
  @file
end

#overrideObject

Returns the value of attribute override.



22
23
24
# File 'app/sample_manifest_excel/sample_manifest_excel/upload/base.rb', line 22

def override
  @override
end

#processorObject (readonly)

rubocop:todo Layout/LineLength



25
26
27
# File 'app/sample_manifest_excel/sample_manifest_excel/upload/base.rb', line 25

def processor
  @processor
end

#rowsObject (readonly)

rubocop:todo Layout/LineLength



25
26
27
# File 'app/sample_manifest_excel/sample_manifest_excel/upload/base.rb', line 25

def rows
  @rows
end

#sample_manifestObject (readonly)

rubocop:todo Layout/LineLength



25
26
27
# File 'app/sample_manifest_excel/sample_manifest_excel/upload/base.rb', line 25

def sample_manifest
  @sample_manifest
end

#sanger_sample_id_columnObject (readonly)

rubocop:todo Layout/LineLength



25
26
27
# File 'app/sample_manifest_excel/sample_manifest_excel/upload/base.rb', line 25

def sanger_sample_id_column
  @sanger_sample_id_column
end

#spreadsheetObject (readonly)

rubocop:todo Layout/LineLength



25
26
27
# File 'app/sample_manifest_excel/sample_manifest_excel/upload/base.rb', line 25

def spreadsheet
  @spreadsheet
end

#start_rowObject

Returns the value of attribute start_row.



22
23
24
# File 'app/sample_manifest_excel/sample_manifest_excel/upload/base.rb', line 22

def start_row
  @start_row
end

Instance Method Details

#broadcast_sample_manifest_updated_event(user) ⇒ Object



94
95
96
97
98
99
100
101
102
103
104
# File 'app/sample_manifest_excel/sample_manifest_excel/upload/base.rb', line 94

def broadcast_sample_manifest_updated_event(user)
  # Send to event warehouse
  sample_manifest.updated_broadcast_event(user, changed_samples.map(&:id))

  # Log legacy events: Show on history page, and may be used by reports.
  # We can get rid of these when:
  # - History page is updated with event warehouse viewer
  # - We've confirmed that no external reports use these events
  changed_samples.each { |sample| sample.handle_update_event(user) }
  changed_labware.each { |labware| labware.events.updated_using_sample_manifest!(user) }
end

#data_at(column_name) ⇒ Object

rubocop:todo Lint/DuplicateMethods



89
90
91
92
# File 'app/sample_manifest_excel/sample_manifest_excel/upload/base.rb', line 89

def data_at(column_name) # rubocop:todo Lint/DuplicateMethods
  required_column = columns.find_by(:name, column_name)
  rows.data_at(required_column.number) if required_column.present?
end

#derive_sample_manifestObject

The sample manifest is retrieved by taking the sanger sample id from the first row and retrieving its sample manifest. If it can't be found the upload will fail.



64
65
66
67
68
69
70
# File 'app/sample_manifest_excel/sample_manifest_excel/upload/base.rb', line 64

def derive_sample_manifest
  return unless start_row.present? && sanger_sample_id_column.present?

  sanger_sample_id = data.cell(1, sanger_sample_id_column.number)
  SampleManifestAsset.find_by(sanger_sample_id:)&.sample_manifest ||
    Sample.find_by(sanger_sample_id:)&.sample_manifest
end

#failObject



126
127
128
129
130
131
132
133
134
# File 'app/sample_manifest_excel/sample_manifest_excel/upload/base.rb', line 126

def fail
  # If we've failed, do not update the manifest file, trying to do so
  # causes exceptions
  sample_manifest.association(:uploaded_document).reset
  # Errs here because sample_manifest.samples is a collection that's not empty in Rails 6.1,
  # but is empty in Rails 5.0. Therefore, reloaded the samples.
  sample_manifest.samples.reload
  sample_manifest.fail!
end

#inspectObject



54
55
56
57
58
# File 'app/sample_manifest_excel/sample_manifest_excel/upload/base.rb', line 54

def inspect
  # rubocop:todo Layout/LineLength
  "<#{self.class}: @file=#{file}, @columns=#{columns.inspect}, @start_row=#{start_row}, @sanger_sample_id_column=#{sanger_sample_id_column}, @data=#{data.inspect}>"
  # rubocop:enable Layout/LineLength
end

#process(tag_group) ⇒ Object

An upload can only be processed if the upload is valid. Processing involves updating the sample manifest and all of its associated samples.



75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'app/sample_manifest_excel/sample_manifest_excel/upload/base.rb', line 75

def process(tag_group)
  # Temporarily disable accessioning until we invoke it explicitly
  # If we don't do this, then any accidental triggering of sample
  # saves will result in duplicate accessions
  Sample::Current.processing_manifest = true
  sample_manifest.last_errors = nil
  @cache.populate!
  processor.run(tag_group)

  processed?
ensure
  Sample::Current.processing_manifest = false
end

#register_stock_resourcesObject

If samples have been created, register a stock_resource record in the MLWH



122
123
124
# File 'app/sample_manifest_excel/sample_manifest_excel/upload/base.rb', line 122

def register_stock_resources
  stock_receptacles_to_be_registered.each(&:register_stock!)
end

#trigger_accessioning(event_user) ⇒ Object

Accession each sample individually, logging and skipping any that fail validation NOTE: this does not check if the current user has permission to accession samples in this manifest



108
109
110
111
112
113
114
115
116
117
118
119
# File 'app/sample_manifest_excel/sample_manifest_excel/upload/base.rb', line 108

def trigger_accessioning(event_user)
  unless accessioning_enabled?
    Rails.logger.info 'Accessioning is not enabled in this environment. Skipping accessioning.'
    return
  end

  changed_samples.each do |sample|
    Accession.accession_sample(sample, event_user)
  rescue AccessionService::AccessionValidationFailed => e
    Rails.logger.info "#{e.message} Skipping accessioning for this sample."
  end
end