Skip to content

Commit

Permalink
Merge pull request #170 from sanger/GPL-442-feedback-scanning-plates
Browse files Browse the repository at this point in the history
Gpl 442 feedback scanning plates
  • Loading branch information
KatyTaylor authored Jun 22, 2020
2 parents 1c15b87 + 4539f0e commit d629709
Show file tree
Hide file tree
Showing 16 changed files with 261 additions and 90 deletions.
115 changes: 76 additions & 39 deletions app/controllers/process_plates_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,56 +15,61 @@ def new
end

def create
respond_to do |format|
bed_verification_model = InstrumentProcessesInstrument.get_bed_verification_type(params[:instrument_barcode], params[:instrument_process])

if bed_verification_model.nil?
flash[:error] = 'Invalid instrument or process'
else
bed_layout_verification = bed_verification_model.new(
instrument_barcode: params[:instrument_barcode],
scanned_values: params[:robot],
api: api
)
if bed_layout_verification.validate_and_create_audits?(params)
# the param is called 'source_plates' but we could be working with tube racks or plates etc.
barcodes = sanitize_barcodes(params[:source_plates])

# find out if the 'receive_plates' process was executed
receive_plates_process = InstrumentProcess.find_by(id: params[:instrument_process]).key.eql?('slf_receive_plates')

call_external_services(barcodes) if barcodes && receive_plates_process

# add a flash on the page for the number of unique barcodes scanned in
num_unique_barcodes = bed_layout_verification.process_plate&.num_unique_barcodes
flash[:notice] = if num_unique_barcodes
"Success - #{num_unique_barcodes} unique plate(s) scanned"
else
'Success'
end
else
flash[:error] = bed_layout_verification.errors.values.flatten.join("\n")
end
end
format.html { redirect_to(new_process_plate_path) }
end
bed_verification_model = InstrumentProcessesInstrument.get_bed_verification_type(params[:instrument_barcode], params[:instrument_process])
raise 'Invalid instrument or process' if bed_verification_model.nil?

bed_layout_verification = bed_verification_model.new(
instrument_barcode: params[:instrument_barcode],
scanned_values: params[:robot],
api: api
)
raise format_errors(bed_layout_verification) unless bed_layout_verification.validate_and_create_audits?(params)

back_to_new_with_message('Success') && return unless receive_plates_process?(params)

# here on is relevant to 'receiving plates' only
# the param is called 'source_plates' but we could be working with tube racks or plates etc.
barcodes = sanitize_barcodes(params[:source_plates])
raise 'No barcodes were provided' if barcodes.empty?

responses = call_external_services(barcodes)
@results = generate_results(barcodes, responses)

flash[:notice] = "Scanned #{bed_layout_verification.process_plate&.num_unique_barcodes} barcodes."
render :results
rescue StandardError => e
flash[:error] = e.message
redirect_to(new_process_plate_path)
end

def format_errors(obj)
obj.errors.values.flatten.join("\n")
end

def back_to_new_with_message(message, flash_type = :notice)
flash[flash_type] = message
redirect_to(new_process_plate_path)
end

# find out if the 'receive_plates' process was executed
def receive_plates_process?(params)
@receive_plates_process ||= InstrumentProcess.find_by(id: params[:instrument_process]).key.eql?('slf_receive_plates')
end

# rubocop:todo Lint/UselessAssignment
# Disabling Lint/UselessAssignment here as I know KT and AS are both actively working on
# displaying some of this information to the user. So don't want to create merge issues by removing it.
# Call any external services - currently lighthouse service for plates from Lighthouse Labs and
# wrangler for tube racks. If no samples are found in the lighthouse service, try the wrangler
def call_external_services(barcodes)
output = { lighthouse: [], wrangler: [] }
# call the lighthouse service first as we are assuming that most labware scanned will be
# plates from Lighthouse Labs
lighthouse_responses = Lighthouse.call_api(barcodes)
output[:lighthouse] = Lighthouse.call_api(barcodes)

# keeping it simple for now, if all the responses are not CREATED, send ALL the barcodes
# to the wrangler
wrangler_responses = Wrangler.call_api(barcodes) unless all_created?(lighthouse_responses)
output[:wrangler] = Wrangler.call_api(barcodes) unless all_created?(output[:lighthouse])

