Skip to content

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also .

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also .
...
  • 10 commits
  • 18 files changed
  • 0 commit comments
  • 1 contributor
View
71 doc/plate-view-profiles.txt
@@ -0,0 +1,71 @@
+
+We want to do something like:
+
+GET /ui/view_plate/CREBACP1?profile=cre_bac_recom
+
+my $data = $c->model('Golgi')->retrieve_plate( plate_name => 'CREBACP1', profile => 'cre_bac_recom' )
+
+The retrieve_plate() method should accept either a plate name or a
+plate id.
+
+The profile controls which data are returned for the plate and for
+each well. This implies some sort of class hierarchy so that common
+data are handled by the superclass, and the subclass pulls in extra
+data for a given profile. It might also be desirable to implement a
+number of roles to provide shared functionality across profiles. For
+example, Sequencing QC will be required by many profiles, but should
+not be in the default profile (handled by the superclass).
+
+If we follow the pattern of all LIMS2::Model methods returning an
+object that implements the LIMS2::Model::Entity role, $data has to be
+some object that implements an as_hash() method. Then the next row in
+the Catalyst controller will do:
+
+$c->stash( data => $data->as_hash );
+
+It might be an idea to add an optional 'linkify' role to the
+LIMS2::Model::Entity. This would descend into the data and
+automatically linkify items that refer to other LIMS2 entities. The
+linkify method would have to be passed a Catalyst object so it can
+call uri_for().
+
+Maybe LIMS2::Model::Entity should implement both as_hash() and
+as_linkified_hash(). It might be an idea to move the recursive hash
+construction out of LIMS2::Catalyst::Controller::REST into the entity
+role.
+
+Should we add the LIMS2::Model::Entity role to
+LIMS2::Model::Schema::Result classes at run-time?
+
+Should we create LIMS2::Model::Entity::Foo classes as subclasses of
+LIMS2::Model::Schema::Result::Foo ?
+
+Should we introduce LIMS2::Model::Entity::ARRAY and LIMS2::Model::Entity::HASH ?
+
+The idea here is that all model methods will return something that isa
+LIMS2::Model::Entity, hence has as_hash() and as_linkified_hash() methods.
+
+Should we put the paths for actions in a config file?
+
+Ideally, we'd have a common template for all plate profiles. This
+implies that we carry around some sort of metadata with each profile,
+e.g. so the template can determine column headers for the grid. The
+metadata could also control which columns are linkified.
+
+The profile class hierarchy might look something like:
+
+LIMS2::Model::Profile::Plate
+
+ - data common to all plate types
+
+LIMS2::Model::Profile::Plate::CreBacRecom
+
+ - data for Cre BAC recombineering plates
+
+LIMS2::Model::Profile::Design
+
+ - default view for designs
+
+LIMS2::Model::Profile::Design::CreBac
+
+ - extra data for Cre BAC designs
View
21 packages/LIMS2-Model/lib/LIMS2/Model/Constants.pm
@@ -0,0 +1,21 @@
+package LIMS2::Model::Constants;
+
+use strict;
+use warnings FATAL => 'all';
+
+use base 'Exporter';
+
+use Const::Fast;
+
+BEGIN {
+ our @EXPORT = ();
+ our @EXPORT_OK = qw( $DEFAULT_ASSEMBLY );
+ our %EXPORT_TAGS = ();
+}
+
+const our $DEFAULT_ASSEMBLY => 'NCBIM37';
+
+1;
+
+__END__
+
View
13 packages/LIMS2-Model/lib/LIMS2/Model/Entity.pm
@@ -1,13 +0,0 @@
-package LIMS2::Model::Entity;
-
-use strict;
-use warnings FATAL => 'all';
-
-use Moose::Role;
-use namespace::autoclean;
-
-requires qw( as_hash );
-
-1;
-
-__END__
View
2 packages/LIMS2-Model/lib/LIMS2/Model/Entity/Gene.pm
@@ -7,8 +7,6 @@ use Moose;
use Scalar::Util qw( blessed );
use namespace::autoclean;
-with qw( LIMS2::Model::Entity );
-
has ensembl_gene => (
is => 'ro',
isa => 'Bio::EnsEMBL::Gene',
View
15 packages/LIMS2-Model/lib/LIMS2/Model/Error/System.pm
@@ -0,0 +1,15 @@
+package LIMS2::Model::Error::System;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Moose;
+use namespace::autoclean;
+
+extends qw( LIMS2::Model::Error );
+
+__PACKAGE__->meta->make_immutable( inline_constructor => 0 );
+
+1;
+
+__END__
View
7 packages/LIMS2-Model/lib/LIMS2/Model/FormValidator.pm
@@ -94,6 +94,9 @@ sub dfv_profile {
# Add the 'trim' filter for every profile
push @filters, 'trim';
+ my $dependencies = delete $spec->{DEPENDENCIES};
+ my $dependency_groups = delete $spec->{DEPENDENCY_GROUPS};
+
while ( my ( $field, $f_spec ) = each %{$spec} ) {
if ( $f_spec->{optional} ) {
push @optional, $field;
@@ -118,7 +121,9 @@ sub dfv_profile {
optional => \@optional,
defaults => \%defaults,
field_filters => \%field_filters,
- constraint_methods => \%constraint_methods
+ constraint_methods => \%constraint_methods,
+ dependencies => $dependencies,
+ dependency_groups => $dependency_groups,
};
}
View
156 packages/LIMS2-Model/lib/LIMS2/Model/Helpers/SyntheticConstruct.pm
@@ -0,0 +1,156 @@
+package LIMS2::Model::Helpers::SyntheticConstruct;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Sub::Exporter -setup => {
+ exports => [ qw( synthetic_construct_params ) ]
+};
+
+use LIMS2::Model::Constants qw( $DEFAULT_ASSEMBLY );
+use LIMS2::Model::Error::Database;
+use LIMS2::Model::Error::Implementation;
+use LIMS2::Util::EnsEMBL;
+use Data::Compare qw( Compare );
+
+sub synthetic_construct_params {
+ my $process = shift;
+
+ my $process_type = $process->process_type->process_type;
+
+ if ( $process_type eq 'rearray' ) {
+ _process_rearray_params( $process->process_rearray );
+ }
+ elsif ( $process_type eq 'bac_recom' ) {
+ _process_bac_recom_params( $process->process_cre_bac_recom );
+ }
+ elsif ( $process_type eq 'int_recom' ) {
+ _process_int_recom_params( $process->process_int_recom );
+ }
+ else {
+ LIMS2::Model::Error::Implementation->throw(
+ "Don't know how to construct synthetic vector for process "
+ . $process->process_type->process_description
+ );
+ }
+}
+
+sub _process_rearray_params {
+ my $process_rearray = shift;
+
+ my @source_processes = map { $_->source_well->process }
+ $process_rearray->process_rearray_source_wells_rs->search( {}, { prefetch => { source_well => 'process' } } );
+ my @source_params = map { synthetic_construct_params( $_ ) } @source_processes;
+
+ my $params = shift @source_params;
+
+ # Usually there will only be one source well, but in the case
+ # of a pooled re-array, there may be more than one. We have to
+ # make sure that all the source wells contain the same
+ # construct
+ for my $other_params ( @source_params ) {
+ if ( ! Compare( $params, $other_params ) ) {
+ LIMS2::Model::Error::Database->throw(
+ 'Rearray process ' . $process_rearray->process_id . ' has source wells containing different constructs'
+ );
+ }
+ }
+
+ return $params;
+}
+
+
+sub _process_bac_recom_params {
+ my $bac_recom_process = shift;
+
+ my $design = $bac_recom_process->design;
+ my $bac_clone = $bac_recom_process->bac_clone;
+ my $bac_locus = $bac_clone->search_related( loci => { assembly => $DEFAULT_ASSEMBLY } )->first;
+
+ unless ( $bac_locus ) {
+ LIMS2::Model::Error::Database->throw(
+ sprintf 'No locus for bac %s/%s on assembly %s',
+ $bac_clone->bac_library, $bac_clone->bac_name, $DEFAULT_ASSEMBLY
+ );
+ }
+
+ my $gene = LIMS2::Util::EnsEMBL->new->gene_adaptor->fetch_by_transcript_stable_id( $design->target_transcript );
+
+ my $display_id = join '_', ( $gene ? $gene->external_name : () ),
+ $bac_clone->bac_name, $design->design_id;
+
+ my %params = (
+ method => 'insertion_vector_seq',
+ display_id => $display_id,
+ chromosome => $design->chr_name,
+ strand => $design->chr_strand,
+ transcript => $design->target_transcript,
+ insertion => { type => 'final-cassette', name => $bac_recom_process->cassette },
+ backbone => { type => 'final-backbone', name => $bac_recom_process->backbone },
+ );
+
+ if ( $design->chr_strand == 1 ) {
+ $params{five_arm_start} = $bac_locus->chr_start;
+ $params{five_arm_end} = $design->locus_for( 'U5' )->chr_end;
+ $params{three_arm_start} = $design->locus_for( 'D3' )->chr_start;
+ $params{three_arm_end} = $bac_locus->chr_end;
+ }
+ else {
+ $params{five_arm_start} = $design->locus_for( 'U5' )->chr_start;
+ $params{five_arm_end} = $bac_locus->chr_end;
+ $params{three_arm_start} = $bac_locus->chr_start;
+ $params{three_arm_end} = $design->locus_for( 'D3' )->chr_end;
+ }
+
+ return \%params;
+}
+
+
+sub _process_int_recom_params {
+ my $int_recom_process = shift;
+
+ my $design = $int_recom_process->design_well->process->process_create_di->design;
+ my $design_type = $design->design_type;
+ my $cassette = $int_recom_process->cassette;
+ my $backbone = $int_recom_process->backbone;
+ my $display_id = sprintf( 'int_vec_%d#%s#%s', $design->design_id, $cassette, $backbone );
+ $display_id =~ s/\s+/_/g;
+
+ my %params = (
+ chromosome => $design->chr_name,
+ strand => $design->chr_strand,
+ backbone => { type => 'intermediate-backbone', name => $backbone },
+ five_arm_start => $design->five_arm_start,
+ five_arm_end => $design->five_arm_end,
+ three_arm_start => $design->three_arm_start,
+ three_arm_end => $design->three_arm_end,
+ transcript => $design->target_transcript,
+ );
+
+ if ( $design_type eq 'conditional' or $design_type eq 'artificial-intron' ) {
+ $params{method} = 'conditional_vector_seq';
+ $params{u_insertion} = { type => 'intermediate-cassette', name => $cassette };
+ $params{d_insertion} = { type => 'LoxP', name => 'LoxP' };
+ $params{target_region_start} = $design->target_region_start;
+ $params{target_region_end} = $design->target_region_end;
+ }
+ elsif ( $design_type eq 'deletion' ) {
+ $params{method} = 'deletion_vector_seq';
+ $params{insertion} = { type => 'intermediate-cassette', name => $cassette };
+ }
+ elsif ( $design_type eq 'insertion' ) {
+ $params{method} = 'insertion_vector_seq';
+ $params{insertion} = { type => 'intermediate-cassette', name => $cassette };
+ }
+ else {
+ LIMS2::Model::Error::Implementation->throw(
+ "Don't know how to create an intermediate vector for design type $design_type"
+ );
+ }
+
+ return \%params;
+}
+
+1;
+
+__END__
View
18 packages/LIMS2-Model/lib/LIMS2/Model/Plugin/Plate.pm
@@ -74,7 +74,12 @@ sub create_plate {
sub pspec_retrieve_plate {
return {
- plate_id => { validate => 'integer' }
+ plate_id => { validate => 'integer', optional => 1 },
+ plate_name => { validate => 'existing_plate_name', optional => 1 },
+ profile => { validate => 'plate_profile', optional => 1, default => 'Default' },
+ DEPENDENCIES => {
+ plate_id => [ 'plate_name' ], # plate_name must be specified if plate_id is missing
+ }
}
}
@@ -83,7 +88,16 @@ sub retrieve_plate {
my $validated_params = $self->check_params( $params, $self->pspec_retrieve_plate );
- $self->retrieve( Plate => $validated_params );
+ my $profile = delete $validated_params{profile};
+
+ my $plate = $self->retrieve( Plate => $validated_params );
+
+ my $class = 'LIMS2::Model::Profile::Plate::' . $profile;
+ eval "require $class"
+ or $self->throw( "Failed to load $class: $@" );
+
+ # The profile class *must* implement as_hash()
+ return $class->new( plate => $plate );
}
sub list_plate_types {
View
59 packages/LIMS2-Model/lib/LIMS2/Model/Plugin/SyntheticConstruct.pm
@@ -0,0 +1,59 @@
+package LIMS2::Model::Plugin::SyntheticConstruct;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Moose::Role;
+use LIMS2::Model::Helpers::SyntheticConstruct;
+use IO::String;
+use Bio::SeqIO;
+use namespace::autoclean;
+
+requires qw( schema check_params throw );
+
+sub pspec_retrieve_synthetic_construct {
+ return {
+ plate_name => { validate => 'existing_plate_name' },
+ well_name => { validate => 'well_name' }
+ }
+}
+
+sub retrieve_synthetic_construct {
+ my ( $self, $params ) = @_;
+
+ my $validated_params = $self->check_params( $params, $self->pspec_retrieve_synthetic_construct );
+
+ my $well = $self->retrieve( Well => $validated_params, { prefetch => { 'process' => [ 'process_type', 'process_synthetic_construct' ] } } );
+
+ my $process = $well->process;
+
+ if ( $process->process_synthetic_construct ) {
+ return $process->process_synthetic_construct->synthetic_construct;
+ }
+
+ my $eng_seq_params = LIMS2::Model::Helpers::SyntheticConstruct::synthetic_construct_params( $process );
+
+ my $eng_seq_method = delete $eng_seq_params->{method};
+
+ my $bio_seq = $self->eng_seq_builder->$eng_seq_method( %{$eng_seq_params} );
+
+ my $genbank_str;
+ my $seq_io = Bio::SeqIO->new( -fh => IO::String->new( $genbank_str ), -format => 'genbank' );
+ $seq_io->write_seq( $bio_seq );
+
+ my $synthetic_construct = $self->schema->resultset( 'SyntheticConstruct' )->create(
+ {
+ synthetic_construct_genbank => $genbank_str
+ }
+ );
+
+ $process->create_related(
+ process_synthetic_construct => { synthetic_construct_id => $synthetic_construct->synthetic_construct_id }
+ );
+
+ return $synthetic_construct;
+}
+
+1;
+
+__END__
View
207 packages/LIMS2-Model/lib/LIMS2/Model/Schema/Extensions/Design.pm
@@ -0,0 +1,207 @@
+package LIMS2::Model::Schema::Extensions::Design;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Moose::Role;
+use LIMS2::Model::Constants qw( $DEFAULT_ASSEMBLY );
+use LIMS2::Model::Error::Database;
+use namespace::autoclean;
+
+has chr_name => (
+ is => 'ro',
+ isa => 'Str',
+ init_arg => undef,
+ lazy_build => 1
+);
+
+has chr_strand => (
+ is => 'ro',
+ isa => 'Int',
+ init_arg => undef,
+ lazy_build => 1
+);
+
+has [
+ qw(
+ five_arm_start
+ five_arm_end
+ three_arm_start
+ three_arm_end
+ target_region_start
+ target_region_end
+ )
+] => (
+ is => 'ro',
+ isa => 'Int',
+ init_arg => undef,
+ lazy_build => 1,
+);
+
+has synthetic_vector_params => (
+ is => 'ro',
+ isa => 'HashRef',
+ init_arg => undef,
+ lazy_build => 1
+);
+
+sub has_oligo {
+ my ( $self, $oligo_type ) = @_;
+
+ $self->search_related_rs( design_oligos => { design_oligo_type => $oligo_type } )->count > 0;
+}
+
+sub locus_for {
+ my ( $self, $oligo_type ) = @_;
+
+ my $locus = $self->search_related(
+ design_oligos => {
+ 'me.design_oligo_type' => $oligo_type
+ }
+ )->search_related(
+ loci => { assembly => $DEFAULT_ASSEMBLY }
+ )->first;
+
+ unless ( $locus ) {
+ LIMS2::Model::Error::Database->throw( sprintf 'Design %d has no %s oligo with locus on assembly %s',
+ $self->design_id, $oligo_type, $DEFAULT_ASSEMBLY );
+ }
+
+ return $locus;
+};
+
+sub as_hash {
+ my $self = shift;
+
+ return {
+ design_id => $self->design_id,
+ design_name => $self->design_name,
+ design_type => $self->design_type,
+ phase => $self->phase,
+ created_by => $self->created_by->user_name,
+ created_at => $self->created_at->iso8601,
+ comments => [ map { $_->as_hash } $self->design_comments ],
+ oligos => [ map { $_->as_hash } $self->design_oligos ],
+ genotyping_primers => [ map { $_->as_hash } $self->genotyping_primers ],
+ };
+}
+
+sub _build_chr_name {
+ my $self = shift;
+
+ my @loci = $self->design_oligos_rs->search_related(
+ loci => { assembly => $DEFAULT_ASSEMBLY },
+ {
+ columns => 'chr_name',
+ distinct => 1
+ }
+ );
+
+ if ( @loci == 1 ) {
+ return $loci[0]->chr_name;
+ }
+ elsif ( @loci == 0 ) {
+ LIMS2::Model::Error::Database->throw( sprintf 'Design %d has no oligos with locus on assembly %s',
+ $self->design_id, $DEFAULT_ASSEMBLY );
+ }
+ else {
+ LIMS2::Model::Error::Database->throw( sprintf 'Design %d oligos have inconsistent chromosome name',
+ $self->design_id );
+ }
+}
+
+sub _build_chr_strand {
+ my $self = shift;
+
+
+ my @loci = $self->design_oligos_rs->search_related(
+ loci => { assembly => $DEFAULT_ASSEMBLY },
+ {
+ columns => 'chr_strand',
+ distinct => 1
+ }
+ );
+
+ if ( @loci == 1 ) {
+ return $loci[0]->chr_strand;
+ }
+ elsif ( @loci == 0 ) {
+ LIMS2::Model::Error::Database->throw( sprintf 'Design %d has no oligos with locus on assembly %s',
+ $self->design_id, $DEFAULT_ASSEMBLY );
+ }
+ else {
+ LIMS2::Model::Error::Database->throw( sprintf 'Design %d oligos have inconsistent strand',
+ $self->design_id );
+ }
+}
+
+sub _build_five_arm_start {
+ my $self = shift;
+
+ if ( $self->chr_strand == 1 ) {
+ $self->locus_for( 'G5' )->chr_start;
+ }
+ else {
+ $self->locus_for( 'U5' )->chr_start;
+ }
+}
+
+sub _build_five_arm_end {
+ my $self = shift;
+
+ if ( $self->chr_strand == 1 ) {
+ $self->locus_for( 'U5' )->chr_end;
+ }
+ else {
+ $self->locus_for( 'G5' )->chr_end;
+ }
+}
+
+sub _build_three_arm_start {
+ my $self = shift;
+
+ if ( $self->chr_strand == 1 ) {
+ $self->locus_for( 'D3' )->chr_start;
+ }
+ else {
+ $self->locus_for( 'G3' )->chr_start;
+ }
+
+}
+
+sub _build_three_arm_end {
+ my $self = shift;
+
+ if ( $self->chr_strand == 1 ) {
+ $self->locus_for( 'G3' )->chr_end;
+ }
+ else {
+ $self->locus_for( 'D3' )->chr_end;
+ }
+}
+
+sub _build_target_region_start {
+ my $self = shift;
+
+ if ( $self->chr_strand == 1 ) {
+ $self->locus_for( 'U3' )->chr_start;
+ }
+ else {
+ $self->locus_for( 'D5' )->chr_start;
+ }
+}
+
+sub _build_target_region_end {
+ my $self = shift;
+
+ if ( $self->chr_strand == 1 ) {
+ $self->locus_for( 'D5' )->chr_end;
+ }
+ else {
+ $self->locus_for( 'U3' )->chr_end;
+ }
+}
+
+1;
+
+__END__
View
16 packages/LIMS2-Model/lib/LIMS2/Model/Schema/Result/Design.pm
@@ -234,21 +234,7 @@ __PACKAGE__->has_many(
# You can replace this text with custom code or comments, and it will be preserved on regeneration
-sub as_hash {
- my $self = shift;
-
- return {
- design_id => $self->design_id,
- design_name => $self->design_name,
- design_type => $self->design_type,
- phase => $self->phase,
- created_by => $self->created_by->user_name,
- created_at => $self->created_at->iso8601,
- comments => [ map { $_->as_hash } $self->design_comments ],
- oligos => [ map { $_->as_hash } $self->design_oligos ],
- genotyping_primers => [ map { $_->as_hash } $self->genotyping_primers ],
- };
-}
+with qw( LIMS2::Model::Schema::Extensions::Design );
__PACKAGE__->meta->make_immutable;
1;
View
37 packages/LIMS2-Model/t/40-schema-result-design.t
@@ -0,0 +1,37 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings FATAL => 'all';
+
+use LIMS2::Model;
+use LIMS2::Model::DBConnect;
+use Test::Most;
+
+ok my $schema = LIMS2::Model::DBConnect->connect( 'LIMS2_TEST', 'tests' ),
+ 'connect to LIMS2_TEST';
+
+ok my $model = LIMS2::Model->new( schema => $schema ), 'instantiate model';
+
+{
+ my %data = (
+ design_id => 1,
+ chr_name => '4',
+ chr_strand => -1,
+ five_arm_start => 83128900,
+ five_arm_end => 83132876,
+ target_region_start => 83128032,
+ target_region_end => 83128805,
+ three_arm_start => 83124378,
+ three_arm_end => 83127993,
+ design_type => 'conditional'
+ );
+
+ ok my $design = $model->retrieve_design( { design_id => $data{design_id} } ), "retrieve design $data{design_id}";
+
+ while ( my ( $k, $v ) = each %data ) {
+ can_ok $design, $k;
+ is $design->$k, $v, "$k is $v";
+ }
+}
+
+done_testing();
View
82 packages/LIMS2-Model/t/50-helpers-synthetic-construct.t
@@ -0,0 +1,82 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings FATAL => 'all';
+
+use Test::Most;
+use LIMS2::Model::DBConnect;
+
+use_ok 'LIMS2::Model::Helpers::SyntheticConstruct', 'synthetic_construct_params';
+
+ok my $schema = LIMS2::Model::DBConnect->connect( 'LIMS2_TEST', 'tests' ),
+ 'connect to LIMS2_TEST';
+
+{
+ note "Testing Cre BAC Recombineering Process";
+
+ ok my $process = $schema->resultset( 'Process' )->search(
+ {
+ 'process_cre_bac_recom.design_id' => { '!=', undef }
+ },
+ {
+ join => 'process_cre_bac_recom'
+ }
+ )->first, "Retrieve cre_bac_recom process";
+
+ my $process_id = $process->process_id;
+
+ ok my $params = synthetic_construct_params( $process ), "synthetic_construct_params for $process_id";
+
+ is $params->{method}, 'insertion_vector_seq', 'method is insertion_vector_seq';
+
+}
+
+{
+
+ note "Testing Intermediate Recombineering Process (conditional design)";
+
+ ok my $process = $schema->resultset( 'Process' )->search(
+ {
+ 'process_int_recom.design_well_id' => { '!=', undef },
+ 'design.design_type' => 'conditional'
+
+ },
+ {
+ join => { process_int_recom => { design_well => { process => { process_create_di => 'design' } } } }
+ }
+ )->first, 'Retrieve int_recom process';
+
+ my $process_id = $process->process_id;
+
+ ok my $params = synthetic_construct_params( $process ), "synthetic_construct_params for $process_id";
+
+ is $params->{method}, 'conditional_vector_seq', 'method is conditional_vector_seq';
+}
+
+{
+ note "Testing Rearrayed Intermediate (deletion design)";
+
+ ok my $process = $schema->resultset( 'Process' )->search(
+ {
+ process_id => { -in => \[ "select distinct dest_well.process_id
+ from wells dest_well
+ join process_rearray_source_wells on process_rearray_source_wells.process_id = dest_well.process_id
+ join wells src_well on src_well.well_id = process_rearray_source_wells.source_well_id
+ join process_int_recom on process_int_recom.process_id = src_well.process_id
+ join wells design_well on design_well.well_id = process_int_recom.design_well_id
+ join process_create_di on process_create_di.process_id = design_well.process_id
+ join designs on designs.design_id = process_create_di.design_id
+ where designs.design_type = ? ", [ design_type => 'deletion' ] ]
+ }
+ }
+ )->first, 'Retrieve rearrayed int_recom process';
+
+ my $process_id = $process->process_id;
+
+ ok my $params = synthetic_construct_params( $process ), "synthetic_construct_params for $process_id";
+
+ is $params->{method}, 'deletion_vector_seq', 'method is deletion_vector_seq';
+
+}
+
+done_testing;
View
79 packages/LIMS2-WebApp/lib/LIMS2/WebApp/Controller/UI/UploadPlate.pm
@@ -0,0 +1,79 @@
+package LIMS2::WebApp::Controller::UI::UploadPlate;
+use Moose;
+use Try::Tiny;
+use namespace::autoclean;
+
+BEGIN {extends 'Catalyst::Controller'; }
+
+=head1 NAME
+
+LIMS2::WebApp::Controller::UI::UploadPlate - Catalyst Controller
+
+=head1 DESCRIPTION
+
+Catalyst Controller.
+
+=head1 METHODS
+
+=cut
+
+sub begin :Private {
+ my ( $self, $c ) = @_;
+ $c->assert_user_roles( 'edit' );
+}
+
+=head2 index
+
+=cut
+
+sub index :Path( '/ui/upload_plate' ) :Args(0) {
+ my ( $self, $c ) = @_;
+
+ $c->stash(
+ plate_types => [ sort { $a->{plate_type} cmp $b->{plate_type} } map $_->as_hash, @{ $c->model( 'Golgi' )->list_plate_types } ],
+ template => 'ui/upload_plate/index.tt'
+ );
+}
+
+sub process :Path( '/ui/process_upload_plate' ) :Args(0) {
+ my ( $self, $c ) = @_;
+
+ my $params = $c->request->params();
+ $params->{created_by} = $c->user->user_name;
+
+ my $golgi = $c->model( 'Golgi' );
+
+ try {
+ $golgi->check_params( $params, $golgi->pspec_create_plate );
+ }
+ catch {
+ if ( blessed( $_ ) and $_->isa( 'LIMS2::Model::Error::Validation' ) ) {
+ $_->show_params( 0 );
+ $c->stash( error_msg => $_->as_string );
+ $c->detach( 'index' );
+ }
+ else {
+ die $_;
+ }
+ };
+
+ $c->response->body( "Processing..." );
+}
+
+
+
+
+=head1 AUTHOR
+
+Ray Miller
+
+=head1 LICENSE
+
+This library is free software. You can redistribute it and/or modify
+it under the same terms as Perl itself.
+
+=cut
+
+__PACKAGE__->meta->make_immutable;
+
+1;
View
42 packages/LIMS2-WebApp/lib/LIMS2/WebApp/Controller/UI/ViewPlate.pm
@@ -0,0 +1,42 @@
+package LIMS2::WebApp::Controller::UI::ViewPlate;
+use Moose;
+use namespace::autoclean;
+
+BEGIN {extends 'Catalyst::Controller'; }
+
+=head1 NAME
+
+LIMS2::WebApp::Controller::UI::ViewPlate - Catalyst Controller
+
+=head1 DESCRIPTION
+
+Catalyst Controller.
+
+=head1 METHODS
+
+=cut
+
+
+sub view_plate :Path( '/ui/view_plate' ) :Args(1) {
+ my ( $self, $c ) = @_;
+
+
+
+ $c->response->body('Matched LIMS2::WebApp::Controller::UI::ViewPlate in UI::ViewPlate.');
+}
+
+
+=head1 AUTHOR
+
+Ray Miller
+
+=head1 LICENSE
+
+This library is free software. You can redistribute it and/or modify
+it under the same terms as Perl itself.
+
+=cut
+
+__PACKAGE__->meta->make_immutable;
+
+1;
View
27 packages/LIMS2-WebApp/root/site/ui/upload_plate/index.tt
@@ -0,0 +1,27 @@
+[% META title = "Upload Plate" %]
+<div class="upload_plate_form">
+ <form method="POST" action="[% c.uri_for( '/ui/process_upload_plate' ) %]" enctype="multipart/form-data">
+ <fieldset>
+ <legend>Upload Plate</legend>
+ <label for="plate_name_field">Plate name</label>
+ <input name="plate_name" id="plate_name_field" type="text" value="[% c.req.param('plate_name') %]" />
+ <br />
+ <label for="plate_desc_field">Plate description</label>
+ <input name="plate_desc" id="plate_desc_field" type="text" value="[% c.req.param('plate_desc') %]" />
+ <br />
+ <label for="plate_type_field">Plate type</label>
+ <select name="plate_type" id="plate_type_field" type="select">
+ <option value="">-</option>
+ [%- FOR pt IN plate_types %]
+ <option value="[% pt.plate_type | html %]" [%- IF c.req.param( 'plate_type' ) == pt.plate_type %] selected="selected" [% END %]/>
+ [% pt.plate_type_desc || pt.plate_type | html %]
+ </option>
+ [%- END %]
+ </select>
+ <br />
+ <input name="plate_data" id="plate_data_field" type="file" />
+ <br />
+ <input name="next" id="next_button" type="submit" value="Next" />
+ </fieldset>
+ </form>
+</div>
View
10 packages/LIMS2-WebApp/t/controller_UI-UploadPlate.t
@@ -0,0 +1,10 @@
+use strict;
+use warnings;
+use Test::More;
+
+
+use Catalyst::Test 'LIMS2::WebApp';
+use LIMS2::WebApp::Controller::UI::UploadPlate;
+
+ok( request('/ui/uploadplate')->is_success, 'Request should succeed' );
+done_testing();
View
10 packages/LIMS2-WebApp/t/controller_UI-ViewPlate.t
@@ -0,0 +1,10 @@
+use strict;
+use warnings;
+use Test::More;
+
+
+use Catalyst::Test 'LIMS2::WebApp';
+use LIMS2::WebApp::Controller::UI::ViewPlate;
+
+ok( request('/ui/viewplate')->is_success, 'Request should succeed' );
+done_testing();

No commit comments for this range

Something went wrong with that request. Please try again.