Skip to content

Commit

Permalink
Merge pull request #1595 from sanger/DPL-1054-Add-Vac-tube-barcode-to…
Browse files Browse the repository at this point in the history
…-the-Aliquot-tube-labels

DPL-1054 Add Vac tube barcode to the Aliquot tube labels
  • Loading branch information
KatyTaylor authored Mar 1, 2024
2 parents 62aa86c + aca4a9b commit ff6ce6c
Show file tree
Hide file tree
Showing 7 changed files with 112 additions and 89 deletions.
17 changes: 1 addition & 16 deletions app/sequencescape/sequencescape/api/v2/plate.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ class Sequencescape::Api::V2::Plate < Sequencescape::Api::V2::Base
include Sequencescape::Api::V2::Shared::HasRequests
include Sequencescape::Api::V2::Shared::HasPurpose
include Sequencescape::Api::V2::Shared::HasBarcode
include Sequencescape::Api::V2::Shared::HasWorklineIdentifier

self.plate = true
has_many :wells
Expand Down Expand Up @@ -97,22 +98,6 @@ def stock_plate
stock_plates.order(id: :asc).last
end

def workline_identifier
workline_reference&.barcode&.human
end

# This is the plate that will act as a reference in my workflow that will be
# printed in the label at the top_right field. It is the first stock by default,
# but in some cases we may want to display a different plate. To change the default
# selection from stock plate to other plate purpose, we have to modify the purposes.yml
# config file and add a workline_reference_identifier attribute with the purpose we want to select.
def workline_reference
alternative_workline_identifier_purpose = SearchHelper.alternative_workline_reference_name(self)
return stock_plate if alternative_workline_identifier_purpose.nil?

ancestors.where(purpose_name: alternative_workline_identifier_purpose).last
end

def stock_plate?(purpose_names: SearchHelper.stock_plate_names)
purpose_names.include?(purpose_name)
end
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# frozen_string_literal: true

# This was refactored as a concern so that it could be included in the Tube model (as well as Plae),
# because one tube used a plate label and needed to use the alternative_workline_identifier config option.
module Sequencescape::Api::V2::Shared
# Include in API endpoints that have barcodes to add a few standard methods
module HasWorklineIdentifier
extend ActiveSupport::Concern

# Finds a relevant related labware in order to include its barode on the barcode label.
# Existing use at time of writing is in the top right part of plate labels.
# In future it could also be included on tube labels if needed.
# Uses alternative_workline_identifier from the purpose config if present, otherwise uses the stock plate.
def workline_reference
alternative_workline_identifier_purpose = SearchHelper.alternative_workline_reference_name(self)
return stock_plate if alternative_workline_identifier_purpose.nil?

ancestors.where(purpose_name: alternative_workline_identifier_purpose).last
end

def workline_identifier
workline_reference&.barcode&.human
end
end
end
5 changes: 1 addition & 4 deletions app/sequencescape/sequencescape/api/v2/tube.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ class Sequencescape::Api::V2::Tube < Sequencescape::Api::V2::Base
include Sequencescape::Api::V2::Shared::HasRequests
include Sequencescape::Api::V2::Shared::HasPurpose
include Sequencescape::Api::V2::Shared::HasBarcode
include Sequencescape::Api::V2::Shared::HasWorklineIdentifier

DEFAULT_INCLUDES = [:purpose, 'aliquots.request.request_type'].freeze

Expand Down Expand Up @@ -66,8 +67,4 @@ def stock_plate(purpose_names: SearchHelper.stock_plate_names)
# max_by naturally sorts in ascending order
@stock_plate ||= ancestors.where(purpose_name: purpose_names).max_by(&:id)
end

def workline_identifier
stock_plate&.barcode&.human
end
end
1 change: 1 addition & 0 deletions config/purposes/scrna_core_cell_extraction.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ LRC Blood Aliquot:
:presenter_class: Presenters::SimpleTubePresenter
:creator_class: LabwareCreators::TubeFromTube
:label_template: plate_a # uses a plate printer because it's a 'falcon tube'
:alternative_workline_identifier: LRC Blood Vac
###
# scRNA Core Cell Extraction Blood Pipeline
###
Expand Down
72 changes: 3 additions & 69 deletions spec/sequencescape/api/v2/plate_spec.rb
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
# frozen_string_literal: true

require 'rails_helper'
require_relative 'shared_examples'

RSpec.describe Sequencescape::Api::V2::Plate do
subject(:plate) { create :v2_plate, barcode_number: 12_345 }
let(:the_labware) { plate }

it { is_expected.to be_plate }
it { is_expected.to_not be_tube }
Expand Down Expand Up @@ -57,75 +59,7 @@
end
end

describe '#workline_identifier' do
it 'displays the barcode of the workline_reference element' do
plate2 = create :v2_plate
allow(plate).to receive(:workline_reference).and_return(plate2)
expect(plate.workline_identifier).to eq(plate2.barcode.human)
end
it 'does not break if there is no workline reference' do
allow(plate).to receive(:workline_reference).and_return(nil)
expect(plate.workline_identifier).to eq(nil)
end
end

describe '#workline_reference' do
let(:stock_plate_names) { ['Stock stuff', 'Some other stock stuff'] }
let(:ancestors_scope) { double('ancestors_scope') }
before do
allow(plate).to receive(:ancestors).and_return(ancestors_scope)
allow(plate).to receive(:stock_plate).and_return(stock_plate)
allow(SearchHelper).to receive(:stock_plate_names).and_return(stock_plate_names)
allow(ancestors_scope).to receive(:where).with(purpose_name: stock_plate_names).and_return(stock_plates)
end