output
end
# rubocop:enable Lint/UselessAssignment

# Returns a list of unique barcodes by removing blanks and duplicates
def sanitize_barcodes(barcodes)
Expand All @@ -77,4 +82,36 @@ def all_created?(responses)

responses.all? { |response| response[:code] == '201' }
end

def generate_results(barcodes, responses)
output = {}
# default 'success' for each barcode to 'No'
barcodes.each { |b| output[b] = { success: 'No' } }

# loop through service responses to update 'output' with successes
# puts "DEBUG: responses: #{JSON.pretty_generate(responses)}"
responses[:lighthouse]&.select { |r| r[:code] == '201' }&.each do |r|
output[r[:barcode]] = parse_response(r, :Lighthouse)
end
responses[:wrangler]&.select { |r| r[:code] == '201' }&.each do |r|
output[r[:barcode]] = parse_response(r, :CGaP)
end

output
end

def parse_response(response, service)
{
success: 'Yes',
source: service,
purpose: response.dig(:body, 'data', 'attributes', 'purpose_name'),
study: response.dig(:body, 'data', 'attributes', 'study_names')&.join(', ')
}
end

def all_labware_created?(results)
return false if results.any? { |_barcode, details| details[:success] == 'No' }

true
end
end
2 changes: 1 addition & 1 deletion app/views/admin/instruments/index.html.haml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
%h1 "Manage Instruments"
%h1 Manage Instruments

%table#instruments
%thead
Expand Down
2 changes: 1 addition & 1 deletion app/views/admin/processes/index.html.haml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
%h1 "Manage Processes"
%h1 Manage Processes

%table#processes
%thead
Expand Down
6 changes: 3 additions & 3 deletions app/views/layouts/application.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
<html lang='en'>
<head>
<title><%= ProcessTracking::Application.config.name %></title>
<!-- The following are all unmanaged static assets. skip_pipeline: true Tells raisl to jump straight to public -->
<%= stylesheet_link_tag(:flash,:form,:formtastic_static,:formtastic_changes, skip_pipeline: true ) %>
<%= javascript_include_tag('jquery.min.js','rails.js','application.js', skip_pipeline: true ) %>
<!-- The following are all unmanaged static assets. skip_pipeline: true Tells rails to jump straight to public -->
<%= stylesheet_link_tag(:flash, :form_custom, :formtastic_static, :formtastic_changes, skip_pipeline: true) %>
<%= javascript_include_tag('jquery.min.js','rails.js','application.js', skip_pipeline: true) %>
<%= csrf_meta_tag %>

Expand Down
55 changes: 28 additions & 27 deletions app/views/process_plates/new.html.haml
Original file line number Diff line number Diff line change
@@ -1,42 +1,43 @@
%h2 Activity Logging
%div{:id => "info_box"}

= form_for :process_plate, :url => process_plates_path , :html => {:class => "submit-once"} do |form|
%fieldset
%ul
%li
%label{ :for => "user_barcode" } User barcode
= text_field_tag "user_barcode"
.live_results#user_barcode_results
%fieldset
%ul
%li
%label{ :for => "user_barcode" } User barcode
= text_field_tag "user_barcode"
.live_results#user_barcode_results

%li
%label{ :for => "instrument_barcode" } Instrument barcode
= text_field_tag "instrument_barcode"
.live_results#instrument_barcode_results
%li
%label{ :for => "instrument_barcode" } Instrument barcode
= text_field_tag "instrument_barcode"
.live_results#instrument_barcode_results


%li
%label{ :for => "instrument_process" } Instrument process
%select#instrument_process{ :name => "instrument_process" }
%option{ :value => -1 } Select a process...
- for process_name, process_id in InstrumentProcess.sorted_by_name.map { |x| [x.name, x.id]}
%option{ :value => process_id } #{process_name}
%li
%label{ :for => "instrument_process" } Instrument process
%select#instrument_process{ :name => "instrument_process" }
%option{ :value => -1 } Select a process...
- for process_name, process_id in InstrumentProcess.sorted_by_name.map { |x| [x.name, x.id]}
%option{ :value => process_id } #{process_name}

