4 SGN::Controller::AJAX::Cross - a REST controller class to provide the
5 backend for objects linked with new cross
9 Add submit new cross, etc...
13 Jeremy Edwards <jde22@cornell.edu>
14 Lukas Mueller <lam87@cornell.edu>
19 package SGN
::Controller
::Cross
;
23 use List
::MoreUtils qw
/any /;
25 use CXGN
::Phenome
::Schema
;
26 use CXGN
::Phenome
::Allele
;
27 use CXGN
::Chado
::Stock
;
28 use CXGN
::Page
::FormattingHelpers qw
/ columnar_table_html info_table_html html_alternate_show /;
29 use CXGN
::Pedigree
::AddProgeny
;
30 use Scalar
::Util
qw(looks_like_number);
32 use SGN
::Model
::Cvterm
;
34 use File
::Basename qw
| basename dirname
|;
35 use File
::Spec
::Functions
;
37 BEGIN { extends
'Catalyst::Controller'; }
41 isa
=> 'DBIx::Class::Schema',
45 shift->_app->dbic_schema( 'Bio::Chado::Schema', 'sgn_chado' )
48 sub upload_cross
: Path
('/cross/upload_cross') Args
(0) {
50 my $upload = $c->req->upload('upload_file');
51 my $visible_to_role = $c->req->param('visible_to_role');
52 my $format_type = $c->req->param('format_type');
53 my $basename = $upload->basename;
54 my $tempfile = $upload->tempname;
59 my @contents = split /\n/, $upload->slurp;
60 print STDERR
"loading cross file: $tempfile Basename: $basename $format_type $visible_to_role\n";
61 $c->stash->{tempfile
} = $tempfile;
62 if ($format_type eq "spreadsheet") {
63 print STDERR
"is spreadsheet \n";
66 print STDERR
"User not logged in... not adding crosses.\n";
67 $c->stash->{rest
} = {error
=> "You need to be logged in to add a cross." };
71 if (!any
{ $_ eq "curator" || $_ eq "submitter" } ($c->user()->roles) ) {
72 print STDERR
"User does not have sufficient privileges.\n";
73 $c->stash->{rest
} = {error
=> "you have insufficient privileges to add a cross." };
77 my $first_line = shift(@contents);
78 my @first_row = split /\t/, $first_line;
79 if ($first_row[0] ne 'cross_name' ||
80 $first_row[1] ne 'cross_type' ||
81 $first_row[2] ne 'maternal_parent' ||
82 $first_row[3] ne 'paternal_parent' ||
83 $first_row[4] ne 'trial' ||
84 $first_row[5] ne 'location' ||
85 $first_row[6] ne 'number_of_progeny' ||
86 $first_row[7] ne 'prefix' ||
87 $first_row[8] ne 'suffix' ||
88 $first_row[9] ne 'number_of_flowers' ||
89 $first_row[10] ne 'number_of_seeds') {
90 $header_error = "<b>Error in header:</b><br>Header should contain the following tab-delimited fields:<br>cross_name<br>cross_type<br>maternal_parent<br>paternal_parent<br>trial<br>location<br>number_of_progeny<br>prefix<br>suffix<br>number_of_flowers<br>number_of_seeds<br>";
91 print STDERR
"$header_error\n";
95 foreach my $line (@contents) {
97 my @row = split /\t/, $line;
98 if (scalar(@row) < 6) {
99 $line_errors{$line_number} = "Line $line_number has too few columns\n";
101 elsif (!$row[0] || !$row[1] || !$row[2] || !$row[3] || !$row[4] || !$row[5]) {
102 $line_errors{$line_number} = "Line $line_number is missing a required field\n";
106 $cross{'cross_name'} = $row[0];
107 $cross{'cross_type'} = $row[1];
108 $cross{'maternal_parent'} = $row[2];
109 $cross{'paternal_parent'} = $row[3];
110 $cross{'cross_trial'} = $row[4];
111 $cross{'cross_location'} = $row[5];
112 if ($row[5]) {$cross{'number_of_progeny'} = $row[6];}
113 if ($row[6]) {$cross{'prefix'} = $row[7];}
114 if ($row[7]) {$cross{'suffix'} = $row[8];}
115 if ($row[8]) {$cross{'number_of_flowers'} = $row[9];}
116 if ($row[9]) {$cross{'number_of_seeds'} = $row[10];}
117 my $line_verification = _verify_cross
($c,\
%cross, \
%line_errors, $line_number);
118 if ($line_verification) {
119 print STDERR
"Verified\n";
120 $upload_data{$line_number}=\
%cross;
123 print STDERR
"Not verified\n";
130 # tempfile => $tempfile,
131 # template => '/breeders_toolbox/upload_crosses_confirm_spreadsheet.mas',
133 } elsif ($format_type eq "barcode") {
135 # tempfile => $tempfile,
136 # template => '/breeders_toolbox/upload_crosses_confirm_barcode.mas',
140 print STDERR
"Upload file format type $format_type not recognized\n";
143 if (%line_errors || $header_error) {
147 file_name
=> $basename,
148 header_error
=> $header_error,
149 line_errors_ref
=> \
%line_errors,
150 template
=> '/breeders_toolbox/upload_crosses_file_error.mas',
152 #print STDERR "there are errors in the upload file\n$line_errors_string";
155 my $number_of_crosses_added = 0;
156 my $number_of_unique_parents = 0;
158 foreach my $line (@contents) {
160 my @row = split /\t/, $line;
161 $cross{'cross_name'} = $row[0];
162 $cross{'cross_type'} = $row[1];
163 $cross{'maternal_parent'} = $row[2];
164 $cross{'paternal_parent'} = $row[3];
165 $cross{'cross_trial'} = $row[4];
166 $cross{'cross_location'} = $row[5];
168 $cross{'number_of_progeny'} = $row[6];
171 $cross{'prefix'} = $row[7];
174 $cross{'suffix'} = $row[8];
177 $cross{'number_of_flowers'} = $row[9];
180 $cross{'number_of_seeds'} = $row[10];
182 $cross{'visible_to_role'} = $visible_to_role;
183 _add_cross
($c,\
%cross);
184 $number_of_crosses_added++;
185 $unique_parents{$cross{'maternal_parent'}} = 1;
186 $unique_parents{$cross{'paternal_parent'}} = 1;
189 foreach my $parent (keys %unique_parents) {
190 $number_of_unique_parents++;
193 number_of_crosses_added
=> $number_of_crosses_added,
194 number_of_unique_parents
=> $number_of_unique_parents,
195 upload_data_ref
=> \
%upload_data,
196 template
=> '/breeders_toolbox/upload_crosses_confirm_spreadsheet.mas',
204 my $cross_ref = shift;
205 my $error_ref = shift;
206 my $line_number = shift;
207 my $schema = $c->dbic_schema('Bio::Chado::Schema', 'sgn_chado');
209 my $cross_name = $cross_ref->{'cross_name'};
210 my $cross_type = $cross_ref->{'cross_type'};
211 my $maternal_parent = $cross_ref->{'maternal_parent'};
212 my $paternal_parent = $cross_ref->{'paternal_parent'};
213 my $cross_trial = $cross_ref->{'cross_trial'};
214 my $cross_location = $cross_ref->{'cross_location'};
215 my $max_progeny = 20000;
216 my $max_flowers = 10000;
217 my $max_seeds = 10000;
218 #print STDERR "name: ".$cross_ref->{'cross_name'}."\n";
219 if (! $schema->resultset("Stock::Stock")->find({name
=>$maternal_parent,})){
220 $error_ref->{$line_number} .= "Line number $line_number, Maternal parent $maternal_parent does not exist in database\n <br>";
222 if ($cross_type ne "biparental" && $cross_type ne "self" && $cross_type ne "open" && $cross_type ne "bulk" && $cross_type ne "bulk_self" && $cross_type ne "bulk_open" && $cross_type ne "doubled_haploid") {
223 $error_ref->{$line_number} .= "Line number $line_number, Cross type $cross_type is not valid\n <br>";
225 if ($cross_type eq "self" || $cross_type eq "bulk_self" || $cross_type eq "doubled_haploid") {
226 if ($maternal_parent ne $paternal_parent) {
227 $error_ref->{$line_number} .= "Line number $line_number, maternal and paternal parents must match for cross type $cross_type\n <br>";
230 if (! $schema->resultset("Stock::Stock")->find({name
=>$paternal_parent,})){
231 $error_ref->{$line_number} .= "Line number $line_number, Paternal parent $paternal_parent does not exist in database\n <br>";
233 if (! $schema->resultset("Project::Project")->find({name
=>$cross_trial,})){
234 $error_ref->{$line_number} .= "Line number $line_number, Trial $cross_trial does not exist in database\n <br>";
236 if (! $schema->resultset("NaturalDiversity::NdGeolocation")->find({description
=>$cross_location,})){
237 $error_ref->{$line_number} .= "Line number $line_number, Location $cross_location does not exist in database\n <br>";
239 #check that cross name does not already exist
240 if ($schema->resultset("Stock::Stock")->find({name
=>$cross_name})){
241 $error_ref->{$line_number} .= "Line number $line_number, Cross $cross_name already exists in database\n <br>";
243 if ($cross_ref->{'number_of_progeny'}) {
244 if ($cross_ref->{'number_of_progeny'} =~ /^[0-9]+$/) { #is an integer
245 if ($cross_ref->{'number_of_progeny'} > $max_progeny || $cross_ref->{'number_of_progeny'} < 1) {
246 $error_ref->{$line_number} .= "Line number $line_number, Number of progeny ". $cross_ref->{'number_of_progeny'}." exceeds the maximum of $max_progeny or is invalid\n <br>";
249 $error_ref->{$line_number} .= "Line number $line_number, Number of progeny ". $cross_ref->{'number_of_progeny'}." is not an integer\n <br>";
252 if ($cross_ref->{'number_of_flowers'}) {
253 if ($cross_ref->{'number_of_flowers'} =~ /^[0-9]+$/) { #is an integer
254 if ($cross_ref->{'number_of_flowers'} > $max_flowers || $cross_ref->{'number_of_flowers'} < 1) {
255 $error_ref->{$line_number} .= "Line number $line_number, Number of flowers ". $cross_ref->{'number_of_flowers'}." exceeds the maximum of $max_flowers or is invalid\n <br>";
258 $error_ref->{$line_number} .= "Line number $line_number, Number of flowers ". $cross_ref->{'number_of_flowers'}." is not an integer\n <br>";
261 if ($cross_ref->{'number_of_seeds'}) {
262 if ($cross_ref->{'number_of_seeds'} =~ /^[0-9]+$/) { #is an integer
263 if ($cross_ref->{'number_of_seeds'} > $max_seeds || $cross_ref->{'number_of_seeds'} < 1) {
264 $error_ref->{$line_number} .= "Line number $line_number, Number of seeds ". $cross_ref->{'number_of_seeds'}." exceeds the maximum of $max_seeds or is invalid\n <br>";
267 $error_ref->{$line_number} .= "Line number $line_number, Number of seeds ". $cross_ref->{'number_of_seeds'}." is not an integer\n <br>";
270 if ($cross_ref->{'prefix'} =~ m/\-/) {
271 $error_ref->{$line_number} .= "Line number $line_number, Prefix ". $cross_ref->{'prefix'}." contains an illegal character: -\n <br>";
273 if ($cross_ref->{'suffix'} =~ m/\-/) {
274 $error_ref->{$line_number} .= "Line number $line_number, Suffix ". $cross_ref->{'suffix'}." contains an illegal character: -\n <br>";
276 if ($error_ref->{$line_number}) {print $error_ref->{$line_number}."\n";return;} else {return 1;}
281 my $cross_ref = shift;
282 my %cross = %{$cross_ref};
283 my $schema = $c->dbic_schema('Bio::Chado::Schema', 'sgn_chado');
284 my $cross_name = $cross{'cross_name'};
285 my $cross_type = $cross{'cross_type'};
286 my $maternal_parent = $cross{'maternal_parent'};
287 my $paternal_parent = $cross{'paternal_parent'};
288 my $trial = $cross{'cross_trial'};
289 my $location = $cross{'cross_location'};
290 my $number_of_progeny = $cross{'number_of_progeny'};#check if exists
291 my $prefix = $cross{'prefix'};#check if exists
292 my $suffix = $cross{'suffix'};#check if exists
293 my $number_of_flowers = $cross{'number_of_flowers'};#check if exists
294 my $number_of_seeds = $cross{'number_of_seeds'};#check if exists
295 my $visible_to_role = $cross{'visible_to_role'};
296 my $geolocation = $schema->resultset("NaturalDiversity::NdGeolocation")->find({description
=>$location,});
297 my $project = $schema->resultset("Project::Project")->find({name
=>$trial,});
298 my $accession_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($schema, 'accession', 'stock_type');
300 my $population_cvterm = $schema->resultset("Cv::Cvterm")->find(
304 my $cross_type_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($schema, 'cross_type', 'nd_experiment_property');
306 my $female_parent_stock = $schema->resultset("Stock::Stock")->find(
307 { name
=> $maternal_parent,
309 my $organism_id = $female_parent_stock->organism_id();
311 my $male_parent_stock = $schema->resultset("Stock::Stock")->find(
312 { name
=> $paternal_parent,
314 my $population_stock = $schema->resultset("Stock::Stock")->find_or_create(
315 { organism_id
=> $organism_id,
317 uniquename
=> $cross_name,
318 type_id
=> $population_cvterm->cvterm_id,
320 my $female_parent = SGN
::Model
::Cvterm
->get_cvterm_row($schema, 'female_parent', 'stock_relationship');
322 my $male_parent = SGN
::Model
::Cvterm
->get_cvterm_row($schema, 'male_parent', 'stock_relationship');
324 ## change 'cross_name' to a more explicit term
326 my $population_members = SGN
::Model
::Cvterm
->get_cvterm_row($schema, 'cross_relationship', 'stock_relationship');
328 my $visible_to_role_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($schema, 'visible_to_role', 'local');
330 my $number_of_flowers_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($schema, 'number_of_flowers', 'nd_experiment_property');
332 my $number_of_seeds_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($schema,'number_of_seeds','nd_experiment_property');
334 my $experiment = $schema->resultset('NaturalDiversity::NdExperiment')->create(
336 nd_geolocation_id
=> $geolocation->nd_geolocation_id(),
337 type_id
=> $population_cvterm->cvterm_id(),
340 $experiment->find_or_create_related('nd_experiment_projects', {
341 project_id
=> $project->project_id()
343 #link the experiment to the stock
344 $experiment->find_or_create_related('nd_experiment_stocks' , {
345 stock_id
=> $population_stock->stock_id(),
346 type_id
=> $population_cvterm->cvterm_id(),
348 if ($number_of_flowers) {
349 #set flower number in experimentprop
350 $experiment->find_or_create_related('nd_experimentprops' , {
351 nd_experiment_id
=> $experiment->nd_experiment_id(),
352 type_id
=> $number_of_flowers_cvterm->cvterm_id(),
353 value
=> $number_of_flowers,
356 if ($number_of_seeds) {
357 #set seed number in experimentprop
358 $experiment->find_or_create_related('nd_experimentprops' , {
359 nd_experiment_id
=> $experiment->nd_experiment_id(),
360 type_id
=> $number_of_seeds_cvterm->cvterm_id(),
361 value
=> $number_of_seeds,
366 $experiment->find_or_create_related('nd_experimentprops' , {
367 nd_experiment_id
=> $experiment->nd_experiment_id(),
368 type_id
=> $cross_type_cvterm->cvterm_id(),
369 value
=> $cross_type,
374 #if progeny number exists
376 while ($increment < $number_of_progeny + 1) {
377 $increment = sprintf "%03d", $increment;
378 my $stock_name = $prefix.$cross_name."_".$increment.$suffix;
379 my $accession_stock = $schema->resultset("Stock::Stock")->create(
380 { organism_id
=> $organism_id,
382 uniquename
=> $stock_name,
383 type_id
=> $accession_cvterm->cvterm_id,
385 $accession_stock->find_or_create_related('stock_relationship_objects', {
386 type_id
=> $female_parent->cvterm_id(),
387 object_id
=> $accession_stock->stock_id(),
388 subject_id
=> $female_parent_stock->stock_id(),
390 $accession_stock->find_or_create_related('stock_relationship_objects', {
391 type_id
=> $male_parent->cvterm_id(),
392 object_id
=> $accession_stock->stock_id(),
393 subject_id
=> $male_parent_stock->stock_id(),
395 $accession_stock->find_or_create_related('stock_relationship_objects', {
396 type_id
=> $population_members->cvterm_id(),
397 object_id
=> $accession_stock->stock_id(),
398 subject_id
=> $population_stock->stock_id(),
400 #######################
401 #link the experiment to the progeny
404 if ($visible_to_role) {
405 my $accession_stock_prop = $schema->resultset("Stock::Stockprop")->find_or_create(
406 { type_id
=>$visible_to_role_cvterm->cvterm_id(),
407 value
=> $visible_to_role,
408 stock_id
=> $accession_stock->stock_id()
416 $c->stash->{rest
} = { error
=> "An error occurred: $@"};
419 $c->stash->{rest
} = { error
=> '', };
424 sub make_cross_form
:Path
("/stock/cross/new") :Args
(0) {
426 $c->stash->{template
} = '/breeders_toolbox/new_cross.mas';
428 my $schema = $c->dbic_schema('Bio::Chado::Schema', 'sgn_chado');
430 my @rows = $schema->resultset('Project::Project')->all();
432 foreach my $row (@rows) {
433 push @projects, [ $row->project_id, $row->name, $row->description ];
435 $c->stash->{project_list
} = \
@projects;
436 @rows = $schema->resultset('NaturalDiversity::NdGeolocation')->all();
438 foreach my $row (@rows) {
439 push @locations, [ $row->nd_geolocation_id,$row->description ];
441 $c->stash->{locations
} = \
@locations;
446 $c->res->redirect( uri
( path
=> '/user/login', query
=> { goto_url
=> $c->req->uri->path_query } ) );
452 sub make_cross
:Path
("/stock/cross/generate") :Args
(0) {
454 $c->stash->{template
} = '/breeders_toolbox/progeny_from_crosses.mas';
455 my $schema = $c->dbic_schema('Bio::Chado::Schema', 'sgn_chado');
456 my $cross_name = $c->req->param('cross_name');
457 $c->stash->{cross_name
} = $cross_name;
458 my $trial_id = $c->req->param('trial_id');
459 $c->stash->{trial_id
} = $trial_id;
460 #my $location = $c->req->param('location_id');
461 my $maternal = $c->req->param('maternal');
462 my $paternal = $c->req->param('paternal');
463 my $prefix = $c->req->param('prefix');
464 my $suffix = $c->req->param('suffix');
465 my $progeny_number = $c->req->param('progeny_number');
466 my $visible_to_role = $c->req->param('visible_to_role');
468 if (! $c->user()) { # redirect
469 $c->res->redirect( uri
( path
=> '/user/login', query
=> { goto_url
=> $c->req->uri->path_query } ) );
474 #check that progeny number is an integer less than maximum allowed
475 my $maximum_progeny_number = 1000;
476 if ((! $progeny_number =~ m/^\d+$/) or ($progeny_number > $maximum_progeny_number)){
477 #redirect to error page?
481 #check that parent names are not blank
482 if ($maternal eq "" or $paternal eq "") {
486 #check that parents exist in the database
487 if (! $schema->resultset("Stock::Stock")->find({name
=>$maternal,})){
490 if (! $schema->resultset("Stock::Stock")->find({name
=>$paternal,})){
494 #check that cross name does not already exist
495 if ($schema->resultset("Stock::Stock")->find({name
=>$cross_name})){
499 #check that progeny do not already exist
500 if ($schema->resultset("Stock::Stock")->find({name
=>$prefix.$cross_name.$suffix."-1",})){
504 my $organism = $schema->resultset("Organism::Organism")->find_or_create(
507 species
=> 'Manihot esculenta',
509 my $organism_id = $organism->organism_id();
511 my $accession_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($schema, 'accession', 'stock_type');
514 my $population_cvterm = $schema->resultset("Cv::Cvterm")->find(
515 { name
=> 'population',
519 my $female_parent_stock = $schema->resultset("Stock::Stock")->find(
523 my $male_parent_stock = $schema->resultset("Stock::Stock")->find(
527 my $population_stock = $schema->resultset("Stock::Stock")->find_or_create(
528 { organism_id
=> $organism_id,
530 uniquename
=> $cross_name,
531 type_id
=> $population_cvterm->cvterm_id,
533 my $female_parent = SGN
::Model
::Cvterm
->get_cvterm_row($schema, 'female_parent', 'stock_relationship');
535 my $male_parent = SGN
::Model
::Cvterm
->get_cvterm_row($schema, 'male_parent', 'stock_relationship');
537 my $population_members = SGN
::Model
::Cvterm
->get_cvterm_row($schema, 'cross_name', 'stock_relationship');
539 my $visible_to_role_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($schema, 'visible_to_role', 'local');
542 while ($increment < $progeny_number + 1) {
543 my $stock_name = $prefix.$cross_name."-".$increment.$suffix;
544 my $accession_stock = $schema->resultset("Stock::Stock")->create(
545 { organism_id
=> $organism_id,
547 uniquename
=> $stock_name,
548 type_id
=> $accession_cvterm->cvterm_id,
550 $accession_stock->find_or_create_related('stock_relationship_objects', {
551 type_id
=> $female_parent->cvterm_id(),
552 object_id
=> $accession_stock->stock_id(),
553 subject_id
=> $female_parent_stock->stock_id(),
555 $accession_stock->find_or_create_related('stock_relationship_objects', {
556 type_id
=> $male_parent->cvterm_id(),
557 object_id
=> $accession_stock->stock_id(),
558 subject_id
=> $male_parent_stock->stock_id(),
560 $accession_stock->find_or_create_related('stock_relationship_objects', {
561 type_id
=> $population_members->cvterm_id(),
562 object_id
=> $accession_stock->stock_id(),
563 subject_id
=> $population_stock->stock_id(),
565 if ($visible_to_role ne "") {
566 my $accession_stock_prop = $schema->resultset("Stock::Stockprop")->find_or_create(
567 { type_id
=>$visible_to_role_cvterm->cvterm_id(),
568 value
=> $visible_to_role,
569 stock_id
=> $accession_stock->stock_id()
579 sub cross_detail
: Path
('/cross') Args
(1) {
583 my $cross_type_id = SGN
::Model
::Cvterm
->get_cvterm_row($c->dbic_schema("Bio::Chado::Schema"), 'cross', 'stock_type')->cvterm_id();
585 #get cross from stock id
586 my $cross = $c->dbic_schema("Bio::Chado::Schema")->resultset("Stock::Stock")->search( { stock_id
=> $id, type_id
=> $cross_type_id } )->first();
588 if (!$cross) { #or from project id
589 $cross = $c->dbic_schema("Bio::Chado::Schema")->resultset("Project::Project")->search({ 'me.project_id' => $id })->search_related('nd_experiment_projects')->search_related('nd_experiment')->search_related('nd_experiment_stocks')->search_related('stock', {'stock.type_id'=>$cross_type_id})->first();
595 $c->stash->{template
} = '/generic_message.mas';
596 $c->stash->{message
} = 'The requested cross does not exist.';
599 $cross_id = $cross->stock_id();
602 #print STDERR "Cross stock_id is $cross_id\n";
604 my $progeny = $c->dbic_schema("Bio::Chado::Schema")->resultset("Stock::StockRelationship") -> search
( { object_id
=> $cross_id, 'type.name' => 'offspring_of' }, { join => 'type' } );
606 my $progeny_count = $progeny->count();
608 $c->stash->{cross_name
} = $cross->uniquename();
609 $c->stash->{user_id
} = $c->user ?
$c->user->get_object()->get_sp_person_id() : undef;
610 $c->stash->{cross_id
} = $cross_id;
611 $c->stash->{progeny_count
} = $progeny_count;
612 $c->stash->{template
} = '/breeders_toolbox/cross/index.mas';
616 sub cross_wishlist_download
: Path
('/cross_wishlist/file_download/') Args
(1) {
620 my $metadata_schema = $c->dbic_schema('CXGN::Metadata::Schema');
621 my $file_row = $metadata_schema->resultset("MdFiles")->find({file_id
=> $file_id});
622 my $file_destination = catfile
($file_row->dirname, $file_row->basename);
623 my $contents = read_file
($file_destination);
624 my $file_name = $file_row->basename;
625 $c->res->content_type('Application/xls');
626 $c->res->header('Content-Disposition', qq[attachment
; filename
="$file_name"]);
627 $c->res->body($contents);
631 sub family_name_detail
: Path
('/family') Args
(1) {
635 my $schema = $c->dbic_schema("Bio::Chado::Schema");
636 my $family_stock_type_id = SGN
::Model
::Cvterm
->get_cvterm_row($schema, 'family_name', 'stock_type')->cvterm_id();
637 my $family_type_id = SGN
::Model
::Cvterm
->get_cvterm_row($schema, 'family_type', 'stock_property')->cvterm_id();
639 #get family_name from stock id
640 my $family = $schema->resultset("Stock::Stock")->find( { stock_id
=> $id, type_id
=> $family_stock_type_id } );
646 $c->stash->{template
} = '/generic_message.mas';
647 $c->stash->{message
} = 'The requested family name does not exist.';
650 $family_id = $family->stock_id();
651 $family_name = $family->uniquename();
652 my $type = $schema->resultset("Stock::Stockprop")->find({ stock_id
=> $family_id, type_id
=> $family_type_id})->value();
653 if (($type eq 'same_parents') || ($type eq '')){
654 $family_type = 'This family includes only crosses having the same parental genotypes';
655 } elsif ($type eq 'reciprocal_parents'){
656 $family_type = 'This family includes reciprocal crosses';
660 $c->stash->{family_name
} = $family_name;
661 $c->stash->{user_id
} = $c->user ?
$c->user->get_object()->get_sp_person_id() : undef;
662 $c->stash->{family_id
} = $family_id;
663 $c->stash->{family_type
} = $family_type;
664 $c->stash->{template
} = '/breeders_toolbox/cross/family.mas';