context 'when the plate has no stock plates' do
let(:stock_plates) { [] }
let(:stock_plate) { nil }
it 'returns nil' do
expect(plate.workline_reference).to be_nil
end
end
context 'when the plate has one stock plate' do
let(:stock_plates) { create_list :v2_plate, 1 }
let(:stock_plate) { stock_plates.last }
it 'returns the stock plate' do
expect(plate.workline_reference).to eq(stock_plates.last)
end
end
context 'when the plate has more than one stock plate' do
let(:stock_plates) { create_list :v2_plate, 2 }
let(:stock_plate) { stock_plates.last }

context 'when there are no alternative workline purpose references' do
before do
allow(SearchHelper).to receive(:alternative_workline_reference_name).with(plate).and_return(nil)
allow(ancestors_scope).to receive(:where).with(purpose_name: []).and_return([])
end
it 'returns the last stock plate' do
expect(plate.workline_reference).to eq(stock_plates.last)
end
end

context 'when there is a list of alternative workline purpose references' do
let(:alternative_workline_reference_plates) { create_list :v2_plate, 2 }
let(:alternative_workline_name) { 'Some other plate with some stuff inside' }

before do
allow(SearchHelper).to receive(:alternative_workline_reference_name)
.with(plate)
.and_return(alternative_workline_name)
allow(ancestors_scope).to receive(:where)
.with(purpose_name: alternative_workline_name)
.and_return(alternative_workline_reference_plates)
end

it 'returns the last alternative workline reference' do
expect(plate.workline_reference).to eq(alternative_workline_reference_plates.last)
end
end
end
end
it_behaves_like 'a labware with a workline identifier'

describe '#human_barcode' do
it 'returns the human readable barcode' do
Expand Down
77 changes: 77 additions & 0 deletions spec/sequencescape/api/v2/shared_examples.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# frozen_string_literal: true
RSpec.shared_examples 'a labware with a workline identifier' do
describe '#workline_identifier' do
it 'displays the barcode of the workline_reference element' do
plate2 = create :v2_plate
allow(the_labware).to receive(:workline_reference).and_return(plate2)
expect(the_labware.workline_identifier).to eq(plate2.barcode.human)
end

it 'does not break if there is no workline reference' do
allow(the_labware).to receive(:workline_reference).and_return(nil)
expect(the_labware.workline_identifier).to eq(nil)
end
end

describe '#workline_reference' do
let(:stock_plate_names) { ['Stock stuff', 'Some other stock stuff'] }
let(:ancestors_scope) { double('ancestors_scope') }

before do
allow(the_labware).to receive(:ancestors).and_return(ancestors_scope)
allow(the_labware).to receive(:stock_plate).and_return(stock_plate)
allow(SearchHelper).to receive(:stock_plate_names).and_return(stock_plate_names)
allow(ancestors_scope).to receive(:where).with(purpose_name: stock_plate_names).and_return(stock_plates)
end

context 'when the plate has no stock plates' do
let(:stock_plates) { [] }
let(:stock_plate) { nil }
it 'returns nil' do
expect(the_labware.workline_reference).to be_nil
end
end

context 'when the plate has one stock plate' do
let(:stock_plates) { create_list :v2_plate, 1 }
let(:stock_plate) { stock_plates.last }
it 'returns the stock plate' do
expect(the_labware.workline_reference).to eq(stock_plates.last)
end
end

context 'when the plate has more than one stock plate' do
let(:stock_plates) { create_list :v2_plate, 2 }
let(:stock_plate) { stock_plates.last }

context 'when there are no alternative workline purpose references' do
before do
allow(SearchHelper).to receive(:alternative_workline_reference_name).with(the_labware).and_return(nil)
allow(ancestors_scope).to receive(:where).with(purpose_name: []).and_return([])
end

it 'returns the last stock plate' do
expect(the_labware.workline_reference).to eq(stock_plates.last)
end
end

context 'when there is a list of alternative workline purpose references' do
let(:alternative_workline_reference_plates) { create_list :v2_plate, 2 }
let(:alternative_workline_name) { 'Some other plate with some stuff inside' }

before do
allow(SearchHelper).to receive(:alternative_workline_reference_name)
.with(the_labware)
.and_return(alternative_workline_name)
allow(ancestors_scope).to receive(:where)
.with(purpose_name: alternative_workline_name)
.and_return(alternative_workline_reference_plates)
end

it 'returns the last alternative workline reference' do
expect(the_labware.workline_reference).to eq(alternative_workline_reference_plates.last)
end
end
end
end
end
4 changes: 4 additions & 0 deletions spec/sequencescape/api/v2/tube_spec.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# frozen_string_literal: true

require 'rails_helper'
require_relative 'shared_examples'

class SomeStockPlates
def initialize(stock_plates)
Expand All @@ -14,6 +15,7 @@ def where(_arg)

RSpec.describe Sequencescape::Api::V2::Tube do
subject(:tube) { create :v2_tube, barcode_number: 12_345 }
let(:the_labware) { tube }

it { is_expected.to_not be_plate }
it { is_expected.to be_tube }
Expand All @@ -30,4 +32,6 @@ def where(_arg)
expect(tube_with_ancestors.stock_plate).to eq(stock_plates.last)
end
end

it_behaves_like 'a labware with a workline identifier'
end

0 comments on commit ff6ce6c

Please sign in to comment.