added search stock by editor name, stock object and stockprops are now added to...
[sgn.git] / lib / SGN / Controller / Stock.pm
blobb306d6c0ab1dff11526e59799757cff1057a4449
1 package SGN::Controller::Stock;
3 =head1 NAME
5 SGN::Controller::Stock - Catalyst controller for pages dealing with stocks (e.g. accession, poopulation, etc.)
7 =cut
9 use Moose;
10 use namespace::autoclean;
12 use URI::FromHash 'uri';
14 use CXGN::Chado::Stock;
15 use SGN::View::Stock qw/stock_link stock_organisms stock_types/;
17 has 'schema' => (
18 is => 'rw',
19 isa => 'DBIx::Class::Schema',
20 required => 0,
23 has 'default_page_size' => (
24 is => 'ro',
25 default => 20,
29 BEGIN { extends 'Catalyst::Controller' }
30 with 'Catalyst::Component::ApplicationAttribute';
32 sub _validate_pair {
33 my ($self,$c,$key,$value) = @_;
34 $c->throw( is_client_error => 1, public_message => "$value is not a valid value for $key" )
35 if ($key =~ m/_id$/ and $value !~ m/\d+/);
38 sub search :Path('/stock/search') Args(0) {
39 my ( $self, $c ) = @_;
40 $self->schema( $c->dbic_schema('Bio::Chado::Schema','sgn_chado') );
42 my $req = $c->req;
44 my $results;
45 $results = $self->_make_stock_search_rs( $c, $req ) if $req->param('submit');
47 $c->stash(
48 template => '/stock/search.mas',
49 request => $req,
50 form_opts => { stock_types=>stock_types($self->schema), organisms=>stock_organisms($self->schema)} ,
51 results => $results,
52 sp_person_autocomplete_uri => $c->uri_for( '/ajax/people/autocomplete' ),
53 pagination_link_maker => sub {
54 return uri( query => { %{$req}, page => shift } );
60 # assembles a DBIC resultset for the search based on the submitted
61 # form values
62 sub _make_stock_search_rs {
63 my ( $self, $c, $req ) = @_;
65 my $rs = $self->schema->resultset('Stock::Stock');
66 my $rs_synonyms;
68 if( my $name = $req->param('stock_name') ) {
69 $rs = $rs->search({
70 -or => [
71 'lower(me.name)' => { like => '%'.lc( $name ).'%' } ,
72 'lower(uniquename)' => { like => '%'.lc( $name ).'%' },
73 # -and => [
74 # 'lower(type.name)' => { like =>'%synonym%' },
75 # 'lower(value)' => { like =>'%'.lc( $name ).'%' },
76 # ],
77 # ], },
78 # { join => { 'stockprops' => 'type' } },
79 ], } ,
81 #add the stockprop values here
82 $rs_synonyms = $self->schema->resultset('Cv::Cvterm')->search( {
83 'lower(me.name)' => { like =>'%synonym%' } , } )->search_related('stockprops', {
84 'lower(value)' => { like =>'%'.lc( $name ).'%' } , } )->
85 search_related('stock');
88 if( my $type = $req->param('stock_type') ) {
89 $self->_validate_pair($c,'type_id',$type);
90 $rs = $rs->search({ 'type_id' => $type });
93 if( my $organism = $req->param('organism') ) {
94 $self->_validate_pair( $c, 'organism_id', $organism );
95 $rs = $rs->search({ 'organism_id' => $organism });
98 if ( my $editor = $req->param('person') ) {
99 print STDERR "Searching stock by editor | $editor | ***********\n\n";
100 $self->_validate_pair( $c, 'person') ;
101 my ($first_name, $last_name) = split ',' , $editor ;
102 $first_name =~ s/\s//g;
103 $last_name =~ s/\s//g;
104 print STDERR "first_name = |$first_name| , last_name = |$last_name| ***********\n\n";
105 my $q = "SELECT stock_id FROM stock
106 JOIN stockprop USING (stock_id)
107 JOIN sgn_people.sp_person on cast(value AS numeric) = sp_person_id
108 JOIN cvterm on stockprop.type_id = cvterm_id
109 WHERE first_name = ? AND last_name = ?
110 AND cvterm.name = ?";
111 my $sth = $c->dbc->dbh->prepare($q);
112 $sth->execute($first_name, $last_name, 'sp_person_id');
114 my $query = "SELECT sp_person_id FROM sgn_people.sp_person
115 WHERE first_name = ? AND last_name = ?";
116 $sth = $c->dbc->dbh->prepare($query);
117 $sth->execute($first_name, $last_name);
118 my ($sp_person_id) = $sth->fetchrow_array ;
119 print STDERR "SP_PERSON_ID = $sp_person_id *********\n\n";
120 $rs = $rs->search( {
121 'type.name' => 'sp_person_id',
122 'stockprops.value' => $sp_person_id, } ,
123 { join => { stockprops =>['type'] } },
124 ) if $sp_person_id;
126 # page number and page size, and order by name
127 $rs = $rs->search( undef, {
128 page => $req->param('page') || 1,
129 rows => $req->param('page_size') || $self->default_page_size,
130 order_by => 'name',
132 return $rs;
136 # sub view_id :Path('/stock/view/id') :Args(1) {
137 # my ( $self, $c , $stock_id) = @_;
139 # $self->schema( $c->dbic_schema( 'Bio::Chado::Schema', 'sgn_chado' ) );
140 # $self->_view_stock($c, 'view', $stock_id);
144 sub new_stock :Chained('get_stock') : PathPart('new') :Args(0) {
145 my ( $self, $c ) = @_;
146 # $self->schema( $c->dbic_schema( 'Bio::Chado::Schema', 'sgn_chado' ) );
147 #### $c->forward("view_stock", 'new');
148 $c->stash(
149 template => '/stock/index.mas',
151 stockref => {
152 action => "new",
153 stock_id => 0 ,
154 #curator => $curator,
155 #submitter => $submitter,
156 #sequencer => $sequencer,
157 #person_id => $person_id,
158 stock => $c->stash->{stock},
159 schema => $self->schema,
160 #dbh => $dbh,
161 #is_owner => $is_owner,
162 #props => $props,
163 #dbxrefs => $dbxrefs,
164 #owners => $owner_ids,
170 sub view_stock :Chained('get_stock') :PathPart('view') :Args(0) {
171 my ( $self, $c, $action) = @_;
172 my $logged_user = $c->user;
173 my $person_id = $logged_user->get_object->get_sp_person_id if $logged_user;
174 my $curator = $logged_user->check_roles('curator') if $logged_user;
175 my $submitter = $logged_user->check_roles('submitter') if $logged_user;
176 my $sequencer = $logged_user->check_roles('sequencer') if $logged_user;
178 my $dbh = $c->dbc->dbh;
180 ##################
182 ###Check if a stock page can be printed###
184 my $stock = $c->stash->{stock};
185 my $stock_id = $stock ? $stock->get_stock_id : undef ;
187 # print message if stock_id is not valid
188 unless ( ( $stock_id =~ m /^\d+$/ ) || ($action eq 'new' && !$stock_id) ) {
189 $c->throw_404( "No stock/accession exists for identifier $stock_id" );
191 if ( !$stock->get_object_row || ($action ne 'new' && !$stock_id) ) {
192 $c->throw_404( "No stock/accession exists for identifier $stock_id" );
195 # print message if the stock is obsolete
196 my $obsolete = $stock->get_is_obsolete();
197 if ( $obsolete && !$curator ) {
198 $c->throw(is_client_error => 0,
199 title => 'Obsolete stock',
200 message => "Stock $stock_id is obsolete!",
201 developer_message => 'only curators can see obsolete stock',
202 notify => 0, #< does not send an error email
205 # print message if stock_id does not exist
206 if ( !$stock && $action ne 'new' && $action ne 'store' ) {
207 $c->throw_404('No stock exists for this identifier');
210 ####################
211 my $props = $self->_stockprops($stock);
212 my $is_owner;
213 my $owner_ids = $props->{sp_person_id} || [] ;
214 if ( $stock && ($curator || $person_id && ( grep /^$person_id$/, @$owner_ids ) ) ) {
215 $is_owner = 1;
217 my $dbxrefs = $self->_stock_dbxrefs($stock);
219 ################
220 $c->stash(
221 template => '/stock/index.mas',
223 stockref => {
224 action => $action,
225 stock_id => $stock_id ,
226 curator => $curator,
227 submitter => $submitter,
228 sequencer => $sequencer,
229 person_id => $person_id,
230 stock => $stock,
231 schema => $self->schema,
232 dbh => $dbh,
233 is_owner => $is_owner,
234 props => $props,
235 dbxrefs => $dbxrefs,
236 owners => $owner_ids,
238 locus_add_uri => $c->uri_for( '/ajax/stock/associate_locus' ),
239 locus_autocomplete_uri => $c->uri_for( '/ajax/locus/autocomplete' ),
244 sub _stockprops {
245 my ($self,$stock) = @_;
248 my $stockprops = $stock->get_object_row()->search_related("stockprops");
250 my $properties ;
251 while ( my $prop = $stockprops->next ) {
252 push @{ $properties->{$prop->type->name} } , $prop->value ;
254 return $properties;
258 sub _stock_dbxrefs {
259 my ($self,$stock) = @_;
261 my $stock_dbxrefs = $stock->get_object_row()->search_related("stock_dbxrefs");
263 my $dbxrefs ;
264 while ( my $sdbxref = $stock_dbxrefs->next ) {
265 my $url = $sdbxref->dbxref->db->urlprefix . $sdbxref->dbxref->db->url;
267 my $accession = $sdbxref->dbxref->accession;
268 $url = $url ? qq |<a href = "$url/$accession">$accession</a>| : $accession ;
269 push @{ $dbxrefs->{$sdbxref->dbxref->db->name} } , $accession ;
271 return $dbxrefs;
274 sub get_stock :Chained('/') :PathPart('stock') :CaptureArgs(1) {
275 my ($self, $c, $stock_id) = @_;
277 $self->schema( $c->dbic_schema( 'Bio::Chado::Schema', 'sgn_chado' ) );
278 $c->stash->{stock} = CXGN::Chado::Stock->new($self->schema, $stock_id);
280 #add the stockprops to the stash
281 my $stock = $c->stash->{stock}->get_object_row;
282 my $stockprops = $stock ? $stock->search_related("stockprops") : undef ;
284 my $properties ;
285 if ($stockprops) {
286 while ( my $prop = $stockprops->next ) {
287 push @{ $properties->{$prop->type->name} } , $prop->value ;
290 $c->stash->{stockprops} = $properties;
295 ######
297 ######