customized field headers
[sgn.git] / lib / SGN / Controller / AJAX / TrackingActivity.pm
blob743fda1f0194d934e7b58fa8f1c9ac031848b041
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 SGN::Model::Cvterm;
20 use CXGN::Location::LocationLookup;
21 use CXGN::List;
22 use CXGN::Stock::Status;
24 use File::Basename qw | basename dirname|;
25 use File::Copy;
26 use File::Slurp;
27 use File::Spec::Functions;
28 use Digest::MD5;
29 use File::Path qw(make_path);
30 use File::Spec::Functions qw / catfile catdir/;
32 use LWP::UserAgent;
33 use LWP::Simple;
34 use HTML::Entities;
35 use URI::Encode qw(uri_encode uri_decode);
36 use Tie::UrlEncoder; our(%urlencode);
39 BEGIN { extends 'Catalyst::Controller::REST' }
41 __PACKAGE__->config(
42 default => 'application/json',
43 stash_key => 'rest',
44 map => { 'application/json' => 'JSON', 'text/html' => 'JSON' },
48 sub create_tracking_activity_project : Path('/ajax/tracking_activity/create_tracking_activity_project') : ActionClass('REST'){ }
50 sub create_tracking_activity_project_POST : Args(0) {
51 my $self = shift;
52 my $c = shift;
54 my $user = $c->user();
55 if (!$user) {
56 $c->res->redirect( uri( path => '/user/login', query => { goto_url => $c->req->uri->path_query } ) );
57 return;
60 if (!($user->has_role('submitter') or $user->has_role('curator'))) {
61 $c->stash->{rest} = { error => "You do not have sufficient privileges to create tracking activity project." };
62 return;
65 my $user_id = $c->user()->get_object()->get_sp_person_id();
66 my $schema = $c->dbic_schema('Bio::Chado::Schema', 'sgn_chado');
67 my $dbh = $c->dbc->dbh;
69 my $project_name = $c->req->param("project_name");
70 my $activity_type = $c->req->param("activity_type");
71 my $breeding_program_id = $c->req->param("breeding_program");
72 my $project_location = $c->req->param("project_location");
73 my $year = $c->req->param("year");
74 my $project_description = $c->req->param("project_description");
76 my $geolocation_lookup = CXGN::Location::LocationLookup->new(schema =>$schema);
77 $geolocation_lookup->set_location_name($project_location);
78 if(!$geolocation_lookup->get_geolocation()){
79 $c->stash->{rest}={error => "Location not found"};
80 return;
83 my $error;
84 eval{
85 my $add_activity_project = CXGN::TrackingActivity::AddActivityProject->new({
86 bcs_schema => $schema,
87 dbh => $dbh,
88 breeding_program_id => $breeding_program_id,
89 year => $year,
90 project_description => $project_description,
91 activity_project_name => $project_name,
92 activity_type => $activity_type,
93 nd_geolocation_id => $geolocation_lookup->get_geolocation()->nd_geolocation_id(),
94 owner_id => $user_id
95 });
97 my $return = $add_activity_project->save_activity_project();
98 if (!$return){
99 $c->stash->{rest} = {error => "Error saving project",};
100 return;
103 # if ($return->{error}){
104 # $error = $return->{error};
108 if ($@) {
109 $c->stash->{rest} = {error => $@};
110 return;
114 if ($error){
115 $c->stash->{rest} = {error => $error};
116 } else {
117 $c->stash->{rest} = {success => 1};
123 sub generate_tracking_identifiers : Path('/ajax/tracking_activity/generate_tracking_identifiers') : ActionClass('REST'){ }
125 sub generate_tracking_identifiers_POST : Args(0) {
126 my $self = shift;
127 my $c = shift;
129 if (!$c->user()) {
130 $c->stash->{rest} = { error_string => "You must be logged in to generate tracking identifiers." };
131 return;
133 if (!($c->user()->has_role('submitter') or $c->user()->has_role('curator'))) {
134 $c->stash->{rest} = { error_string => "You do not have sufficient privileges to generate tracking identifiers." };
135 return;
138 my $user_id = $c->user()->get_object()->get_sp_person_id();
139 my $schema = $c->dbic_schema('Bio::Chado::Schema', 'sgn_chado');
140 my $phenome_schema = $c->dbic_schema("CXGN::Phenome::Schema");
141 my $dbh = $c->dbc->dbh();
143 my $project_name = $c->req->param("project_name");
144 my $list_id = $c->req->param("list_id");
145 my $project_id;
146 my $project_rs = $schema->resultset("Project::Project")->find( { name => $project_name });
147 if (!$project_rs) {
148 $c->stash->{rest} = { error_string => "Error! Project name: $project_name was not found in the database.\n" };
149 return;
150 } else {
151 $project_id = $project_rs->project_id();
154 my $activity_project = CXGN::TrackingActivity::ActivityProject->new(bcs_schema => $schema, trial_id => $project_id);
155 my $all_identifiers = $activity_project->get_project_active_identifiers();
156 my $last_number = scalar (@$all_identifiers);
158 my $list = CXGN::List->new( { dbh=>$dbh, list_id=>$list_id });
159 my $material_names = $list->elements();
161 my @check_identifier_names;
162 my @tracking_identifiers;
163 my @error_messages;
164 foreach my $name (sort @$material_names) {
165 $last_number++;
166 my $tracking_id = $project_name.":".$name."_"."T".(sprintf "%04d", $last_number);
167 push @tracking_identifiers, [$tracking_id, $name];
168 push @check_identifier_names, $tracking_id;
171 my $rs = $schema->resultset("Stock::Stock")->search({
172 'is_obsolete' => { '!=' => 't' },
173 'uniquename' => { -in => \@check_identifier_names }
175 while (my $r=$rs->next){
176 push @error_messages, "Tracking identifier name already exists in database: ".$r->uniquename;
179 if (scalar(@error_messages) >= 1) {
180 $c->stash->{rest} = { error_string => \@error_messages};
181 return;
184 foreach my $identifier_info (@tracking_identifiers) {
185 my $tracking_identifier = $identifier_info->[0];
186 my $material = $identifier_info->[1];
188 my $tracking_obj = CXGN::TrackingActivity::AddTrackingIdentifier->new({
189 schema => $schema,
190 phenome_schema => $phenome_schema,
191 tracking_identifier => $tracking_identifier,
192 material => $material,
193 project_id => $project_id,
194 user_id => $user_id
197 my $return = $tracking_obj->store();
198 if (!$return){
199 $c->stash->{rest} = {error_string => "Error generating tracking identifier",};
200 return;
204 $c->stash->{rest} = { success => 1};
209 sub activity_info_save : Path('/ajax/tracking_activity/save') : ActionClass('REST'){ }
211 sub activity_info_save_POST : Args(0) {
212 my $self = shift;
213 my $c = shift;
215 if (!$c->user()) {
216 $c->stash->{rest} = { error => "You must be logged in to add new information." };
217 return;
219 if (!($c->user()->has_role('submitter') or $c->user()->has_role('curator'))) {
220 $c->stash->{rest} = { error => "You do not have sufficient privileges to record new information." };
221 return;
224 my $user_id = $c->user()->get_object()->get_sp_person_id();
226 my $tracking_identifier = $c->req->param("tracking_identifier");
227 my $tracking_identifier_id = $c->req->param("tracking_identifier_id");
228 my $selected_type = $c->req->param("selected_type");
229 my $input = $c->req->param("input");
230 my $notes = $c->req->param("notes");
231 my $record_timestamp = $c->req->param("record_timestamp");
232 my $tracking_transformation = $c->config->{tracking_transformation};
234 if ($selected_type =~ m/number/ && !($input =~ /^\d+?$/) ) {
235 $c->stash->{rest} = {error => "Input is not a positive integer"};
236 return;
239 my $schema = $c->dbic_schema('Bio::Chado::Schema', 'sgn_chado');
240 my $phenome_schema = $c->dbic_schema("CXGN::Phenome::Schema");
241 my $dbh = $c->dbc->dbh();
242 my $number_of_transformants;
243 if (($selected_type eq 'number_of_transformants') && $tracking_transformation) {
244 $number_of_transformants = $input;
245 my $tracking_identifier_obj = CXGN::TrackingActivity::TrackingIdentifier->new({schema => $schema, dbh => $dbh, tracking_identifier_stock_id => $tracking_identifier_id});
246 my $project_and_program_info = $tracking_identifier_obj->get_associated_project_program();
247 my $program_id = $project_and_program_info->[0]->[2];
248 my $linked_project_id = $project_and_program_info->[0]->[4];
249 my $autogenerated_name_prefix_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'autogenerated_name_prefix', 'project_property')->cvterm_id();
250 my $material_of_type_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'material_of', 'stock_relationship')->cvterm_id;
251 if ($linked_project_id) {
252 my $new_names_info;
253 my $stored_prefix = $schema->resultset('Project::Projectprop')->find({ project_id => $linked_project_id, type_id => $autogenerated_name_prefix_cvterm_id});
254 if ($stored_prefix) {
255 my $prefix = $stored_prefix->value();
256 my $autogenerated_names = CXGN::Transformation::CreateAutogeneratedNames->new({schema => $schema, dbh => $dbh, breeding_program_id => $program_id, prefix => $prefix, number_of_names => $number_of_transformants });
257 $new_names_info = $autogenerated_names->create_names();
258 print STDERR "NEW NAMES INFO=".Dumper($new_names_info)."\n";
259 my $new_names = $new_names_info->{'new_autogenerated_names'};
260 my $new_current_serial_number = $new_names_info->{'new_current_serial_number'};
262 my $transformation_stock_id = $schema->resultset("Stock::StockRelationship")->find({object_id=>$tracking_identifier_id, type_id=>$material_of_type_id})->subject_id();
263 my $add_transformants = CXGN::Transformation::AddTransformant->new({
264 schema => $schema,
265 phenome_schema => $phenome_schema,
266 dbh => $dbh,
267 transformation_stock_id => $transformation_stock_id,
268 transformant_names => $new_names,
269 owner_id => $user_id,
272 $add_transformants->add_transformant();
274 my $name_metadata_cvterm = SGN::Model::Cvterm->get_cvterm_row($schema, 'autogenerated_name_metadata', 'project_property');
275 my $program = $schema->resultset('Project::Project')->find({ project_id => $program_id});
276 my $metadata_projectprop_rs = $program->projectprops({type_id => $name_metadata_cvterm->cvterm_id});
277 if ($metadata_projectprop_rs->count == 1){
278 my $stored_name_metadata_string = $metadata_projectprop_rs->first->value();
279 my $name_metadata_hash = decode_json $stored_name_metadata_string;
280 print STDERR "PREVIOUS METADATA =".Dumper($name_metadata_hash)."\n";
281 $name_metadata_hash->{$prefix}->{'current_serial_number'} = $new_current_serial_number;
282 my $new_name_metadata_string = encode_json $name_metadata_hash;
283 print STDERR "UPDATED METADATA =".Dumper($name_metadata_hash)."\n";
284 $metadata_projectprop_rs->first->update({value=>$new_name_metadata_string});
291 my $add_activity_info = CXGN::TrackingActivity::ActivityInfo->new({
292 schema => $schema,
293 tracking_identifier => $tracking_identifier,
294 selected_type => $selected_type,
295 input => $input,
296 timestamp => $record_timestamp,
297 operator_id => $user_id,
298 notes => $notes,
300 my $return = $add_activity_info->add_info();
301 # print STDERR "ADD INFO =".Dumper ($add_activity_info->add_info())."\n";
303 if (!$return){
304 $c->stash->{rest} = {error => "Error saving info",};
305 return;
306 } else {
307 $c->stash->{rest} = $return;
313 sub get_activity_details :Path('/ajax/tracking_activity/details') :Args(1) {
314 my $self = shift;
315 my $c = shift;
316 my $identifier_id = shift;
317 my $schema = $c->dbic_schema('Bio::Chado::Schema', 'sgn_chado');
318 my $dbh = $c->dbc->dbh;
320 my $tracking_identifier_obj = CXGN::TrackingActivity::TrackingIdentifier->new({schema=>$schema, dbh=>$dbh, tracking_identifier_stock_id=>$identifier_id});
321 my $associated_projects = $tracking_identifier_obj->get_associated_project_program();
322 my $tracking_project_id = $associated_projects->[0]->[0];
323 my $tracking_project = CXGN::TrackingActivity::ActivityProject->new(bcs_schema => $schema, trial_id => $tracking_project_id);
324 my $activity_type = $tracking_project->get_project_activity_type();
326 my $tracking_activities;
327 if ($activity_type eq 'tissue_culture') {
328 $tracking_activities = $c->config->{tracking_tissue_culture};
329 } elsif ($activity_type eq 'transformation') {
330 $tracking_activities = $c->config->{tracking_transformation};
333 my @details;
334 my @activity_types = split ',',$tracking_activities;
336 my $tracking_data_json_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'tracking_tissue_culture_json', 'stock_property')->cvterm_id();
337 my $activity_info_rs = $schema->resultset("Stock::Stockprop")->find({stock_id => $identifier_id, type_id => $tracking_data_json_cvterm_id});
338 if ($activity_info_rs) {
339 my $activity_json = $activity_info_rs->value();
340 my $info = JSON::Any->jsonToObj($activity_json);
341 my %info_hash = %{$info};
342 foreach my $type (@activity_types){
343 my $empty_string;
344 my @each_type_details = ();
345 my $each_timestamp_string;
346 my $each_type_string;
347 if ($info_hash{$type}) {
348 my @each_type_details = ();
349 my $details = {};
350 my %details_hash = ();
351 $details = $info_hash{$type};
352 %details_hash = %{$details};
353 # print STDERR "DETAILS HASH =".Dumper(\%details_hash);
354 foreach my $timestamp (sort keys %details_hash) {
355 my @each_timestamp_details = ();
356 push @each_timestamp_details, "timestamp".":"."".$timestamp;
357 my $operator_id = $details_hash{$timestamp}{'operator_id'};
359 my $person= CXGN::People::Person->new($dbh, $operator_id);
360 my $operator_name = $person->get_first_name()." ".$person->get_last_name();
362 push @each_timestamp_details, "operator".":"."".$operator_name;
363 my $input = $details_hash{$timestamp}{'input'};
364 push @each_timestamp_details, "input".":"."".$input;
365 my $notes = $details_hash{$timestamp}{'notes'};
366 push @each_timestamp_details, "notes".":"."".$notes;
368 push @each_timestamp_details, $empty_string;
370 $each_timestamp_string = join("<br>", @each_timestamp_details);
371 push @each_type_details, $each_timestamp_string;
374 $each_type_string = join("<br>", @each_type_details);
375 # print STDERR "EACH TYPE STRING =".Dumper($each_type_string)."\n";
376 push @details, $each_type_string;
377 } else {
378 my $empty_string;
379 push @details, $empty_string;
382 } else {
383 foreach my $type (@activity_types) {
384 push @details, 'NA';
388 my @all_details;
389 push @all_details, [@details];
391 # print STDERR "ALL DETAILS =".Dumper(\@all_details)."\n";
393 $c->stash->{rest} = { data => \@all_details };
398 sub get_activity_summary :Path('/ajax/tracking_activity/summary') :Args(1) {
399 my $self = shift;
400 my $c = shift;
401 my $identifier_id = shift;
402 my $schema = $c->dbic_schema('Bio::Chado::Schema', 'sgn_chado');
403 my $dbh = $c->dbc->dbh;
405 my $tracking_identifier_obj = CXGN::TrackingActivity::TrackingIdentifier->new({schema=>$schema, dbh=>$dbh, tracking_identifier_stock_id=>$identifier_id});
406 my $associated_projects = $tracking_identifier_obj->get_associated_project_program();
407 my $tracking_project_id = $associated_projects->[0]->[0];
408 my $tracking_project = CXGN::TrackingActivity::ActivityProject->new(bcs_schema => $schema, trial_id => $tracking_project_id);
409 my $activity_type = $tracking_project->get_project_activity_type();
411 my $tracking_activities;
412 if ($activity_type eq 'tissue_culture') {
413 $tracking_activities = $c->config->{tracking_tissue_culture};
414 } elsif ($activity_type eq 'transformation') {
415 $tracking_activities = $c->config->{tracking_transformation};
418 my @summary = ();
419 my @activity_types = split ',',$tracking_activities;
421 my $tracking_data_json_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'tracking_tissue_culture_json', 'stock_property')->cvterm_id();
422 my $activity_info_rs = $schema->resultset("Stock::Stockprop")->find({stock_id => $identifier_id, type_id => $tracking_data_json_cvterm_id});
423 if ($activity_info_rs) {
424 my $activity_json = $activity_info_rs->value();
425 my $info = JSON::Any->jsonToObj($activity_json);
426 my %info_hash = %{$info};
427 foreach my $type (@activity_types){
428 my $input = '';
429 my $empty_string;
430 my @each_type_details = ();
431 my $each_timestamp_string;
432 my $each_type_string;
433 if ($info_hash{$type}) {
434 my $details = {};
435 my %details_hash = ();
436 $details = $info_hash{$type};
437 %details_hash = %{$details};
439 if (($type =~ m/number/) || ($type =~ m/count/)) {
440 $input = 0;
441 foreach my $key (keys %details_hash) {
442 $input += $details_hash{$key}{'input'};
444 push @summary, $input;
445 } elsif ($type =~ m/date/) {
446 foreach my $key (keys %details_hash) {
447 $input = $details_hash{$key}{'input'};
449 push @summary, $input;
451 } else {
452 push @summary, $input;
455 } else {
456 foreach my $type (@activity_types) {
457 push @summary, 'NA';
461 my @all_summary;
462 push @all_summary, [@summary];
464 $c->stash->{rest} = { data => \@all_summary };
468 sub get_project_active_identifiers :Path('/ajax/tracking_activity/project_active_identifiers') :Args(1) {
469 my $self = shift;
470 my $c = shift;
471 my $project_id = shift;
472 my $schema = $c->dbic_schema('Bio::Chado::Schema', 'sgn_chado');
474 my $tracking_project = CXGN::TrackingActivity::ActivityProject->new(bcs_schema => $schema, trial_id => $project_id);
475 my $activity_type = $tracking_project->get_project_activity_type();
477 my $tracking_activities;
478 if ($activity_type eq 'tissue_culture') {
479 $tracking_activities = $c->config->{tracking_tissue_culture};
480 } elsif ($activity_type eq 'transformation') {
481 $tracking_activities = $c->config->{tracking_transformation};
484 my @activity_types = split ',',$tracking_activities;
486 my $transformation_type_id = SGN::Model::Cvterm->get_cvterm_row($schema, "transformation", 'stock_type')->cvterm_id();
488 my $activity_project = CXGN::TrackingActivity::ActivityProject->new(bcs_schema => $schema, trial_id => $project_id);
489 my $all_identifier_info = $activity_project->get_project_active_identifiers();
490 my @all_identifiers;
491 foreach my $identifier_info (@$all_identifier_info) {
492 my @row = ();
493 my $identifier_id = $identifier_info->[0];
494 my $identifier_name = $identifier_info->[1];
495 push @row, qq{<a href="/activity/details/$identifier_id">$identifier_name</a>};
497 my $material_id = $identifier_info->[2];
498 my $material_rs = $schema->resultset("Stock::Stock")->find( { stock_id => $material_id });
499 my $material_stock_type_id = $material_rs->type_id;
500 my $material_name = $identifier_info->[3];
501 if ($material_stock_type_id == $transformation_type_id) {
502 push @row, qq{<a href="/transformation/$material_id">$material_name</a>}
503 } else {
504 push @row, qq{<a href="/stock/$material_id/view">$material_name</a>};
506 my $progress = $identifier_info->[5];
507 if ($progress) {
508 my $progress_ref = JSON::Any->jsonToObj($progress);
509 my %progress_hash = %{$progress_ref};
510 foreach my $type (@activity_types){
511 my $input = '';
512 if ($progress_hash{$type}) {
513 my $details = {};
514 my %details_hash = ();
515 $details = $progress_hash{$type};
516 %details_hash = %{$details};
518 if (($type =~ m/number/) || ($type =~ m/count/)) {
519 $input = 0;
520 foreach my $key (keys %details_hash) {
521 $input += $details_hash{$key}{'input'};
523 push @row, $input;
524 } elsif ($type =~ m/date/) {
525 foreach my $key (keys %details_hash) {
526 $input = $details_hash{$key}{'input'};
528 push @row, $input;
530 } else {
531 push @row, $input;
534 } else {
535 foreach my $type (@activity_types) {
536 push @row, '';
539 push @row, $identifier_name;
540 push @all_identifiers,[@row];
543 $c->stash->{rest} = { data => \@all_identifiers };
548 sub get_project_active_identifier_names :Path('/ajax/tracking_activity/project_active_identifier_names') :Args(1) {
549 my $self = shift;
550 my $c = shift;
551 my $project_id = shift;
552 my $schema = $c->dbic_schema('Bio::Chado::Schema', 'sgn_chado');
554 my $activity_project = CXGN::TrackingActivity::ActivityProject->new(bcs_schema => $schema, trial_id => $project_id);
555 my $all_identifier_info = $activity_project->get_project_active_identifiers();
556 my @identifier_names;
557 foreach my $identifier_info (@$all_identifier_info) {
558 push @identifier_names, $identifier_info->[1];
561 $c->stash->{rest} = { data => \@identifier_names };
566 sub update_status : Path('/ajax/tracking_activity/update_status') : ActionClass('REST'){ }
568 sub update_status_POST : Args(0) {
569 my $self = shift;
570 my $c = shift;
571 my $schema = $c->dbic_schema('Bio::Chado::Schema', 'sgn_chado');
572 my $dbh = $c->dbc->dbh();
573 my $identifier_id = $c->req->param("identifier_id");
574 my $status_type = $c->req->param("status_type");
575 my $comments = $c->req->param("comments");
576 my $material_id = $c->req->param("material_id");
577 my $time = DateTime->now();
578 my $update_date = $time->ymd();
579 my @stocks_to_update;
581 if (!$c->user()){
582 $c->stash->{rest} = { error_string => "You must be logged in to update status" };
583 return;
585 if (!$c->user()->check_roles("curator")) {
586 $c->stash->{rest} = { error_string => "You do not have the correct role to update status. Please contact us." };
587 return;
590 my $user_id = $c->user()->get_object()->get_sp_person_id();
592 my $tracking_identifier_type_id = SGN::Model::Cvterm->get_cvterm_row($schema, "tracking_identifier", 'stock_type')->cvterm_id();
593 my $transformation_type_id = SGN::Model::Cvterm->get_cvterm_row($schema, "transformation", 'stock_type')->cvterm_id();
595 my $identifier_rs = $schema->resultset("Stock::Stock")->find( { stock_id => $identifier_id, type_id => $tracking_identifier_type_id });
596 if (!$identifier_rs) {
597 $c->stash->{rest} = { error_string => 'Error. No tracking identifier entry found in the database.' };
598 return;
599 } else {
600 push @stocks_to_update, $identifier_id;
603 my $material_stock_type_id;
604 my $material_rs = $schema->resultset("Stock::Stock")->find( { stock_id => $material_id });
605 if (!$material_rs) {
606 $c->stash->{rest} = { error_string => 'Error. No material entry found in the database.' };
607 return;
608 } else {
609 $material_stock_type_id = $material_rs->type_id;
612 if ($material_stock_type_id == $transformation_type_id) {
613 push @stocks_to_update, $material_id;
616 my $completed_metadata;
617 my $terminated_metadata;
618 if ($status_type eq 'completed') {
619 $completed_metadata = 1;
620 } elsif ($status_type eq 'terminated') {
621 $terminated_metadata = 1;
624 foreach my $stock_id (@stocks_to_update) {
625 my $update_status = CXGN::Stock::Status->new({
626 bcs_schema => $schema,
627 parent_id => $stock_id,
628 person_id => $user_id,
629 update_date => $update_date,
630 comments => $comments,
631 completed_metadata => $completed_metadata,
632 terminated_metadata => $terminated_metadata
635 $update_status->store();
637 if (!$update_status->store()){
638 $c->stash->{rest} = {error_string => "Error updating status"};
639 return;
643 $c->stash->{rest} = {success => "1",};
647 sub reverse_status : Path('/ajax/tracking_activity/reverse_status') : ActionClass('REST'){ }
649 sub reverse_status_POST : Args(0) {
650 my $self = shift;
651 my $c = shift;
652 my $schema = $c->dbic_schema('Bio::Chado::Schema', 'sgn_chado');
653 my $dbh = $c->dbc->dbh();
654 my $identifier_id = $c->req->param("identifier_id");
655 my $updated_status_type = $c->req->param("updated_status_type");
656 my $material_id = $c->req->param("material_id");
658 if (!$c->user()){
659 $c->stash->{rest} = { error_string => "You must be logged in to reverse status of this tracking identifier" };
660 return;
662 if (!$c->user()->check_roles("curator")) {
663 $c->stash->{rest} = { error_string => "You do not have the correct role to reverse status of this tracking identifier. Please contact us." };
664 return;
667 my $user_id = $c->user()->get_object()->get_sp_person_id();
669 my $status_type_id;
670 if ($updated_status_type) {
671 $status_type_id = SGN::Model::Cvterm->get_cvterm_row($schema, $updated_status_type, 'stock_property')->cvterm_id();
672 my $status_stockprop_rs = $schema->resultset("Stock::Stockprop")->find({stock_id => $identifier_id, type_id => $status_type_id});
674 if (defined $status_stockprop_rs->stockprop_id) {
675 $status_stockprop_rs->delete();
679 my $material_stock_type_id;
680 my $material_rs = $schema->resultset("Stock::Stock")->find( { stock_id => $material_id });
681 if (!$material_rs) {
682 $c->stash->{rest} = { error_string => 'Error. No material entry found in the database.' };
683 return;
684 } else {
685 $material_stock_type_id = $material_rs->type_id;
688 my $transformation_type_id = SGN::Model::Cvterm->get_cvterm_row($schema, "transformation", 'stock_type')->cvterm_id();
690 if ($material_stock_type_id == $transformation_type_id) {
691 if ($status_type_id) {
692 my $transformation_stockprop_rs = $schema->resultset("Stock::Stockprop")->find({stock_id => $material_id, type_id => $status_type_id});
694 if (defined $transformation_stockprop_rs->stockprop_id) {
695 $transformation_stockprop_rs->delete();
700 $c->stash->{rest} = { success => 1 };
705 sub get_project_inactive_identifiers :Path('/ajax/tracking_activity/project_inactive_identifiers') :Args(1) {
706 my $self = shift;
707 my $c = shift;
708 my $project_id = shift;
709 my $schema = $c->dbic_schema('Bio::Chado::Schema', 'sgn_chado');
711 my $tracking_project = CXGN::TrackingActivity::ActivityProject->new(bcs_schema => $schema, trial_id => $project_id);
712 my $activity_type = $tracking_project->get_project_activity_type();
714 my $tracking_activities;
715 if ($activity_type eq 'tissue_culture') {
716 $tracking_activities = $c->config->{tracking_tissue_culture};
717 } elsif ($activity_type eq 'transformation') {
718 $tracking_activities = $c->config->{tracking_transformation};
721 my @activity_types = split ',',$tracking_activities;
723 my $transformation_type_id = SGN::Model::Cvterm->get_cvterm_row($schema, "transformation", 'stock_type')->cvterm_id();
725 my $activity_project = CXGN::TrackingActivity::ActivityProject->new(bcs_schema => $schema, trial_id => $project_id);
726 my $all_identifier_info = $activity_project->get_project_inactive_identifiers();
727 my @all_identifiers;
728 foreach my $identifier_info (@$all_identifier_info) {
729 my @row = ();
730 my $identifier_id = $identifier_info->[0];
731 my $identifier_name = $identifier_info->[1];
732 push @row, qq{<a href="/activity/details/$identifier_id">$identifier_name</a>};
734 my $status = $identifier_info->[6];
735 if ($status eq 'terminated_metadata') {
736 $status = '<span style="color:red">'.'TERMINATED'.'</span>';
737 } elsif ($status eq 'completed_metadata') {
738 $status = '<span style="color:red">'.'COMPLETED'.'</span>';
740 push @row, $status;
742 my $material_id = $identifier_info->[2];
743 my $material_name = $identifier_info->[3];
744 my $material_rs = $schema->resultset("Stock::Stock")->find( { stock_id => $material_id });
745 my $material_stock_type_id = $material_rs->type_id;
746 if ($material_stock_type_id == $transformation_type_id) {
747 push @row, qq{<a href="/transformation/$material_id">$material_name</a>}
748 } else {
749 push @row, qq{<a href="/stock/$material_id/view">$material_name</a>};
752 my $progress = $identifier_info->[5];
753 if ($progress) {
754 my $progress_ref = JSON::Any->jsonToObj($progress);
755 my %progress_hash = %{$progress_ref};
756 foreach my $type (@activity_types){
757 my $input = '';
758 if ($progress_hash{$type}) {
759 my $details = {};
760 my %details_hash = ();
761 $details = $progress_hash{$type};
762 %details_hash = %{$details};
764 if (($type =~ m/number/) || ($type =~ m/count/)) {
765 $input = 0;
766 foreach my $key (keys %details_hash) {
767 $input += $details_hash{$key}{'input'};
769 push @row, $input;
770 } elsif ($type =~ m/date/) {
771 foreach my $key (keys %details_hash) {
772 $input = $details_hash{$key}{'input'};
774 push @row, $input;
776 } else {
777 push @row, $input;
780 } else {
781 foreach my $type (@activity_types) {
782 push @row, '';
785 push @row, $identifier_name;
786 push @all_identifiers,[@row];
789 $c->stash->{rest} = { data => \@all_identifiers };