Class: QcResultsUploadFactory

Inherits:
Object
  • Object
show all
Includes:
ActiveModel::Model
Defined in:
app/models/qc_results_upload_factory.rb

Overview

Handles the logic of receiving a CSV and creating QC entities

Defined Under Namespace

Classes: QcResultMessage

Constant Summary collapse

LR_DECISION_FIELD =
'LR EXTRACTION DECISION [ESP1]'
TOL_DECISION_FIELD =
'TOL DECISION [ESP1]'
TISSUE_TUBE_ID_FIELD =
'Tissue Tube ID'
SANGER_SAMPLE_ID_FIELD =
'Sanger sample ID'
LIST =
[
  LR_DECISION_FIELD,
  TOL_DECISION_FIELD,
  TISSUE_TUBE_ID_FIELD,
  SANGER_SAMPLE_ID_FIELD
].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#qc_results_uploadObject

Returns the value of attribute qc_results_upload.



7
8
9
# File 'app/models/qc_results_upload_factory.rb', line 7

def qc_results_upload
  @qc_results_upload
end

Instance Method Details

#build_qc_result_message(qc_result, decision_made_by) ⇒ Object



111
112
113
# File 'app/models/qc_results_upload_factory.rb', line 111

def build_qc_result_message(qc_result, decision_made_by)
  messages << QcResultMessage.new(qc_result:, decision_made_by:)
end

#create_data(row_object) ⇒ Object

Parameters:

  • row_object (Object)

    csv row e.g. { col_header_1: row_1_col_1 }



42
43
44
45
46
47
48
49
50
51
52
# File 'app/models/qc_results_upload_factory.rb', line 42

def create_data(row_object)
  # 1. Create QC Decisions
  qc_decisions = create_qc_decisions(row_object)

  # 2. Create QC Results
  qc_results = create_qc_results(row_object)

  # 3. Create QC Decision Results
  create_qc_decision_results(qc_results, qc_decisions[:lr_qc_decision],
                             qc_decisions[:tol_qc_decision])
end

#create_entities!Object



34
35
36
37
38
39
# File 'app/models/qc_results_upload_factory.rb', line 34

def create_entities!
  rows.each do |row_object|
    create_data(row_object)
  end
  true
end

#create_qc_decision!(status, decision_made_by) ⇒ QcDecision

Returns:



116
117
118
# File 'app/models/qc_results_upload_factory.rb', line 116

def create_qc_decision!(status, decision_made_by)
  QcDecision.create!(status:, decision_made_by:)
end

#create_qc_decision_result!(qc_result, qc_decision) ⇒ QcDecisionResult

Returns:



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

def create_qc_decision_result!(qc_result, qc_decision)
  QcDecisionResult.create!(qc_result:, qc_decision:)
end

#create_qc_decision_results(qc_results, lr_qc_decision, tol_qc_decision) ⇒ Object

create a qc decision for each decision maker



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'app/models/qc_results_upload_factory.rb', line 93

def create_qc_decision_results(qc_results, lr_qc_decision, tol_qc_decision)
  # Always create Long Read QC Decision Results

  qc_results.each do |qc_result|
    # If required, create LR QC Decision Results
    if lr_qc_decision
      create_qc_decision_result!(qc_result, lr_qc_decision)
      build_qc_result_message(qc_result, :long_read)
    end

    # If required, create TOL QC Decision Results
    if tol_qc_decision
      create_qc_decision_result!(qc_result, tol_qc_decision)
      build_qc_result_message(qc_result, :tol)
    end
  end
end

#create_qc_decisions(row_object) ⇒ Object



54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'app/models/qc_results_upload_factory.rb', line 54

def create_qc_decisions(row_object)
  # If required, create Long Read QC Decision
  if row_object[LR_DECISION_FIELD]
    lr_qc_decision = create_qc_decision!(row_object[LR_DECISION_FIELD], :long_read)
  end

  # If required, create TOL QC Decision
  if row_object[TOL_DECISION_FIELD]
    tol_qc_decision = create_qc_decision!(row_object[TOL_DECISION_FIELD], :tol)
  end

  { lr_qc_decision:, tol_qc_decision: }
end

#create_qc_result!(labware_barcode, sample_external_id, qc_assay_type_id, value) ⇒ QcResult

Returns:



121
122
123
# File 'app/models/qc_results_upload_factory.rb', line 121

def create_qc_result!(labware_barcode, sample_external_id, qc_assay_type_id, value)
  QcResult.create!(labware_barcode:, sample_external_id:, qc_assay_type_id:, value:)
end

#create_qc_results(row_object) ⇒ List

Returns of created QcResults.

Parameters:

  • row_object (Object)

    csv row e.g. { col_header_1: row_1_col_1 }

Returns:

  • (List)

    of created QcResults



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'app/models/qc_results_upload_factory.rb', line 70

def create_qc_results(row_object)
  # Get relevant QcAssayTypes, for used_by
  qc_assay_types = QcAssayType.where(used_by:)

  # Get the common data for each row
  tissue_tube_id = row_object[TISSUE_TUBE_ID_FIELD]
  sanger_sample_id = row_object[SANGER_SAMPLE_ID_FIELD]

  # Loop through QcAssayTypes
  qc_assay_types.map do |qc_assay_type|
    # TODO: clean up below comment
    # next returns nil if row is missing QcAssayType data
    # method retuns list.compact, as create_qc_results may contain nil objects
    # ingnore the value?
    next unless row_object[qc_assay_type.key]

    # Create a QcResult for each QcAssayType
    create_qc_result!(tissue_tube_id, sanger_sample_id, qc_assay_type.id,
                      row_object[qc_assay_type.key])
  end.compact
end

#csv_string_without_first_rowString

Returns the CSV, with the first row (groupings) removed

Returns:

  • (String)

    CSV



175
176
177
# File 'app/models/qc_results_upload_factory.rb', line 175

def csv_string_without_first_row
  csv_data.split("\n")[1..].join("\n")
end

#messagesList

Returns of all QcResultMessages - a different one is needed for each decision point.

Returns:

  • (List)

    of all QcResultMessages - a different one is needed for each decision point



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

def messages
  @messages ||= []
end

#pivot_csv_data_to_objList

Pivots the CSV data Returns a list of objects, where each object is a CSV row

Returns:

  • (List)

    e.g. [{ col_header_1: row_1_col_1, col_header_2: row_1_col_2 }, …]



156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
# File 'app/models/qc_results_upload_factory.rb', line 156

def pivot_csv_data_to_obj
  header_converter = proc do |header|
    assay_type = QcAssayType.find_by(label: header.strip)
    assay_type ? assay_type.key : header.strip
  end

  csv = CSV.new(csv_string_without_first_row, headers: true, header_converters: header_converter)

  arr_of_hashes = csv.to_a.map(&:to_hash)

  # Remove any rows which are missing the Tissue Tube ID, or which are controls
  arr_of_hashes.reject! do |row|
    row[TISSUE_TUBE_ID_FIELD].nil? || row[TISSUE_TUBE_ID_FIELD].match(/control/i)
  end
  arr_of_hashes
end

#rowsObject

creates data from the initial csv



28
29
30
31
32
# File 'app/models/qc_results_upload_factory.rb', line 28

def rows
  return unless qc_results_upload

  @rows ||= pivot_csv_data_to_obj
end