check ids
[sgn.git] / lib / SGN / Controller / AJAX / TrackingActivity.pm
blob7ab948ecf744fc5f4654f4d8fcc2eaf4e7e9a5b7
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 $return;
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 $return = $add_activity_project->save_activity_project();
100 if (!$return){
101 $c->stash->{rest} = {error => "Error saving project",};
102 return;
105 if ($return->{error}){
106 $c->stash->{rest} = {error => $return->{error}};
107 return;
110 if ($@) {
111 $c->stash->{rest} = {error => $@};
112 return;
113 } else {
114 $c->stash->{rest} = {success => 1};
121 sub generate_tracking_identifiers : Path('/ajax/tracking_activity/generate_tracking_identifiers') : ActionClass('REST'){ }
123 sub generate_tracking_identifiers_POST : Args(0) {
124 my $self = shift;
125 my $c = shift;
127 if (!$c->user()) {
128 $c->stash->{rest} = { error => "You must be logged in to generate tracking identifiers." };
129 return;
131 if (!($c->user()->has_role('submitter') or $c->user()->has_role('curator'))) {
132 $c->stash->{rest} = { error => "You do not have sufficient privileges to generate tracking identifiers." };
133 return;
136 my $user_id = $c->user()->get_object()->get_sp_person_id();
137 my $schema = $c->dbic_schema('Bio::Chado::Schema', 'sgn_chado');
138 my $phenome_schema = $c->dbic_schema("CXGN::Phenome::Schema");
139 my $dbh = $c->dbc->dbh();
141 my $project_name = $c->req->param("project_name");
142 my $list_id = $c->req->param("list_id");
143 my $project_id;
144 my $project_rs = $schema->resultset("Project::Project")->find( { name => $project_name });
145 if (!$project_rs) {
146 $c->stash->{rest} = { error => "Error! Project name: $project_name was not found in the database.\n" };
147 return;
148 } else {
149 $project_id = $project_rs->project_id();
152 my $activity_project = CXGN::TrackingActivity::ActivityProject->new(bcs_schema => $schema, trial_id => $project_id);
153 my $all_identifiers = $activity_project->get_project_active_identifiers();
154 my $last_number = scalar (@$all_identifiers);
156 my $list = CXGN::List->new( { dbh=>$dbh, list_id=>$list_id });
157 my $material_names = $list->elements();
159 my @check_identifier_names;
160 my @tracking_identifiers;
161 my @error_messages;
162 foreach my $name (sort @$material_names) {
163 $last_number++;
164 # my $tracking_id = $project_name.":".$name."_"."T".(sprintf "%04d", $last_number);
165 my $tracking_id = $project_name.":".$name."_"."T".$last_number;
166 push @tracking_identifiers, [$tracking_id, $name];
167 push @check_identifier_names, $tracking_id;
170 my $rs = $schema->resultset("Stock::Stock")->search({
171 'is_obsolete' => { '!=' => 't' },
172 'uniquename' => { -in => \@check_identifier_names }
174 while (my $r=$rs->next){
175 push @error_messages, "Tracking identifier name already exists in database: ".$r->uniquename;
178 if (scalar(@error_messages) >= 1) {
179 $c->stash->{rest} = { error => \@error_messages};
180 return;
183 foreach my $identifier_info (@tracking_identifiers) {
184 my $tracking_identifier = $identifier_info->[0];
185 my $material = $identifier_info->[1];
187 my $tracking_obj = CXGN::TrackingActivity::AddTrackingIdentifier->new({
188 schema => $schema,
189 phenome_schema => $phenome_schema,
190 tracking_identifier => $tracking_identifier,
191 material => $material,
192 project_id => $project_id,
193 user_id => $user_id
196 my $return = $tracking_obj->store();
197 if (!$return) {
198 $c->stash->{rest} = {error => "Error generating tracking identifier"};
199 return;
200 } elsif ($return->{error}) {
201 my $error = $return->{error};
202 $c->stash->{rest} = {error => $error};
203 return;
207 $c->stash->{rest} = { success => 1};
212 sub activity_info_save : Path('/ajax/tracking_activity/save') : ActionClass('REST'){ }
214 sub activity_info_save_POST : Args(0) {
215 my $self = shift;
216 my $c = shift;
218 if (!$c->user()) {
219 $c->stash->{rest} = { error => "You must be logged in to add new information." };
220 return;
222 if (!($c->user()->has_role('submitter') or $c->user()->has_role('curator'))) {
223 $c->stash->{rest} = { error => "You do not have sufficient privileges to record new information." };
224 return;
227 my $user_id = $c->user()->get_object()->get_sp_person_id();
229 my $tracking_identifier = $c->req->param("tracking_identifier_name");
230 my $tracking_identifier_id = $c->req->param("tracking_identifier_id");
231 my $selected_type = $c->req->param("selected_type");
232 my $input = $c->req->param("input");
233 my $notes = $c->req->param("notes");
234 my $record_timestamp = $c->req->param("record_timestamp");
235 my $tracking_transformation = $c->config->{tracking_transformation};
237 if ($selected_type =~ m/number/ && !($input =~ /^\d+?$/) ) {
238 $c->stash->{rest} = {error => "Input is not a positive integer"};
239 return;
242 my $schema = $c->dbic_schema('Bio::Chado::Schema', 'sgn_chado');
243 my $phenome_schema = $c->dbic_schema("CXGN::Phenome::Schema");
244 my $dbh = $c->dbc->dbh();
245 my $number_of_transformants;
246 if (($selected_type eq 'number_of_transformants') && $tracking_transformation) {
247 $number_of_transformants = $input;
248 my $tracking_identifier_obj = CXGN::TrackingActivity::TrackingIdentifier->new({schema => $schema, dbh => $dbh, tracking_identifier_stock_id => $tracking_identifier_id});
249 my $project_and_program_info = $tracking_identifier_obj->get_associated_project_program();
250 my $program_id = $project_and_program_info->[0]->[2];
251 my $linked_project_id = $project_and_program_info->[0]->[4];
252 my $autogenerated_name_prefix_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'autogenerated_name_prefix', 'project_property')->cvterm_id();
253 my $material_of_type_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'material_of', 'stock_relationship')->cvterm_id;
254 if ($linked_project_id) {
255 my $new_names_info;
256 my $stored_prefix = $schema->resultset('Project::Projectprop')->find({ project_id => $linked_project_id, type_id => $autogenerated_name_prefix_cvterm_id});
257 if ($stored_prefix) {
258 my $prefix = $stored_prefix->value();
259 my $autogenerated_names = CXGN::Transformation::CreateAutogeneratedNames->new({schema => $schema, dbh => $dbh, breeding_program_id => $program_id, prefix => $prefix, number_of_names => $number_of_transformants });
260 $new_names_info = $autogenerated_names->create_names();
261 print STDERR "NEW NAMES INFO=".Dumper($new_names_info)."\n";
262 my $new_names = $new_names_info->{'new_autogenerated_names'};
263 my $new_current_serial_number = $new_names_info->{'new_current_serial_number'};
265 my $transformation_stock_id = $schema->resultset("Stock::StockRelationship")->find({object_id=>$tracking_identifier_id, type_id=>$material_of_type_id})->subject_id();
266 my $add_transformants = CXGN::Transformation::AddTransformant->new({
267 schema => $schema,
268 phenome_schema => $phenome_schema,
269 dbh => $dbh,
270 transformation_stock_id => $transformation_stock_id,
271 transformant_names => $new_names,
272 owner_id => $user_id,
275 $add_transformants->add_transformant();
277 my $name_metadata_cvterm = SGN::Model::Cvterm->get_cvterm_row($schema, 'autogenerated_name_metadata', 'project_property');
278 my $program = $schema->resultset('Project::Project')->find({ project_id => $program_id});
279 my $metadata_projectprop_rs = $program->projectprops({type_id => $name_metadata_cvterm->cvterm_id});
280 if ($metadata_projectprop_rs->count == 1){
281 my $stored_name_metadata_string = $metadata_projectprop_rs->first->value();
282 my $name_metadata_hash = decode_json $stored_name_metadata_string;
283 print STDERR "PREVIOUS METADATA =".Dumper($name_metadata_hash)."\n";
284 $name_metadata_hash->{$prefix}->{'current_serial_number'} = $new_current_serial_number;
285 my $new_name_metadata_string = encode_json $name_metadata_hash;
286 print STDERR "UPDATED METADATA =".Dumper($name_metadata_hash)."\n";
287 $metadata_projectprop_rs->first->update({value=>$new_name_metadata_string});
294 my $add_activity_info = CXGN::TrackingActivity::ActivityInfo->new({
295 schema => $schema,
296 tracking_identifier => $tracking_identifier,
297 selected_type => $selected_type,
298 input => $input,
299 timestamp => $record_timestamp,
300 operator_id => $user_id,
301 notes => $notes,
303 my $return = $add_activity_info->add_info();
304 # print STDERR "ADD INFO =".Dumper ($add_activity_info->add_info())."\n";
306 if (!$return){
307 $c->stash->{rest} = {error => "Error saving info",};
308 return;
309 } else {
310 $c->stash->{rest} = $return;
316 sub get_activity_details :Path('/ajax/tracking_activity/details') :Args(1) {
317 my $self = shift;
318 my $c = shift;
319 my $identifier_id = shift;
320 my $schema = $c->dbic_schema('Bio::Chado::Schema', 'sgn_chado');
321 my $dbh = $c->dbc->dbh;
323 my $tracking_identifier_obj = CXGN::TrackingActivity::TrackingIdentifier->new({schema=>$schema, dbh=>$dbh, tracking_identifier_stock_id=>$identifier_id});
324 my $associated_projects = $tracking_identifier_obj->get_associated_project_program();
325 my $tracking_project_id = $associated_projects->[0]->[0];
326 my $tracking_project = CXGN::TrackingActivity::ActivityProject->new(bcs_schema => $schema, trial_id => $tracking_project_id);
327 my $activity_type = $tracking_project->get_project_activity_type();
329 my $tracking_activities;
330 if ($activity_type eq 'tissue_culture') {
331 $tracking_activities = $c->config->{tracking_tissue_culture_info};
332 } elsif ($activity_type eq 'transformation') {
333 $tracking_activities = $c->config->{tracking_transformation_info};
336 my @details;
337 my @activity_types = split ',',$tracking_activities;
339 my $tracking_data_json_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'tracking_tissue_culture_json', 'stock_property')->cvterm_id();
340 my $activity_info_rs = $schema->resultset("Stock::Stockprop")->find({stock_id => $identifier_id, type_id => $tracking_data_json_cvterm_id});
341 if ($activity_info_rs) {
342 my $activity_json = $activity_info_rs->value();
343 my $info = JSON::Any->jsonToObj($activity_json);
344 my %info_hash = %{$info};
345 foreach my $type (@activity_types){
346 my $empty_string;
347 my @each_type_details = ();
348 my $each_timestamp_string;
349 my $each_type_string;
350 if ($info_hash{$type}) {
351 my @each_type_details = ();
352 my $details = {};
353 my %details_hash = ();
354 $details = $info_hash{$type};
355 %details_hash = %{$details};
356 # print STDERR "DETAILS HASH =".Dumper(\%details_hash);
357 foreach my $timestamp (sort keys %details_hash) {
358 my @each_timestamp_details = ();
359 push @each_timestamp_details, "timestamp".":"."".$timestamp;
360 my $operator_id = $details_hash{$timestamp}{'operator_id'};
362 my $person= CXGN::People::Person->new($dbh, $operator_id);
363 my $operator_name = $person->get_first_name()." ".$person->get_last_name();
365 push @each_timestamp_details, "operator".":"."".$operator_name;
366 my $input = $details_hash{$timestamp}{'input'};
367 push @each_timestamp_details, "input".":"."".$input;
368 my $notes = $details_hash{$timestamp}{'notes'};
369 push @each_timestamp_details, "notes".":"."".$notes;
371 push @each_timestamp_details, $empty_string;
373 $each_timestamp_string = join("<br>", @each_timestamp_details);
374 push @each_type_details, $each_timestamp_string;
377 $each_type_string = join("<br>", @each_type_details);
378 # print STDERR "EACH TYPE STRING =".Dumper($each_type_string)."\n";
379 push @details, $each_type_string;
380 } else {
381 my $empty_string;
382 push @details, $empty_string;
385 } else {
386 foreach my $type (@activity_types) {
387 push @details, 'NA';
391 my @all_details;
392 push @all_details, [@details];
394 # print STDERR "ALL DETAILS =".Dumper(\@all_details)."\n";
396 $c->stash->{rest} = { data => \@all_details };
401 sub get_activity_summary :Path('/ajax/tracking_activity/summary') :Args(1) {
402 my $self = shift;
403 my $c = shift;
404 my $identifier_id = shift;
405 my $schema = $c->dbic_schema('Bio::Chado::Schema', 'sgn_chado');
406 my $dbh = $c->dbc->dbh;
408 my $tracking_identifier_obj = CXGN::TrackingActivity::TrackingIdentifier->new({schema=>$schema, dbh=>$dbh, tracking_identifier_stock_id=>$identifier_id});
409 my $associated_projects = $tracking_identifier_obj->get_associated_project_program();
410 my $tracking_project_id = $associated_projects->[0]->[0];
411 my $tracking_project = CXGN::TrackingActivity::ActivityProject->new(bcs_schema => $schema, trial_id => $tracking_project_id);
412 my $activity_type = $tracking_project->get_project_activity_type();
414 my $tracking_activities;
415 if ($activity_type eq 'tissue_culture') {
416 $tracking_activities = $c->config->{tracking_tissue_culture_info};
417 } elsif ($activity_type eq 'transformation') {
418 $tracking_activities = $c->config->{tracking_transformation_info};
421 my @summary = ();
422 my @activity_types = split ',',$tracking_activities;
424 my $tracking_data_json_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'tracking_tissue_culture_json', 'stock_property')->cvterm_id();
425 my $activity_info_rs = $schema->resultset("Stock::Stockprop")->find({stock_id => $identifier_id, type_id => $tracking_data_json_cvterm_id});
426 if ($activity_info_rs) {
427 my $activity_json = $activity_info_rs->value();
428 my $info = JSON::Any->jsonToObj($activity_json);
429 my %info_hash = %{$info};
430 foreach my $type (@activity_types){
431 my $input = '';
432 my $empty_string;
433 my @each_type_details = ();
434 my $each_timestamp_string;
435 my $each_type_string;
436 if ($info_hash{$type}) {
437 my $details = {};
438 my %details_hash = ();
439 $details = $info_hash{$type};
440 %details_hash = %{$details};
442 if (($type =~ m/number/) || ($type =~ m/count/)) {
443 $input = 0;
444 foreach my $key (keys %details_hash) {
445 $input += $details_hash{$key}{'input'};
447 push @summary, $input;
448 } elsif ($type =~ m/date/) {
449 foreach my $key (keys %details_hash) {
450 $input = $details_hash{$key}{'input'};
452 push @summary, $input;
454 } else {
455 push @summary, $input;
458 } else {
459 foreach my $type (@activity_types) {
460 push @summary, 'NA';
464 my @all_summary;
465 push @all_summary, [@summary];
467 $c->stash->{rest} = { data => \@all_summary };
471 sub get_project_active_identifiers :Path('/ajax/tracking_activity/project_active_identifiers') :Args(1) {
472 my $self = shift;
473 my $c = shift;
474 my $project_id = shift;
475 my $schema = $c->dbic_schema('Bio::Chado::Schema', 'sgn_chado');
477 my $tracking_project = CXGN::TrackingActivity::ActivityProject->new(bcs_schema => $schema, trial_id => $project_id);
478 my $activity_type = $tracking_project->get_project_activity_type();
480 my $tracking_activities;
481 if ($activity_type eq 'tissue_culture') {
482 $tracking_activities = $c->config->{tracking_tissue_culture_info};
483 } elsif ($activity_type eq 'transformation') {
484 $tracking_activities = $c->config->{tracking_transformation_info};
487 my @activity_types = split ',',$tracking_activities;
488 my $transformation_type_id = SGN::Model::Cvterm->get_cvterm_row($schema, "transformation", 'stock_type')->cvterm_id();
490 my $activity_project = CXGN::TrackingActivity::ActivityProject->new(bcs_schema => $schema, trial_id => $project_id);
491 my $all_identifier_info = $activity_project->get_project_active_identifiers();
492 my @all_identifiers;
493 foreach my $identifier_info (@$all_identifier_info) {
494 my @row = ();
495 my $identifier_id = $identifier_info->[0];
496 my $identifier_name = $identifier_info->[1];
497 push @row, qq{<a href="/activity/details/$identifier_id">$identifier_name</a>};
499 my $material_id = $identifier_info->[2];
500 my $material_rs = $schema->resultset("Stock::Stock")->find( { stock_id => $material_id });
501 my $material_stock_type_id = $material_rs->type_id;
502 my $material_name = $identifier_info->[3];
503 if ($material_stock_type_id == $transformation_type_id) {
504 push @row, qq{<a href="/transformation/$material_id">$material_name</a>}
505 } else {
506 push @row, qq{<a href="/stock/$material_id/view">$material_name</a>};
508 my $progress = $identifier_info->[5];
509 if ($progress) {
510 my $progress_ref = JSON::Any->jsonToObj($progress);
511 my %progress_hash = %{$progress_ref};
512 foreach my $type (@activity_types){
513 my $input = '';
514 if ($progress_hash{$type}) {
515 my $details = {};
516 my %details_hash = ();
517 $details = $progress_hash{$type};
518 %details_hash = %{$details};
520 if (($type =~ m/number/) || ($type =~ m/count/)) {
521 $input = 0;
522 foreach my $key (keys %details_hash) {
523 $input += $details_hash{$key}{'input'};
525 push @row, $input;
526 } elsif ($type =~ m/date/) {
527 foreach my $key (keys %details_hash) {
528 $input = $details_hash{$key}{'input'};
530 push @row, $input;
532 } else {
533 push @row, $input;
536 } else {
537 foreach my $type (@activity_types) {
538 push @row, '';
541 push @row, $identifier_name;
542 push @all_identifiers,[@row];
545 $c->stash->{rest} = { data => \@all_identifiers };
550 sub get_project_active_identifier_names :Path('/ajax/tracking_activity/project_active_identifier_names') :Args(1) {
551 my $self = shift;
552 my $c = shift;
553 my $project_id = shift;
554 my $schema = $c->dbic_schema('Bio::Chado::Schema', 'sgn_chado');
556 my $activity_project = CXGN::TrackingActivity::ActivityProject->new(bcs_schema => $schema, trial_id => $project_id);
557 my $all_identifier_info = $activity_project->get_project_active_identifiers();
558 my @identifier_names;
559 foreach my $identifier_info (@$all_identifier_info) {
560 push @identifier_names, $identifier_info->[1];
563 $c->stash->{rest} = { data => \@identifier_names };
568 sub update_status : Path('/ajax/tracking_activity/update_status') : ActionClass('REST'){ }
570 sub update_status_POST : Args(0) {
571 my $self = shift;
572 my $c = shift;
573 my $schema = $c->dbic_schema('Bio::Chado::Schema', 'sgn_chado');
574 my $dbh = $c->dbc->dbh();
575 my $identifier_id = $c->req->param("identifier_id");
576 my $status_type = $c->req->param("status_type");
577 my $comments = $c->req->param("comments");
578 my $material_id = $c->req->param("material_id");
579 my $time = DateTime->now();
580 my $update_date = $time->ymd();
581 my @stocks_to_update;
583 if (!$c->user()){
584 $c->stash->{rest} = { error_string => "You must be logged in to update status" };
585 return;
587 if (!$c->user()->check_roles("curator")) {
588 $c->stash->{rest} = { error_string => "You do not have the correct role to update status. Please contact us." };
589 return;
592 my $user_id = $c->user()->get_object()->get_sp_person_id();
594 my $tracking_identifier_type_id = SGN::Model::Cvterm->get_cvterm_row($schema, "tracking_identifier", 'stock_type')->cvterm_id();
595 my $transformation_type_id = SGN::Model::Cvterm->get_cvterm_row($schema, "transformation", 'stock_type')->cvterm_id();
597 my $identifier_rs = $schema->resultset("Stock::Stock")->find( { stock_id => $identifier_id, type_id => $tracking_identifier_type_id });
598 if (!$identifier_rs) {
599 $c->stash->{rest} = { error_string => 'Error. No tracking identifier entry found in the database.' };
600 return;
601 } else {
602 push @stocks_to_update, $identifier_id;
605 my $material_stock_type_id;
606 my $material_rs = $schema->resultset("Stock::Stock")->find( { stock_id => $material_id });
607 if (!$material_rs) {
608 $c->stash->{rest} = { error_string => 'Error. No material entry found in the database.' };
609 return;
610 } else {
611 $material_stock_type_id = $material_rs->type_id;
614 if ($material_stock_type_id == $transformation_type_id) {
615 push @stocks_to_update, $material_id;
618 my $completed_metadata;
619 my $terminated_metadata;
620 if ($status_type eq 'completed') {
621 $completed_metadata = 1;
622 } elsif ($status_type eq 'terminated') {
623 $terminated_metadata = 1;
626 foreach my $stock_id (@stocks_to_update) {
627 my $update_status = CXGN::Stock::Status->new({
628 bcs_schema => $schema,
629 parent_id => $stock_id,
630 person_id => $user_id,
631 update_date => $update_date,
632 comments => $comments,
633 completed_metadata => $completed_metadata,
634 terminated_metadata => $terminated_metadata
637 $update_status->store();
639 if (!$update_status->store()){
640 $c->stash->{rest} = {error_string => "Error updating status"};
641 return;
645 $c->stash->{rest} = {success => "1",};
649 sub reverse_status : Path('/ajax/tracking_activity/reverse_status') : ActionClass('REST'){ }
651 sub reverse_status_POST : Args(0) {
652 my $self = shift;
653 my $c = shift;
654 my $schema = $c->dbic_schema('Bio::Chado::Schema', 'sgn_chado');
655 my $dbh = $c->dbc->dbh();
656 my $identifier_id = $c->req->param("identifier_id");
657 my $updated_status_type = $c->req->param("updated_status_type");
658 my $material_id = $c->req->param("material_id");
660 if (!$c->user()){
661 $c->stash->{rest} = { error_string => "You must be logged in to reverse status of this tracking identifier" };
662 return;
664 if (!$c->user()->check_roles("curator")) {
665 $c->stash->{rest} = { error_string => "You do not have the correct role to reverse status of this tracking identifier. Please contact us." };
666 return;
669 my $user_id = $c->user()->get_object()->get_sp_person_id();
671 my $status_type_id;
672 if ($updated_status_type) {
673 $status_type_id = SGN::Model::Cvterm->get_cvterm_row($schema, $updated_status_type, 'stock_property')->cvterm_id();
674 my $status_stockprop_rs = $schema->resultset("Stock::Stockprop")->find({stock_id => $identifier_id, type_id => $status_type_id});
676 if (defined $status_stockprop_rs->stockprop_id) {
677 $status_stockprop_rs->delete();
681 my $material_stock_type_id;
682 my $material_rs = $schema->resultset("Stock::Stock")->find( { stock_id => $material_id });
683 if (!$material_rs) {
684 $c->stash->{rest} = { error_string => 'Error. No material entry found in the database.' };
685 return;
686 } else {
687 $material_stock_type_id = $material_rs->type_id;
690 my $transformation_type_id = SGN::Model::Cvterm->get_cvterm_row($schema, "transformation", 'stock_type')->cvterm_id();
692 if ($material_stock_type_id == $transformation_type_id) {
693 if ($status_type_id) {
694 my $transformation_stockprop_rs = $schema->resultset("Stock::Stockprop")->find({stock_id => $material_id, type_id => $status_type_id});
696 if (defined $transformation_stockprop_rs->stockprop_id) {
697 $transformation_stockprop_rs->delete();
702 $c->stash->{rest} = { success => 1 };
707 sub get_project_inactive_identifiers :Path('/ajax/tracking_activity/project_inactive_identifiers') :Args(1) {
708 my $self = shift;
709 my $c = shift;
710 my $project_id = shift;
711 my $schema = $c->dbic_schema('Bio::Chado::Schema', 'sgn_chado');
713 my $tracking_project = CXGN::TrackingActivity::ActivityProject->new(bcs_schema => $schema, trial_id => $project_id);
714 my $activity_type = $tracking_project->get_project_activity_type();
716 my $tracking_activities;
717 if ($activity_type eq 'tissue_culture') {
718 $tracking_activities = $c->config->{tracking_tissue_culture_info};
719 } elsif ($activity_type eq 'transformation') {
720 $tracking_activities = $c->config->{tracking_transformation_info};
723 my @activity_types = split ',',$tracking_activities;
725 my $transformation_type_id = SGN::Model::Cvterm->get_cvterm_row($schema, "transformation", 'stock_type')->cvterm_id();
727 my $activity_project = CXGN::TrackingActivity::ActivityProject->new(bcs_schema => $schema, trial_id => $project_id);
728 my $all_identifier_info = $activity_project->get_project_inactive_identifiers();
729 my @all_identifiers;
730 foreach my $identifier_info (@$all_identifier_info) {
731 my @row = ();
732 my $identifier_id = $identifier_info->[0];
733 my $identifier_name = $identifier_info->[1];
734 push @row, qq{<a href="/activity/details/$identifier_id">$identifier_name</a>};
736 my $status = $identifier_info->[6];
737 if ($status eq 'terminated_metadata') {
738 $status = '<span style="color:red">'.'TERMINATED'.'</span>';
739 } elsif ($status eq 'completed_metadata') {
740 $status = '<span style="color:red">'.'COMPLETED'.'</span>';
742 push @row, $status;
744 my $material_id = $identifier_info->[2];
745 my $material_name = $identifier_info->[3];
746 my $material_rs = $schema->resultset("Stock::Stock")->find( { stock_id => $material_id });
747 my $material_stock_type_id = $material_rs->type_id;
748 if ($material_stock_type_id == $transformation_type_id) {
749 push @row, qq{<a href="/transformation/$material_id">$material_name</a>}
750 } else {
751 push @row, qq{<a href="/stock/$material_id/view">$material_name</a>};
754 my $progress = $identifier_info->[5];
755 if ($progress) {
756 my $progress_ref = JSON::Any->jsonToObj($progress);
757 my %progress_hash = %{$progress_ref};
758 foreach my $type (@activity_types){
759 my $input = '';
760 if ($progress_hash{$type}) {
761 my $details = {};
762 my %details_hash = ();
763 $details = $progress_hash{$type};
764 %details_hash = %{$details};
766 if (($type =~ m/number/) || ($type =~ m/count/)) {
767 $input = 0;
768 foreach my $key (keys %details_hash) {
769 $input += $details_hash{$key}{'input'};
771 push @row, $input;
772 } elsif ($type =~ m/date/) {
773 foreach my $key (keys %details_hash) {
774 $input = $details_hash{$key}{'input'};
776 push @row, $input;
778 } else {
779 push @row, $input;
782 } else {
783 foreach my $type (@activity_types) {
784 push @row, '';
787 push @row, $identifier_name;
788 push @all_identifiers,[@row];
791 $c->stash->{rest} = { data => \@all_identifiers };