From 6720be955a2d8cf0ab67004bef1127196cc38602 Mon Sep 17 00:00:00 2001 From: James Glover Date: Thu, 14 Feb 2019 10:05:56 +0000 Subject: [PATCH] Quick switch to Print My Barcode This is hopefully the final release of Generic Lims, made a few days after we thought we could kill it. The replacement pipleine in LImber is almost complete, which should render this redundant. --- app/controllers/barcode_labels_controller.rb | 57 ++++++------- app/models/illumina_c/final_plate.rb | 6 ++ .../illumina_c/multiplexed_library_tube.rb | 6 ++ app/models/illumina_c/plate.rb | 7 ++ app/models/illumina_c/stock_library_tube.rb | 6 ++ ..._individual_barcode_printing_form.html.erb | 5 +- .../_multiple_barcodes_printing_form.html.erb | 4 +- app/views/plates/_plate_printing.html.erb | 3 +- app/views/tubes/show.html.erb | 1 + config/environments/development.rb | 7 +- lib/pmb_wrapper.rb | 85 +++++++++++++++++++ 11 files changed, 154 insertions(+), 33 deletions(-) create mode 100644 lib/pmb_wrapper.rb diff --git a/app/controllers/barcode_labels_controller.rb b/app/controllers/barcode_labels_controller.rb index db67e62..62e098f 100644 --- a/app/controllers/barcode_labels_controller.rb +++ b/app/controllers/barcode_labels_controller.rb @@ -1,41 +1,40 @@ +require './lib/pmb_wrapper' + class BarcodeLabelsController < ApplicationController before_filter :initialize_printer_and_barcode_service + # Handles printing a single label + def individual + if print([params[:label]]) + redirect_to(params[:redirect_to], :notice => "Barcode printed to #{@printer.name}") + else + redirect_to(params[:redirect_to], :error => "Barcode failed to print to #{@printer.name}") + end + end + + # Handles printing multiple labels + def multiple + if print(params[:labels].values) + redirect_to(params[:redirect_to], :notice => "#{params[:labels].size} barcodes printed to #{@printer.try(:name)}") + else + redirect_to(params[:redirect_to], :error => "Barcodes failed to print to #{@printer.name}") + end + end + + private + def initialize_printer_and_barcode_service raise StandardError, "No printer specified!" if params[:printer].blank? - @printer = api.barcode_printer.find(params[:printer]) - @service = Sanger::Barcode::Printing::Service.new(@printer.service.url) @copies = params[:number].to_i end - private :initialize_printer_and_barcode_service - - # Creates a label - def create_label(details) - Sanger::Barcode::Printing::Label.new(details) - end - private :create_label # Does the actual printing of the labels passed def print(labels) - @service.print_labels(Array(labels)*@copies, @printer.name, @printer.type.layout) - end - private :print - - # Handles printing a single label - def individual - print(create_label(params[:label])) - redirect_to(params[:redirect_to], :notice => "Barcode printed to #{@printer.name}") - end - - before_filter :convert_labels_to_array, :only => :multiple - def convert_labels_to_array - params[:labels] = params.fetch(:labels, []).map { |_, v| v } - end - private :convert_labels_to_array - - # Handles printing multiple labels - def multiple - print(params[:labels].map(&method(:create_label))) - redirect_to(params[:redirect_to], :notice => "#{params[:labels].size} barcodes printed to #{@printer.try(:name)}") + PmbWrapper.new( + IlluminaCPipeline::Application.config.pmb_url, + @printer.name, + @printer.type.layout, + labels*@copies + ).print_label end end diff --git a/app/models/illumina_c/final_plate.rb b/app/models/illumina_c/final_plate.rb index d1648ce..3eb2175 100644 --- a/app/models/illumina_c/final_plate.rb +++ b/app/models/illumina_c/final_plate.rb @@ -61,4 +61,10 @@ def tubes_and_sources end end + attribute_group :barcode do + attribute_accessor :prefix, :number # The pieces that make up a barcode + attribute_accessor :ean13 # The EAN13 barcode number + attribute_accessor :machine # Barcode suitable for code39 + attribute_accessor :type # Frustratingly obtuse indicator of label type (1 = plate, 2= tube) + end end diff --git a/app/models/illumina_c/multiplexed_library_tube.rb b/app/models/illumina_c/multiplexed_library_tube.rb index 2281519..ad19f0e 100644 --- a/app/models/illumina_c/multiplexed_library_tube.rb +++ b/app/models/illumina_c/multiplexed_library_tube.rb @@ -7,4 +7,10 @@ def location 'A1' end + attribute_group :barcode do + attribute_accessor :prefix, :number # The pieces that make up a barcode + attribute_accessor :ean13 # The EAN13 barcode number + attribute_accessor :machine # Barcode suitable for code39 + attribute_accessor :type # Frustratingly obtuse indicator of label type (1 = plate, 2= tube) + end end diff --git a/app/models/illumina_c/plate.rb b/app/models/illumina_c/plate.rb index ff3f9a2..44f2248 100644 --- a/app/models/illumina_c/plate.rb +++ b/app/models/illumina_c/plate.rb @@ -13,6 +13,13 @@ def coerce 'ILC Lib Chromium' ] + attribute_group :barcode do + attribute_accessor :prefix, :number # The pieces that make up a barcode + attribute_accessor :ean13 # The EAN13 barcode number + attribute_accessor :machine # Barcode suitable for code39 + attribute_accessor :type # Frustratingly obtuse indicator of label type (1 = plate, 2= tube) + end + def is_a_final_pooling_plate? FINAL_POOLING_PLATE_PURPOSES.include?(plate_purpose.name) end diff --git a/app/models/illumina_c/stock_library_tube.rb b/app/models/illumina_c/stock_library_tube.rb index 5fb85ee..3e04ae6 100644 --- a/app/models/illumina_c/stock_library_tube.rb +++ b/app/models/illumina_c/stock_library_tube.rb @@ -4,4 +4,10 @@ def can_be_passed? ["pending", "started"].include? state end + attribute_group :barcode do + attribute_accessor :prefix, :number # The pieces that make up a barcode + attribute_accessor :ean13 # The EAN13 barcode number + attribute_accessor :machine # Barcode suitable for code39 + attribute_accessor :type # Frustratingly obtuse indicator of label type (1 = plate, 2= tube) + end end diff --git a/app/views/labware/_individual_barcode_printing_form.html.erb b/app/views/labware/_individual_barcode_printing_form.html.erb index 09580ce..9c728ca 100644 --- a/app/views/labware/_individual_barcode_printing_form.html.erb +++ b/app/views/labware/_individual_barcode_printing_form.html.erb @@ -7,7 +7,10 @@ <% end %> <%= f.hidden_field :prefix %> <%= f.hidden_field :number %> - <%= f.hidden_field :study, :value => text %> + <%= f.hidden_field :machine %> + <%= f.hidden_field :ean13 %> + <%= f.hidden_field :stock_barcode, :value => stock_barcode %> + <%= f.hidden_field :text, :value => text %>
  • <%= label_tag :printer, 'Barcode Printer:' %> diff --git a/app/views/labware/_multiple_barcodes_printing_form.html.erb b/app/views/labware/_multiple_barcodes_printing_form.html.erb index 1c0c6d2..2d7262c 100644 --- a/app/views/labware/_multiple_barcodes_printing_form.html.erb +++ b/app/views/labware/_multiple_barcodes_printing_form.html.erb @@ -6,7 +6,9 @@ <%= f.fields_for(index.to_s.to_sym, barcode) do |barcode_form| %> <%= barcode_form.hidden_field(:prefix) %> <%= barcode_form.hidden_field(:number) %> - <%= barcode_form.hidden_field(:study, :value => text[index]) %> + <%= barcode_form.hidden_field(:machine) %> + <%= barcode_form.hidden_field(:ean13) %> + <%= barcode_form.hidden_field(:text, :value => text[index]) %> <% end %> <% end %> diff --git a/app/views/plates/_plate_printing.html.erb b/app/views/plates/_plate_printing.html.erb index 52b22f3..6bb1a0a 100644 --- a/app/views/plates/_plate_printing.html.erb +++ b/app/views/plates/_plate_printing.html.erb @@ -3,7 +3,8 @@ <%= individual_barcode_printing_form( @presenter.labware.barcode, :redirection_url => illumina_c_plate_path(@presenter.labware), - :text => "#{@presenter.label_text} #{@presenter.labware.stock_plate.try(:barcode).try(:number)}" + :stock_barcode => "#{@presenter.labware.stock_plate.try(:barcode).try(:prefix)}#{@presenter.labware.stock_plate.try(:barcode).try(:number)}", + :text => "#{@presenter.label_text}" ) %> <% end %> diff --git a/app/views/tubes/show.html.erb b/app/views/tubes/show.html.erb index 77b25c0..100747a 100644 --- a/app/views/tubes/show.html.erb +++ b/app/views/tubes/show.html.erb @@ -57,6 +57,7 @@ <%= individual_barcode_printing_form( @presenter.labware.barcode, :redirection_url => illumina_c_tube_path(@presenter.labware), + :stock_barcode => '', :text => @presenter.label_text ) %> diff --git a/config/environments/development.rb b/config/environments/development.rb index dbc5ffe..10936f4 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -31,7 +31,6 @@ config.details_root = ENV.fetch('DETAILS_ROOT','http://localhost:3000/uuids/') config.summary_root = ENV.fetch('SUMMARY_ROOT','http://localhost:3000/plate_summaries/') - # Email settings... config.action_mailer.raise_delivery_errors = true config.action_mailer.perform_deliveries = false @@ -55,5 +54,11 @@ } } + config.barcode_type_label_id = { + 1 => '198', + 2 => '86' + } + + config.pmb_url = ENV.fetch('PMB_URL','http://localhost:3002') end diff --git a/lib/pmb_wrapper.rb b/lib/pmb_wrapper.rb new file mode 100644 index 0000000..6962323 --- /dev/null +++ b/lib/pmb_wrapper.rb @@ -0,0 +1,85 @@ +require 'net/http' + +# Quick and dirty PMB wrapper. +# - We are retiring Generic Lims ASAP (stories for replacement in progress) +# - The existing client requires rails 3.2 +# - This forces us into a constant stream of gem updates. +# - Test coverage is lacking +class PmbWrapper + def initialize(url, printer, layout, labels) + @uri = URI(url) + @layout = layout + @printer = printer + @labels = labels + end + + def print_label + req = Net::HTTP::Post.new(@uri.to_s) + req.content_type = 'application/vnd.api+json' + req.body = payload + res = Net::HTTP.start(@uri.hostname, @uri.port) do |http| + http.request(req) + end + res.code == '201' + rescue Errno::ECONNREFUSED + false + end + + private + + def label_id + IlluminaCPipeline::Application.config.barcode_type_label_id.fetch(@layout) + end + + def plate_label(label) + { + main_label: { + top_left: date, + bottom_left: label[:machine], + top_right: label[:stock_barcode], + bottom_right: label[:text], + barcode: label[:machine] || label[:ean13] + } + } + end + + def tube_label(label) + { + main_label: { + top_line: label[:text], + bottom_line: date, + round_label_top_line: label[:prefix], + round_label_bottom_line: label[:number], + barcode: label[:ean13] + } + } + end + + def convert_label(label) + case @layout + when 1 then plate_label(label) + when 2 then tube_label(label) + else + raise StandardError, "Unknown printer layout #{@layout}" + end + end + + def payload + { + data: { + type: 'print_jobs', + attributes: { + printer_name: @printer, + label_template_id: label_id, + labels: { + body: @labels.map { |label| convert_label(label) } + } + } + } + }.to_json + end + + def date + Time.zone.today.strftime('%d-%b-%Y') + end +end