Merge pull request #5205 from solgenomics/topic/generic_trial_upload
[sgn.git] / lib / SGN / Controller / AJAX / PhenotypesDownload.pm
blobf3fea01e69e875a2eab7454b5ba428a6451d5ae0
2 =head1 NAME
4 SGN::Controller::AJAX::PhenotypesDownload - a REST controller class to provide the
5 backend for downloading phenotype spreadsheets
7 =head1 DESCRIPTION
9 Downloading Phenotype Spreadsheets
11 =head1 AUTHOR
13 Jeremy Edwards <jde22@cornell.edu>
15 =cut
17 package SGN::Controller::AJAX::PhenotypesDownload;
19 use Moose;
20 use Try::Tiny;
21 use DateTime;
22 use File::Slurp;
23 use File::Spec::Functions;
24 use File::Copy;
25 use List::MoreUtils qw /any /;
26 use SGN::View::ArrayElements qw/array_elements_simple_view/;
27 use CXGN::Stock::StockTemplate;
28 use JSON -support_by_pp;
29 use CXGN::Phenotypes::CreateSpreadsheet;
30 use CXGN::Trial::Download;
31 use Tie::UrlEncoder; our(%urlencode);
32 use Data::Dumper;
33 use JSON qw( decode_json );
35 BEGIN { extends 'Catalyst::Controller::REST' }
37 __PACKAGE__->config(
38 default => 'application/json',
39 stash_key => 'rest',
40 map => { 'application/json' => 'JSON' },
44 sub create_phenotype_spreadsheet : Path('/ajax/phenotype/create_spreadsheet') : ActionClass('REST') { }
46 sub create_phenotype_spreadsheet_GET : Args(0) {
47 my $self = shift;
48 my $c = shift;
49 $c->forward('create_phenotype_spreadsheet_POST');
52 sub create_phenotype_spreadsheet_POST : Args(0) {
53 print STDERR "phenotype download controller\n";
54 my ($self, $c) = @_;
55 if (!$c->user()) {
56 $c->stash->{rest} = {error => "You need to be logged in to download a phenotype spreadsheet." };
57 return;
60 my $sp_person_id = $c->user() ? $c->user->get_object()->get_sp_person_id() : undef;
61 my $schema = $c->dbic_schema('Bio::Chado::Schema', 'sgn_chado', $sp_person_id);
62 my @trial_ids = @{_parse_list_from_json($c->req->param('trial_ids'))};
63 #print STDERR Dumper \@trial_ids;
64 my $format = $c->req->param('format') || "ExcelBasic";
65 my $include_notes = $c->req->param('include_notes');
66 my $data_level = $c->req->param('data_level') || "plots";
67 my $file_format = $c->req->param('create_spreadsheet_phenotype_file_format') || "detailed";
68 my $sample_number = $c->req->param('sample_number');
69 if ($sample_number eq '') {$sample_number = undef};
70 my $predefined_columns = $c->req->param('predefined_columns') ? decode_json $c->req->param('predefined_columns') : [];
71 my $trial_stock_type = $c->req->param('trial_stock_type');
72 #print STDERR Dumper $sample_number;
73 #print STDERR Dumper $predefined_columns;
75 my $trial_name = "";
76 foreach (@trial_ids){
77 my $trial = CXGN::Trial->new( { bcs_schema => $c->dbic_schema("Bio::Chado::Schema", undef, $sp_person_id), trial_id => $_ });
78 $trial_name = $trial->get_name();
79 $trial_name =~ s/ /\_/g;
81 if ($data_level eq 'plants') {
82 if (!$trial->has_plant_entries()) {
83 $c->stash->{rest} = { error => "The requested trial (".$trial->get_name().") does not have plant entries. Please create the plant entries first." };
84 return;
87 if ($data_level eq 'subplots' || $data_level eq 'plants_subplots') {
88 if (!$trial->has_subplot_entries()) {
89 $c->stash->{rest} = { error => "The requested trial (".$trial->get_name().") does not have subplot entries." };
90 return;
93 if ($data_level eq 'tissue_samples') {
94 if (!$trial->has_tissue_sample_entries()) {
95 $c->stash->{rest} = { error => "The requested trial (".$trial->get_name().") does not have tissue sample entries. Please create the tissue sample entries first." };
96 return;
101 my @trait_list = @{_parse_list_from_json($c->req->param('trait_list'))};
102 my $dir = $c->tempfiles_subdir('/download');
103 my $rel_file = $c->tempfile( TEMPLATE => "download/$trial_name"."_phenotype_collectionXXXX");
104 $rel_file = substr $rel_file, 0, -4;
105 my $tempfile = $c->config->{basepath}."/".$rel_file.".xlsx";
106 my $create_spreadsheet = CXGN::Trial::Download->new({
107 bcs_schema => $schema,
108 trial_list => \@trial_ids,
109 trait_list => \@trait_list,
110 filename => $tempfile,
111 format => $format,
112 data_level => $data_level,
113 include_notes => $include_notes,
114 sample_number => $sample_number,
115 predefined_columns => $predefined_columns,
116 trial_stock_type => $trial_stock_type,
119 $create_spreadsheet->download();
121 print STDERR "DOWNLOAD FILENAME = ".$create_spreadsheet->filename()."\n";
122 print STDERR "RELATIVE = $rel_file\n";
124 #Add postcomposed terms from selected predefined_columns
125 if (scalar(@$predefined_columns)>0){
126 my @allowed_composed_cvs = split ',', $c->config->{composable_cvs};
127 my $composable_cvterm_delimiter = $c->config->{composable_cvterm_delimiter};
128 my $composable_cvterm_format = $c->config->{composable_cvterm_format};
129 my @allowed_composed_cvs_minus_trait = grep { $_ ne 'trait' } @allowed_composed_cvs;
130 my %id_hash;
131 for my $i (0 .. scalar @$predefined_columns){
132 my $cv_type = $allowed_composed_cvs_minus_trait[$i];
133 foreach my $selected_term (values %{$predefined_columns->[$i]}){
134 my $cvterm_id = SGN::Model::Cvterm->get_cvterm_row_from_trait_name($schema, $selected_term)->cvterm_id();
135 push @{$id_hash{$cv_type}}, $cvterm_id;
138 my @trait_cvterm_ids;
139 foreach (@trait_list){
140 push @trait_cvterm_ids, SGN::Model::Cvterm->get_cvterm_row_from_trait_name($schema, $_)->cvterm_id();
142 $id_hash{'trait'} = \@trait_cvterm_ids;
143 #print STDERR Dumper \%id_hash;
144 my $traits = SGN::Model::Cvterm->get_traits_from_component_categories($schema, \@allowed_composed_cvs, $composable_cvterm_delimiter, $composable_cvterm_format, \%id_hash);
145 my %new_traits;
146 foreach (@{$traits->{new_traits}}){
147 $new_traits{$_->[1]} = join ',', @{$_->[0]};
149 #print STDERR Dumper \%new_traits;
150 my $new_terms;
151 eval {
152 my $onto = CXGN::Onto->new({ schema => $schema });
153 $new_terms = $onto->store_composed_term(\%new_traits);
155 if ($@) {
156 die "An error occurred saving the new trait details: $@";
158 #print STDERR Dumper $new_terms;
161 $c->stash->{rest} = { filename => $urlencode{$rel_file.".xlsx"} };
164 sub _parse_list_from_json {
165 my $list_json = shift;
166 my $json = new JSON;
167 if ($list_json) {
168 #my $decoded_list = $json->allow_nonref->utf8->relaxed->escape_slash->loose->allow_singlequote->allow_barekey->decode($list_json);
169 my $decoded_list = decode_json($list_json);
170 my @array_of_list_items = @{$decoded_list};
171 return \@array_of_list_items;
173 else {
174 return;
178 #########
180 #########