seedlot upload with accession synonyms. seedlot upload works to update existing seedlots
[sgn.git] / lib / SGN / Controller / AJAX / TrialMetadata.pm
blob10899a78057241d8f92039fef16ce483d4e06939
1 package SGN::Controller::AJAX::TrialMetadata;
3 use Moose;
4 use Data::Dumper;
5 use List::Util 'max';
6 use Bio::Chado::Schema;
7 use List::Util qw | any |;
8 use CXGN::Trial;
9 use Math::Round::Var;
10 use List::MoreUtils qw(uniq);
11 use CXGN::Trial::FieldMap;
12 use JSON;
13 use CXGN::Phenotypes::PhenotypeMatrix;
14 use CXGN::Cross;
16 use CXGN::Phenotypes::TrialPhenotype;
17 use CXGN::Login;
18 use CXGN::UploadFile;
19 use CXGN::Stock::Seedlot;
20 use CXGN::Stock::Seedlot::Transaction;
21 use File::Basename qw | basename dirname|;
22 use List::MoreUtils ':all';
23 use Try::Tiny;
24 use CXGN::BreederSearch;
25 use CXGN::Page::FormattingHelpers qw / html_optional_show /;
26 use SGN::Image;
28 BEGIN { extends 'Catalyst::Controller::REST' }
30 __PACKAGE__->config(
31 default => 'application/json',
32 stash_key => 'rest',
33 map => { 'application/json' => 'JSON', 'text/html' => 'JSON' },
36 has 'schema' => (
37 is => 'rw',
38 isa => 'DBIx::Class::Schema',
39 lazy_build => 1,
43 sub trial : Chained('/') PathPart('ajax/breeders/trial') CaptureArgs(1) {
44 my $self = shift;
45 my $c = shift;
46 my $trial_id = shift;
48 my $bcs_schema = $c->dbic_schema("Bio::Chado::Schema");
49 my $metadata_schema = $c->dbic_schema('CXGN::Metadata::Schema');
50 my $phenome_schema = $c->dbic_schema('CXGN::Phenome::Schema');
52 $c->stash->{trial_id} = $trial_id;
53 $c->stash->{schema} = $bcs_schema;
54 $c->stash->{trial} = CXGN::Trial->new({
55 bcs_schema => $bcs_schema,
56 metadata_schema => $metadata_schema,
57 phenome_schema => $phenome_schema,
58 trial_id => $trial_id
59 });
61 if (!$c->stash->{trial}) {
62 $c->stash->{rest} = { error => "The specified trial with id $trial_id does not exist" };
63 return;
66 try {
67 my %param = ( schema => $bcs_schema, trial_id => $trial_id );
68 if ($c->stash->{trial}->get_design_type() eq 'genotyping_plate'){
69 $param{experiment_type} = 'genotyping_layout';
70 } else {
71 $param{experiment_type} = 'field_layout';
73 $c->stash->{trial_layout} = CXGN::Trial::TrialLayout->new(\%param);
75 catch {
76 print STDERR "Trial Layout for $trial_id does not exist. @_\n";
81 =head2 delete_trial_by_file
82 Usage:
83 Desc:
84 Ret:
85 Args:
86 Side Effects:
87 Example:
88 =cut
90 sub delete_trial_data : Local() ActionClass('REST');
92 sub delete_trial_data_GET : Chained('trial') PathPart('delete') Args(1) {
93 my $self = shift;
94 my $c = shift;
95 my $datatype = shift;
97 if ($self->privileges_denied($c)) {
98 $c->stash->{rest} = { error => "You have insufficient access privileges to delete trial data." };
99 return;
102 my $error = "";
104 if ($datatype eq 'phenotypes') {
105 $error = $c->stash->{trial}->delete_phenotype_metadata($c->dbic_schema("CXGN::Metadata::Schema"), $c->dbic_schema("CXGN::Phenome::Schema"));
106 $error .= $c->stash->{trial}->delete_phenotype_data();
109 elsif ($datatype eq 'layout') {
110 $error = $c->stash->{trial}->delete_metadata();
111 $error = $c->stash->{trial}->delete_field_layout();
113 my $dbh = $c->dbc->dbh();
114 my $bs = CXGN::BreederSearch->new( { dbh=>$dbh, dbname=>$c->config->{dbname}, } );
115 my $refresh = $bs->refresh_matviews($c->config->{dbhost}, $c->config->{dbname}, $c->config->{dbuser}, $c->config->{dbpass}, 'stockprop');
117 elsif ($datatype eq 'entry') {
118 $error = $c->stash->{trial}->delete_project_entry();
120 else {
121 $c->stash->{rest} = { error => "unknown delete action for $datatype" };
122 return;
124 if ($error) {
125 $c->stash->{rest} = { error => $error };
126 return;
128 $c->stash->{rest} = { message => "Successfully deleted trial data.", success => 1 };
131 sub trial_phenotypes_fully_uploaded : Chained('trial') PathPart('phenotypes_fully_uploaded') Args(0) ActionClass('REST') {};
133 sub trial_phenotypes_fully_uploaded_GET {
134 my $self = shift;
135 my $c = shift;
136 my $trial = $c->stash->{trial};
137 $c->stash->{rest} = { phenotypes_fully_uploaded => $trial->get_phenotypes_fully_uploaded() };
140 sub trial_phenotypes_fully_uploaded_POST {
141 my $self = shift;
142 my $c = shift;
143 my $value = $c->req->param("phenotypes_fully_uploaded");
144 my $trial = $c->stash->{trial};
145 eval {
146 $trial->set_phenotypes_fully_uploaded($value);
148 if ($@) {
149 $c->stash->{rest} = { error => "An error occurred setting phenotypes_fully_uploaded: $@" };
151 else {
152 $c->stash->{rest} = { success => 1 };
156 sub trial_details : Chained('trial') PathPart('details') Args(0) ActionClass('REST') {};
158 sub trial_details_GET {
159 my $self = shift;
160 my $c = shift;
162 my $trial = $c->stash->{trial};
164 $c->stash->{rest} = { details => $trial->get_details() };
168 sub trial_details_POST {
169 my $self = shift;
170 my $c = shift;
172 my @categories = $c->req->param("categories[]");
174 my $details = {};
175 foreach my $category (@categories) {
176 $details->{$category} = $c->req->param("details[$category]");
179 if (!%{$details}) {
180 $c->stash->{rest} = { error => "No values were edited, so no changes could be made for this trial's details." };
181 return;
183 else {
184 print STDERR "Here are the deets: " . Dumper($details) . "\n";
187 #check privileges
188 print STDERR " curator status = ".$c->user()->check_roles('curator')." and submitter status = ".$c->user()->check_roles('submitter')."\n";
189 if (!($c->user()->check_roles('curator') || $c->user()->check_roles('submitter'))) {
190 $c->stash->{rest} = { error => 'You do not have the required privileges to edit trial details, trial details can only be edited by accounts with submitter or curator privileges' };
191 return;
194 my $trial_id = $c->stash->{trial_id};
195 my $trial = $c->stash->{trial};
196 my $program_object = CXGN::BreedersToolbox::Projects->new( { schema => $c->stash->{schema} });
197 my $program_ref = $program_object->get_breeding_programs_by_trial($trial_id);
199 my $program_array = @$program_ref[0];
200 my $breeding_program_name = @$program_array[1];
201 my @user_roles = $c->user->roles();
202 my %has_roles = ();
203 map { $has_roles{$_} = 1; } @user_roles;
205 print STDERR "my user roles = @user_roles and trial breeding program = $breeding_program_name \n";
207 if (!exists($has_roles{$breeding_program_name})) {
208 $c->stash->{rest} = { error => "You need to be associated with breeding program $breeding_program_name to change the details of this trial." };
209 return;
212 # set each new detail that is defined
213 eval {
214 if ($details->{name}) { $trial->set_name($details->{name}); }
215 if ($details->{breeding_program}) { $trial->set_breeding_program($details->{breeding_program}); }
216 if ($details->{location}) { $trial->set_location($details->{location}); }
217 if ($details->{year}) { $trial->set_year($details->{year}); }
218 if ($details->{type}) { $trial->set_project_type($details->{type}); }
219 if ($details->{planting_date}) {
220 if ($details->{planting_date} eq 'remove') { $trial->remove_planting_date($trial->get_planting_date()); }
221 else { $trial->set_planting_date($details->{planting_date}); }
223 if ($details->{harvest_date}) {
224 if ($details->{harvest_date} eq 'remove') { $trial->remove_harvest_date($trial->get_harvest_date()); }
225 else { $trial->set_harvest_date($details->{harvest_date}); }
227 if ($details->{description}) { $trial->set_description($details->{description}); }
230 if ($@) {
231 $c->stash->{rest} = { error => "An error occurred setting the new trial details: $@" };
233 else {
234 $c->stash->{rest} = { success => 1 };
238 sub traits_assayed : Chained('trial') PathPart('traits_assayed') Args(0) {
239 my $self = shift;
240 my $c = shift;
241 my $stock_type = $c->req->param('stock_type');
243 my @traits_assayed = $c->stash->{trial}->get_traits_assayed($stock_type);
244 $c->stash->{rest} = { traits_assayed => \@traits_assayed };
247 sub trait_phenotypes : Chained('trial') PathPart('trait_phenotypes') Args(0) {
248 my $self = shift;
249 my $c = shift;
250 #get userinfo from db
251 my $schema = $c->dbic_schema("Bio::Chado::Schema");
252 my $user = $c->user();
253 if (! $c->user) {
254 $c->stash->{rest} = {
255 status => "not logged in"
257 return;
259 my $display = $c->req->param('display');
260 my $trait = $c->req->param('trait');
261 my $phenotypes_search = CXGN::Phenotypes::PhenotypeMatrix->new(
262 bcs_schema=> $schema,
263 search_type => "Native",
264 data_level => $display,
265 trait_list=> [$trait],
266 trial_list => [$c->stash->{trial_id}]
268 my @data = $phenotypes_search->get_phenotype_matrix();
269 $c->stash->{rest} = {
270 status => "success",
271 data => \@data
275 sub phenotype_summary : Chained('trial') PathPart('phenotypes') Args(0) {
276 my $self = shift;
277 my $c = shift;
279 my $schema = $c->stash->{schema};
280 my $round = Math::Round::Var->new(0.01);
281 my $dbh = $c->dbc->dbh();
282 my $trial_id = $c->stash->{trial_id};
283 my $display = $c->req->param('display');
284 my $select_clause_additional = '';
285 my $group_by_additional = '';
286 my $order_by_additional = '';
287 my $stock_type_id;
288 my $rel_type_id;
289 my $total_complete_number;
290 if ($display eq 'plots') {
291 $stock_type_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'plot', 'stock_type')->cvterm_id();
292 $rel_type_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'plot_of', 'stock_relationship')->cvterm_id();
293 my $plots = $c->stash->{trial}->get_plots();
294 $total_complete_number = scalar (@$plots);
296 if ($display eq 'plants') {
297 $stock_type_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'plant', 'stock_type')->cvterm_id();
298 $rel_type_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'plant_of', 'stock_relationship')->cvterm_id();
299 my $plants = $c->stash->{trial}->get_plants();
300 $total_complete_number = scalar (@$plants);
302 if ($display eq 'subplots') {
303 $stock_type_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'subplot', 'stock_type')->cvterm_id();
304 $rel_type_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'subplot_of', 'stock_relationship')->cvterm_id();
305 my $subplots = $c->stash->{trial}->get_subplots();
306 $total_complete_number = scalar (@$subplots);
308 my $stocks_per_accession;
309 if ($display eq 'plots_accession') {
310 $stock_type_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'plot', 'stock_type')->cvterm_id();
311 $rel_type_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'plot_of', 'stock_relationship')->cvterm_id();
312 $select_clause_additional = ', accession.uniquename, accession.stock_id';
313 $group_by_additional = ', accession.stock_id, accession.uniquename';
314 $stocks_per_accession = $c->stash->{trial}->get_plots_per_accession();
315 $order_by_additional = ' ,accession.uniquename DESC';
317 if ($display eq 'plants_accession') {
318 $stock_type_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'plant', 'stock_type')->cvterm_id();
319 $rel_type_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'plant_of', 'stock_relationship')->cvterm_id();
320 $select_clause_additional = ', accession.uniquename, accession.stock_id';
321 $group_by_additional = ', accession.stock_id, accession.uniquename';
322 $stocks_per_accession = $c->stash->{trial}->get_plants_per_accession();
323 $order_by_additional = ' ,accession.uniquename DESC';
325 my $accesion_type_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'accession', 'stock_type')->cvterm_id();
327 my $h = $dbh->prepare("SELECT (((cvterm.name::text || '|'::text) || db.name::text) || ':'::text) || dbxref.accession::text AS trait,
328 cvterm.cvterm_id,
329 count(phenotype.value),
330 to_char(avg(phenotype.value::real), 'FM999990.990'),
331 to_char(max(phenotype.value::real), 'FM999990.990'),
332 to_char(min(phenotype.value::real), 'FM999990.990'),
333 to_char(stddev(phenotype.value::real), 'FM999990.990')
334 $select_clause_additional
335 FROM cvterm
336 JOIN phenotype ON (cvterm_id=cvalue_id)
337 JOIN nd_experiment_phenotype USING(phenotype_id)
338 JOIN nd_experiment_project USING(nd_experiment_id)
339 JOIN nd_experiment_stock USING(nd_experiment_id)
340 JOIN stock as plot USING(stock_id)
341 JOIN stock_relationship on (plot.stock_id = stock_relationship.subject_id)
342 JOIN stock as accession on (accession.stock_id = stock_relationship.object_id)
343 JOIN dbxref ON cvterm.dbxref_id = dbxref.dbxref_id JOIN db ON dbxref.db_id = db.db_id
344 WHERE project_id=?
345 AND phenotype.value~?
346 AND stock_relationship.type_id=?
347 AND plot.type_id=?
348 AND accession.type_id=?
349 GROUP BY (((cvterm.name::text || '|'::text) || db.name::text) || ':'::text) || dbxref.accession::text, cvterm.cvterm_id $group_by_additional
350 ORDER BY cvterm.name ASC
351 $order_by_additional;");
353 my $numeric_regex = '^[0-9]+([,.][0-9]+)?$';
354 $h->execute($c->stash->{trial_id}, $numeric_regex, $rel_type_id, $stock_type_id, $accesion_type_id);
356 my @phenotype_data;
358 while (my ($trait, $trait_id, $count, $average, $max, $min, $stddev, $stock_name, $stock_id) = $h->fetchrow_array()) {
360 my $cv = 0;
361 if ($stddev && $average != 0) {
362 $cv = ($stddev / $average) * 100;
363 $cv = $round->round($cv) . '%';
365 if ($average) { $average = $round->round($average); }
366 if ($min) { $min = $round->round($min); }
367 if ($max) { $max = $round->round($max); }
368 if ($stddev) { $stddev = $round->round($stddev); }
370 my @return_array;
371 if ($stock_name && $stock_id) {
372 $total_complete_number = scalar (@{$stocks_per_accession->{$stock_id}});
373 push @return_array, qq{<a href="/stock/$stock_id/view">$stock_name</a>};
375 my $percent_missing = '';
376 if ($total_complete_number){
377 $percent_missing = 100 - sprintf("%.2f", ($count/$total_complete_number)*100)."%";
380 push @return_array, ( qq{<a href="/cvterm/$trait_id/view">$trait</a>}, $average, $min, $max, $stddev, $cv, $count, $percent_missing, qq{<a href="#raw_data_histogram_well" onclick="trait_summary_hist_change($trait_id)"><span class="glyphicon glyphicon-stats"></span></a>} );
381 push @phenotype_data, \@return_array;
384 $c->stash->{rest} = { data => \@phenotype_data };
387 sub trait_histogram : Chained('trial') PathPart('trait_histogram') Args(1) {
388 my $self = shift;
389 my $c = shift;
390 my $trait_id = shift;
391 my $stock_type = $c->req->param('stock_type') || 'plot';
393 my @data = $c->stash->{trial}->get_phenotypes_for_trait($trait_id, $stock_type);
395 $c->stash->{rest} = { data => \@data };
398 sub get_trial_folder :Chained('trial') PathPart('folder') Args(0) {
399 my $self = shift;
400 my $c = shift;
402 if (!($c->user()->check_roles('curator') || $c->user()->check_roles('submitter'))) {
403 $c->stash->{rest} = { error => 'You do not have the required privileges to edit the trial type of this trial.' };
404 return;
407 my $project_parent = $c->stash->{trial}->get_folder();
409 $c->stash->{rest} = { folder => [ $project_parent->project_id(), $project_parent->name() ] };
413 sub get_trial_location :Chained('trial') PathPart('location') Args(0) {
414 my $self = shift;
415 my $c = shift;
416 my $location = $c->stash->{trial}->get_location;
417 $c->stash->{rest} = { location => $location };
420 sub trial_accessions : Chained('trial') PathPart('accessions') Args(0) {
421 my $self = shift;
422 my $c = shift;
423 my $schema = $c->dbic_schema("Bio::Chado::Schema");
425 my $trial = CXGN::Trial->new( { bcs_schema => $schema, trial_id => $c->stash->{trial_id} });
427 my @data = $trial->get_accessions();
429 $c->stash->{rest} = { accessions => \@data };
432 sub trial_tissue_sources : Chained('trial') PathPart('tissue_sources') Args(0) {
433 my $self = shift;
434 my $c = shift;
435 my $schema = $c->dbic_schema("Bio::Chado::Schema");
437 my $trial = CXGN::Trial->new( { bcs_schema => $schema, trial_id => $c->stash->{trial_id} });
438 my $data = $trial->get_tissue_sources();
439 print STDERR Dumper $data;
440 $c->stash->{rest} = { tissue_sources => $data };
443 sub trial_seedlots : Chained('trial') PathPart('seedlots') Args(0) {
444 my $self = shift;
445 my $c = shift;
446 my $schema = $c->dbic_schema("Bio::Chado::Schema");
448 my $trial = CXGN::Trial->new( { bcs_schema => $schema, trial_id => $c->stash->{trial_id} });
450 my @data = $trial->get_seedlots();
452 $c->stash->{rest} = { seedlots => \@data };
455 sub trial_used_seedlots_upload : Chained('trial') PathPart('upload_used_seedlots') Args(0) {
456 my $self = shift;
457 my $c = shift;
458 my $user_id;
459 my $user_name;
460 my $user_role;
461 my $session_id = $c->req->param("sgn_session_id");
463 if ($session_id){
464 my $dbh = $c->dbc->dbh;
465 my @user_info = CXGN::Login->new($dbh)->query_from_cookie($session_id);
466 if (!$user_info[0]){
467 $c->stash->{rest} = {error=>'You must be logged in to upload this seedlot info!'};
468 $c->detach();
470 $user_id = $user_info[0];
471 $user_role = $user_info[1];
472 my $p = CXGN::People::Person->new($dbh, $user_id);
473 $user_name = $p->get_username;
474 } else{
475 if (!$c->user){
476 $c->stash->{rest} = {error=>'You must be logged in to upload this seedlot info!'};
477 $c->detach();
479 $user_id = $c->user()->get_object()->get_sp_person_id();
480 $user_name = $c->user()->get_object()->get_username();
481 $user_role = $c->user->get_object->get_user_type();
484 my $schema = $c->dbic_schema("Bio::Chado::Schema");
485 my $upload = $c->req->upload('trial_upload_used_seedlot_file');
486 my $subdirectory = "trial_used_seedlot_upload";
487 my $upload_original_name = $upload->filename();
488 my $upload_tempfile = $upload->tempname;
489 my $time = DateTime->now();
490 my $timestamp = $time->ymd()."_".$time->hms();
492 ## Store uploaded temporary file in archive
493 my $uploader = CXGN::UploadFile->new({
494 tempfile => $upload_tempfile,
495 subdirectory => $subdirectory,
496 archive_path => $c->config->{archive_path},
497 archive_filename => $upload_original_name,
498 timestamp => $timestamp,
499 user_id => $user_id,
500 user_role => $user_role
502 my $archived_filename_with_path = $uploader->archive();
503 my $md5 = $uploader->get_md5($archived_filename_with_path);
504 if (!$archived_filename_with_path) {
505 $c->stash->{rest} = {error => "Could not save file $upload_original_name in archive",};
506 $c->detach();
508 unlink $upload_tempfile;
509 my $parser = CXGN::Trial::ParseUpload->new(chado_schema => $schema, filename => $archived_filename_with_path);
510 $parser->load_plugin('TrialUsedSeedlotsXLS');
511 my $parsed_data = $parser->parse();
512 #print STDERR Dumper $parsed_data;
514 if (!$parsed_data) {
515 my $return_error = '';
516 my $parse_errors;
517 if (!$parser->has_parse_errors() ){
518 $c->stash->{rest} = {error_string => "Could not get parsing errors"};
519 $c->detach();
520 } else {
521 $parse_errors = $parser->get_parse_errors();
522 #print STDERR Dumper $parse_errors;
524 foreach my $error_string (@{$parse_errors->{'error_messages'}}){
525 $return_error .= $error_string."<br>";
528 $c->stash->{rest} = {error_string => $return_error, missing_seedlots => $parse_errors->{'missing_seedlots'}, missing_plots => $parse_errors->{'missing_plots'}};
529 $c->detach();
532 my $upload_used_seedlots_txn = sub {
533 while (my ($key, $val) = each(%$parsed_data)){
534 my $sl = CXGN::Stock::Seedlot->new(schema => $schema, seedlot_id => $val->{seedlot_stock_id});
536 my $transaction = CXGN::Stock::Seedlot::Transaction->new(schema => $schema);
537 $transaction->factor(1);
538 $transaction->from_stock([$val->{seedlot_stock_id}, $val->{seedlot_name}]);
539 $transaction->to_stock([$val->{plot_stock_id}, $val->{plot_name}]);
540 $transaction->amount($val->{amount});
541 $transaction->weight_gram($val->{weight_gram});
542 $transaction->timestamp($timestamp);
543 $transaction->description($val->{description});
544 $transaction->operator($user_name);
545 $transaction->store();
547 $sl->set_current_count_property();
548 $sl->set_current_weight_property();
550 my $layout = $c->stash->{trial_layout};
551 $layout->generate_and_cache_layout();
553 eval {
554 $schema->txn_do($upload_used_seedlots_txn);
556 if ($@) {
557 $c->stash->{rest} = { error => $@ };
558 print STDERR "An error condition occurred, was not able to upload trial used seedlots. ($@).\n";
559 $c->detach();
562 my $dbh = $c->dbc->dbh();
563 my $bs = CXGN::BreederSearch->new( { dbh=>$dbh, dbname=>$c->config->{dbname}, } );
564 my $refresh = $bs->refresh_matviews($c->config->{dbhost}, $c->config->{dbname}, $c->config->{dbuser}, $c->config->{dbpass}, 'stockprop');
566 $c->stash->{rest} = { success => 1 };
569 sub trial_upload_plants : Chained('trial') PathPart('upload_plants') Args(0) {
570 my $self = shift;
571 my $c = shift;
572 my $user_id;
573 my $user_name;
574 my $user_role;
575 my $session_id = $c->req->param("sgn_session_id");
577 if ($session_id){
578 my $dbh = $c->dbc->dbh;
579 my @user_info = CXGN::Login->new($dbh)->query_from_cookie($session_id);
580 if (!$user_info[0]){
581 $c->stash->{rest} = {error=>'You must be logged in to upload this seedlot info!'};
582 $c->detach();
584 $user_id = $user_info[0];
585 $user_role = $user_info[1];
586 my $p = CXGN::People::Person->new($dbh, $user_id);
587 $user_name = $p->get_username;
588 } else{
589 if (!$c->user){
590 $c->stash->{rest} = {error=>'You must be logged in to upload this seedlot info!'};
591 $c->detach();
593 $user_id = $c->user()->get_object()->get_sp_person_id();
594 $user_name = $c->user()->get_object()->get_username();
595 $user_role = $c->user->get_object->get_user_type();
598 my $schema = $c->dbic_schema("Bio::Chado::Schema");
599 my $upload = $c->req->upload('trial_upload_plants_file');
600 my $inherits_plot_treatments = $c->req->param('upload_plants_per_plot_inherit_treatments');
601 my $plants_per_plot = $c->req->param('upload_plants_per_plot_number');
603 my $subdirectory = "trial_plants_upload";
604 my $upload_original_name = $upload->filename();
605 my $upload_tempfile = $upload->tempname;
606 my $time = DateTime->now();
607 my $timestamp = $time->ymd()."_".$time->hms();
609 ## Store uploaded temporary file in archive
610 my $uploader = CXGN::UploadFile->new({
611 tempfile => $upload_tempfile,
612 subdirectory => $subdirectory,
613 archive_path => $c->config->{archive_path},
614 archive_filename => $upload_original_name,
615 timestamp => $timestamp,
616 user_id => $user_id,
617 user_role => $user_role
619 my $archived_filename_with_path = $uploader->archive();
620 my $md5 = $uploader->get_md5($archived_filename_with_path);
621 if (!$archived_filename_with_path) {
622 $c->stash->{rest} = {error => "Could not save file $upload_original_name in archive",};
623 $c->detach();
625 unlink $upload_tempfile;
626 my $parser = CXGN::Trial::ParseUpload->new(chado_schema => $schema, filename => $archived_filename_with_path);
627 $parser->load_plugin('TrialPlantsXLS');
628 my $parsed_data = $parser->parse();
629 #print STDERR Dumper $parsed_data;
631 if (!$parsed_data) {
632 my $return_error = '';
633 my $parse_errors;
634 if (!$parser->has_parse_errors() ){
635 $c->stash->{rest} = {error_string => "Could not get parsing errors"};
636 $c->detach();
637 } else {
638 $parse_errors = $parser->get_parse_errors();
639 #print STDERR Dumper $parse_errors;
641 foreach my $error_string (@{$parse_errors->{'error_messages'}}){
642 $return_error .= $error_string."<br>";
645 $c->stash->{rest} = {error_string => $return_error, missing_plots => $parse_errors->{'missing_plots'}};
646 $c->detach();
649 my $upload_plants_txn = sub {
650 my %plot_plant_hash;
651 while (my ($key, $val) = each(%$parsed_data)){
652 $plot_plant_hash{$val->{plot_stock_id}}->{plot_name} = $val->{plot_name};
653 push @{$plot_plant_hash{$val->{plot_stock_id}}->{plant_names}}, $val->{plant_name};
655 my $t = CXGN::Trial->new( { bcs_schema => $c->dbic_schema("Bio::Chado::Schema"), trial_id => $c->stash->{trial_id} });
656 $t->save_plant_entries(\%plot_plant_hash, $plants_per_plot, $inherits_plot_treatments);
658 my $layout = $c->stash->{trial_layout};
659 $layout->generate_and_cache_layout();
661 eval {
662 $schema->txn_do($upload_plants_txn);
664 if ($@) {
665 $c->stash->{rest} = { error => $@ };
666 print STDERR "An error condition occurred, was not able to upload trial plants. ($@).\n";
667 $c->detach();
670 my $dbh = $c->dbc->dbh();
671 my $bs = CXGN::BreederSearch->new( { dbh=>$dbh, dbname=>$c->config->{dbname}, } );
672 my $refresh = $bs->refresh_matviews($c->config->{dbhost}, $c->config->{dbname}, $c->config->{dbuser}, $c->config->{dbpass}, 'stockprop');
674 $c->stash->{rest} = { success => 1 };
677 sub trial_plot_gps_upload : Chained('trial') PathPart('upload_plot_gps') Args(0) {
678 my $self = shift;
679 my $c = shift;
680 my $user_id;
681 my $user_name;
682 my $user_role;
683 my $session_id = $c->req->param("sgn_session_id");
685 if ($session_id){
686 my $dbh = $c->dbc->dbh;
687 my @user_info = CXGN::Login->new($dbh)->query_from_cookie($session_id);
688 if (!$user_info[0]){
689 $c->stash->{rest} = {error=>'You must be logged in to upload this seedlot info!'};
690 $c->detach();
692 $user_id = $user_info[0];
693 $user_role = $user_info[1];
694 my $p = CXGN::People::Person->new($dbh, $user_id);
695 $user_name = $p->get_username;
696 } else{
697 if (!$c->user){
698 $c->stash->{rest} = {error=>'You must be logged in to upload this seedlot info!'};
699 $c->detach();
701 $user_id = $c->user()->get_object()->get_sp_person_id();
702 $user_name = $c->user()->get_object()->get_username();
703 $user_role = $c->user->get_object->get_user_type();
706 my $schema = $c->dbic_schema("Bio::Chado::Schema");
708 #Check that trial has a location set
709 my $field_experiment_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'field_layout', 'experiment_type')->cvterm_id();
710 my $nd_geolocation_rs = $schema->resultset('NaturalDiversity::NdGeolocation')->search(
711 {'nd_experiments.type_id'=>$field_experiment_cvterm_id, 'project.project_id'=>$c->stash->{trial_id}},
712 { 'join' => { 'nd_experiments' => {'nd_experiment_projects'=>'project'} } }
714 my $nd_geolocation = $nd_geolocation_rs->first;
715 if (!$nd_geolocation){
716 $c->stash->{rest} = {error=>'This trial has no location set!'};
717 $c->detach();
720 my $upload = $c->req->upload('trial_upload_plot_gps_file');
721 my $subdirectory = "trial_plot_gps_upload";
722 my $upload_original_name = $upload->filename();
723 my $upload_tempfile = $upload->tempname;
724 my $time = DateTime->now();
725 my $timestamp = $time->ymd()."_".$time->hms();
727 ## Store uploaded temporary file in archive
728 my $uploader = CXGN::UploadFile->new({
729 tempfile => $upload_tempfile,
730 subdirectory => $subdirectory,
731 archive_path => $c->config->{archive_path},
732 archive_filename => $upload_original_name,
733 timestamp => $timestamp,
734 user_id => $user_id,
735 user_role => $user_role
737 my $archived_filename_with_path = $uploader->archive();
738 my $md5 = $uploader->get_md5($archived_filename_with_path);
739 if (!$archived_filename_with_path) {
740 $c->stash->{rest} = {error => "Could not save file $upload_original_name in archive",};
741 $c->detach();
743 unlink $upload_tempfile;
744 my $parser = CXGN::Trial::ParseUpload->new(chado_schema => $schema, filename => $archived_filename_with_path);
745 $parser->load_plugin('TrialPlotGPSCoordinatesXLS');
746 my $parsed_data = $parser->parse();
747 #print STDERR Dumper $parsed_data;
749 if (!$parsed_data) {
750 my $return_error = '';
751 my $parse_errors;
752 if (!$parser->has_parse_errors() ){
753 $c->stash->{rest} = {error_string => "Could not get parsing errors"};
754 $c->detach();
755 } else {
756 $parse_errors = $parser->get_parse_errors();
757 #print STDERR Dumper $parse_errors;
759 foreach my $error_string (@{$parse_errors->{'error_messages'}}){
760 $return_error .= $error_string."<br>";
763 $c->stash->{rest} = {error_string => $return_error, missing_plots => $parse_errors->{'missing_plots'}};
764 $c->detach();
767 my $stock_geo_json_cvterm = SGN::Model::Cvterm->get_cvterm_row($schema, 'plot_geo_json', 'stock_property');
769 my $upload_plot_gps_txn = sub {
770 my %plot_stock_ids_hash;
771 while (my ($key, $val) = each(%$parsed_data)){
772 $plot_stock_ids_hash{$val->{plot_stock_id}} = $val;
774 my @plot_stock_ids = keys %plot_stock_ids_hash;
775 my $plots_rs = $schema->resultset("Stock::Stock")->search({stock_id => {-in=>\@plot_stock_ids}});
776 while (my $plot=$plots_rs->next){
777 my $coords = $plot_stock_ids_hash{$plot->stock_id};
778 my $geo_json = {
779 "type"=> "Feature",
780 "geometry"=> {
781 "type"=> "Polygon",
782 "coordinates"=> [
784 [$coords->{WGS84_bottom_left_x}, $coords->{WGS84_bottom_left_y}],
785 [$coords->{WGS84_bottom_right_x}, $coords->{WGS84_bottom_right_y}],
786 [$coords->{WGS84_top_right_x}, $coords->{WGS84_top_right_y}],
787 [$coords->{WGS84_top_left_x}, $coords->{WGS84_top_left_y}],
788 [$coords->{WGS84_bottom_left_x}, $coords->{WGS84_bottom_left_y}],
792 "properties"=> {
793 "format"=> "WGS84",
796 my $geno_json_string = encode_json $geo_json;
797 #print STDERR $geno_json_string."\n";
798 my $previous_plot_gps_rs = $schema->resultset("Stock::Stockprop")->search({stock_id=>$plot->stock_id, type_id=>$stock_geo_json_cvterm->cvterm_id});
799 $previous_plot_gps_rs->delete_all();
800 $plot->create_stockprops({$stock_geo_json_cvterm->name() => $geno_json_string});
802 my $layout = $c->stash->{trial_layout};
803 $layout->generate_and_cache_layout();
805 eval {
806 $schema->txn_do($upload_plot_gps_txn);
808 if ($@) {
809 $c->stash->{rest} = { error => $@ };
810 print STDERR "An error condition occurred, was not able to upload trial plot GPS coordinates. ($@).\n";
811 $c->detach();
814 my $dbh = $c->dbc->dbh();
815 my $bs = CXGN::BreederSearch->new( { dbh=>$dbh, dbname=>$c->config->{dbname}, } );
816 my $refresh = $bs->refresh_matviews($c->config->{dbhost}, $c->config->{dbname}, $c->config->{dbuser}, $c->config->{dbpass}, 'stockprop');
818 $c->stash->{rest} = { success => 1 };
821 sub trial_additional_file_upload : Chained('trial') PathPart('upload_additional_file') Args(0) {
822 my $self = shift;
823 my $c = shift;
824 my $user_id;
825 my $user_name;
826 my $user_role;
827 my $session_id = $c->req->param("sgn_session_id");
829 if ($session_id){
830 my $dbh = $c->dbc->dbh;
831 my @user_info = CXGN::Login->new($dbh)->query_from_cookie($session_id);
832 if (!$user_info[0]){
833 $c->stash->{rest} = {error=>'You must be logged in to upload additional trials to a file!'};
834 $c->detach();
836 $user_id = $user_info[0];
837 $user_role = $user_info[1];
838 my $p = CXGN::People::Person->new($dbh, $user_id);
839 $user_name = $p->get_username;
840 } else{
841 if (!$c->user){
842 $c->stash->{rest} = {error=>'You must be logged in to upload additional files to a trial!'};
843 $c->detach();
845 $user_id = $c->user()->get_object()->get_sp_person_id();
846 $user_name = $c->user()->get_object()->get_username();
847 $user_role = $c->user->get_object->get_user_type();
850 my $upload = $c->req->upload('trial_upload_additional_file');
851 my $subdirectory = "trial_additional_file_upload";
852 my $upload_original_name = $upload->filename();
853 my $upload_tempfile = $upload->tempname;
854 my $time = DateTime->now();
855 my $timestamp = $time->ymd()."_".$time->hms();
857 ## Store uploaded temporary file in archive
858 my $uploader = CXGN::UploadFile->new({
859 tempfile => $upload_tempfile,
860 subdirectory => $subdirectory,
861 archive_path => $c->config->{archive_path},
862 archive_filename => $upload_original_name,
863 timestamp => $timestamp,
864 user_id => $user_id,
865 user_role => $user_role
867 my $archived_filename_with_path = $uploader->archive();
868 my $md5 = $uploader->get_md5($archived_filename_with_path);
869 if (!$archived_filename_with_path) {
870 $c->stash->{rest} = {error => "Could not save file $upload_original_name in archive",};
871 $c->detach();
873 unlink $upload_tempfile;
874 my $md5checksum = $md5->hexdigest();
876 my $result = $c->stash->{trial}->add_additional_uploaded_file($user_id, $archived_filename_with_path, $md5checksum);
877 if ($result->{error}){
878 $c->stash->{rest} = {error=>$result->{error}};
879 $c->detach();
881 $c->stash->{rest} = { success => 1, file_id => $result->{file_id} };
884 sub get_trial_additional_file_uploaded : Chained('trial') PathPart('get_uploaded_additional_file') Args(0) {
885 my $self = shift;
886 my $c = shift;
888 if (!$c->user){
889 $c->stash->{rest} = {error=>'You must be logged in to see uploaded additional files!'};
890 $c->detach();
893 my $files = $c->stash->{trial}->get_additional_uploaded_files();
894 $c->stash->{rest} = {success=>1, files=>$files};
897 sub trial_controls : Chained('trial') PathPart('controls') Args(0) {
898 my $self = shift;
899 my $c = shift;
900 my $schema = $c->dbic_schema("Bio::Chado::Schema");
902 my $trial = CXGN::Trial->new( { bcs_schema => $schema, trial_id => $c->stash->{trial_id} });
904 my @data = $trial->get_controls();
906 $c->stash->{rest} = { accessions => \@data };
909 sub controls_by_plot : Chained('trial') PathPart('controls_by_plot') Args(0) {
910 my $self = shift;
911 my $c = shift;
912 my $schema = $c->dbic_schema("Bio::Chado::Schema");
913 my @plot_ids = $c->req->param('plot_ids[]');
915 my $trial = CXGN::Trial->new({ bcs_schema => $schema, trial_id => $c->stash->{trial_id} });
917 my @data = $trial->get_controls_by_plot(\@plot_ids);
919 $c->stash->{rest} = { accessions => \@data };
922 sub trial_plots : Chained('trial') PathPart('plots') Args(0) {
923 my $self = shift;
924 my $c = shift;
925 my $schema = $c->dbic_schema("Bio::Chado::Schema");
927 my $trial = $c->stash->{trial};
929 my @data = $trial->get_plots();
931 $c->stash->{rest} = { plots => \@data };
934 sub trial_has_subplots : Chained('trial') PathPart('has_subplots') Args(0) {
935 my $self = shift;
936 my $c = shift;
937 my $schema = $c->dbic_schema("Bio::Chado::Schema");
939 my $trial = $c->stash->{trial};
940 $c->stash->{rest} = { has_subplots => $trial->has_subplot_entries(), trial_name => $trial->get_name };
943 sub trial_subplots : Chained('trial') PathPart('subplots') Args(0) {
944 my $self = shift;
945 my $c = shift;
946 my $schema = $c->dbic_schema("Bio::Chado::Schema");
948 my $trial = $c->stash->{trial};
950 my @data = $trial->get_subplots();
952 $c->stash->{rest} = { subplots => \@data };
955 sub trial_has_plants : Chained('trial') PathPart('has_plants') Args(0) {
956 my $self = shift;
957 my $c = shift;
958 my $schema = $c->dbic_schema("Bio::Chado::Schema");
960 my $trial = $c->stash->{trial};
961 $c->stash->{rest} = { has_plants => $trial->has_plant_entries(), trial_name => $trial->get_name };
964 sub trial_plants : Chained('trial') PathPart('plants') Args(0) {
965 my $self = shift;
966 my $c = shift;
967 my $schema = $c->dbic_schema("Bio::Chado::Schema");
969 my $trial = $c->stash->{trial};
971 my @data = $trial->get_plants();
973 $c->stash->{rest} = { plants => \@data };
976 sub trial_has_tissue_samples : Chained('trial') PathPart('has_tissue_samples') Args(0) {
977 my $self = shift;
978 my $c = shift;
979 my $schema = $c->dbic_schema("Bio::Chado::Schema");
981 my $trial = $c->stash->{trial};
982 $c->stash->{rest} = { has_tissue_samples => $trial->has_tissue_sample_entries(), trial_name => $trial->get_name };
985 sub trial_tissue_samples : Chained('trial') PathPart('tissue_samples') Args(0) {
986 my $self = shift;
987 my $c = shift;
988 my $schema = $c->dbic_schema("Bio::Chado::Schema");
990 my $trial = $c->stash->{trial};
992 my $data = $trial->get_tissue_samples();
994 $c->stash->{rest} = { trial_tissue_samples => $data };
997 sub trial_treatments : Chained('trial') PathPart('treatments') Args(0) {
998 my $self = shift;
999 my $c = shift;
1000 my $schema = $c->dbic_schema("Bio::Chado::Schema");
1002 my $trial = $c->stash->{trial};
1004 my $data = $trial->get_treatments();
1006 $c->stash->{rest} = { treatments => $data };
1009 sub trial_add_treatment : Chained('trial') PathPart('add_treatment') Args(0) {
1010 my $self = shift;
1011 my $c = shift;
1013 if (!$c->user()){
1014 $c->stash->{rest} = {error => "You must be logged in to add a treatment"};
1015 $c->detach();
1018 my $schema = $c->dbic_schema('Bio::Chado::Schema');
1019 my $trial_id = $c->stash->{trial_id};
1020 my $trial = $c->stash->{trial};
1021 my $design = decode_json $c->req->param('design');
1022 my $new_treatment_has_plant_entries = $c->req->param('has_plant_entries');
1023 my $new_treatment_has_subplot_entries = $c->req->param('has_subplot_entries');
1024 my $new_treatment_has_tissue_entries = $c->req->param('has_tissue_sample_entries');
1026 my $trial_design_store = CXGN::Trial::TrialDesignStore->new({
1027 bcs_schema => $schema,
1028 trial_id => $trial_id,
1029 trial_name => $trial->get_name(),
1030 nd_geolocation_id => $trial->get_location()->[0],
1031 design_type => $trial->get_design_type(),
1032 design => $design,
1033 new_treatment_has_plant_entries => $new_treatment_has_plant_entries,
1034 new_treatment_has_subplot_entries => $new_treatment_has_subplot_entries,
1035 new_treatment_has_tissue_sample_entries => $new_treatment_has_subplot_entries,
1036 operator => $c->user()->get_object()->get_username()
1038 my $error = $trial_design_store->store();
1039 if ($error){
1040 $c->stash->{rest} = {error => "Treatment not added: ".$error};
1041 } else {
1042 $c->stash->{rest} = {success => 1};
1046 sub trial_layout : Chained('trial') PathPart('layout') Args(0) {
1047 my $self = shift;
1048 my $c = shift;
1049 my $schema = $c->dbic_schema("Bio::Chado::Schema");
1051 my $layout = $c->stash->{trial_layout};
1053 my $design = $layout->get_design();
1054 $c->stash->{rest} = {design => $design};
1057 sub trial_design : Chained('trial') PathPart('design') Args(0) {
1058 my $self = shift;
1059 my $c = shift;
1060 my $schema = $c->dbic_schema("Bio::Chado::Schema");
1062 my $layout = $c->stash->{trial_layout};
1064 my $design = $layout->get_design();
1065 my $design_type = $layout->get_design_type();
1066 my $plot_dimensions = $layout->get_plot_dimensions();
1068 my $plot_length = '';
1069 if ($plot_dimensions->[0]) {
1070 $plot_length = $plot_dimensions->[0];
1073 my $plot_width = '';
1074 if ($plot_dimensions->[1]){
1075 $plot_width = $plot_dimensions->[1];
1078 my $plants_per_plot = '';
1079 if ($plot_dimensions->[2]){
1080 $plants_per_plot = $plot_dimensions->[2];
1083 my $block_numbers = $layout->get_block_numbers();
1084 my $number_of_blocks = '';
1085 if ($block_numbers) {
1086 $number_of_blocks = scalar(@{$block_numbers});
1089 my $replicate_numbers = $layout->get_replicate_numbers();
1090 my $number_of_replicates = '';
1091 if ($replicate_numbers) {
1092 $number_of_replicates = scalar(@{$replicate_numbers});
1095 $c->stash->{rest} = { design_type => $design_type, num_blocks => $number_of_blocks, num_reps => $number_of_replicates, plot_length => $plot_length, plot_width => $plot_width, plants_per_plot => $plants_per_plot, design => $design };
1098 sub get_spatial_layout : Chained('trial') PathPart('coords') Args(0) {
1100 my $self = shift;
1101 my $c = shift;
1102 my $schema = $c->dbic_schema("Bio::Chado::Schema");
1104 my $fieldmap = CXGN::Trial::FieldMap->new({
1105 bcs_schema => $schema,
1106 trial_id => $c->stash->{trial_id},
1108 my $return = $fieldmap->display_fieldmap();
1110 $c->stash->{rest} = $return;
1113 sub retrieve_trial_info : Path('/ajax/breeders/trial_phenotyping_info') : ActionClass('REST') { }
1114 sub retrieve_trial_info_POST : Args(0) {
1115 #sub retrieve_trial_info : chained('trial') Pathpart("trial_phenotyping_info") Args(0) {
1116 my $self =shift;
1117 my $c = shift;
1118 my $schema = $c->dbic_schema('Bio::Chado::Schema', 'sgn_chado');
1119 my $trial_id = $c->req->param('trial_id');
1120 my $layout = CXGN::Trial::TrialLayout->new({schema => $schema, trial_id => $trial_id, experiment_type=>'field_layout'});
1121 my $design = $layout-> get_design();
1122 #print STDERR Dumper($design);
1124 my @layout_info;
1125 foreach my $plot_number (keys %{$design}) {
1126 push @layout_info, {
1127 plot_id => $design->{$plot_number}->{plot_id},
1128 plot_number => $plot_number,
1129 row_number => $design->{$plot_number}->{row_number},
1130 col_number => $design->{$plot_number}->{col_number},
1131 block_number=> $design->{$plot_number}-> {block_number},
1132 rep_number => $design->{$plot_number}-> {rep_number},
1133 plot_name => $design->{$plot_number}-> {plot_name},
1134 accession_name => $design->{$plot_number}-> {accession_name},
1135 plant_names => $design->{$plot_number}-> {plant_names},
1137 @layout_info = sort { $a->{plot_number} <=> $b->{plot_number} } @layout_info;
1140 #print STDERR Dumper(@layout_info);
1141 $c->stash->{rest} = {trial_info => \@layout_info};
1142 #$c->stash->{layout_info} = \@layout_info;
1146 sub trial_completion_layout_section : Chained('trial') PathPart('trial_completion_layout_section') Args(0) {
1147 my $self = shift;
1148 my $c = shift;
1149 my $schema = $c->dbic_schema("Bio::Chado::Schema");
1151 my $trial_layout = CXGN::Trial::TrialLayout->new({schema => $schema, trial_id => $c->stash->{trial_id}, experiment_type => 'field_layout', verify_layout=>1, verify_physical_map=>1});
1152 my $trial_errors = $trial_layout->generate_and_cache_layout();
1153 my $has_layout_check = $trial_errors->{errors}->{layout_errors} || $trial_errors->{error} ? 0 : 1;
1154 my $has_physical_map_check = $trial_errors->{errors}->{physical_map_errors} || $trial_errors->{error} ? 0 : 1;
1155 my $has_seedlots = $trial_errors->{errors}->{seedlot_errors} || $trial_errors->{error} ? 0 : 1;
1156 my $error_string = $trial_errors->{error} ? $trial_errors->{error} : '';
1157 my $layout_error_string = $trial_errors->{errors}->{layout_errors} ? join ', ', @{$trial_errors->{errors}->{layout_errors}} : '';
1158 my $map_error_string = $trial_errors->{errors}->{physical_map_errors} ? join ', ', @{$trial_errors->{errors}->{physical_map_errors}} : '';
1159 my $seedlot_error_string = $trial_errors->{errors}->{seedlot_errors} ? join ', ', @{$trial_errors->{errors}->{seedlot_errors}} : '';
1161 $c->stash->{rest} = {
1162 has_layout => $has_layout_check,
1163 layout_errors => $error_string." ".$layout_error_string,
1164 has_physical_map => $has_physical_map_check,
1165 physical_map_errors => $error_string." ".$map_error_string,
1166 has_seedlots => $has_seedlots,
1167 seedlot_errors => $error_string." ".$seedlot_error_string
1171 sub trial_completion_phenotype_section : Chained('trial') PathPart('trial_completion_phenotype_section') Args(0) {
1172 my $self = shift;
1173 my $c = shift;
1174 my $schema = $c->dbic_schema("Bio::Chado::Schema");
1176 my $plot_type_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'plot', 'stock_type')->cvterm_id();
1177 my $plant_type_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'plant', 'stock_type')->cvterm_id();
1178 my $phenotyping_experiment_type_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'phenotyping_experiment', 'experiment_type')->cvterm_id();
1179 my $has_phenotype_check = $schema->resultset('Phenotype::Phenotype')->search({'stock.type_id'=> [$plot_type_id, $plant_type_id], 'nd_experiment.type_id'=>$phenotyping_experiment_type_id, 'me.value' => { '!=' => ''}, 'project.project_id'=>$c->stash->{trial_id}}, {join=>{'nd_experiment_phenotypes'=>{'nd_experiment'=>[{'nd_experiment_stocks'=>'stock' }, {'nd_experiment_projects'=>'project'}] } }, rows=>1 });
1180 my $has_phenotypes = $has_phenotype_check->first ? 1 : 0;
1182 $c->stash->{rest} = {has_phenotypes => $has_phenotypes};
1185 sub delete_field_coord : Path('/ajax/phenotype/delete_field_coords') Args(0) {
1186 my $self = shift;
1187 my $c = shift;
1188 my $trial_id = $c->req->param('trial_id');
1190 my $schema = $c->dbic_schema('Bio::Chado::Schema');
1192 if ($self->privileges_denied($c)) {
1193 $c->stash->{rest} = { error => "You have insufficient access privileges to update this map." };
1194 return;
1197 my $fieldmap = CXGN::Trial::FieldMap->new({
1198 bcs_schema => $schema,
1199 trial_id => $trial_id,
1201 my $delete_return_error = $fieldmap->delete_fieldmap();
1202 if ($delete_return_error) {
1203 $c->stash->{rest} = { error => $delete_return_error };
1204 return;
1207 my $dbh = $c->dbc->dbh();
1208 my $bs = CXGN::BreederSearch->new( { dbh=>$dbh, dbname=>$c->config->{dbname}, } );
1209 my $refresh = $bs->refresh_matviews($c->config->{dbhost}, $c->config->{dbname}, $c->config->{dbuser}, $c->config->{dbpass}, 'stockprop');
1210 my $trial_layout = CXGN::Trial::TrialLayout->new({ schema => $schema, trial_id => $trial_id, experiment_type => 'field_layout' });
1211 $trial_layout->generate_and_cache_layout();
1213 $c->stash->{rest} = {success => 1};
1216 sub replace_trial_accession : Chained('trial') PathPart('replace_accession') Args(0) {
1217 my $self = shift;
1218 my $c = shift;
1219 my $schema = $c->dbic_schema('Bio::Chado::Schema');
1220 my $old_accession_id = $c->req->param('old_accession_id');
1221 my $new_accession = $c->req->param('new_accession');
1222 my $trial_id = $c->stash->{trial_id};
1224 if ($self->privileges_denied($c)) {
1225 $c->stash->{rest} = { error => "You have insufficient access privileges to edit this map." };
1226 return;
1229 if (!$new_accession){
1230 $c->stash->{rest} = { error => "Provide new accession name." };
1231 return;
1234 my $replace_accession_fieldmap = CXGN::Trial::FieldMap->new({
1235 bcs_schema => $schema,
1236 trial_id => $trial_id,
1237 old_accession_id => $old_accession_id,
1238 new_accession => $new_accession,
1241 my $return_error = $replace_accession_fieldmap->update_fieldmap_precheck();
1242 if ($return_error) {
1243 $c->stash->{rest} = { error => $return_error };
1244 return;
1247 my $replace_return_error = $replace_accession_fieldmap->replace_trial_accession_fieldMap();
1248 if ($replace_return_error) {
1249 $c->stash->{rest} = { error => $replace_return_error };
1250 return;
1253 $c->stash->{rest} = { success => 1};
1256 sub replace_plot_accession : Chained('trial') PathPart('replace_plot_accessions') Args(0) {
1257 my $self = shift;
1258 my $c = shift;
1259 my $schema = $c->dbic_schema('Bio::Chado::Schema');
1260 my $old_accession = $c->req->param('old_accession');
1261 my $new_accession = $c->req->param('new_accession');
1262 my $old_plot_id = $c->req->param('old_plot_id');
1263 my $trial_id = $c->stash->{trial_id};
1265 if ($self->privileges_denied($c)) {
1266 $c->stash->{rest} = { error => "You have insufficient access privileges to edit this map." };
1267 return;
1270 if (!$new_accession){
1271 $c->stash->{rest} = { error => "Provide new accession name." };
1272 return;
1275 my $replace_plot_accession_fieldmap = CXGN::Trial::FieldMap->new({
1276 bcs_schema => $schema,
1277 trial_id => $trial_id,
1278 new_accession => $new_accession,
1279 old_accession => $old_accession,
1280 old_plot_id => $old_plot_id,
1284 my $return_error = $replace_plot_accession_fieldmap->update_fieldmap_precheck();
1285 if ($return_error) {
1286 $c->stash->{rest} = { error => $return_error };
1287 return;
1290 print "Calling Replace Function...............\n";
1291 my $replace_return_error = $replace_plot_accession_fieldmap->replace_plot_accession_fieldMap();
1292 if ($replace_return_error) {
1293 $c->stash->{rest} = { error => $replace_return_error };
1294 return;
1297 print "OldAccession: $old_accession, NewAcc: $new_accession, OldPlotId: $old_plot_id\n";
1298 $c->stash->{rest} = { success => 1};
1301 sub substitute_accession : Chained('trial') PathPart('substitute_accession') Args(0) {
1302 my $self = shift;
1303 my $c = shift;
1304 my $schema = $c->dbic_schema('Bio::Chado::Schema');
1305 my $trial_id = $c->stash->{trial_id};
1306 my $plot_1_info = $c->req->param('plot_1_info');
1307 my $plot_2_info = $c->req->param('plot_2_info');
1309 my ($plot_1_id, $accession_1) = split /,/, $plot_1_info;
1310 my ($plot_2_id, $accession_2) = split /,/, $plot_2_info;
1312 if ($self->privileges_denied($c)) {
1313 $c->stash->{rest} = { error => "You have insufficient access privileges to update this map." };
1314 return;
1317 if ($plot_1_id == $plot_2_id){
1318 $c->stash->{rest} = { error => "Choose a different plot/accession in 'select Accession 2' to perform this operation." };
1319 return;
1322 my @controls;
1323 my @ids;
1325 my $fieldmap = CXGN::Trial::FieldMap->new({
1326 bcs_schema => $schema,
1327 trial_id => $trial_id,
1328 first_plot_selected => $plot_1_id,
1329 second_plot_selected => $plot_2_id,
1330 first_accession_selected => $accession_1,
1331 second_accession_selected => $accession_2,
1334 my $return_error = $fieldmap->update_fieldmap_precheck();
1335 if ($return_error) {
1336 $c->stash->{rest} = { error => $return_error };
1337 return;
1340 my $return_check_error = $fieldmap->substitute_accession_precheck();
1341 if ($return_check_error) {
1342 $c->stash->{rest} = { error => $return_check_error };
1343 return;
1346 my $update_return_error = $fieldmap->substitute_accession_fieldmap();
1347 if ($update_return_error) {
1348 $c->stash->{rest} = { error => $update_return_error };
1349 return;
1352 $c->stash->{rest} = { success => 1};
1355 sub create_plant_subplots : Chained('trial') PathPart('create_plant_entries') Args(0) {
1356 my $self = shift;
1357 my $c = shift;
1358 my $plants_per_plot = $c->req->param("plants_per_plot") || 8;
1359 my $inherits_plot_treatments = $c->req->param("inherits_plot_treatments");
1360 my $plants_with_treatments;
1361 if($inherits_plot_treatments eq '1'){
1362 $plants_with_treatments = 1;
1365 if (my $error = $self->privileges_denied($c)) {
1366 $c->stash->{rest} = { error => $error };
1367 return;
1370 if (!$plants_per_plot || $plants_per_plot > 50) {
1371 $c->stash->{rest} = { error => "Plants per plot number is required and must be smaller than 50." };
1372 return;
1375 my $t = CXGN::Trial->new( { bcs_schema => $c->dbic_schema("Bio::Chado::Schema"), trial_id => $c->stash->{trial_id} });
1377 if ($t->create_plant_entities($plants_per_plot, $plants_with_treatments)) {
1379 my $dbh = $c->dbc->dbh();
1380 my $bs = CXGN::BreederSearch->new( { dbh=>$dbh, dbname=>$c->config->{dbname}, } );
1381 my $refresh = $bs->refresh_matviews($c->config->{dbhost}, $c->config->{dbname}, $c->config->{dbuser}, $c->config->{dbpass}, 'stockprop');
1383 $c->stash->{rest} = {success => 1};
1384 return;
1385 } else {
1386 $c->stash->{rest} = { error => "Error creating plant entries in controller." };
1387 return;
1392 sub create_tissue_samples : Chained('trial') PathPart('create_tissue_samples') Args(0) {
1393 my $self = shift;
1394 my $c = shift;
1395 my $tissues_per_plant = $c->req->param("tissue_samples_per_plant") || 3;
1396 my $tissue_names = decode_json $c->req->param("tissue_samples_names");
1397 my $inherits_plot_treatments = $c->req->param("inherits_plot_treatments");
1398 my $tissues_with_treatments;
1399 if($inherits_plot_treatments eq '1'){
1400 $tissues_with_treatments = 1;
1403 if (my $error = $self->privileges_denied($c)) {
1404 $c->stash->{rest} = { error => $error };
1405 $c->detach;
1408 if (!$c->stash->{trial}->has_plant_entries){
1409 $c->stash->{rest} = { error => "Trial must have plant entries before you can add tissue samples entries. Plant entries are added from the trial detail page." };
1410 $c->detach;
1413 if (!$tissue_names || scalar(@$tissue_names) < 1){
1414 $c->stash->{rest} = { error => "You must provide tissue name(s) for your samples" };
1415 $c->detach;
1418 if (!$tissues_per_plant || $tissues_per_plant > 50) {
1419 $c->stash->{rest} = { error => "Tissues per plant is required and must be smaller than 50." };
1420 $c->detach;
1423 my $t = CXGN::Trial->new({ bcs_schema => $c->dbic_schema("Bio::Chado::Schema"), trial_id => $c->stash->{trial_id} });
1425 if ($t->create_tissue_samples($tissue_names, $inherits_plot_treatments)) {
1426 my $dbh = $c->dbc->dbh();
1427 my $bs = CXGN::BreederSearch->new( { dbh=>$dbh, dbname=>$c->config->{dbname}, } );
1428 my $refresh = $bs->refresh_matviews($c->config->{dbhost}, $c->config->{dbname}, $c->config->{dbuser}, $c->config->{dbpass}, 'stockprop');
1430 $c->stash->{rest} = {success => 1};
1431 $c->detach;;
1432 } else {
1433 $c->stash->{rest} = { error => "Error creating tissues samples in controller." };
1434 $c->detach;;
1439 sub privileges_denied {
1440 my $self = shift;
1441 my $c = shift;
1443 my $trial_id = $c->stash->{trial_id};
1445 if (! $c->user) { return "Login required for modifying trial."; }
1446 my $user_id = $c->user->get_object->get_sp_person_id();
1448 if ($c->user->check_roles('curator')) {
1449 return 0;
1452 my $breeding_programs = $c->stash->{trial}->get_breeding_programs();
1454 if ( ($c->user->check_roles('submitter')) && ( $c->user->check_roles($breeding_programs->[0]->[1]))) {
1455 return 0;
1457 return "You have insufficient privileges to modify or delete this trial.";
1460 # loading field coordinates
1462 sub upload_trial_coordinates : Path('/ajax/breeders/trial/coordsupload') Args(0) {
1463 my $self = shift;
1464 my $c = shift;
1466 if (!$c->user()) {
1467 print STDERR "User not logged in... not uploading coordinates.\n";
1468 $c->stash->{rest} = {error => "You need to be logged in to upload coordinates." };
1469 return;
1472 if (!any { $_ eq "curator" || $_ eq "submitter" } ($c->user()->roles) ) {
1473 $c->stash->{rest} = {error => "You have insufficient privileges to add coordinates." };
1474 return;
1477 my $time = DateTime->now();
1478 my $user_id = $c->user()->get_object()->get_sp_person_id();
1479 my $user_name = $c->user()->get_object()->get_username();
1480 my $timestamp = $time->ymd()."_".$time->hms();
1481 my $subdirectory = 'trial_coords_upload';
1482 my $upload = $c->req->upload('trial_coordinates_uploaded_file');
1483 my $trial_id = $c->req->param('trial_coordinates_upload_trial_id');
1484 my $upload_tempfile = $upload->tempname;
1485 my $upload_original_name = $upload->filename();
1486 my $md5;
1487 my %upload_metadata;
1489 # Store uploaded temporary file in archive
1490 print STDERR "TEMP FILE: $upload_tempfile\n";
1491 my $uploader = CXGN::UploadFile->new({
1492 tempfile => $upload_tempfile,
1493 subdirectory => $subdirectory,
1494 archive_path => $c->config->{archive_path},
1495 archive_filename => $upload_original_name,
1496 timestamp => $timestamp,
1497 user_id => $user_id,
1498 user_role => $c->user()->roles
1500 my $archived_filename_with_path = $uploader->archive();
1502 if (!$archived_filename_with_path) {
1503 $c->stash->{rest} = {error => "Could not save file $upload_original_name in archive",};
1504 return;
1507 $md5 = $uploader->get_md5($archived_filename_with_path);
1508 unlink $upload_tempfile;
1510 my $error_string = '';
1511 # open file and remove return of line
1512 open(my $F, "<", $archived_filename_with_path) || die "Can't open archive file $archived_filename_with_path";
1513 my $schema = $c->dbic_schema("Bio::Chado::Schema");
1514 my $header = <$F>;
1515 while (<$F>) {
1516 chomp;
1517 $_ =~ s/\r//g;
1518 my ($plot,$row,$col) = split /\t/ ;
1519 my $rs = $schema->resultset("Stock::Stock")->search({uniquename=> $plot });
1520 if ($rs->count()== 1) {
1521 my $r = $rs->first();
1522 print STDERR "The plots $plot was found.\n Loading row $row col $col\n";
1523 $r->create_stockprops({row_number => $row, col_number => $col}, {autocreate => 1});
1525 else {
1526 print STDERR "WARNING! $plot was not found in the database.\n";
1527 $error_string .= "WARNING! $plot was not found in the database.";
1531 my $trial_layout = CXGN::Trial::TrialLayout->new({ schema => $c->dbic_schema("Bio::Chado::Schema"), trial_id => $trial_id, experiment_type => 'field_layout' });
1532 $trial_layout->generate_and_cache_layout();
1534 if ($error_string){
1535 $c->stash->{rest} = {error_string => $error_string};
1536 $c->detach();
1539 my $dbh = $c->dbc->dbh();
1540 my $bs = CXGN::BreederSearch->new( { dbh=>$dbh, dbname=>$c->config->{dbname}, } );
1541 my $refresh = $bs->refresh_matviews($c->config->{dbhost}, $c->config->{dbname}, $c->config->{dbuser}, $c->config->{dbpass}, 'stockprop');
1543 $c->stash->{rest} = {success => 1};
1546 sub crosses_in_trial : Chained('trial') PathPart('crosses_in_trial') Args(0) {
1547 my $self = shift;
1548 my $c = shift;
1549 my $schema = $c->dbic_schema("Bio::Chado::Schema");
1551 my $trial_id = $c->stash->{trial_id};
1552 my $trial = CXGN::Cross->new({bcs_schema => $schema, trial_id => $trial_id});
1554 my $result = $trial->get_crosses_in_trial();
1555 my @crosses;
1556 foreach my $r (@$result){
1557 my ($cross_id, $cross_name, $female_parent_id, $female_parent_name, $male_parent_id, $male_parent_name, $cross_type, $female_plot_id, $female_plot_name, $male_plot_id, $male_plot_name) =@$r;
1558 push @crosses, [qq{<a href = "/cross/$cross_id">$cross_name</a>},
1559 qq{<a href = "/stock/$female_parent_id/view">$female_parent_name</a>},
1560 qq{<a href = "/stock/$male_parent_id/view">$male_parent_name</a>}, $cross_type,
1561 qq{<a href = "/stock/$female_plot_id/view">$female_plot_name</a>},
1562 qq{<a href = "/stock/$male_plot_id/view">$male_plot_name</a>}];
1565 $c->stash->{rest} = { data => \@crosses };
1568 sub cross_properties_trial : Chained('trial') PathPart('cross_properties_trial') Args(0) {
1569 my $self = shift;
1570 my $c = shift;
1571 my $schema = $c->dbic_schema("Bio::Chado::Schema");
1573 my $trial_id = $c->stash->{trial_id};
1574 my $trial = CXGN::Cross->new({bcs_schema => $schema, trial_id => $trial_id});
1576 my $result = $trial->get_cross_properties_trial();
1578 my $cross_properties = $c->config->{cross_properties};
1579 my @column_order = split ',', $cross_properties;
1581 my @crosses;
1582 foreach my $r (@$result){
1583 my ($cross_id, $cross_name, $cross_props_hash) =@$r;
1585 my @row = ( qq{<a href = "/cross/$cross_id">$cross_name</a>} );
1586 foreach my $key (@column_order){
1587 push @row, $cross_props_hash->{$key};
1590 push @crosses, \@row;
1593 $c->stash->{rest} = { data => \@crosses };
1596 sub cross_progenies_trial : Chained('trial') PathPart('cross_progenies_trial') Args(0) {
1597 my $self = shift;
1598 my $c = shift;
1599 my $schema = $c->dbic_schema("Bio::Chado::Schema");
1601 my $trial_id = $c->stash->{trial_id};
1602 my $trial = CXGN::Cross->new({bcs_schema => $schema, trial_id => $trial_id});
1604 my $result = $trial->get_cross_progenies_trial();
1605 my @crosses;
1606 foreach my $r (@$result){
1607 my ($cross_id, $cross_name, $progeny_number) =@$r;
1608 push @crosses, [qq{<a href = "/cross/$cross_id">$cross_name</a>}, $progeny_number];
1611 $c->stash->{rest} = { data => \@crosses };
1615 sub phenotype_heatmap : Chained('trial') PathPart('heatmap') Args(0) {
1616 my $self = shift;
1617 my $c = shift;
1618 my $schema = $c->dbic_schema('Bio::Chado::Schema', 'sgn_chado');
1619 my $trial_id = $c->stash->{trial_id};
1620 my $trait_id = $c->req->param("selected");
1622 # my $phenotypes_heatmap = CXGN::Phenotypes::TrialPhenotype->new({
1623 # bcs_schema=>$schema,
1624 # trial_id=>$trial_id,
1625 # trait_id=>$trait_id
1626 # });
1627 # my $phenotype = $phenotypes_heatmap->get_trial_phenotypes_heatmap();
1629 my @items = map {@{$_}[0]} @{$c->stash->{trial}->get_plots()};
1630 print STDERR Dumper(\@items);
1631 my @trait_ids = ($trait_id);
1633 my $layout = $c->stash->{trial_layout};
1634 my $design_type = $layout->get_design_type();
1636 my $phenotypes_search = CXGN::Phenotypes::SearchFactory->instantiate(
1637 "MaterializedView",
1639 bcs_schema=> $schema,
1640 data_level=> 'plot',
1641 trait_list=> \@trait_ids,
1642 plot_list=> \@items,
1643 include_row_and_column_numbers=> 1
1646 my $data = $phenotypes_search->search();
1647 my (@col_No, @row_No, @pheno_val, @plot_Name, @stock_Name, @plot_No, @block_No, @rep_No, @msg, $result, @phenoID);
1648 foreach my $d (@$data) {
1649 my ($year, $project_name, $stock_name, $location, $trait, $value, $plot_name, $rep, $block_number, $plot_number, $row_number, $col_number, $trait_id, $project_id, $location_id, $stock_id, $plot_id, $timestamp_value, $synonyms, $design, $stock_type_name, $phenotype_id, $full_count) = @$d;
1650 if (!$row_number && !$col_number){
1651 if ($block_number && $design_type ne 'splitplot'){
1652 $row_number = $block_number;
1653 }elsif ($rep && !$block_number && $design_type ne 'splitplot'){
1654 $row_number = $rep;
1655 }elsif ($design_type eq 'splitplot'){
1656 $row_number = $rep;
1660 my $plot_popUp = $plot_name."\nplot_No:".$plot_number."\nblock_No:".$block_number."\nrep_No:".$rep."\nstock:".$stock_name."\nvalue:".$value;
1661 push @$result, {plotname => $plot_name, stock => $stock_name, plotn => $plot_number, blkn=>$block_number, rep=>$rep, row=>$row_number, col=>$col_number, pheno=>$value, plot_msg=>$plot_popUp, pheno_id=>$phenotype_id} ;
1662 if ($col_number){
1663 push @col_No, $col_number;
1665 push @row_No, $row_number;
1666 push @pheno_val, $value;
1667 push @plot_Name, $plot_name;
1668 push @stock_Name, $stock_name;
1669 push @plot_No, $plot_number;
1670 push @block_No, $block_number;
1671 push @rep_No, $rep;
1672 push @phenoID, $phenotype_id;
1675 my $false_coord;
1676 if (!$col_No[0]){
1677 @col_No = ();
1678 $false_coord = 'false_coord';
1679 my @row_instances = uniq @row_No;
1680 my %unique_row_counts;
1681 $unique_row_counts{$_}++ for @row_No;
1682 my @col_number2;
1683 for my $key (keys %unique_row_counts){
1684 push @col_number2, (1..$unique_row_counts{$key});
1686 for (my $i=0; $i < scalar(@$result); $i++){
1687 @$result[$i]->{'col'} = $col_number2[$i];
1688 push @col_No, $col_number2[$i];
1692 my ($min_col, $max_col) = minmax @col_No;
1693 my ($min_row, $max_row) = minmax @row_No;
1694 my (@unique_col,@unique_row);
1695 for my $x (1..$max_col){
1696 push @unique_col, $x;
1698 for my $y (1..$max_row){
1699 push @unique_row, $y;
1702 my $trial = CXGN::Trial->new({
1703 bcs_schema => $schema,
1704 trial_id => $trial_id
1706 my $data_check = $trial->get_controls();
1707 my @control_name;
1708 foreach my $cntrl (@{$data_check}) {
1709 push @control_name, $cntrl->{'accession_name'};
1711 #print STDERR Dumper($result);
1712 $c->stash->{rest} = { #phenotypes => $phenotype,
1713 col => \@col_No,
1714 row => \@row_No,
1715 pheno => \@pheno_val,
1716 plotName => \@plot_Name,
1717 stock => \@stock_Name,
1718 plot => \@plot_No,
1719 block => \@block_No,
1720 rep => \@rep_No,
1721 result => $result,
1722 plot_msg => \@msg,
1723 col_max => $max_col,
1724 row_max => $max_row,
1725 unique_col => \@unique_col,
1726 unique_row => \@unique_row,
1727 false_coord => $false_coord,
1728 phenoID => \@phenoID,
1729 controls => \@control_name
1733 sub get_suppress_plot_phenotype : Chained('trial') PathPart('suppress_phenotype') Args(0) {
1734 my $self = shift;
1735 my $c = shift;
1736 my $schema = $c->dbic_schema('Bio::Chado::Schema');
1737 my $plot_name = $c->req->param('plot_name');
1738 my $plot_pheno_value = $c->req->param('phenotype_value');
1739 my $trait_id = $c->req->param('trait_id');
1740 my $phenotype_id = $c->req->param('phenotype_id');
1741 my $trial_id = $c->stash->{trial_id};
1742 my $trial = $c->stash->{trial};
1743 my $user_name = $c->user()->get_object()->get_username();
1744 my $time = DateTime->now();
1745 my $timestamp = $time->ymd()."_".$time->hms();
1747 if ($self->privileges_denied($c)) {
1748 $c->stash->{rest} = { error => "You have insufficient access privileges to suppress this phenotype." };
1749 return;
1752 my $suppress_return_error = $trial->suppress_plot_phenotype($trait_id, $plot_name, $plot_pheno_value, $phenotype_id, $user_name, $timestamp);
1753 if ($suppress_return_error) {
1754 $c->stash->{rest} = { error => $suppress_return_error };
1755 return;
1758 $c->stash->{rest} = { success => 1};
1761 sub delete_single_assayed_trait : Chained('trial') PathPart('delete_single_trait') Args(0) {
1762 my $self = shift;
1763 my $c = shift;
1764 my $pheno_ids = $c->req->param('pheno_id');
1765 my $trait_ids = $c->req->param('traits_id');
1766 my $schema = $c->dbic_schema('Bio::Chado::Schema');
1767 my $trial = $c->stash->{trial};
1769 if (!$c->user()) {
1770 print STDERR "User not logged in... not deleting trait.\n";
1771 $c->stash->{rest} = {error => "You need to be logged in to delete trait." };
1772 return;
1775 if ($self->privileges_denied($c)) {
1776 $c->stash->{rest} = { error => "You have insufficient access privileges to delete assayed trait for this trial." };
1777 return;
1780 my $delete_trait_return_error;
1781 if ($pheno_ids){
1782 my $phenotypes_ids = JSON::decode_json($pheno_ids);
1783 $delete_trait_return_error = $trial->delete_assayed_trait($phenotypes_ids, [] );
1785 if ($trait_ids){
1786 my $traits_ids = JSON::decode_json($trait_ids);
1787 $delete_trait_return_error = $trial->delete_assayed_trait([], $traits_ids );
1790 if ($delete_trait_return_error) {
1791 $c->stash->{rest} = { error => $delete_trait_return_error };
1792 return;
1795 $c->stash->{rest} = { success => 1};
1798 sub retrieve_plot_image : Chained('trial') PathPart('retrieve_plot_images') Args(0) {
1799 my $self = shift;
1800 my $c = shift;
1801 my $schema = $c->dbic_schema('Bio::Chado::Schema');
1802 my $image_ids = decode_json $c->req->param('image_ids');
1803 my $plot_name = $c->req->param('plot_name');
1804 my $plot_id = $c->req->param('plot_id');
1805 my $trial_id = $c->stash->{trial_id};
1806 my $stockref;
1807 my $image_objects;
1808 my $dbh = $c->dbc->dbh;
1809 $stockref->{dbh} = $dbh;
1810 $stockref->{image_ids} = $image_ids || [] ;
1811 my $images = $stockref->{image_ids};
1812 $dbh = $stockref->{dbh};
1814 print STDERR Dumper($stockref);
1815 print "$plot_name and $plot_id and $image_ids\n";
1817 my $image_html = "";
1818 my $m_image_html = "";
1819 my $count;
1820 my @more_is;
1822 if ($images && !$image_objects) {
1823 my @image_object_list = map { SGN::Image->new( $dbh , $_ ) } @$images ;
1824 $image_objects = \@image_object_list;
1827 if ($image_objects) { # don't display anything for empty list of images
1828 $image_html .= qq|<table cellpadding="5">|;
1829 foreach my $image_ob (@$image_objects) {
1830 $count++;
1831 my $image_id = $image_ob->get_image_id;
1832 my $image_name = $image_ob->get_name();
1833 my $image_description = $image_ob->get_description();
1834 my $image_img = $image_ob->get_image_url("medium");
1835 my $small_image = $image_ob->get_image_url("thumbnail");
1836 my $image_page = "/image/view/$image_id";
1838 my $colorbox =
1839 qq|<a href="$image_img" class="stock_image_group" rel="gallery-figures"><img src="$small_image" alt="$image_description" onclick="close_view_plot_image_dialog()"/></a> |;
1840 my $fhtml =
1841 qq|<tr><td width=120>|
1842 . $colorbox
1843 . $image_name
1844 . "</td><td>"
1845 . $image_description
1846 . "</td></tr>";
1847 if ( $count < 3 ) { $image_html .= $fhtml; }
1848 else {
1849 push @more_is, $fhtml;
1850 } #more than 3 figures- show these in a hidden div
1852 $image_html .= "</table>"; #close the table tag or the first 3 figures
1854 $image_html .= "<script> jQuery(document).ready(function() { jQuery('a.stock_image_group').colorbox(); }); </script>\n";
1857 $m_image_html .=
1858 "<table cellpadding=5>"; #open table tag for the hidden figures #4 and on
1859 my $more = scalar(@more_is);
1860 foreach (@more_is) { $m_image_html .= $_; }
1862 $m_image_html .= "</table>"; #close tabletag for the hidden figures
1864 if (@more_is) { #html_optional_show if there are more than 3 figures
1865 $image_html .= html_optional_show(
1866 "Images",
1867 "<b>See $more more images...</b>",
1868 qq| $m_image_html |,
1869 0, #< do not show by default
1870 'abstract_optional_show', #< don't use the default button-like style
1874 $c->stash->{rest} = { image_html => $image_html};