%li
#source_plates_results
%li
#source_plates_results

%li.hidden#visual_check_input
%label{ :for => "visual_check"} Visual check performed
= check_box_tag "visual_check"
%li.hidden#visual_check_input
%label{ :for => "visual_check"} Visual check performed
= check_box_tag "visual_check"

%li.hidden#witness_barcode_input
%label{ :for => "witness_barcode"} Witness barcode
= text_field_tag "witness_barcode"
%li.hidden#witness_barcode_input
%label{ :for => "witness_barcode"} Witness barcode
= text_field_tag "witness_barcode"

%li
%input{ :id => "btnSubmit", :type => "submit", :value => 'Submit' }
%li
%input{ :id => "btnSubmit", :type => "submit", :value => 'Submit' }

- content_for :page_javascript do
:javascript
:javascript

(function($) {

Expand Down
27 changes: 27 additions & 0 deletions app/views/process_plates/results.html.haml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
%h2 Activity Logging
%h3 Labware import results

%table
%thead
%tr
%th Barcode
%th Imported?
%th Source
%th Purpose
%th Study
%tbody
- @results.each do |barcode, details|
%tr
%td
= barcode
%td
= details[:success]
%td
= details[:source]
%td
= details[:purpose]
%td
= details[:study]

%br
= link_to 'Scan more labware', new_process_plate_path
2 changes: 1 addition & 1 deletion config.ru
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
# This file is used by Rack-based servers to start the application.

require ::File.expand_path('../config/environment', __FILE__)
run ProcessTracking::Application
run Rails.application
2 changes: 1 addition & 1 deletion config/environments/development.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
config.admin_email = '[email protected]'

# https://github.com/sanger/wrangler
config.wrangler_url = 'http://127.0.0.1:5001/tube_rack'
config.wrangler_url = 'http://127.0.0.1:5000/wrangle'

# https://github.com/sanger/lighthouse
config.lighthouse_host = 'http://127.0.0.1:5000'
Expand Down
2 changes: 1 addition & 1 deletion config/environments/test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
config.admin_email = '[email protected]'

# https://github.com/sanger/wrangler
config.wrangler_url = 'http://example.com/tube_rack'
config.wrangler_url = 'http://example.com/wrangle'

# https://github.com/sanger/lighthouse
config.lighthouse_host = 'http://127.0.0.1:5000'
Expand Down
9 changes: 8 additions & 1 deletion lib/lighthouse.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def self.call_api(barcodes)
http.request(req)
end

responses << { code: res.code, body: res.body }
responses << { barcode: barcode, code: res.code, body: Lighthouse.parse_body(res.body) }
end
rescue StandardError => e
Rails.logger.error(e)
Expand All @@ -30,4 +30,11 @@ def self.call_api(barcodes)
end
responses
end

def self.parse_body(body)
JSON.parse(body)
rescue StandardError
# return the body as is if not valid JSON
body
end
end
11 changes: 10 additions & 1 deletion lib/wrangler.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# frozen_string_literal: true

require 'json'

class Wrangler
require 'net/http'

Expand All @@ -18,7 +20,7 @@ def self.call_api(barcodes)
http.request(req)
end

responses << { barcode: barcode, code: res.code }
responses << { barcode: barcode, code: res.code, body: Wrangler.parse_body(res.body) }
end
rescue StandardError => e
Rails.logger.error(e)
Expand All @@ -29,4 +31,11 @@ def self.call_api(barcodes)
end
responses
end

def self.parse_body(body)
JSON.parse(body)
rescue StandardError
# return the body as is if not valid JSON
body
end
end
10 changes: 10 additions & 0 deletions public/stylesheets/form.css → public/stylesheets/form_custom.css
Original file line number Diff line number Diff line change
Expand Up @@ -62,5 +62,15 @@ li#beds_and_plates ul{
padding: 0px;
}

table, td, th {
border: 1px solid #ddd;
text-align: left;
}

table {
border-collapse: collapse;
}

th, td {
padding: 15px;
}
Loading

0 comments on commit d629709

Please sign in to comment.