added tests
[sgn.git] / lib / SGN / Controller / AJAX / Cross / CrossingExperiment.pm
blob5c7937608eb7cdc09831ea2b4969fa2554253a23
1 =head1 NAME
3 SGN::Controller::AJAX::Cross::CrossingExperiment - a REST controller class to provide
4 functions related to crossing experiment
6 =head1 DESCRIPTION
9 =head1 AUTHOR
11 Titima Tantikanjana <tt15@cornell.edu>
13 =cut
15 package SGN::Controller::AJAX::Cross::CrossingExperiment;
16 use Moose;
17 use Try::Tiny;
18 use DateTime;
19 use Time::HiRes qw(time);
20 use POSIX qw(strftime);
21 use Data::Dumper;
22 use File::Basename qw | basename dirname|;
23 use File::Copy;
24 use File::Slurp;
25 use File::Spec::Functions;
26 use Digest::MD5;
27 use List::MoreUtils qw /any /;
28 use List::MoreUtils 'none';
29 use Bio::GeneticRelationships::Pedigree;
30 use Bio::GeneticRelationships::Individual;
31 use CXGN::UploadFile;
32 use CXGN::Pedigree::ParseUpload;
33 use CXGN::List::Validate;
34 use CXGN::List;
35 use CXGN::Pedigree::TargetNumbers;
36 use Carp;
37 use File::Path qw(make_path);
38 use File::Spec::Functions qw / catfile catdir/;
39 use CXGN::Cross;
40 use JSON;
41 use SGN::Model::Cvterm;
42 use Tie::UrlEncoder; our(%urlencode);
43 use LWP::UserAgent;
44 use URI::Encode qw(uri_encode uri_decode);
45 use Sort::Key::Natural qw(natsort);
46 BEGIN { extends 'Catalyst::Controller::REST' }
48 __PACKAGE__->config(
49 default => 'application/json',
50 stash_key => 'rest',
51 map => { 'application/json' => 'JSON', 'text/html' => 'JSON' },
54 sub upload_target_numbers : Path('/ajax/crossing_experiment/upload_target_numbers') : ActionClass('REST'){ }
56 sub upload_target_numbers_POST : Args(0) {
57 my $self = shift;
58 my $c = shift;
59 my $schema = $c->dbic_schema('Bio::Chado::Schema', 'sgn_chado');
60 my $metadata_schema = $c->dbic_schema("CXGN::Metadata::Schema");
61 my $dbh = $c->dbc->dbh;
62 my $target_numbers_experiment_id = $c->req->param('target_numbers_experiment_id');
63 my $upload = $c->req->upload('target_numbers_file');
64 my $parser;
65 my $parsed_data;
66 my $upload_original_name = $upload->filename();
67 my $upload_tempfile = $upload->tempname;
68 my $subdirectory = "target_numbers_upload";
69 my $archived_filename_with_path;
70 my $md5;
71 my $validate_file;
72 my $parsed_file;
73 my $parse_errors;
74 my %parsed_data;
75 my $time = DateTime->now();
76 my $timestamp = $time->ymd()."_".$time->hms();
77 my $user_role;
78 my $user_id;
79 my $user_name;
80 my $owner_name;
81 my $session_id = $c->req->param("sgn_session_id");
82 my @error_messages;
84 if ($session_id){
85 my $dbh = $c->dbc->dbh;
86 my @user_info = CXGN::Login->new($dbh)->query_from_cookie($session_id);
87 if (!$user_info[0]){
88 $c->stash->{rest} = {error=>'You must be logged in to upload target numbers!'};
89 $c->detach();
91 $user_id = $user_info[0];
92 $user_role = $user_info[1];
93 my $p = CXGN::People::Person->new($dbh, $user_id);
94 $user_name = $p->get_username;
95 } else {
96 if (!$c->user){
97 $c->stash->{rest} = {error=>'You must be logged in to upload intercross data!'};
98 $c->detach();
100 $user_id = $c->user()->get_object()->get_sp_person_id();
101 $user_name = $c->user()->get_object()->get_username();
102 $user_role = $c->user->get_object->get_user_type();
105 if (($user_role ne 'curator') && ($user_role ne 'submitter')) {
106 $c->stash->{rest} = {error=>'Only a submitter or a curator can upload target numbers of seed/progenies'};
107 $c->detach();
110 my $uploader = CXGN::UploadFile->new({
111 tempfile => $upload_tempfile,
112 subdirectory => $subdirectory,
113 archive_path => $c->config->{archive_path},
114 archive_filename => $upload_original_name,
115 timestamp => $timestamp,
116 user_id => $user_id,
117 user_role => $user_role
120 ## Store uploaded temporary file in arhive
121 $archived_filename_with_path = $uploader->archive();
122 $md5 = $uploader->get_md5($archived_filename_with_path);
123 if (!$archived_filename_with_path) {
124 $c->stash->{rest} = {error => "Could not save file $upload_original_name in archive",};
125 return;
127 unlink $upload_tempfile;
129 #parse uploaded file with appropriate plugin
130 $parser = CXGN::Pedigree::ParseUpload->new(chado_schema => $schema, filename => $archived_filename_with_path);
131 $parser->load_plugin('TargetNumbersExcel');
132 $parsed_data = $parser->parse();
133 #print STDERR "PARSED DATA =". Dumper($parsed_data)."\n";
134 if (!$parsed_data){
135 my $return_error = '';
136 my $parse_errors;
137 if (!$parser->has_parse_errors() ){
138 $c->stash->{rest} = {error_string => "Could not get parsing errors"};
139 } else {
140 $parse_errors = $parser->get_parse_errors();
141 #print STDERR Dumper $parse_errors;
142 foreach my $error_string (@{$parse_errors->{'error_messages'}}){
143 $return_error .= $error_string."<br>";
146 $c->stash->{rest} = {error_string => $return_error};
147 $c->detach();
150 if ($parsed_data){
152 my $md_row = $metadata_schema->resultset("MdMetadata")->create({create_person_id => $user_id});
153 $md_row->insert();
154 my $upload_file = CXGN::UploadFile->new();
155 my $md5 = $upload_file->get_md5($archived_filename_with_path);
156 my $md5checksum = $md5->hexdigest();
157 my $file_row = $metadata_schema->resultset("MdFiles")->create({
158 basename => basename($archived_filename_with_path),
159 dirname => dirname($archived_filename_with_path),
160 filetype => 'target_numbers_upload',
161 md5checksum => $md5checksum,
162 metadata_id => $md_row->metadata_id(),
164 my $file_id = $file_row->file_id();
165 my %target_numbers = %{$parsed_data};
167 # print STDERR "UPLOAD TARGET NUMBERS=".Dumper(\%target_numbers)."\n";
168 my $targets = CXGN::Pedigree::TargetNumbers->new({ chado_schema => $schema, crossing_experiment_id => $target_numbers_experiment_id, target_numbers => \%target_numbers });
169 $targets->store();
173 $c->stash->{rest} = {success => "1",};
177 sub record_target_numbers_using_lists : Path('/ajax/crossing_experiment/record_target_numbers') : ActionClass('REST') { }
179 sub record_target_numbers_using_lists_POST : Args(0) {
180 my $self = shift;
181 my $c = shift;
182 my $schema = $c->dbic_schema('Bio::Chado::Schema', 'sgn_chado');
183 my $crossing_experiment_id = $c->req->param('crossing_experiment_id');
184 my $number_of_seeds = decode_json $c->req->param('number_of_seeds');
185 my $number_of_progenies = decode_json $c->req->param('number_of_progenies');
187 my %target_numbers_hash;
188 foreach my$seed_info_hash (@$number_of_seeds) {
189 $target_numbers_hash{$seed_info_hash->{female_name}}{$seed_info_hash->{male_name}}{'target_number_of_seeds'} = $seed_info_hash->{number_of_seeds};
192 foreach my$progeny_info_hash (@$number_of_progenies) {
193 $target_numbers_hash{$progeny_info_hash->{female_name}}{$progeny_info_hash->{male_name}}{'target_number_of_progenies'} = $progeny_info_hash->{number_of_progenies};
196 print STDERR "TARGET NUMBERS HASH =".Dumper(\%target_numbers_hash)."\n";
197 my $targets = CXGN::Pedigree::TargetNumbers->new({ chado_schema => $schema, crossing_experiment_id => $crossing_experiment_id, target_numbers => \%target_numbers_hash });
198 $targets->store();
200 $c->stash->{rest} = {success => "1",};
204 sub get_target_numbers_and_progress :Path('/ajax/crossing_experiment/target_numbers_and_progress') Args(1) {
205 my $self = shift;
206 my $c = shift;
207 my $crossing_experiment_id = shift;
208 my $schema = $c->dbic_schema("Bio::Chado::Schema");
210 my $target_numbers = CXGN::Pedigree::TargetNumbers->new({ chado_schema => $schema, crossing_experiment_id => $crossing_experiment_id});
211 my $target_info = $target_numbers->get_target_numbers_and_progress();
212 # print STDERR "AJAX TARGET NUMBERS =".Dumper($target_info)."\n";
215 $c->stash->{rest} = { data => $target_info };