Class: Robot::Verification::Base

Inherits:
Object
  • Object
show all
Defined in:
app/models/robot/verification/base.rb

Overview

Base class for handling bed verification for picking robots

Direct Known Subclasses

SourceDestBeds, SourceDestControlBeds

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#errorsObject (readonly)

rubocop:todo Metrics/ClassLength


7
8
9
# File 'app/models/robot/verification/base.rb', line 7

def errors
  @errors
end

Instance Method Details

#all_picks(batch, max_beds) ⇒ Object

Returns all pick information by destination_bed barcode }}

Examples:

{ 'DN3R' => {
 1 => [{'DN3R'=>1},{'DN1S'=>1, 'DN2T'=>2}, {}]

Parameters:

  • batch (Batch)

    The batch to get the pick-list for

  • max_beds (Integer)

    The max_beds for plates on the robot


68
69
70
71
72
73
74
75
# File 'app/models/robot/verification/base.rb', line 68

def all_picks(batch, max_beds)
  # @note No optimization yet.
  batch
    .output_plates
    .each_with_object({}) do |plate, store|
      store[plate.machine_barcode] = pick_number_to_expected_layout(batch, plate.machine_barcode, max_beds)
    end
end

#pick_number_to_expected_layout(batch, destination_plate_barcode, max_beds) ⇒ Object

Returns a hash of { pick_number => layout_data_object }, for a batch and a specific destination plate pick_number is a sequential number, starting at 1 layout_data_object is an array of hashes: 1st Element: Hash of destination plate barcodes and their sort position

                                      2nd Element: Hash of source plate barcodes and their sort position
                                      3rd Element: Hash of control plate barcodes and their sort position when
                                                   appropriate. (nil otherwise)
@example [{'DN3R'=>1},{'DN1S'=>1, 'DN2T'=>2}, {}]

There will only be more than one pick if the number of source plates exceed the max plates allowed on the robot and therefore more than one pick is needed to transfer from all the wells onto the destination plate


54
55
56
57
58
# File 'app/models/robot/verification/base.rb', line 54

def pick_number_to_expected_layout(batch, destination_plate_barcode, max_beds)
  generate_picking_data_hash(batch, destination_plate_barcode, max_beds).transform_values do |data_object|
    layout_data_object(data_object)
  end
end

#pick_numbers(batch, destination_plate_barcode, max_beds) ⇒ Array<String>

Note:

Added as I refactor the batches/_assets.html.erb page. Currently just wraps pick_number_to_expected_layout and as a result performs a lot of unnecessary work.

Returns an array of all pick numbers associated with the corresponding batch and plate_barcode

Parameters:

  • batch (Batch)

    The Batch to get pick numbers for

  • destination_plate_barcode (String)

    The barcode of the destination plate

  • max_beds (Integer)

    The max_beds for plates on the robot

Returns:

  • (Array<String>)

    Array of pick numbers associated with the batch/plate


41
42
43
# File 'app/models/robot/verification/base.rb', line 41

def pick_numbers(batch, destination_plate_barcode, max_beds)
  pick_number_to_expected_layout(batch, destination_plate_barcode, max_beds).keys
end

#record_plate_types(plate_types_params) ⇒ Object

rubocop:enable Metrics/AbcSize, Metrics/MethodLength, Metrics/PerceivedComplexity


114
115
116
117
118
119
120
121
122
123
# File 'app/models/robot/verification/base.rb', line 114

def record_plate_types(plate_types_params)
  plate_types_params.each do |plate_barcode, plate_type|
    next if plate_barcode.blank? || plate_type.blank?

    plate = Plate.with_barcode(plate_barcode).first or
      raise "Unable to locate plate #{plate_barcode.inspect} for robot verification"
    plate.plate_type = plate_type
    plate.save!
  end
end

#valid_submission?(params) ⇒ Boolean

rubocop:todo Metrics/PerceivedComplexity, Metrics/MethodLength, Metrics/AbcSize

Returns:

  • (Boolean)

78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'app/models/robot/verification/base.rb', line 78

def valid_submission?(params) # rubocop:todo Metrics/CyclomaticComplexity
  destination_plate_barcode = params[:barcodes][:destination_plate_barcode]
  batch = Batch.find_by(id: params[:batch_id])
  robot = Robot.find_by(id: params[:robot_id])
  user = User.find_by(id: params[:user_id])
  pick_number = params[:pick_number]

  @errors = []
  @errors << "Could not find batch #{params[:batch_id]}" if batch.nil?
  @errors << 'Could not find robot' if robot.nil?
  @errors << 'Could not find user' if user.nil?
  @errors << 'No destination barcode specified' if destination_plate_barcode.blank?
  @errors << 'Could not determine pick number' if pick_number.blank?
  return false unless @errors.empty?

  expected_plate_layout = robot.pick_number_to_expected_layout(batch, destination_plate_barcode)[pick_number.to_i]

  if valid_plate_locations?(params, batch, robot, expected_plate_layout)
    batch.events.create(
      message: I18n.t('bed_verification.layout.valid', plate_barcode: destination_plate_barcode),
      created_by: user.
    )
  else
    batch.events.create(
      message: I18n.t('bed_verification.layout.invalid', plate_barcode: destination_plate_barcode),
      created_by: user.
    )
    @errors << 'Bed layout invalid'
    return false
  end

  true
end

#validate_barcode_params(barcode_hash) ⇒ Object

rubocop:todo Metrics/PerceivedComplexity, Metrics/MethodLength, Metrics/AbcSize


10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# File 'app/models/robot/verification/base.rb', line 10

def validate_barcode_params(barcode_hash) # rubocop:todo Metrics/CyclomaticComplexity
  return yield('No barcodes specified') if barcode_hash.nil?

  if barcode_hash[:batch_barcode].blank? || !Batch.valid_barcode?(barcode_hash[:batch_barcode])
    yield('Worksheet barcode invalid')
  end
  if barcode_hash[:robot_barcode].blank? || !Robot.valid_barcode?(barcode_hash[:robot_barcode])
    yield('Robot barcode invalid')
  end
  if barcode_hash[:user_barcode].blank? || !User.find_with_barcode_or_swipecard_code(barcode_hash[:user_barcode])
    yield('User barcode invalid')
  end
  if barcode_hash[:destination_plate_barcode].blank? ||
       !Plate.with_barcode(barcode_hash[:destination_plate_barcode]).exists?
    yield('Destination plate barcode invalid')
  end
end