warning message for setting prefix
[sgn.git] / lib / SGN / Controller / AJAX / TrackingActivity.pm
blob7a785ad9d2b9f70b22dfea13193b4ff511950712
2 package SGN::Controller::AJAX::TrackingActivity;
4 use Moose;
5 use CXGN::Stock::Order;
6 use CXGN::Stock::OrderBatch;
7 use Data::Dumper;
8 use JSON;
9 use DateTime;
10 use CXGN::People::Person;
11 use CXGN::Contact;
12 use CXGN::Trial::Download;
13 use CXGN::TrackingActivity::AddTrackingIdentifier;
14 use CXGN::TrackingActivity::ActivityInfo;
15 use CXGN::TrackingActivity::AddActivityProject;
16 use CXGN::TrackingActivity::ActivityProject;
17 use CXGN::TrackingActivity::TrackingIdentifier;
18 use CXGN::Transformation::CreateAutogeneratedNames;
19 use CXGN::Transformation::Transformation;
20 use SGN::Model::Cvterm;
21 use CXGN::Location::LocationLookup;
22 use CXGN::List;
23 use CXGN::Stock::Status;
25 use File::Basename qw | basename dirname|;
26 use File::Copy;
27 use File::Slurp;
28 use File::Spec::Functions;
29 use Digest::MD5;
30 use File::Path qw(make_path);
31 use File::Spec::Functions qw / catfile catdir/;
33 use LWP::UserAgent;
34 use LWP::Simple;
35 use HTML::Entities;
36 use URI::Encode qw(uri_encode uri_decode);
37 use Tie::UrlEncoder; our(%urlencode);
40 BEGIN { extends 'Catalyst::Controller::REST' }
42 __PACKAGE__->config(
43 default => 'application/json',
44 stash_key => 'rest',
45 map => { 'application/json' => 'JSON', 'text/html' => 'JSON' },
49 sub create_tracking_activity_project : Path('/ajax/tracking_activity/create_tracking_activity_project') : ActionClass('REST'){ }
51 sub create_tracking_activity_project_POST : Args(0) {
52 my $self = shift;
53 my $c = shift;
54 my $schema = $c->dbic_schema('Bio::Chado::Schema', 'sgn_chado');
55 my $dbh = $c->dbc->dbh;
56 my $project_name = $c->req->param("project_name");
57 my $activity_type = $c->req->param("activity_type");
58 my $breeding_program_id = $c->req->param("breeding_program");
59 my $project_location = $c->req->param("project_location");
60 my $year = $c->req->param("year");
61 my $project_description = $c->req->param("project_description");
63 my $user = $c->user();
64 if (!$user) {
65 $c->res->redirect( uri( path => '/user/login', query => { goto_url => $c->req->uri->path_query } ) );
66 return;
69 if (!($user->has_role('submitter') or $user->has_role('curator'))) {
70 $c->stash->{rest} = { error => "You do not have sufficient privileges to create tracking activity project." };
71 return;
74 my $program_name = $schema->resultset('Project::Project')->find({project_id => $breeding_program_id})->name();
75 my @user_roles = $c->user->roles();
76 my %has_roles = ();
77 map { $has_roles{$_} = 1; } @user_roles;
79 if (! ( (exists($has_roles{$program_name}) && exists($has_roles{submitter})) || exists($has_roles{curator}))) {
80 $c->stash->{rest} = { error => "You need to be either a curator, or a submitter associated with breeding program $program_name to add tracking project." };
81 return;
84 my $user_id = $c->user()->get_object()->get_sp_person_id();
86 my $geolocation_lookup = CXGN::Location::LocationLookup->new(schema =>$schema);
87 $geolocation_lookup->set_location_name($project_location);
88 if(!$geolocation_lookup->get_geolocation()){
89 $c->stash->{rest}={error => "Location not found"};
90 return;
93 my $return;
94 eval{
95 my $add_activity_project = CXGN::TrackingActivity::AddActivityProject->new({
96 bcs_schema => $schema,
97 dbh => $dbh,
98 breeding_program_id => $breeding_program_id,
99 year => $year,
100 project_description => $project_description,
101 activity_project_name => $project_name,
102 activity_type => $activity_type,
103 nd_geolocation_id => $geolocation_lookup->get_geolocation()->nd_geolocation_id(),
104 owner_id => $user_id
107 $return = $add_activity_project->save_activity_project();
110 if (!$return){
111 $c->stash->{rest} = {error => "Error saving project",};
112 return;
115 if ($return->{error}){
116 $c->stash->{rest} = {error => $return->{error}};
117 return;
120 if ($@) {
121 $c->stash->{rest} = {error => $@};
122 return;
123 } else {
124 $c->stash->{rest} = {success => 1};
131 sub generate_tracking_identifiers : Path('/ajax/tracking_activity/generate_tracking_identifiers') : ActionClass('REST'){ }
133 sub generate_tracking_identifiers_POST : Args(0) {
134 my $self = shift;
135 my $c = shift;
136 my $project_name = $c->req->param("project_name");
137 my $list_id = $c->req->param("list_id");
138 my $program_name = $c->req->param("program_name");
140 if (!$c->user()) {
141 $c->stash->{rest} = { error => "You must be logged in to generate tracking identifiers." };
142 return;
144 if (!($c->user()->has_role('submitter') or $c->user()->has_role('curator'))) {
145 $c->stash->{rest} = { error => "You do not have sufficient privileges to add tracking identifiers." };
146 return;
149 my @user_roles = $c->user->roles();
150 my %has_roles = ();
151 map { $has_roles{$_} = 1; } @user_roles;
153 if (! ( (exists($has_roles{$program_name}) && exists($has_roles{submitter})) || exists($has_roles{curator}))) {
154 $c->stash->{rest} = { error => "You need to be either a curator, or a submitter associated with breeding program $program_name to add tracking identifiers." };
155 return;
158 my $user_id = $c->user()->get_object()->get_sp_person_id();
159 my $schema = $c->dbic_schema('Bio::Chado::Schema', 'sgn_chado');
160 my $phenome_schema = $c->dbic_schema("CXGN::Phenome::Schema");
161 my $dbh = $c->dbc->dbh();
163 my $project_id;
164 my $project_rs = $schema->resultset("Project::Project")->find( { name => $project_name });
165 if (!$project_rs) {
166 $c->stash->{rest} = { error => "Error! Project name: $project_name was not found in the database.\n" };
167 return;
168 } else {
169 $project_id = $project_rs->project_id();
172 my $activity_project = CXGN::TrackingActivity::ActivityProject->new(bcs_schema => $schema, trial_id => $project_id);
173 my $all_identifiers = $activity_project->get_project_active_identifiers();
174 my $last_number = scalar (@$all_identifiers);
176 my $list = CXGN::List->new( { dbh=>$dbh, list_id=>$list_id });
177 my $material_names = $list->elements();
179 my @check_identifier_names;
180 my @tracking_identifiers;
181 my @error_messages;
182 foreach my $name (sort @$material_names) {
183 $last_number++;
184 # my $tracking_id = $project_name.":".$name."_"."T".(sprintf "%04d", $last_number);
185 my $tracking_id = $project_name.":".$name."_"."T".$last_number;
186 push @tracking_identifiers, [$tracking_id, $name];
187 push @check_identifier_names, $tracking_id;
190 my $rs = $schema->resultset("Stock::Stock")->search({
191 'is_obsolete' => { '!=' => 't' },
192 'uniquename' => { -in => \@check_identifier_names }
194 while (my $r=$rs->next){
195 push @error_messages, "Tracking identifier name already exists in database: ".$r->uniquename;
198 if (scalar(@error_messages) >= 1) {
199 $c->stash->{rest} = { error => \@error_messages};
200 return;
203 foreach my $identifier_info (@tracking_identifiers) {
204 my $tracking_identifier = $identifier_info->[0];
205 my $material = $identifier_info->[1];
207 my $tracking_obj = CXGN::TrackingActivity::AddTrackingIdentifier->new({
208 schema => $schema,
209 phenome_schema => $phenome_schema,
210 tracking_identifier => $tracking_identifier,
211 material => $material,
212 project_id => $project_id,
213 user_id => $user_id
216 my $return = $tracking_obj->store();
217 if (!$return) {
218 $c->stash->{rest} = {error => "Error generating tracking identifier"};
219 return;
220 } elsif ($return->{error}) {
221 my $error = $return->{error};
222 $c->stash->{rest} = {error => $error};
223 return;
227 $c->stash->{rest} = { success => 1};
232 sub activity_info_save : Path('/ajax/tracking_activity/save') : ActionClass('REST'){ }
234 sub activity_info_save_POST : Args(0) {
235 my $self = shift;
236 my $c = shift;
237 my $tracking_identifier = $c->req->param("tracking_identifier_name");
238 my $tracking_identifier_id = $c->req->param("tracking_identifier_id");
239 my $selected_type = $c->req->param("selected_type");
240 my $input = $c->req->param("input");
241 my $notes = $c->req->param("notes");
242 my $record_timestamp = $c->req->param("record_timestamp");
243 my $activity_type = $c->req->param("activity_type");
244 my $program_name = $c->req->param("program_name");
245 my $tracking_transformation = $c->config->{tracking_transformation};
247 if (!$c->user()) {
248 $c->stash->{rest} = { error => "You must be logged in to add new information." };
249 return;
251 if (!($c->user()->has_role('submitter') or $c->user()->has_role('curator'))) {
252 $c->stash->{rest} = { error => "You do not have sufficient privileges to record new information." };
253 return;
256 my @user_roles = $c->user->roles();
257 my %has_roles = ();
258 map { $has_roles{$_} = 1; } @user_roles;
260 if (! ( (exists($has_roles{$program_name}) && exists($has_roles{submitter})) || exists($has_roles{curator}))) {
261 $c->stash->{rest} = { error => "You need to be either a curator, or a submitter associated with breeding program $program_name to record new information." };
262 return;
265 my $user_id = $c->user()->get_object()->get_sp_person_id();
267 if ($selected_type =~ m/number/ && !($input =~ /^\d+?$/) ) {
268 $c->stash->{rest} = {error => "Input is not a positive integer"};
269 return;
272 my $schema = $c->dbic_schema('Bio::Chado::Schema', 'sgn_chado');
273 my $phenome_schema = $c->dbic_schema("CXGN::Phenome::Schema");
274 my $dbh = $c->dbc->dbh();
275 my $number_of_transformants;
276 if (($selected_type eq 'number_of_transformants') && $tracking_transformation) {
277 $number_of_transformants = $input;
278 my $tracking_identifier_obj = CXGN::TrackingActivity::TrackingIdentifier->new({schema => $schema, dbh => $dbh, tracking_identifier_stock_id => $tracking_identifier_id});
279 my $project_and_program_info = $tracking_identifier_obj->get_associated_project_program();
280 my $program_id = $project_and_program_info->[0]->[2];
281 my $linked_project_id = $project_and_program_info->[0]->[4];
282 my $autogenerated_name_prefix_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'autogenerated_name_prefix', 'project_property')->cvterm_id();
283 my $material_of_type_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'material_of', 'stock_relationship')->cvterm_id;
285 if ($linked_project_id) {
286 my $new_names_info;
287 my $stored_prefix = $schema->resultset('Project::Projectprop')->find({ project_id => $linked_project_id, type_id => $autogenerated_name_prefix_cvterm_id});
288 if (!$stored_prefix) {
289 $c->stash->{rest} = {error => "Please set up prefix for autogenerated names for this transformation project before using tracking tool"};
290 return;
291 } else {
292 my $prefix = $stored_prefix->value();
293 my $autogenerated_names = CXGN::Transformation::CreateAutogeneratedNames->new({schema => $schema, dbh => $dbh, breeding_program_id => $program_id, prefix => $prefix, number_of_names => $number_of_transformants });
294 my $return = $autogenerated_names->create_names();
295 if (!$return){
296 $c->stash->{rest} = {error => "Error generating transformant names"};
297 return;
298 } elsif ($return->{error}) {
299 $c->stash->{rest} = {error => $return->{error}};
300 return;
303 $new_names_info = $return->{new_names};
304 my $new_names = $new_names_info->{'new_autogenerated_names'};
305 my $new_last_serial_number = $new_names_info->{'new_last_serial_number'};
307 my $transformation_stock_id = $schema->resultset("Stock::StockRelationship")->find({object_id=>$tracking_identifier_id, type_id=>$material_of_type_id})->subject_id();
308 my $add_transformants = CXGN::Transformation::AddTransformant->new({
309 schema => $schema,
310 phenome_schema => $phenome_schema,
311 dbh => $dbh,
312 transformation_stock_id => $transformation_stock_id,
313 transformant_names => $new_names,
314 owner_id => $user_id,
317 $add_transformants->add_transformant();
319 my $name_metadata_cvterm = SGN::Model::Cvterm->get_cvterm_row($schema, 'autogenerated_name_metadata', 'project_property');
320 my $program = $schema->resultset('Project::Project')->find({ project_id => $program_id});
321 my $metadata_projectprop_rs = $program->projectprops({type_id => $name_metadata_cvterm->cvterm_id});
322 if ($metadata_projectprop_rs->count == 1){
323 my $stored_name_metadata_string = $metadata_projectprop_rs->first->value();
324 my $name_metadata_hash = decode_json $stored_name_metadata_string;
325 $name_metadata_hash->{$prefix}->{'last_serial_number'} = $new_last_serial_number;
326 my $new_name_metadata_string = encode_json $name_metadata_hash;
327 $metadata_projectprop_rs->first->update({value=>$new_name_metadata_string});
333 my $add_activity_info = CXGN::TrackingActivity::ActivityInfo->new({
334 schema => $schema,
335 tracking_identifier => $tracking_identifier,
336 selected_type => $selected_type,
337 input => $input,
338 timestamp => $record_timestamp,
339 operator_id => $user_id,
340 notes => $notes,
341 activity_type => $activity_type
343 my $return = $add_activity_info->add_info();
345 if (!$return){
346 $c->stash->{rest} = {error => "Error saving info",};
347 return;
348 } else {
349 $c->stash->{rest} = $return;
355 sub get_activity_details :Path('/ajax/tracking_activity/details') :Args(1) {
356 my $self = shift;
357 my $c = shift;
358 my $identifier_id = shift;
359 my $schema = $c->dbic_schema('Bio::Chado::Schema', 'sgn_chado');
360 my $dbh = $c->dbc->dbh;
362 my $tracking_identifier_obj = CXGN::TrackingActivity::TrackingIdentifier->new({schema=>$schema, dbh=>$dbh, tracking_identifier_stock_id=>$identifier_id});
363 my $associated_projects = $tracking_identifier_obj->get_associated_project_program();
364 my $tracking_project_id = $associated_projects->[0]->[0];
365 my $tracking_project = CXGN::TrackingActivity::ActivityProject->new(bcs_schema => $schema, trial_id => $tracking_project_id);
366 my $activity_type = $tracking_project->get_project_activity_type();
369 my $tracking_activities;
370 my $tracking_data_json_cvterm_id;
371 if ($activity_type eq 'tissue_culture') {
372 $tracking_activities = $c->config->{tracking_tissue_culture_info};
373 } elsif ($activity_type eq 'transformation') {
374 $tracking_activities = $c->config->{tracking_transformation_info};
377 my @details;
378 my @activity_types = split ',',$tracking_activities;
380 my $tracking_identifier_info = $tracking_identifier_obj->get_tracking_identifier_info();
381 my $tracking_identifier_stockprop = $tracking_identifier_info->[0]->[5];
383 if ($tracking_identifier_stockprop) {
384 my $info = JSON::Any->jsonToObj($tracking_identifier_stockprop);
385 my %info_hash = %{$info};
386 foreach my $type (@activity_types){
387 my $empty_string;
388 my @each_type_details = ();
389 my $each_timestamp_string;
390 my $each_type_string;
391 if ($info_hash{$type}) {
392 my @each_type_details = ();
393 my $details = {};
394 my %details_hash = ();
395 $details = $info_hash{$type};
396 %details_hash = %{$details};
397 foreach my $timestamp (sort keys %details_hash) {
398 my @each_timestamp_details = ();
399 push @each_timestamp_details, "timestamp".":"."".$timestamp;
400 my $operator_id = $details_hash{$timestamp}{'operator_id'};
402 my $person= CXGN::People::Person->new($dbh, $operator_id);
403 my $operator_name = $person->get_first_name()." ".$person->get_last_name();
405 push @each_timestamp_details, "operator".":"."".$operator_name;
406 my $input = $details_hash{$timestamp}{'input'};
407 push @each_timestamp_details, "input".":"."".$input;
408 my $notes = $details_hash{$timestamp}{'notes'};
409 push @each_timestamp_details, "notes".":"."".$notes;
411 push @each_timestamp_details, $empty_string;
413 $each_timestamp_string = join("<br>", @each_timestamp_details);
414 push @each_type_details, $each_timestamp_string;
417 $each_type_string = join("<br>", @each_type_details);
418 # print STDERR "EACH TYPE STRING =".Dumper($each_type_string)."\n";
419 push @details, $each_type_string;
420 } else {
421 my $empty_string;
422 push @details, $empty_string;
425 } else {
426 foreach my $type (@activity_types) {
427 push @details, 'NA';
431 my @all_details;
432 push @all_details, [@details];
434 $c->stash->{rest} = { data => \@all_details };
439 sub get_activity_summary :Path('/ajax/tracking_activity/summary') :Args(1) {
440 my $self = shift;
441 my $c = shift;
442 my $identifier_id = shift;
443 my $schema = $c->dbic_schema('Bio::Chado::Schema', 'sgn_chado');
444 my $dbh = $c->dbc->dbh;
446 my $tracking_identifier_obj = CXGN::TrackingActivity::TrackingIdentifier->new({schema=>$schema, dbh=>$dbh, tracking_identifier_stock_id=>$identifier_id});
447 my $associated_projects = $tracking_identifier_obj->get_associated_project_program();
448 my $tracking_project_id = $associated_projects->[0]->[0];
449 my $tracking_project = CXGN::TrackingActivity::ActivityProject->new(bcs_schema => $schema, trial_id => $tracking_project_id);
450 my $activity_type = $tracking_project->get_project_activity_type();
452 my $tracking_activities;
453 my $tracking_data_json_cvterm_id;
454 if ($activity_type eq 'tissue_culture') {
455 $tracking_activities = $c->config->{tracking_tissue_culture_info};
456 } elsif ($activity_type eq 'transformation') {
457 $tracking_activities = $c->config->{tracking_transformation_info};
460 my @summary = ();
461 my @activity_types = split ',',$tracking_activities;
463 my $tracking_identifier_info = $tracking_identifier_obj->get_tracking_identifier_info();
464 my $tracking_identifier_stockprop = $tracking_identifier_info->[0]->[5];
465 my $material_stock_type = $tracking_identifier_info->[0]->[4];
466 my $material_stock_id = $tracking_identifier_info->[0]->[2];
468 my $obsoleted_transformant_count;
469 if ($material_stock_type eq 'transformation') {
470 my $transformation_obj = CXGN::Transformation::Transformation->new({schema=>$schema, dbh=>$dbh, transformation_stock_id=>$material_stock_id});
471 my $obsoleted_transformants = $transformation_obj->get_obsoleted_transformants();
472 if ($obsoleted_transformants) {
473 $obsoleted_transformant_count = scalar @$obsoleted_transformants;
477 if ($tracking_identifier_stockprop) {
478 my $info = JSON::Any->jsonToObj($tracking_identifier_stockprop);
479 my %info_hash = %{$info};
480 foreach my $type (@activity_types){
481 my $input = '';
482 my $empty_string;
483 my @each_type_details = ();
484 my $each_timestamp_string;
485 my $each_type_string;
486 if ($info_hash{$type}) {
487 my $details = {};
488 my %details_hash = ();
489 $details = $info_hash{$type};
490 %details_hash = %{$details};
492 if (($type =~ m/number/) || ($type =~ m/count/)) {
493 $input = 0;
494 foreach my $key (keys %details_hash) {
495 $input += $details_hash{$key}{'input'};
498 if (($type eq 'number_of_transformants') && ($obsoleted_transformant_count >= 1)) {
499 my @details = ();
500 my $generated_count = 'Selected'. ":"." ".$input;
501 my $obsoleted_count = 'Obsoleted'. ":"." ".$obsoleted_transformant_count;
502 my $current_number = 'Current Number'. ":"." ".($input-=$obsoleted_transformant_count);
503 push @details, ($generated_count, $obsoleted_count, $current_number);
504 my $details_string = join("<br>", @details);
505 push @summary, $details_string;
506 } else {
507 push @summary, $input;
509 } elsif ($type =~ m/date/) {
510 foreach my $key (keys %details_hash) {
511 $input = $details_hash{$key}{'input'};
513 push @summary, $input;
515 } else {
516 push @summary, $input;
519 } else {
520 foreach my $type (@activity_types) {
521 push @summary, 'NA';
525 my @all_summary;
526 push @all_summary, [@summary];
528 $c->stash->{rest} = { data => \@all_summary };
532 sub get_project_active_identifiers :Path('/ajax/tracking_activity/project_active_identifiers') :Args(1) {
533 my $self = shift;
534 my $c = shift;
535 my $project_id = shift;
536 my $schema = $c->dbic_schema('Bio::Chado::Schema', 'sgn_chado');
538 my $tracking_project = CXGN::TrackingActivity::ActivityProject->new(bcs_schema => $schema, trial_id => $project_id);
539 my $activity_type = $tracking_project->get_project_activity_type();
541 my $tracking_activities;
542 if ($activity_type eq 'tissue_culture') {
543 $tracking_activities = $c->config->{tracking_tissue_culture_info};
544 } elsif ($activity_type eq 'transformation') {
545 $tracking_activities = $c->config->{tracking_transformation_info};
548 my @activity_types = split ',',$tracking_activities;
549 my $transformation_type_id = SGN::Model::Cvterm->get_cvterm_row($schema, "transformation", 'stock_type')->cvterm_id();
551 my $activity_project = CXGN::TrackingActivity::ActivityProject->new(bcs_schema => $schema, trial_id => $project_id);
552 my $all_identifier_info = $activity_project->get_project_active_identifiers();
553 my @all_identifiers;
554 foreach my $identifier_info (@$all_identifier_info) {
555 my @row = ();
556 my $identifier_id = $identifier_info->[0];
557 my $identifier_name = $identifier_info->[1];
558 push @row, qq{<a href="/activity/details/$identifier_id">$identifier_name</a>};
560 my $material_id = $identifier_info->[2];
561 my $material_rs = $schema->resultset("Stock::Stock")->find( { stock_id => $material_id });
562 my $material_stock_type_id = $material_rs->type_id;
563 my $material_name = $identifier_info->[3];
564 if ($material_stock_type_id == $transformation_type_id) {
565 push @row, qq{<a href="/transformation/$material_id">$material_name</a>}
566 } else {
567 push @row, qq{<a href="/stock/$material_id/view">$material_name</a>};
569 my $progress = $identifier_info->[5];
570 if ($progress) {
571 my $progress_ref = JSON::Any->jsonToObj($progress);
572 my %progress_hash = %{$progress_ref};
573 foreach my $type (@activity_types){
574 my $input = '';
575 if ($progress_hash{$type}) {
576 my $details = {};
577 my %details_hash = ();
578 $details = $progress_hash{$type};
579 %details_hash = %{$details};
581 if (($type =~ m/number/) || ($type =~ m/count/)) {
582 $input = 0;
583 foreach my $key (keys %details_hash) {
584 $input += $details_hash{$key}{'input'};
586 push @row, $input;
587 } elsif ($type =~ m/date/) {
588 foreach my $key (keys %details_hash) {
589 $input = $details_hash{$key}{'input'};
591 push @row, $input;
593 } else {
594 push @row, $input;
597 } else {
598 foreach my $type (@activity_types) {
599 push @row, '';
602 push @row, $identifier_name;
603 push @all_identifiers,[@row];
606 $c->stash->{rest} = { data => \@all_identifiers };
611 sub get_project_active_identifier_names :Path('/ajax/tracking_activity/project_active_identifier_names') :Args(1) {
612 my $self = shift;
613 my $c = shift;
614 my $project_id = shift;
615 my $schema = $c->dbic_schema('Bio::Chado::Schema', 'sgn_chado');
617 my $activity_project = CXGN::TrackingActivity::ActivityProject->new(bcs_schema => $schema, trial_id => $project_id);
618 my $all_identifier_info = $activity_project->get_project_active_identifiers();
619 my @identifier_names;
620 foreach my $identifier_info (@$all_identifier_info) {
621 push @identifier_names, $identifier_info->[1];
624 $c->stash->{rest} = { data => \@identifier_names };
629 sub update_status : Path('/ajax/tracking_activity/update_status') : ActionClass('REST'){ }
631 sub update_status_POST : Args(0) {
632 my $self = shift;
633 my $c = shift;
634 my $schema = $c->dbic_schema('Bio::Chado::Schema', 'sgn_chado');
635 my $dbh = $c->dbc->dbh();
636 my $identifier_id = $c->req->param("identifier_id");
637 my $status_type = $c->req->param("status_type");
638 my $comments = $c->req->param("comments");
639 my $material_id = $c->req->param("material_id");
640 my $program_name = $c->req->param("program_name");
641 my $time = DateTime->now();
642 my $update_date = $time->ymd();
643 my @stocks_to_update;
645 if (!$c->user()){
646 $c->stash->{rest} = { error_string => "You must be logged in to update status" };
647 return;
649 if (!$c->user()->check_roles("curator")) {
650 $c->stash->{rest} = { error_string => "You do not have the correct role to update status. Please contact us." };
651 return;
654 my @user_roles = $c->user->roles();
655 my %has_roles = ();
656 map { $has_roles{$_} = 1; } @user_roles;
658 if (! ( (exists($has_roles{$program_name}) && exists($has_roles{submitter})) || exists($has_roles{curator}))) {
659 $c->stash->{rest} = { error => "You need to be either a curator, or a submitter associated with breeding program $program_name to update status." };
660 return;
663 my $user_id = $c->user()->get_object()->get_sp_person_id();
665 my $tracking_identifier_type_id = SGN::Model::Cvterm->get_cvterm_row($schema, "tracking_identifier", 'stock_type')->cvterm_id();
666 my $transformation_type_id = SGN::Model::Cvterm->get_cvterm_row($schema, "transformation", 'stock_type')->cvterm_id();
668 my $identifier_rs = $schema->resultset("Stock::Stock")->find( { stock_id => $identifier_id, type_id => $tracking_identifier_type_id });
669 if (!$identifier_rs) {
670 $c->stash->{rest} = { error_string => 'Error. No tracking identifier entry found in the database.' };
671 return;
672 } else {
673 push @stocks_to_update, $identifier_id;
676 my $material_stock_type_id;
677 my $material_rs = $schema->resultset("Stock::Stock")->find( { stock_id => $material_id });
678 if (!$material_rs) {
679 $c->stash->{rest} = { error_string => 'Error. No material entry found in the database.' };
680 return;
681 } else {
682 $material_stock_type_id = $material_rs->type_id;
685 if ($material_stock_type_id == $transformation_type_id) {
686 push @stocks_to_update, $material_id;
689 my $completed_metadata;
690 my $terminated_metadata;
691 if ($status_type eq 'completed') {
692 $completed_metadata = 1;
693 } elsif ($status_type eq 'terminated') {
694 $terminated_metadata = 1;
697 foreach my $stock_id (@stocks_to_update) {
698 my $update_status = CXGN::Stock::Status->new({
699 bcs_schema => $schema,
700 parent_id => $stock_id,
701 person_id => $user_id,
702 update_date => $update_date,
703 comments => $comments,
704 completed_metadata => $completed_metadata,
705 terminated_metadata => $terminated_metadata
708 $update_status->store();
710 if (!$update_status->store()){
711 $c->stash->{rest} = {error_string => "Error updating status"};
712 return;
716 $c->stash->{rest} = {success => "1",};
720 sub reverse_status : Path('/ajax/tracking_activity/reverse_status') : ActionClass('REST'){ }
722 sub reverse_status_POST : Args(0) {
723 my $self = shift;
724 my $c = shift;
725 my $schema = $c->dbic_schema('Bio::Chado::Schema', 'sgn_chado');
726 my $dbh = $c->dbc->dbh();
727 my $identifier_id = $c->req->param("identifier_id");
728 my $updated_status_type = $c->req->param("updated_status_type");
729 my $material_id = $c->req->param("material_id");
730 my $program_name = $c->req->param("program_name");
732 if (!$c->user()){
733 $c->stash->{rest} = { error_string => "You must be logged in to reverse status of this tracking identifier" };
734 return;
736 if (!$c->user()->check_roles("curator")) {
737 $c->stash->{rest} = { error_string => "You do not have the correct role to reverse status of this tracking identifier. Please contact us." };
738 return;
741 my @user_roles = $c->user->roles();
742 my %has_roles = ();
743 map { $has_roles{$_} = 1; } @user_roles;
745 if (! ( (exists($has_roles{$program_name}) && exists($has_roles{submitter})) || exists($has_roles{curator}))) {
746 $c->stash->{rest} = { error => "You need to be either a curator, or a submitter associated with breeding program $program_name to update status." };
747 return;
750 my $user_id = $c->user()->get_object()->get_sp_person_id();
752 my $status_type_id;
753 if ($updated_status_type) {
754 $status_type_id = SGN::Model::Cvterm->get_cvterm_row($schema, $updated_status_type, 'stock_property')->cvterm_id();
755 my $status_stockprop_rs = $schema->resultset("Stock::Stockprop")->find({stock_id => $identifier_id, type_id => $status_type_id});
757 if (defined $status_stockprop_rs->stockprop_id) {
758 $status_stockprop_rs->delete();
762 my $material_stock_type_id;
763 my $material_rs = $schema->resultset("Stock::Stock")->find( { stock_id => $material_id });
764 if (!$material_rs) {
765 $c->stash->{rest} = { error_string => 'Error. No material entry found in the database.' };
766 return;
767 } else {
768 $material_stock_type_id = $material_rs->type_id;
771 my $transformation_type_id = SGN::Model::Cvterm->get_cvterm_row($schema, "transformation", 'stock_type')->cvterm_id();
773 if ($material_stock_type_id == $transformation_type_id) {
774 if ($status_type_id) {
775 my $transformation_stockprop_rs = $schema->resultset("Stock::Stockprop")->find({stock_id => $material_id, type_id => $status_type_id});
777 if (defined $transformation_stockprop_rs->stockprop_id) {
778 $transformation_stockprop_rs->delete();
783 $c->stash->{rest} = { success => 1 };
788 sub get_project_inactive_identifiers :Path('/ajax/tracking_activity/project_inactive_identifiers') :Args(1) {
789 my $self = shift;
790 my $c = shift;
791 my $project_id = shift;
792 my $schema = $c->dbic_schema('Bio::Chado::Schema', 'sgn_chado');
794 my $tracking_project = CXGN::TrackingActivity::ActivityProject->new(bcs_schema => $schema, trial_id => $project_id);
795 my $activity_type = $tracking_project->get_project_activity_type();
797 my $tracking_activities;
798 if ($activity_type eq 'tissue_culture') {
799 $tracking_activities = $c->config->{tracking_tissue_culture_info};
800 } elsif ($activity_type eq 'transformation') {
801 $tracking_activities = $c->config->{tracking_transformation_info};
804 my @activity_types = split ',',$tracking_activities;
806 my $transformation_type_id = SGN::Model::Cvterm->get_cvterm_row($schema, "transformation", 'stock_type')->cvterm_id();
808 my $activity_project = CXGN::TrackingActivity::ActivityProject->new(bcs_schema => $schema, trial_id => $project_id);
809 my $all_identifier_info = $activity_project->get_project_inactive_identifiers();
810 my @all_identifiers;
811 foreach my $identifier_info (@$all_identifier_info) {
812 my @row = ();
813 my $identifier_id = $identifier_info->[0];
814 my $identifier_name = $identifier_info->[1];
815 push @row, qq{<a href="/activity/details/$identifier_id">$identifier_name</a>};
817 my $status = $identifier_info->[6];
818 if ($status eq 'terminated_metadata') {
819 $status = '<span style="color:red">'.'TERMINATED'.'</span>';
820 } elsif ($status eq 'completed_metadata') {
821 $status = '<span style="color:red">'.'COMPLETED'.'</span>';
823 push @row, $status;
825 my $material_id = $identifier_info->[2];
826 my $material_name = $identifier_info->[3];
827 my $material_rs = $schema->resultset("Stock::Stock")->find( { stock_id => $material_id });
828 my $material_stock_type_id = $material_rs->type_id;
829 if ($material_stock_type_id == $transformation_type_id) {
830 push @row, qq{<a href="/transformation/$material_id">$material_name</a>}
831 } else {
832 push @row, qq{<a href="/stock/$material_id/view">$material_name</a>};
835 my $progress = $identifier_info->[5];
836 if ($progress) {
837 my $progress_ref = JSON::Any->jsonToObj($progress);
838 my %progress_hash = %{$progress_ref};
839 foreach my $type (@activity_types){
840 my $input = '';
841 if ($progress_hash{$type}) {
842 my $details = {};
843 my %details_hash = ();
844 $details = $progress_hash{$type};
845 %details_hash = %{$details};
847 if (($type =~ m/number/) || ($type =~ m/count/)) {
848 $input = 0;
849 foreach my $key (keys %details_hash) {
850 $input += $details_hash{$key}{'input'};
852 push @row, $input;
853 } elsif ($type =~ m/date/) {
854 foreach my $key (keys %details_hash) {
855 $input = $details_hash{$key}{'input'};
857 push @row, $input;
859 } else {
860 push @row, $input;
863 } else {
864 foreach my $type (@activity_types) {
865 push @row, '';
868 push @row, $identifier_name;
869 push @all_identifiers,[@row];
872 $c->stash->{rest} = { data => \@all_identifiers };