1 package SGN
::Controller
::AJAX
::Catalog
;
4 use CXGN
::Stock
::Catalog
;
7 use CXGN
::People
::Person
;
9 use CXGN
::Stock
::StockLookup
;
10 use SGN
::Model
::Cvterm
;
11 use CXGN
::List
::Validate
;
13 use CXGN
::Stock
::Seedlot
;
15 BEGIN { extends
'Catalyst::Controller::REST' }
18 default => 'application/json',
20 map => { 'application/json' => 'JSON', 'text/html' => 'JSON' },
24 sub add_catalog_item
: Path
('/ajax/catalog/add_item') : ActionClass
('REST'){ }
26 sub add_catalog_item_POST
: Args
(0) {
29 my $schema = $c->dbic_schema('Bio::Chado::Schema', 'sgn_chado');
30 my $dbh = $c->dbc->dbh;
32 my $item_name = $c->req->param('name');
33 my $item_category = $c->req->param('category');
34 my $item_additional_info = $c->req->param('additional_info');
35 my $item_material_source = $c->req->param('material_source');
36 my $item_breeding_program_id = $c->req->param('breeding_program_id');
37 my $contact_person = $c->req->param('contact_person');
38 my $item_prop_id = $c->req->param('item_prop_id');
39 my $availability = $c->req->param('availability');
40 if (!defined $availability) {
41 $availability = 'available';
45 print STDERR
"User not logged in... not adding a catalog item.\n";
46 $c->stash->{rest
} = {error_string
=> "You must be logged in to add a catalog item." };
50 my $item_material_type;
56 my $accession_cvterm_id = SGN
::Model
::Cvterm
->get_cvterm_row($schema, 'accession', 'stock_type')->cvterm_id();
57 my $seedlot_cvterm_id = SGN
::Model
::Cvterm
->get_cvterm_row($schema, 'seedlot', 'stock_type')->cvterm_id();
58 my $vector_construct_cvterm_id = SGN
::Model
::Cvterm
->get_cvterm_row($schema, 'vector_construct', 'stock_type')->cvterm_id();
59 my $population_cvterm_id = SGN
::Model
::Cvterm
->get_cvterm_row($schema, 'population', 'stock_type')->cvterm_id();
61 my $stock_lookup = CXGN
::Stock
::StockLookup
->new(schema
=> $schema);
62 $stock_lookup->set_stock_name($item_name);
63 my $item_rs = $stock_lookup->get_stock_exact();
65 if (!defined $item_rs) {
66 $c->stash->{rest
} = {error_string
=> "Item name is not in the database or not unique in the database!",};
69 $item_stock_id = $item_rs->stock_id();
70 my $item_type_id = $item_rs->type_id();
72 my $variety_result = $stock_lookup->get_stock_variety();
73 if (defined $variety_result) {
74 $item_variety = $variety_result;
79 if ($item_type_id == $accession_cvterm_id) {
80 my $organism_id = $item_rs->organism_id();
81 my $organism = $schema->resultset("Organism::Organism")->find({organism_id
=> $organism_id});
82 $item_species = $organism->species();
83 $item_material_type = 'plant';
84 $item_type = 'single item';
86 } elsif ($item_type_id == $seedlot_cvterm_id) {
87 my $seedlot_species = CXGN
::Stock
::Seedlot
->new(schema
=> $schema, seedlot_id
=>$item_stock_id);
88 $item_species = $seedlot_species->get_seedlot_species();
89 $item_material_type = 'seed';
90 $item_type = 'single item';
92 } elsif ($item_type_id == $vector_construct_cvterm_id) {
93 $item_material_type = 'construct';
94 $item_type = 'single item';
96 } elsif ($item_type_id == $population_cvterm_id) {
97 $item_material_type = 'plant';
98 $item_type = 'set of items';
103 my $sp_person_id = CXGN
::People
::Person
->get_person_by_username($dbh, $contact_person);
104 if (!$sp_person_id) {
105 $c->stash->{rest
} = {error_string
=> "Contact person has no record in the database!",};
108 # print STDERR "PERSON ID =".Dumper($sp_person_id)."\n";
109 my $program_rs = $schema->resultset('Project::Project')->find({project_id
=> $item_breeding_program_id});
111 $c->stash->{rest
} = {error_string
=> "Breeding program is not in the database!",};
115 my $stock_catalog = CXGN
::Stock
::Catalog
->new({
116 bcs_schema
=> $schema,
117 parent_id
=> $item_stock_id,
118 prop_id
=> $item_prop_id
121 $stock_catalog->item_type($item_type);
122 $stock_catalog->material_type($item_material_type);
123 $stock_catalog->material_source($item_material_source);
124 $stock_catalog->category($item_category);
125 $stock_catalog->species($item_species);
126 $stock_catalog->variety($item_variety);
127 $stock_catalog->breeding_program($item_breeding_program_id);
128 $stock_catalog->availability($availability);
129 $stock_catalog->additional_info($item_additional_info);
130 $stock_catalog->contact_person_id($sp_person_id);
132 $stock_catalog->store();
134 if (!$stock_catalog->store()){
135 $c->stash->{rest
} = {error_string
=> "Error saving catalog item",};
139 $c->stash->{rest
} = {success
=> "1",};
144 sub upload_catalog_items
: Path
('/ajax/catalog/upload_items') : ActionClass
('REST'){ }
146 sub upload_catalog_items_POST
: Args
(0) {
149 my $schema = $c->dbic_schema('Bio::Chado::Schema', 'sgn_chado');
150 my $metadata_schema = $c->dbic_schema("CXGN::Metadata::Schema");
151 my $phenome_schema = $c->dbic_schema("CXGN::Phenome::Schema");
152 my $dbh = $c->dbc->dbh;
153 my $upload = $c->req->upload('catalog_items_upload_file');
154 my $upload_type = 'CatalogXLS';
157 my $upload_original_name = $upload->filename();
158 my $upload_tempfile = $upload->tempname;
159 my $subdirectory = "catalog_upload";
160 my $archived_filename_with_path;
166 my $time = DateTime
->now();
167 my $timestamp = $time->ymd()."_".$time->hms();
172 my $session_id = $c->req->param("sgn_session_id");
175 my $dbh = $c->dbc->dbh;
176 my @user_info = CXGN
::Login
->new($dbh)->query_from_cookie($session_id);
178 $c->stash->{rest
} = {error
=>'You must be logged in to upload!'};
181 $user_id = $user_info[0];
182 $user_role = $user_info[1];
183 my $p = CXGN
::People
::Person
->new($dbh, $user_id);
184 $user_name = $p->get_username;
187 $c->stash->{rest
} = {error
=>'You must be logged in to upload catalog items!'};
190 $user_id = $c->user()->get_object()->get_sp_person_id();
191 $user_name = $c->user()->get_object()->get_username();
192 $user_role = $c->user->get_object->get_user_type();
194 my $uploader = CXGN
::UploadFile
->new({
195 tempfile
=> $upload_tempfile,
196 subdirectory
=> $subdirectory,
197 archive_path
=> $c->config->{archive_path
},
198 archive_filename
=> $upload_original_name,
199 timestamp
=> $timestamp,
201 user_role
=> $user_role
204 ## Store uploaded temporary file in arhive
205 $archived_filename_with_path = $uploader->archive();
206 $md5 = $uploader->get_md5($archived_filename_with_path);
207 if (!$archived_filename_with_path) {
208 $c->stash->{rest
} = {error
=> "Could not save file $upload_original_name in archive",};
211 unlink $upload_tempfile;
212 #parse uploaded file with appropriate plugin
213 my @stock_props = ('stock_catalog_json');
214 $parser = CXGN
::Stock
::ParseUpload
->new(chado_schema
=> $schema, filename
=> $archived_filename_with_path, editable_stock_props
=>\
@stock_props);
215 $parser->load_plugin($upload_type);
216 $parsed_data = $parser->parse();
219 my $return_error = '';
221 if (!$parser->has_parse_errors() ){
222 $c->stash->{rest
} = {error_string
=> "Could not get parsing errors"};
224 $parse_errors = $parser->get_parse_errors();
225 #print STDERR Dumper $parse_errors;
227 foreach my $error_string (@
{$parse_errors->{'error_messages'}}){
228 $return_error .= $error_string."<br>";
231 $c->stash->{rest
} = {error_string
=> $return_error};
236 my $variety_type_id = SGN
::Model
::Cvterm
->get_cvterm_row($schema, 'variety', 'stock_property')->cvterm_id();
237 my %catalog_info = %{$parsed_data};
238 foreach my $item_name (keys %catalog_info) {
243 my $item_material_type;
244 my $accession_cvterm_id = SGN
::Model
::Cvterm
->get_cvterm_row($schema, 'accession', 'stock_type')->cvterm_id();
245 my $seedlot_cvterm_id = SGN
::Model
::Cvterm
->get_cvterm_row($schema, 'seedlot', 'stock_type')->cvterm_id();
246 my $vector_construct_cvterm_id = SGN
::Model
::Cvterm
->get_cvterm_row($schema, 'vector_construct', 'stock_type')->cvterm_id();
247 my $population_cvterm_id = SGN
::Model
::Cvterm
->get_cvterm_row($schema, 'population', 'stock_type')->cvterm_id();
249 my $stock_lookup = CXGN
::Stock
::StockLookup
->new(schema
=> $schema);
250 $stock_lookup->set_stock_name($item_name);
251 my $item_rs = $stock_lookup->get_stock_exact();
253 if (!defined $item_rs) {
254 $c->stash->{rest
} = {error_string
=> "Item name is not unique in the database!",};
257 $item_stock_id = $item_rs->stock_id();
258 my $item_type_id = $item_rs->type_id();
260 my $variety_result = $stock_lookup->get_stock_variety();
261 if (defined $variety_result) {
262 $item_variety = $variety_result;
264 $item_variety = 'NA';
267 if ($item_type_id == $accession_cvterm_id) {
268 my $organism_id = $item_rs->organism_id();
269 my $organism = $schema->resultset("Organism::Organism")->find({organism_id
=> $organism_id});
270 $item_species = $organism->species();
271 $item_material_type = 'plant';
272 $item_type = 'single item';
274 } elsif ($item_type_id == $seedlot_cvterm_id) {
275 my $seedlot_species = CXGN
::Stock
::Seedlot
->new(schema
=> $schema, seedlot_id
=>$item_stock_id);
276 $item_species = $seedlot_species->get_seedlot_species();
277 $item_material_type = 'seed';
278 $item_type = 'single item';
280 } elsif ($item_type_id == $vector_construct_cvterm_id) {
281 $item_material_type = 'construct';
282 $item_type = 'single item';
284 } elsif ($item_type_id == $population_cvterm_id) {
285 $item_material_type = 'plant';
286 $item_type = 'set of items';
291 my %catalog_info_hash = %{$catalog_info{$item_name}};
293 my $stock_catalog = CXGN
::Stock
::Catalog
->new({
294 bcs_schema
=> $schema,
295 item_type
=> $item_type,
296 material_type
=> $item_material_type,
297 species
=> $item_species,
298 variety
=> $item_variety,
299 category
=> $catalog_info_hash{category
},
300 availability
=> 'available',
301 additional_info
=> $catalog_info_hash{additional_info
},
302 material_source
=> $catalog_info_hash{material_source
},
303 breeding_program
=> $catalog_info_hash{breeding_program
},
304 contact_person_id
=> $catalog_info_hash{contact_person_id
},
305 parent_id
=> $item_stock_id
308 $stock_catalog->store();
310 if (!$stock_catalog->store()){
311 $c->stash->{rest
} = {error_string
=> "Error saving catalog items",};
317 $c->stash->{rest
} = {success
=> "1"};
322 sub get_catalog
:Path
('/ajax/catalog/items') :Args
(0) {
325 my $schema = $c->dbic_schema('Bio::Chado::Schema', 'sgn_chado');
328 my $catalog_obj = CXGN
::Stock
::Catalog
->new({ bcs_schema
=> $schema});
329 my $catalog_ref = $catalog_obj->get_catalog_items();
330 # print STDERR "ITEM RESULTS =".Dumper($catalog_ref)."\n";
331 my @catalog_list = @
$catalog_ref;
332 foreach my $catalog_item (@catalog_list) {
333 my @item_details = ();
334 @item_details = @
$catalog_item;
335 my $item_id = shift @item_details;
336 my $stock_rs = $schema->resultset("Stock::Stock")->find({stock_id
=> $item_id });
337 my $item_name = $stock_rs->uniquename();
339 my $program_id = $item_details[7];
340 my $program_rs = $schema->resultset('Project::Project')->find({project_id
=> $program_id});
341 my $program_name = $program_rs->name();
342 my $availability = $item_details[8];
343 if (!defined $availability) {
344 $availability = 'available';
347 push @catalog_items, {
349 item_name
=> $item_name,
350 item_type
=> $item_details[0],
351 species
=> $item_details[1],
352 variety
=> $item_details[2],
353 material_type
=> $item_details[3],
354 category
=> $item_details[4],
355 material_source
=> $item_details[5],
356 additional_info
=> $item_details[6],
357 breeding_program
=> $program_name,
358 availability
=> $availability
362 $c->stash->{rest
} = {data
=> \
@catalog_items};
367 sub item_image_list
:Path
('/ajax/catalog/image_list') :Args
(1) {
371 my $schema = $c->dbic_schema('Bio::Chado::Schema', 'sgn_chado');
372 my $dbh = $c->dbc->dbh;
373 # print STDERR "ITEM ID =".Dumper($item_id)."\n";
376 my $q = "select distinct image_id, cvterm.name, stock_image.display_order FROM phenome.stock_image JOIN stock USING(stock_id) JOIN cvterm ON(type_id=cvterm_id) WHERE stock_id = ? ORDER BY stock_image.display_order ASC";
377 my $h = $schema->storage->dbh()->prepare($q);
378 $h->execute($item_id);
379 while (my ($image_id, $stock_type) = $h->fetchrow_array()){
380 push @image_ids, [$image_id, $stock_type];
382 # print STDERR "IMAGE IDS =".Dumper(\@image_ids)."\n";
384 foreach my $image_info(@image_ids) {
385 my $image_obj = SGN
::Image
->new($dbh, $image_info->[0]);
386 my $image_obj_id = $image_obj->get_image_id;
387 my $image_obj_name = $image_obj->get_name();
388 my $image_obj_description = $image_obj->get_description();
389 if (!$image_obj_description) {
390 $image_obj_description = 'N/A';
392 my $medium_image = $image_obj->get_image_url("medium");
393 my $image_page = "/image/view/$image_obj_id";
394 my $small_image = $image_obj->get_image_url("thumbnail");
397 image_id
=> $image_obj_id,
398 image_name
=> $image_obj_name,
399 small_image
=> qq|<a href
="$medium_image" title
="<a href=$image_page>Go to image page ($image_obj_name)</a>" class="stock_image_group" rel
="gallery-figures"><img src
="$small_image"/></a
> |,
400 image_description
=> $image_obj_description,
404 $c->stash->{rest
} = {data
=> \
@image_list};
408 sub edit_catalog_image
: Path
('/ajax/catalog/edit_image') : ActionClass
('REST'){ }
410 sub edit_catalog_image_POST
: Args
(0) {
413 my $schema = $c->dbic_schema('Bio::Chado::Schema', 'sgn_chado');
414 my $dbh = $c->dbc->dbh;
416 my $item_name = $c->req->param('item_name');
417 my $item_prop_id = $c->req->param('item_prop_id');
418 my $image_id = $c->req->param('image_id');
421 push @images, $image_id;
422 print STDERR
"IMAGE ID =".Dumper
(\
@images)."\n";
424 print STDERR
"User not logged in... not adding a catalog item.\n";
425 $c->stash->{rest
} = {error_string
=> "You must be logged in to add a catalog image." };
429 my $item_rs = $schema->resultset("Stock::Stock")->find({uniquename
=> $item_name});
431 $c->stash->{rest
} = {error_string
=> "Item name is not in the database!",};
434 $item_stock_id = $item_rs->stock_id();
437 my $stock_catalog = CXGN
::Stock
::Catalog
->new({
438 bcs_schema
=> $schema,
439 parent_id
=> $item_stock_id,
440 prop_id
=> $item_prop_id
443 $stock_catalog->images(\
@images);
445 $stock_catalog->store();
447 if (!$stock_catalog->store()){
448 $c->stash->{rest
} = {error_string
=> "Error saving catalog image",};
452 $c->stash->{rest
} = {success
=> "1",};
457 sub delete_catalog_item
: Path
('/ajax/catalog/delete') : ActionClass
('REST'){ }
459 sub delete_catalog_item_POST
: Args
(0) {
462 my $schema = $c->dbic_schema('Bio::Chado::Schema', 'sgn_chado');
464 my $item_prop_id = $c->req->param('item_prop_id');
465 print STDERR
"ITEM PROP ID =".Dumper
($item_prop_id)."\n";
466 my $catalog_obj = CXGN
::Stock
::Catalog
->new({ bcs_schema
=> $schema, prop_id
=> $item_prop_id });
467 $catalog_obj->delete();
468 if ($catalog_obj->delete() == 0) {
469 $c->stash->{rest
} = { error_string
=> "An error occurred attempting to delete a catalog item." };
473 $c->stash->{rest
} = { success
=> 1 };
477 sub add_catalog_item_list
: Path
('/ajax/catalog/add_item_list') : ActionClass
('REST'){ }
479 sub add_catalog_item_list_POST
: Args
(0) {
482 my $schema = $c->dbic_schema('Bio::Chado::Schema', 'sgn_chado');
483 my $dbh = $c->dbc->dbh;
485 my $list_type = $c->req->param('list_type');
486 my $list_id = $c->req->param('catalog_list');
487 my $list_category = $c->req->param('category');
488 my $list_additional_info = $c->req->param('additional_info');
489 my $list_material_source = $c->req->param('material_source');
490 my $list_breeding_program_id = $c->req->param('breeding_program_id');
491 my $list_contact_person = $c->req->param('contact_person');
494 print STDERR
"User not logged in... not adding catalog items.\n";
495 $c->stash->{rest
} = {error_string
=> "You must be logged in to add catalog items." };
499 my $sp_person_id = CXGN
::People
::Person
->get_person_by_username($dbh, $list_contact_person);
500 if (!$sp_person_id) {
501 $c->stash->{rest
} = {error_string
=> "Contact person has no record in the database!",};
506 my $item_material_type;
508 if ($list_type eq 'accessions') {
509 $item_material_type = 'plant';
510 $item_type = 'single item';
511 } elsif ($list_type eq 'seedlots') {
512 $item_material_type = 'seed';
513 $item_type = 'single item';
514 } elsif ($list_type eq 'vector_constructs') {
515 $item_material_type = 'construct';
516 $item_type = 'single item';
517 } elsif ($list_type eq 'populations') {
518 $item_material_type = 'plant';
519 $item_type = 'set of items';
522 my $item_list = CXGN
::List
->new({dbh
=> $dbh, list_id
=> $list_id});
523 my $items = $item_list->retrieve_elements($list_id);
524 my @item_names = @
$items;
526 my $list_error_message;
527 my $item_validator = CXGN
::List
::Validate
->new();
528 my @item_missing = @
{$item_validator->validate($schema, $list_type,\
@item_names)->{'missing'}};
529 if (scalar(@item_missing) > 0) {
530 $list_error_message = "The following items are not in database or are not the specified list type: ".join("\n", @item_missing);
531 $c->stash->{rest
} = { error_string
=> $list_error_message };
534 foreach my $item (@item_names) {
539 my $stock_lookup = CXGN
::Stock
::StockLookup
->new(schema
=> $schema);
540 $stock_lookup->set_stock_name($item);
541 my $item_rs = $stock_lookup->get_stock_exact();
543 if (!defined $item_rs) {
544 $c->stash->{rest
} = {error_string
=> "Item name is not unique in the database!",};
547 $item_stock_id = $item_rs->stock_id();
549 my $variety_result = $stock_lookup->get_stock_variety();
550 if (defined $variety_result) {
551 $item_variety = $variety_result;
553 $item_variety = 'NA';
556 if ($list_type eq 'accessions') {
557 my $organism_id = $item_rs->organism_id();
558 my $organism = $schema->resultset("Organism::Organism")->find({organism_id
=> $organism_id});
559 $item_species = $organism->species();
561 } elsif ($list_type eq 'seedlots') {
562 my $seedlot_species = CXGN
::Stock
::Seedlot
->new(schema
=> $schema, seedlot_id
=>$item_stock_id);
563 $item_species = $seedlot_species->get_seedlot_species();
568 my $stock_catalog = CXGN
::Stock
::Catalog
->new({
569 bcs_schema
=> $schema,
570 item_type
=> $item_type,
571 material_type
=> $item_material_type,
572 species
=> $item_species,
573 variety
=> $item_variety,
574 category
=> $list_category,
575 availability
=> 'available',
576 additional_info
=> $list_additional_info,
577 material_source
=> $list_material_source,
578 breeding_program
=> $list_breeding_program_id,
579 contact_person_id
=> $sp_person_id,
580 parent_id
=> $item_stock_id
583 $stock_catalog->store();
585 if (!$stock_catalog->store()){
586 $c->stash->{rest
} = {error_string
=> "Error saving catalog items",};
593 $c->stash->{rest
} = {success
=> "1",};