diff --git a/app/controllers/process_plates_controller.rb b/app/controllers/process_plates_controller.rb
index d090ea3d..811faa30 100644
--- a/app/controllers/process_plates_controller.rb
+++ b/app/controllers/process_plates_controller.rb
@@ -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)
@@ -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
diff --git a/app/views/admin/instruments/index.html.haml b/app/views/admin/instruments/index.html.haml
index 2871583f..4936ae14 100644
--- a/app/views/admin/instruments/index.html.haml
+++ b/app/views/admin/instruments/index.html.haml
@@ -1,4 +1,4 @@
-%h1 "Manage Instruments"
+%h1 Manage Instruments
%table#instruments
%thead
diff --git a/app/views/admin/processes/index.html.haml b/app/views/admin/processes/index.html.haml
index 9f6e3812..39560d41 100644
--- a/app/views/admin/processes/index.html.haml
+++ b/app/views/admin/processes/index.html.haml
@@ -1,4 +1,4 @@
-%h1 "Manage Processes"
+%h1 Manage Processes
%table#processes
%thead
diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb
index 62a5c437..e27974e7 100644
--- a/app/views/layouts/application.html.erb
+++ b/app/views/layouts/application.html.erb
@@ -2,9 +2,9 @@
<%= ProcessTracking::Application.config.name %>
-
- <%= 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 ) %>
+
+ <%= 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 %>
diff --git a/app/views/process_plates/new.html.haml b/app/views/process_plates/new.html.haml
index e438fa74..5c110530 100644
--- a/app/views/process_plates/new.html.haml
+++ b/app/views/process_plates/new.html.haml
@@ -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($) {
diff --git a/app/views/process_plates/results.html.haml b/app/views/process_plates/results.html.haml
new file mode 100644
index 00000000..089b313b
--- /dev/null
+++ b/app/views/process_plates/results.html.haml
@@ -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
\ No newline at end of file
diff --git a/config.ru b/config.ru
index 93277a0e..3476455e 100644
--- a/config.ru
+++ b/config.ru
@@ -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
diff --git a/config/environments/development.rb b/config/environments/development.rb
index 2b4720e7..f2946219 100644
--- a/config/environments/development.rb
+++ b/config/environments/development.rb
@@ -47,7 +47,7 @@
config.admin_email = 'example@example.com'
# 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'
diff --git a/config/environments/test.rb b/config/environments/test.rb
index 0cee720f..a4243fe2 100644
--- a/config/environments/test.rb
+++ b/config/environments/test.rb
@@ -45,7 +45,7 @@
config.admin_email = 'example@example.com'
# 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'
diff --git a/lib/lighthouse.rb b/lib/lighthouse.rb
index 69842740..cda71078 100644
--- a/lib/lighthouse.rb
+++ b/lib/lighthouse.rb
@@ -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)
@@ -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
diff --git a/lib/wrangler.rb b/lib/wrangler.rb
index d813060e..62359aa2 100644
--- a/lib/wrangler.rb
+++ b/lib/wrangler.rb
@@ -1,5 +1,7 @@
# frozen_string_literal: true
+require 'json'
+
class Wrangler
require 'net/http'
@@ -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)
@@ -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
diff --git a/public/stylesheets/form.css b/public/stylesheets/form_custom.css
similarity index 85%
rename from public/stylesheets/form.css
rename to public/stylesheets/form_custom.css
index d2a54b8f..c126266b 100644
--- a/public/stylesheets/form.css
+++ b/public/stylesheets/form_custom.css
@@ -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;
+}
diff --git a/test/controllers/process_plates_controller.rb b/test/controllers/process_plates_controller.rb
index 26e81fbf..fcbfbd1d 100644
--- a/test/controllers/process_plates_controller.rb
+++ b/test/controllers/process_plates_controller.rb
@@ -37,4 +37,57 @@ class ProcessPlatesControllerTest < ActiveSupport::TestCase
ProcessPlatesController.new.call_external_services(%w[123 456])
end
end
+
+ context '#generate_results' do
+ should 'give failed results if no response' do
+ barcodes = ['AB1']
+
+ responses = { lighthouse: [], wrangler: [] }
+
+ expected_results = { 'AB1' => { success: 'No' } }
+
+ results = ProcessPlatesController.new.generate_results(barcodes, responses)
+ assert_equal(expected_results, results)
+ end
+
+ should 'give detailed results if success' do
+ barcodes = %w[AB1 AB2 AB3]
+
+ responses = {
+ lighthouse: [
+ generate_success_response('AB1', 'Purpose 1', ['Study 1', 'Study 2']),
+ generate_success_response('AB2', 'Purpose 1', ['Study 1']),
+ generate_fail_response('AB3')
+ ],
+ wrangler: [
+ generate_fail_response('AB1'),
+ generate_fail_response('AB2'),
+ generate_success_response('AB3', 'Purpose 1', ['Study 1', 'Study 2'])
+ ]
+ }
+
+ expected_results = {
+ 'AB1' => {
+ success: 'Yes',
+ source: :Lighthouse,
+ purpose: 'Purpose 1',
+ study: 'Study 1, Study 2'
+ },
+ 'AB2' => {
+ success: 'Yes',
+ source: :Lighthouse,
+ purpose: 'Purpose 1',
+ study: 'Study 1'
+ },
+ 'AB3' => {
+ success: 'Yes',
+ source: :CGaP,
+ purpose: 'Purpose 1',
+ study: 'Study 1, Study 2'
+ }
+ }
+ results = ProcessPlatesController.new.generate_results(barcodes, responses)
+ assert_equal(expected_results, results)
+ end
+ end
end
diff --git a/test/test_helper.rb b/test/test_helper.rb
index e832f6f0..3324bdf7 100644
--- a/test/test_helper.rb
+++ b/test/test_helper.rb
@@ -15,4 +15,31 @@ class ActiveSupport::TestCase
# Add more helper methods to be used by all tests here...
include RSpec::Matchers
+
+ def generate_success_response(barcode, purpose_name, study_names)
+ {
+ barcode: barcode,
+ code: '201',
+ body: {
+ 'data' => {
+ 'attributes' => {
+ 'purpose_name' => purpose_name,
+ 'study_names' => study_names
+ }
+ }
+ }
+ }
+ end
+
+ def generate_fail_response(barcode)
+ {
+ barcode: barcode,
+ code: '400',
+ body: {
+ 'errors': [
+ 'No samples for this barcode'
+ ]
+ }
+ }
+ end
end
diff --git a/test/unit/lighthouse_test.rb b/test/unit/lighthouse_test.rb
index d4fc638e..12247fab 100644
--- a/test/unit/lighthouse_test.rb
+++ b/test/unit/lighthouse_test.rb
@@ -30,8 +30,8 @@ class LighthouseTest < ActiveSupport::TestCase
stub_request(:any, uri_template).to_return(status: 201)
assert_equal(
- Lighthouse.call_api([@input_params[:source_plates]]),
- [{ code: '201', body: '' }]
+ [{ barcode: 'barcode_one', code: '201', body: '' }],
+ Lighthouse.call_api([@input_params[:source_plates]])
)
end
@@ -45,12 +45,12 @@ class LighthouseTest < ActiveSupport::TestCase
stub_request(:any, uri_template).to_return(status: 201)
assert_equal(
- Lighthouse.call_api(barcodes),
[
- { code: '201', body: '' },
- { code: '201', body: '' },
- { code: '201', body: '' }
- ]
+ { barcode: 'barcode_one', code: '201', body: '' },
+ { barcode: 'barcode_two', code: '201', body: '' },
+ { barcode: 'barcode_three', code: '201', body: '' }
+ ],
+ Lighthouse.call_api(barcodes)
)
end
end
diff --git a/test/unit/wrangler_test.rb b/test/unit/wrangler_test.rb
index 24a377ba..0a5f487f 100644
--- a/test/unit/wrangler_test.rb
+++ b/test/unit/wrangler_test.rb
@@ -31,8 +31,8 @@ class WranglerTest < ActiveSupport::TestCase
stub_request(:any, uri_template).to_return(status: 200)
assert_equal(
- Wrangler.call_api([@input_params[:source_plates]]),
- [{ barcode: @barcode, code: '200' }]
+ [{ barcode: @barcode, code: '200', body: '' }],
+ Wrangler.call_api([@input_params[:source_plates]])
)
end
@@ -46,12 +46,12 @@ class WranglerTest < ActiveSupport::TestCase
stub_request(:any, uri_template).to_return(status: 200)
assert_equal(
- Wrangler.call_api(barcodes),
[
- { barcode: 'barcode_one', code: '200' },
- { barcode: 'barcode_two', code: '200' },
- { barcode: 'barcode_three', code: '200' }
- ]
+ { barcode: 'barcode_one', code: '200', body: '' },
+ { barcode: 'barcode_two', code: '200', body: '' },
+ { barcode: 'barcode_three', code: '200', body: '' }
+ ],
+ Wrangler.call_api(barcodes)
)
end
end