seedlot upload with accession synonyms. seedlot upload works to update existing seedlots
[sgn.git] / lib / SGN / Controller / AJAX / GenotypingTrial.pm
blobb4ff6117a376a5006dd6499ad49fcd8cd8f6d235
2 package SGN::Controller::AJAX::GenotypingTrial;
4 use Moose;
5 use JSON;
6 use Data::Dumper;
7 use CXGN::Trial::TrialDesign;
8 use Try::Tiny;
9 use List::MoreUtils qw /any /;
10 use CXGN::People::Person;
11 use CXGN::Login;
13 BEGIN { extends 'Catalyst::Controller::REST' }
15 __PACKAGE__->config(
16 default => 'application/json',
17 stash_key => 'rest',
18 map => { 'application/json' => 'JSON', 'text/html' => 'JSON' },
21 sub generate_genotype_trial : Path('/ajax/breeders/generategenotypetrial') ActionClass('REST') {}
22 sub generate_genotype_trial_POST : Args(0) {
23 my $self = shift;
24 my $c = shift;
26 if (!($c->user()->check_roles('curator') || $c->user()->check_roles('submitter'))) {
27 $c->stash->{rest} = { error => 'You do not have the required privileges to create a genotyping trial.' };
28 $c->detach();
31 my $schema = $c->dbic_schema("Bio::Chado::Schema");
32 my $plate_info = decode_json $c->req->param("plate_data");
33 print STDERR Dumper $plate_info;
35 if ( !$plate_info->{elements} || !$plate_info->{genotyping_facility_submit} || !$plate_info->{project_name} || !$plate_info->{description} || !$plate_info->{location} || !$plate_info->{year} || !$plate_info->{name} || !$plate_info->{breeding_program} || !$plate_info->{genotyping_facility} || !$plate_info->{sample_type} || !$plate_info->{plate_format} ) {
36 $c->stash->{rest} = { error => "Please provide all parameters in the plate information section" };
37 $c->detach();
40 if ( $plate_info->{genotyping_facility} eq 'igd' && $plate_info->{genotyping_facility_submit} eq 'yes' && $plate_info->{blank_well} eq ''){
41 $c->stash->{rest} = { error => "To submit to Cornell IGD you need to provide the blank well!" };
42 $c->detach();
45 my $location = $schema->resultset("NaturalDiversity::NdGeolocation")->find( { nd_geolocation_id => $plate_info->{location} } );
46 if (!$location) {
47 $c->stash->{rest} = { error => "Unknown location" };
48 $c->detach();
51 my $breeding_program = $schema->resultset("Project::Project")->find( { project_id => $plate_info->{breeding_program} });
52 if (!$breeding_program) {
53 $c->stash->{rest} = { error => "Unknown breeding program" };
54 $c->detach();
57 my $td = CXGN::Trial::TrialDesign->new( { schema => $schema });
59 $td->set_stock_list($plate_info->{elements});
60 $td->set_block_size($plate_info->{plate_format});
61 $td->set_blank($plate_info->{blank_well});
62 $td->set_trial_name($plate_info->{name});
63 $td->set_design_type("genotyping_plate");
65 eval {
66 $td->calculate_design();
69 if ($@) {
70 $c->stash->{rest} = { error => "Design failed. Error: $@" };
71 print STDERR "Design failed because of $@\n";
72 $c->detach();
75 my $design = $td->get_design();
77 if (exists($design->{error})) {
78 $c->stash->{rest} = $design;
79 $c->detach();
82 #Add common answers from form to all wells
83 foreach (values %$design){
84 $_->{concentration} = $plate_info->{well_concentration};
85 $_->{volume} = $plate_info->{well_volume};
86 $_->{tissue_type} = $plate_info->{well_tissue};
87 $_->{dna_person} = $plate_info->{well_dna_person};
88 $_->{extraction} = $plate_info->{well_extraction};
89 $_->{acquisition_date} = $plate_info->{well_date};
90 $_->{notes} = $plate_info->{well_notes};
91 $_->{ncbi_taxonomy_id} = $plate_info->{ncbi_taxonomy_id};
93 #print STDERR Dumper($design);
95 $c->stash->{rest} = {success => 1, design=>$design};
99 sub parse_genotype_trial_file : Path('/ajax/breeders/parsegenotypetrial') : ActionClass('REST') { }
100 sub parse_genotype_trial_file_POST : Args(0) {
101 my ($self, $c) = @_;
103 my $chado_schema = $c->dbic_schema('Bio::Chado::Schema', 'sgn_chado');
104 my $metadata_schema = $c->dbic_schema("CXGN::Metadata::Schema");
105 my $phenome_schema = $c->dbic_schema("CXGN::Phenome::Schema");
106 my $dbh = $c->dbc->dbh;
107 my $upload_xls = $c->req->upload('genotyping_trial_layout_upload');
108 my $upload_coordinate = $c->req->upload('genotyping_trial_layout_upload_coordinate');
109 if ($upload_xls && $upload_coordinate){
110 $c->stash->{rest} = {error => "Do not upload both XLS and Coordinate file at the same time!" };
111 return;
113 if (!$upload_xls && !$upload_coordinate){
114 $c->stash->{rest} = {error => "You must upload a genotyping trial file!" };
115 return;
117 my $parser;
118 my $parsed_data;
119 my $upload;
120 my $upload_type;
121 if ($upload_xls){
122 $upload = $upload_xls;
123 $upload_type = 'GenotypeTrialXLS';
125 if ($upload_coordinate){
126 $upload = $upload_coordinate;
127 $upload_type = 'GenotypeTrialCoordinate';
129 my $upload_original_name = $upload->filename();
130 my $upload_tempfile = $upload->tempname;
131 my $subdirectory = "genotyping_trial_upload";
132 my $archived_filename_with_path;
133 my $md5;
134 my $validate_file;
135 my $parsed_file;
136 my $parse_errors;
137 my %parsed_data;
138 my %upload_metadata;
139 my $time = DateTime->now();
140 my $timestamp = $time->ymd()."_".$time->hms();
141 my $error;
143 if ($upload_original_name =~ /\s/ || $upload_original_name =~ /\// || $upload_original_name =~ /\\/ ) {
144 print STDERR "File name must not have spaces or slashes.\n";
145 $c->stash->{rest} = {error => "Uploaded file name must not contain spaces or slashes." };
146 return;
149 my $user_id;
150 my $user_name;
151 my $user_role;
152 my $session_id = $c->req->param("sgn_session_id");
154 if ($session_id){
155 my $dbh = $c->dbc->dbh;
156 my @user_info = CXGN::Login->new($dbh)->query_from_cookie($session_id);
157 if (!$user_info[0]){
158 $c->stash->{rest} = {error=>'You must be logged in to upload genotyping trial!'};
159 $c->detach();
161 $user_id = $user_info[0];
162 $user_role = $user_info[1];
163 my $p = CXGN::People::Person->new($dbh, $user_id);
164 $user_name = $p->get_username;
165 } else{
166 if (!$c->user){
167 $c->stash->{rest} = {error=>'You must be logged in to upload a genotyping trial!'};
168 $c->detach();
170 $user_id = $c->user()->get_object()->get_sp_person_id();
171 $user_name = $c->user()->get_object()->get_username();
172 $user_role = $c->user->get_object->get_user_type();
175 if ($user_role ne 'curator' && $user_role ne 'submitter') {
176 $c->stash->{rest} = {error => "You have insufficient privileges to upload a genotyping trial." };
177 $c->detach();
180 ## Store uploaded temporary file in archive
181 my $uploader = CXGN::UploadFile->new({
182 tempfile => $upload_tempfile,
183 subdirectory => $subdirectory,
184 archive_path => $c->config->{archive_path},
185 archive_filename => $upload_original_name,
186 timestamp => $timestamp,
187 user_id => $user_id,
188 user_role => $user_role
190 $archived_filename_with_path = $uploader->archive();
191 $md5 = $uploader->get_md5($archived_filename_with_path);
192 if (!$archived_filename_with_path) {
193 $c->stash->{rest} = {error => "Could not save file $upload_original_name in archive",};
194 return;
196 unlink $upload_tempfile;
198 #parse uploaded file with appropriate plugin
199 $parser = CXGN::Trial::ParseUpload->new(chado_schema => $chado_schema, filename => $archived_filename_with_path);
200 $parser->load_plugin($upload_type);
201 $parsed_data = $parser->parse();
203 if (!$parsed_data) {
204 my $return_error = '';
206 if (! $parser->has_parse_errors() ){
207 $return_error = "Could not get parsing errors";
208 $c->stash->{rest} = {error_string => $return_error,};
210 else {
211 $parse_errors = $parser->get_parse_errors();
212 #print STDERR Dumper $parse_errors;
214 foreach my $error_string (@{$parse_errors->{'error_messages'}}){
215 $return_error=$return_error.$error_string."<br>";
219 $c->stash->{rest} = {error_string => $return_error, missing_accessions => $parse_errors->{'missing_accessions'}};
220 return;
222 #print STDERR Dumper $parsed_data;
224 #Turn parased data into same format as generate_genotype_trial above
225 my %design;
226 foreach (sort keys %$parsed_data){
227 my $val = $parsed_data->{$_};
228 $design{$val->{well}} = {
229 plot_name => $val->{sample_id},
230 stock_name => $val->{source_stock_uniquename},
231 plot_number => $val->{well},
232 row_number => $val->{row},
233 col_number => $val->{column},
234 is_blank => $val->{is_blank},
235 concentration => $val->{concentration},
236 volume => $val->{volume},
237 tissue_type => $val->{tissue_type},
238 dna_person => $val->{dna_person},
239 extraction => $val->{extraction},
240 acquisition_date => $val->{date},
241 notes => $val->{notes},
242 ncbi_taxonomy_id => $val->{ncbi_taxonomy_id}
246 $c->stash->{rest} = {success => "1", design=>\%design};
249 sub store_genotype_trial : Path('/ajax/breeders/storegenotypetrial') ActionClass('REST') {}
250 sub store_genotype_trial_POST : Args(0) {
251 my $self = shift;
252 my $c = shift;
254 my $user_id;
255 my $user_name;
256 my $user_role;
257 my $session_id = $c->req->param("sgn_session_id");
259 if ($session_id){
260 my $dbh = $c->dbc->dbh;
261 my @user_info = CXGN::Login->new($dbh)->query_from_cookie($session_id);
262 if (!$user_info[0]){
263 $c->stash->{rest} = {error=>'You must be logged in to upload genotyping trial!'};
264 $c->detach();
266 $user_id = $user_info[0];
267 $user_role = $user_info[1];
268 my $p = CXGN::People::Person->new($dbh, $user_id);
269 $user_name = $p->get_username;
270 } else{
271 if (!$c->user){
272 $c->stash->{rest} = {error=>'You must be logged in to upload a genotyping trial!'};
273 $c->detach();
275 $user_id = $c->user()->get_object()->get_sp_person_id();
276 $user_name = $c->user()->get_object()->get_username();
277 $user_role = $c->user->get_object->get_user_type();
280 if ($user_role ne 'curator' && $user_role ne 'submitter') {
281 $c->stash->{rest} = {error => "You have insufficient privileges to upload a genotyping trial." };
282 $c->detach();
285 my $schema = $c->dbic_schema("Bio::Chado::Schema");
286 my $plate_info = decode_json $c->req->param("plate_data");
287 #print STDERR Dumper $plate_info;
289 if ( !$plate_info->{design} || !$plate_info->{genotyping_facility_submit} || !$plate_info->{project_name} || !$plate_info->{description} || !$plate_info->{location} || !$plate_info->{year} || !$plate_info->{name} || !$plate_info->{breeding_program} || !$plate_info->{genotyping_facility} || !$plate_info->{sample_type} || !$plate_info->{plate_format} ) {
290 $c->stash->{rest} = { error => "Please provide all parameters in the plate information section" };
291 $c->detach();
294 my $location = $schema->resultset("NaturalDiversity::NdGeolocation")->find( { nd_geolocation_id => $plate_info->{location} } );
295 if (!$location) {
296 $c->stash->{rest} = { error => "Unknown location" };
297 $c->detach();
300 my $breeding_program = $schema->resultset("Project::Project")->find( { project_id => $plate_info->{breeding_program} });
301 if (!$breeding_program) {
302 $c->stash->{rest} = { error => "Unknown breeding program" };
303 $c->detach();
306 print STDERR "Creating the genotyping trial...\n";
308 my $message;
309 my $coderef = sub {
311 my $ct = CXGN::Trial::TrialCreate->new( {
312 chado_schema => $schema,
313 dbh => $c->dbc->dbh(),
314 user_name => $user_name, #not implemented,
315 operator => $user_name,
316 trial_year => $plate_info->{year},
317 trial_location => $location->description(),
318 program => $breeding_program->name(),
319 trial_description => $plate_info->{description},
320 design_type => 'genotyping_plate',
321 design => $plate_info->{design},
322 trial_name => $plate_info->{name},
323 is_genotyping => 1,
324 genotyping_user_id => $user_id,
325 genotyping_project_name => $plate_info->{project_name},
326 genotyping_facility_submitted => $plate_info->{genotyping_facility_submit},
327 genotyping_facility => $plate_info->{genotyping_facility},
328 genotyping_plate_format => $plate_info->{plate_format},
329 genotyping_plate_sample_type => $plate_info->{sample_type},
332 $message = $ct->save_trial();
335 try {
336 $schema->txn_do($coderef);
337 } catch {
338 print STDERR "Transaction Error: $_\n";
339 $c->stash->{rest} = {error => "Error saving genotyping trial in the database: $_"};
340 $c->detach;
343 my $error;
344 if ($message->{'error'}) {
345 $error = $message->{'error'};
347 if ($error){
348 $c->stash->{rest} = {error => "Error saving genotyping trial in the database: $error"};
349 $c->detach;
351 #print STDERR Dumper(%message);
353 my $dbh = $c->dbc->dbh();
354 my $bs = CXGN::BreederSearch->new( { dbh=>$dbh, dbname=>$c->config->{dbname}, } );
355 my $refresh = $bs->refresh_matviews($c->config->{dbhost}, $c->config->{dbname}, $c->config->{dbuser}, $c->config->{dbpass}, 'stockprop');
357 my $saved_layout = CXGN::Trial::TrialLayout->new({schema => $schema, trial_id => $message->{trial_id}, experiment_type=>'genotyping_layout'});
358 my $saved_design = $saved_layout->get_design();
359 #print STDERR Dumper $saved_design;
361 my @brapi_samples;
362 foreach (values %$saved_design){
363 push @brapi_samples, {
364 sampleDbId => $_->{plot_id},
365 sampleName => $_->{plot_name},
366 well => $_->{plot_number},
367 row => $_->{row_number},
368 column => $_->{col_number},
369 concentration => $_->{concentration},
370 volume => $_->{volume},
371 tissueType => $_->{tissue_type},
372 taxonId => {
373 sourceName => 'NCBI',
374 taxonId => $_->{ncbi_taxonomy_id}
379 my $brapi_plate_data = {
380 vendorProjectDbId => $plate_info->{project_name},
381 clientPlateDbId => $message->{trial_id},
382 clientPlateName => $plate_info->{name},
383 plateFormat => $plate_info->{plate_format},
384 sampleType => $plate_info->{sample_type},
385 samples => \@brapi_samples
388 $c->stash->{rest} = {
389 message => "Successfully stored the genotyping trial.",
390 trial_id => $message->{trial_id},
391 plate_data => $brapi_plate_data
395 sub get_genotypingserver_credentials : Path('/ajax/breeders/genotyping_credentials') Args(0) {
396 my $self = shift;
397 my $c = shift;
399 if ($c->user && ($c->user->check_roles("submitter") || $c->user->check_roles("curator"))) {
400 $c->stash->{rest} = {
401 host => $c->config->{genotyping_server_host},
402 username => $c->config->{genotyping_server_username},
403 password => $c->config->{genotyping_server_password},
404 token => $c->config->{genotyping_server_token},
407 else {
408 $c->stash->{rest} = {
409 error => "Insufficient privileges for this operation."