2 package SGN
::Controller
::AJAX
::Order
;
5 use CXGN
::Stock
::Order
;
6 use CXGN
::Stock
::OrderBatch
;
10 use CXGN
::People
::Person
;
13 use File
::Basename qw
| basename dirname
|;
16 use File
::Spec
::Functions
;
18 use File
::Path
qw(make_path);
19 use File
::Spec
::Functions qw
/ catfile catdir/;
24 use URI
::Encode
qw(uri_encode uri_decode);
25 use Tie
::UrlEncoder
; our(%urlencode);
28 BEGIN { extends
'Catalyst::Controller::REST' }
31 default => 'application/json',
33 map => { 'application/json' => 'JSON', 'text/html' => 'JSON' },
37 sub submit_order
: Path
('/ajax/order/submit') : ActionClass
('REST'){ }
39 sub submit_order_POST
: Args
(0) {
42 my $schema = $c->dbic_schema('Bio::Chado::Schema', 'sgn_chado');
43 my $people_schema = $c->dbic_schema('CXGN::People::Schema');
44 my $dbh = $c->dbc->dbh();
45 my $list_id = $c->req->param('list_id');
46 my $time = DateTime
->now();
47 my $timestamp = $time->ymd()."_".$time->hms();
48 my $request_date = $time->ymd();
49 # print STDERR "LIST ID =".Dumper($list_id)."\n";
52 print STDERR
"User not logged in... not adding a catalog item.\n";
53 $c->stash->{rest
} = {error_string
=> "You must be logged in to add a catalog item." };
56 my $user_id = $c->user()->get_object()->get_sp_person_id();
57 my $user_name = $c->user()->get_object()->get_username();
58 my $user_role = $c->user->get_object->get_user_type();
60 my $list = CXGN
::List
->new( { dbh
=>$dbh, list_id
=>$list_id });
61 my $items = $list->elements();
62 # print STDERR "ITEMS =".Dumper($items)."\n";
63 my $catalog_cvterm_id = SGN
::Model
::Cvterm
->get_cvterm_row($schema, 'stock_catalog_json', 'stock_property')->cvterm_id();
64 my %group_by_contact_id;
66 my @all_items = @
$items;
67 foreach my $ordered_item (@all_items) {
69 my @ordered_item_split = split /,/, $ordered_item;
70 my $number_of_fields = @ordered_item_split;
71 my $item_name = $ordered_item_split[0];
72 my $item_rs = $schema->resultset("Stock::Stock")->find( { uniquename
=> $item_name });
73 my $item_id = $item_rs->stock_id();
74 my $item_info_rs = $schema->resultset("Stock::Stockprop")->find({stock_id
=> $item_id, type_id
=> $catalog_cvterm_id});
75 my $item_info_string = $item_info_rs->value();
76 my $item_info_hash = decode_json
$item_info_string;
77 my $contact_person_id = $item_info_hash->{'contact_person_id'};
78 my $item_type = $item_info_hash->{'item_type'};
79 my $item_source = $item_info_hash->{'material_source'};
80 $group_by_contact_id{$contact_person_id}{'item_list'}{$item_name}{'item_type'} = $item_type;
81 $group_by_contact_id{$contact_person_id}{'item_list'}{$item_name}{'material_source'} = $item_source;
83 my $quantity_string = $ordered_item_split[1];
84 my @quantity_info = split /:/, $quantity_string;
85 my $quantity = $quantity_info[1];
86 $quantity =~ s/^\s+|\s+$//g;
87 $group_by_contact_id{$contact_person_id}{'item_list'}{$item_name}{'quantity'} = $quantity;
89 my $ona_additional_info;
90 if ($number_of_fields == 3) {
91 my $optional_field = $ordered_item_split[2];
92 my @optional_field_array = split /:/, $optional_field;
93 my $optional_title = $optional_field_array[0];
94 $optional_title =~ s/^\s+|\s+$//g;
95 print STDERR
"OPTIONAL TITLE =".Dumper
($optional_title)."\n";
96 my $optional_info = $optional_field_array[1];
97 $optional_info =~ s/^\s+|\s+$//g;
98 print STDERR
"OPTIONAL INFO =".Dumper
($optional_info)."\n";
99 if ($optional_title eq 'Comments') {
100 $group_by_contact_id{$contact_person_id}{'item_list'}{$item_name}{'comments'} = $optional_info;
101 } elsif ($optional_title eq 'Additional Info') {
102 $group_by_contact_id{$contact_person_id}{'item_list'}{$item_name}{'additional_info'} = $optional_info;
103 $ona_additional_info = $optional_info;
104 print STDERR
"ONA ADDITIONAL INFO =".Dumper
($ona_additional_info)."\n";
106 } elsif ($number_of_fields == 4) {
107 my $additional_info_field = $ordered_item_split[2];
108 my @additional_info_array = split /:/, $additional_info_field;
109 my $additional_info = $additional_info_array[1];
110 $additional_info =~ s/^\s+|\s+$//g;
111 $group_by_contact_id{$contact_person_id}{'item_list'}{$item_name}{'additional_info'} = $additional_info;
112 $ona_additional_info = $additional_info;
113 my $comments_field = $ordered_item_split[3];
114 my @comments_array = split /:/, $comments_field;
115 my $comments = $comments_array[1];
116 $comments =~ s/^\s+|\s+$//g;
117 $group_by_contact_id{$contact_person_id}{'item_list'}{$item_name}{'comments'} = $comments;
120 @ona_info = ($item_source, $item_name, $quantity, $ona_additional_info, $request_date);
121 $group_by_contact_id{$contact_person_id}{'ona'}{$item_name} = \
@ona_info;
124 my $ordering_service_name = $c->config->{ordering_service_name
};
125 my $ordering_service_url = $c->config->{ordering_service_url
};
128 my @contact_email_list;
129 foreach my $contact_id (keys %group_by_contact_id) {
131 my $history_info = {};
132 my $item_ref = $group_by_contact_id{$contact_id}{'item_list'};
133 my %item_hashes = %{$item_ref};
134 my @item_list = map { { $_ => $item_hashes{$_} } } keys %item_hashes;
136 my $new_order = CXGN
::Stock
::Order
->new( { people_schema
=> $people_schema, dbh
=> $dbh});
137 $new_order->order_from_id($user_id);
138 $new_order->order_to_id($contact_id);
139 $new_order->order_status("submitted");
140 $new_order->create_date($timestamp);
141 my $order_id = $new_order->store();
142 # print STDERR "ORDER ID =".($order_id)."\n";
144 $c->stash->{rest
} = {error_string
=> "Error saving your order",};
148 $history_info ->{'submitted'} = $timestamp;
149 push @history, $history_info;
151 my $order_prop = CXGN
::Stock
::OrderBatch
->new({ bcs_schema
=> $schema, people_schema
=> $people_schema});
152 $order_prop->clone_list(\
@item_list);
153 $order_prop->parent_id($order_id);
154 $order_prop->history(\
@history);
155 my $order_prop_id = $order_prop->store_sp_orderprop();
156 # print STDERR "ORDER PROP ID =".($order_prop_id)."\n";
158 if (!$order_prop_id){
159 $c->stash->{rest
} = {error_string
=> "Error saving your order",};
163 my $contact_person = CXGN
::People
::Person
-> new
($dbh, $contact_id);
164 my $contact_email = $contact_person->get_contact_email();
165 push @contact_email_list, $contact_email;
167 if ($ordering_service_name eq 'ONA') {
168 my $each_contact_id_ona = $group_by_contact_id{$contact_id}{'ona'};
170 foreach my $item (keys %{$each_contact_id_ona}) {
171 my @new_order_row = ();
172 my $ona_ref = $each_contact_id_ona->{$item};
173 $order_location = $ona_ref->[0];
174 @new_order_row = @
$ona_ref;
175 splice @new_order_row, 1, 0, $order_id;
176 push @all_new_rows, [@new_order_row];
179 my $order_file_name = $order_location.'_orders.csv';
182 my $ua = LWP
::UserAgent
->new;
183 $ua->credentials( 'api.ona.io:443', 'DJANGO', $c->config->{ordering_service_username
}, $c->config->{ordering_service_password
} );
184 my $login_resp = $ua->get("https://api.ona.io/api/v1/user.json");
185 my $server_endpoint_1 = "https://api.ona.io/api/v1/data";
186 my $resp = $ua->get($server_endpoint_1);
188 if ($resp->is_success) {
189 my $message = $resp->decoded_content;
190 my $all_info = decode_json
$message;
191 foreach my $info (@
$all_info) {
192 my %info_hash = %{$info};
193 if ($info_hash{'id_string'} eq $order_location) {
194 $form_id = $info_hash{'id'};
200 my ($previous_order_temp_file, $previous_order_uri1) = $c->tempfile( TEMPLATE
=> 'download/previous_ona_order_infoXXXXX');
201 my $previous_order_temp_file_path = $previous_order_temp_file->filename;
204 my $server_endpoint_2 = "https://api.ona.io/api/v1/metadata?xform=".$form_id;
205 my $resp_d = $ua->get($server_endpoint_2);
206 if ($resp_d->is_success) {
207 my $message_d = $resp_d->decoded_content;
208 my $message_hash_d = decode_json
$message_d;
209 foreach my $t (@
$message_hash_d) {
210 if ($t->{'data_value'} eq $order_file_name) {
211 # print STDERR "DELETE INFO =".Dumper($t)."\n";
212 getstore
($t->{media_url
}, $previous_order_temp_file_path);
213 $order_ona_id = $t->{id
};
217 my @previous_order_rows;
220 open(my $fh, '<', $previous_order_temp_file_path)
221 or die "Could not open file!";
222 my $old_header_row = <$fh>;
223 while ( my $row = <$fh> ){
225 push @previous_order_rows, [split ',', $row];
227 push @all_order_rows, (@previous_order_rows);
230 push @all_order_rows, (@all_new_rows);
232 my $metadata_schema = $c->dbic_schema('CXGN::Metadata::Schema');
233 my $ona_header = '"location","orderNo","accessionName","requestedNumberOfClones","additionalInfo","requestDate"';
234 my $template_file_name = $order_location.'_orders';
235 my $user_id = $c->user()->get_object()->get_sp_person_id();
236 my $user_name = $c->user()->get_object()->get_username();
237 my $time = DateTime
->now();
238 my $timestamp = $time->ymd()."_".$time->hms();
239 my $subdirectory_name = "ona_order_info";
240 my $archived_file_name = catfile
($user_id, $subdirectory_name,$template_file_name.".csv");
241 my $archive_path = $c->config->{archive_path
};
242 my $file_destination = catfile
($archive_path, $archived_file_name);
243 my $dir = $c->tempfiles_subdir('/download');
244 my $rel_file = $c->tempfile( TEMPLATE
=> 'download/ona_order_infoXXXXX');
245 my $tempfile = $c->config->{basepath
}."/".$rel_file.".csv";
246 # print STDERR "TEMPFILE =".Dumper($tempfile)."\n";
247 open(my $FILE, '> :encoding(UTF-8)', $tempfile) or die "Cannot open tempfile $tempfile: $!";
249 print $FILE $ona_header."\n";
251 foreach my $row (@all_order_rows) {
254 my $csv_format = join(',',@row_array);
255 print $FILE $csv_format."\n";
260 open(my $F, "<", $tempfile) || die "Can't open file ".$self->tempfile();
262 my $md5 = Digest
::MD5
->new();
266 if (!-d
$archive_path) {
270 if (! -d catfile
($archive_path, $user_id)) {
271 mkdir (catfile
($archive_path, $user_id));
274 if (! -d catfile
($archive_path, $user_id,$subdirectory_name)) {
275 mkdir (catfile
($archive_path, $user_id, $subdirectory_name));
277 my $md_row = $metadata_schema->resultset("MdMetadata")->create({
278 create_person_id
=> $user_id,
281 my $file_row = $metadata_schema->resultset("MdFiles")->create({
282 basename
=> basename
($file_destination),
283 dirname
=> dirname
($file_destination),
284 filetype
=> 'orders',
285 md5checksum
=> $md5->hexdigest(),
286 metadata_id
=> $md_row->metadata_id(),
289 my $file_id = $file_row->file_id();
291 move
($tempfile,$file_destination);
293 print STDERR
"FILE ID =".Dumper
($file_id)."\n";
294 print STDERR
"FILE DESTINATION =".Dumper
($file_destination)."\n";
297 my $server_endpoint_3 = "https://api.ona.io/api/v1/metadata";
298 my $delete_resp = $ua->delete(
299 $server_endpoint_3."/$order_ona_id"
301 if ($delete_resp->is_success) {
302 print STDERR
"Deleted order file on ONA $order_ona_id.\n";
304 print STDERR
"ERROR: Did not delete order file on ONA $order_ona_id.\n";
305 #print STDERR Dumper $delete_resp;
309 my $server_endpoint_4 = "https://api.ona.io/api/v1/metadata";
310 my $add_resp = $ua->post(
312 Content_Type
=> 'form-data',
314 data_file
=> [ $file_destination, $file_destination, Content_Type
=> 'text/plain', ],
316 "data_type"=>"media",
317 "data_value"=>$file_destination
321 if ($add_resp->is_success) {
322 my $message = $add_resp->decoded_content;
323 my $message_hash = decode_json
$message;
324 $ona_new_id = $message_hash->{id
};
326 $c->stash->{rest
} = {error_string
=> "Error sending your order to BANANA ORDERING SYSTEM"};
331 $c->stash->{rest
} = {error_string
=> "BANANA ORDERING SYSTEM hasn't been set up for $order_location. Please contact admin."};
337 my $host = $c->config->{main_production_site_url
};
338 my $project_name = $c->config->{project_name
};
339 my $subject="Ordering Notification from $project_name";
340 my $body=<<END_HEREDOC;
342 You have an order submitted to $project_name ($host/order/stocks/view).
343 Please do *NOT* reply to this message.
350 foreach my $each_email (@contact_email_list) {
351 CXGN::Contact::send_email($subject,$body,$each_email);
355 $c->stash->{rest}->{success} .= 'Your order has been sent successfully to Banana Ordering System.';
357 $c->stash->{rest}->{success} .= 'Your order has been submitted successfully and the vendor has been notified.';
363 sub get_user_current_orders :Path('/ajax/order/current') Args(0) {
366 my $schema = $c->dbic_schema("Bio::Chado::Schema");
367 my $people_schema = $c->dbic_schema('CXGN::People::Schema');
368 my $dbh = $c->dbc->dbh;
372 $c->stash->{rest} = {error=>'You must be logged in to view your current orders!'};
377 $user_id = $c->user()->get_object()->get_sp_person_id();
380 my $orders = CXGN::Stock::Order->new({ dbh => $dbh, people_schema => $people_schema, order_from_id => $user_id});
381 my $all_orders_ref = $orders->get_orders_from_person_id();
383 my @all_orders = @$all_orders_ref;
384 foreach my $order (@all_orders) {
385 if (($order->[3]) ne 'completed') {
386 push @current_orders, [qq{<a href="/order/details/view/$order->[0]">$order->[0]</a>}, $order->[1], $order->[2], $order->[3], $order->[5], $order->[6]]
389 $c->stash->{rest} = {data => \@current_orders};
392 sub get_user_completed_orders :Path('/ajax/order/completed') Args(0) {
395 my $schema = $c->dbic_schema("Bio::Chado::Schema");
396 my $people_schema = $c->dbic_schema('CXGN::People::Schema');
397 my $dbh = $c->dbc->dbh;
401 $c->stash->{rest} = {error=>'You must be logged in to view your completed orders!'};
406 $user_id = $c->user()->get_object()->get_sp_person_id();
409 my $orders = CXGN::Stock::Order->new({ dbh => $dbh, people_schema => $people_schema, order_from_id => $user_id});
410 my $all_orders_ref = $orders->get_orders_from_person_id();
411 my @completed_orders;
412 my @all_orders = @$all_orders_ref;
413 foreach my $order (@all_orders) {
414 if (($order->[3]) eq 'completed') {
415 push @completed_orders, [qq{<a href="/order/details/view/$order->[0]">$order->[0]</a>}, $order->[1], $order->[2], $order->[3], $order->[4], $order->[5], $order->[6]]
419 $c->stash->{rest} = {data => \@completed_orders};
424 sub get_vendor_current_orders :Path('/ajax/order/vendor_current_orders') Args(0) {
427 my $schema = $c->dbic_schema("Bio::Chado::Schema");
428 my $people_schema = $c->dbic_schema('CXGN::People::Schema');
429 my $dbh = $c->dbc->dbh;
433 $c->stash->{rest} = {error=>'You must be logged in to view your orders!'};
438 $user_id = $c->user()->get_object()->get_sp_person_id();
441 my $orders = CXGN::Stock::Order->new({ dbh => $dbh, people_schema => $people_schema, order_to_id => $user_id});
442 my $vendor_orders_ref = $orders->get_orders_to_person_id();
444 my @vendor_current_orders;
445 my @all_vendor_orders = @$vendor_orders_ref;
446 foreach my $vendor_order (@all_vendor_orders) {
447 if (($vendor_order->{'order_status'}) ne 'completed') {
448 push @vendor_current_orders, $vendor_order
452 $c->stash->{rest} = {data => \@vendor_current_orders};
457 sub get_vendor_completed_orders :Path('/ajax/order/vendor_completed_orders') Args(0) {
460 my $schema = $c->dbic_schema("Bio::Chado::Schema");
461 my $people_schema = $c->dbic_schema('CXGN::People::Schema');
462 my $dbh = $c->dbc->dbh;
466 $c->stash->{rest} = {error=>'You must be logged in to view your orders!'};
471 $user_id = $c->user()->get_object()->get_sp_person_id();
474 my $orders = CXGN::Stock::Order->new({ dbh => $dbh, people_schema => $people_schema, order_to_id => $user_id});
475 my $vendor_orders_ref = $orders->get_orders_to_person_id();
477 my @vendor_completed_orders;
478 my @all_vendor_orders = @$vendor_orders_ref;
479 foreach my $vendor_order (@all_vendor_orders) {
480 if (($vendor_order->{'order_status'}) eq 'completed') {
481 push @vendor_completed_orders, $vendor_order
485 $c->stash->{rest} = {data => \@vendor_completed_orders};
490 sub update_order :Path('/ajax/order/update') :Args(0) {
493 my $people_schema = $c->dbic_schema('CXGN::People::Schema');
494 my $schema = $c->dbic_schema('Bio::Chado::Schema', 'sgn_chado');
495 my $dbh = $c->dbc->dbh;
496 my $order_id = $c->req->param('order_id');
497 my $new_status = $c->req->param('new_status');
498 my $contact_person_comments = $c->req->param('contact_person_comments');
499 my $time = DateTime->now();
500 my $timestamp = $time->ymd()."_".$time->hms();
504 $c->stash->{rest} = {error=>'You must be logged in to update the orders!'};
509 $user_id = $c->user()->get_object()->get_sp_person_id();
513 if ($new_status eq 'completed') {
514 $order_obj = CXGN::Stock::Order->new({ dbh => $dbh, people_schema => $people_schema, sp_order_id => $order_id, order_to_id => $user_id, order_status => $new_status, completion_date => $timestamp, comments => $contact_person_comments});
516 $order_obj = CXGN::Stock::Order->new({ dbh => $dbh, people_schema => $people_schema, sp_order_id => $order_id, order_to_id => $user_id, order_status => $new_status, comments => $contact_person_comments});
519 my $updated_order = $order_obj->store();
520 # print STDERR "UPDATED ORDER ID =".Dumper($updated_order)."\n";
521 if (!$updated_order){
522 $c->stash->{rest} = {error_string => "Error updating the order",};
526 my $orderprop_rs = $people_schema->resultset('SpOrderprop')->find( { sp_order_id => $order_id } );
527 my $orderprop_id = $orderprop_rs->sp_orderprop_id();
528 my $details_json = $orderprop_rs->value();
529 print STDERR "ORDER PROP ID =".Dumper($orderprop_id)."\n";
530 my $detail_hash = JSON::Any->jsonToObj($details_json);
532 my $order_history_ref = $detail_hash->{'history'};
533 my @order_history = @$order_history_ref;
534 my $new_status_record = {};
535 $new_status_record->{$new_status} = $timestamp;
536 push @order_history, $new_status_record;
537 $detail_hash->{'history'} = \@order_history;
539 my $order_prop = CXGN::Stock::OrderBatch->new({ bcs_schema => $schema, people_schema => $people_schema, sp_order_id => $order_id, prop_id => $orderprop_id});
540 $order_prop->history(\@order_history);
541 my $updated_orderprop = $order_prop->store_sp_orderprop();
543 if (!$updated_orderprop){
544 $c->stash->{rest} = {error_string => "Error updating the order",};
548 $c->stash->{rest} = {success => "1",};