]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/src/perlmods/OpenILS/Application/Cat.pm
continuing
[working/Evergreen.git] / Open-ILS / src / perlmods / OpenILS / Application / Cat.pm
1 use strict; use warnings;
2 package OpenILS::Application::Cat;
3 use OpenILS::Application::AppUtils;
4 use OpenSRF::Application;
5 use OpenILS::Application::Cat::Utils;
6 use base qw/OpenSRF::Application/;
7 use Time::HiRes qw(time);
8 use OpenSRF::EX qw(:try);
9 use JSON;
10 use OpenILS::Utils::Fieldmapper;
11
12 my $apputils = "OpenILS::Application::AppUtils";
13
14 my $utils = "OpenILS::Application::Cat::Utils";
15
16
17 __PACKAGE__->register_method(
18         method  => "biblio_record_tree_retrieve",
19         api_name        => "open-ils.cat.biblio.record.tree.retrieve",
20         argc            => 1, 
21         note            => "Returns the tree associated with the nodeset of the given doc id"
22 );
23
24 sub biblio_record_tree_retrieve {
25
26         my( $self, $client, $recordid ) = @_;
27
28         my $name = "open-ils.storage.direct.biblio.record_entry.retrieve";
29         my $session = OpenSRF::AppSession->create( "open-ils.storage" );
30         my $request = $session->request( $name, $recordid );
31         my $marcxml = $request->gather(1);
32
33         if(!$marcxml) {
34                 throw OpenSRF::EX::ERROR 
35                         ("No record in database with id $recordid");
36         }
37
38         $session->disconnect();
39         $session->kill_me();
40
41         warn "turning into nodeset\n";
42         my $nodes = OpenILS::Utils::FlatXML->new()->xml_to_nodeset( $marcxml->marc ); 
43         warn "turning nodeset into tree\n";
44         my $tree = $utils->nodeset2tree( $nodes->nodeset );
45
46         $tree->owner_doc( $marcxml->id() );
47
48         warn "returning tree\n";
49
50         return $tree;
51 }
52
53 __PACKAGE__->register_method(
54         method  => "biblio_record_tree_commit",
55         api_name        => "open-ils.cat.biblio.record.tree.commit",
56         argc            => 3, #(session_id, biblio_tree ) 
57         note            => "Walks the tree and commits any changed nodes " .
58                                         "adds any new nodes, and deletes any deleted nodes",
59 );
60
61 sub biblio_record_tree_commit {
62
63         my( $self, $client, $user_session,  $tree ) = @_;
64         new Fieldmapper::biblio::record_node ($tree);
65
66         use Data::Dumper;
67
68         throw OpenSRF::EX::InvalidArg 
69                 ("Not enough args to to open-ils.cat.biblio.record.tree.commit")
70                 unless ( $user_session and $tree );
71
72         my $user_obj = 
73                 OpenILS::Application::AppUtils->check_user_session( $user_session ); #throws EX on error
74
75         # capture the doc id
76         my $docid = $tree->owner_doc();
77         my $session = OpenILS::Application::AppUtils->start_db_session();
78
79         warn "Retrieving biblio record from storage for update\n";
80
81         my $req1 = $session->request(
82                         "open-ils.storage.direct.biblio.record_entry.batch.retrieve", 
83                         $docid );
84         my $biblio = $req1->gather(1);
85
86         warn "retrieved doc $docid\n";
87
88
89         # turn the tree into a nodeset
90         my $nodeset = $utils->tree2nodeset($tree);
91         $nodeset = $utils->clean_nodeset( $nodeset );
92
93         if(!defined($docid)) { # be sure
94                 for my $node (@$nodeset) {
95                         $docid = $node->owner_doc();
96                         last if defined($docid);
97                 }
98         }
99
100         # turn the nodeset into a doc
101         my $marcxml = OpenILS::Utils::FlatXML->new()->nodeset_to_xml( $nodeset );
102
103         $biblio->marc( $marcxml->toString() );
104
105         warn "Starting db session\n";
106
107         my $x = _update_record_metadata( $session, { user => $user_obj, docid => $docid } );
108         OpenILS::Application::AppUtils->rollback_db_session($session) unless $x;
109
110         warn "Sending updated doc $docid to db\n";
111         my $req = $session->request( "open-ils.storage.direct.biblio.record_entry.update", $biblio );
112
113         $req->wait_complete;
114         my $status = $req->recv();
115         if( !$status || $status->isa("Error") || ! $status->content) {
116                 OpenILS::Application::AppUtils->rollback_db_session($session);
117                 if($status->isa("Error")) { throw $status ($status); }
118                 throw OpenSRF::EX::ERROR ("Error updating biblio record");
119         }
120         $req->finish();
121
122         # Send the doc to the wormer for wormizing
123         warn "Starting worm session\n";
124
125         my $success = 0;
126         my $wresp;
127
128         my $wreq = $session->request( "open-ils.worm.wormize", $docid );
129
130         try {
131                 $wreq->gather(1);
132
133         } catch Error with {
134                 my $e = shift;
135                 warn "wormizing failed, rolling back\n";
136                 OpenILS::Application::AppUtils->rollback_db_session($session);
137
138                 if($e) { throw $e ($e); }
139                 throw OpenSRF::EX::ERROR ("Wormizing Failed for $docid" );
140         };
141
142         OpenILS::Application::AppUtils->commit_db_session( $session );
143
144         $nodeset = OpenILS::Utils::FlatXML->new()->xmldoc_to_nodeset($marcxml);
145         $tree = $utils->nodeset2tree($nodeset->nodeset);
146         $tree->owner_doc($docid);
147
148         $client->respond_complete($tree);
149
150         warn "Done wormizing\n";
151
152 }
153
154
155
156 __PACKAGE__->register_method(
157         method  => "biblio_record_record_metadata",
158         api_name        => "open-ils.cat.biblio.record.metadata.retrieve",
159         argc            => 1, #(session_id, biblio_tree ) 
160         note            => "Walks the tree and commits any changed nodes " .
161                                         "adds any new nodes, and deletes any deleted nodes",
162 );
163
164 sub biblio_record_record_metadata {
165         my( $self, $client, @ids ) = @_;
166
167         if(!@ids){return undef;}
168
169         my $session = OpenSRF::AppSession->create("open-ils.storage");
170         my $request = $session->request( 
171                         "open-ils.storage.direct.biblio.record_entry.batch.retrieve", @ids );
172
173         my $results = [];
174
175         while( my $response = $request->recv() ) {
176
177                 if(!$response) {
178                         throw OpenSRF::EX::ERROR ("No Response from Storage");
179                 }
180                 if($response->isa("Error")) {
181                         throw $response ($response->stringify);
182                 }
183
184                 my $record_entry = $response->content;
185
186                 my $creator = $record_entry->creator;
187                 my $editor      = $record_entry->editor;
188
189                 ($creator, $editor) = _get_userid_by_id($creator, $editor);
190
191                 $record_entry->creator( $creator );
192                 $record_entry->editor( $editor );
193
194                 push @$results, $record_entry;
195
196         }
197
198         $request->finish;
199         $session->disconnect();
200         $session->finish();
201
202         return $results;
203
204 }
205
206 # gets the username
207 sub _get_userid_by_id {
208
209         my @ids = @_;
210         my @users;
211
212         my $session = OpenSRF::AppSession->create( "open-ils.storage" );
213         my $request = $session->request( 
214                 "open-ils.storage.direct.actor.user.batch.retrieve.atomic", @ids );
215
216         $request->wait_complete;
217         my $response = $request->recv();
218         if(!$request->complete) { return undef; }
219
220         if($response->isa("Error")){
221                 throw $response ($response);
222         }
223
224         for my $u (@{$response->content}) {
225                 next unless ref($u);
226                 push @users, $u->usrname;
227         }
228
229         $request->finish;
230         $session->disconnect;
231         $session->kill_me();
232
233         return @users;
234 }
235
236 # open-ils.storage.direct.actor.user.search.usrid
237
238 sub _get_id_by_userid {
239
240         my @users = @_;
241         my @ids;
242
243         my $session = OpenSRF::AppSession->create( "open-ils.storage" );
244         my $request = $session->request( 
245                 "open-ils.storage.direct.actor.user.search.usrname", @users );
246
247         $request->wait_complete;
248         my $response = $request->recv();
249         if(!$request->complete) { 
250                 throw OpenSRF::EX::ERROR ("no response from storage on user retrieve");
251         }
252
253         if(UNIVERSAL::isa( $response, "Error")){
254                 throw $response ($response);
255         }
256
257         for my $u (@{$response->content}) {
258                 next unless ref($u);
259                 push @ids, $u->id();
260         }
261
262         $request->finish;
263         $session->disconnect;
264         $session->kill_me();
265
266         return @ids;
267 }
268
269
270 # commits metadata objects to the db
271 sub _update_record_metadata {
272
273         my ($session, @docs ) = @_;
274
275         for my $doc (@docs) {
276
277                 my $user_obj = $doc->{user};
278                 my $docid = $doc->{docid};
279
280                 warn "Updating metata for doc $docid\n";
281
282                 my $request = $session->request( 
283                         "open-ils.storage.direct.biblio.record_entry.retrieve", $docid );
284                 my $record = $request->gather(1);
285
286                 warn "retrieved record\n";
287                 my ($id) = _get_id_by_userid($user_obj->usrname);
288
289                 warn "got $id from _get_id_by_userid\n";
290                 $record->editor($id);
291                 
292                 warn "Grabbed the record, updating and moving on\n";
293
294                 $request = $session->request( 
295                         "open-ils.storage.direct.biblio.record_entry.update", $record );
296                 $request->gather(1);
297         }
298
299         warn "committing metarecord update\n";
300
301         return 1;
302 }
303
304
305
306 __PACKAGE__->register_method(
307         method  => "orgs_for_title",
308         api_name        => "open-ils.cat.actor.org_unit.retrieve_by_title"
309 );
310
311 sub orgs_for_title {
312         my( $self, $client, $record_id ) = @_;
313
314         my $vols = $apputils->simple_scalar_request(
315                 "open-ils.storage",
316                 "open-ils.storage.direct.asset.call_number.search.record",
317                 $record_id );
318
319         my $orgs = { map {$_->owning_lib => 1 } @$vols };
320         return [ keys %$orgs ];
321 }
322
323
324
325 __PACKAGE__->register_method(
326         method  => "retrieve_copies",
327         api_name        => "open-ils.cat.asset.copy_tree.retrieve",
328 );
329
330 __PACKAGE__->register_method(
331         method  => "retrieve_copies",
332         api_name        => "open-ils.cat.asset.copy_tree.global.retrieve",
333 );
334
335 sub retrieve_copies {
336
337         my( $self, $client, $user_session, $docid, @org_ids ) = @_;
338
339         if(ref($org_ids[0])) { @org_ids = @{$org_ids[0]}; }
340
341         $docid = "$docid";
342
343         warn " $$ retrieving copy tree for doc $docid at " . time() . "\n";
344
345         if(!@org_ids) {
346                 my $user_obj = 
347                         OpenILS::Application::AppUtils->check_user_session( $user_session ); #throws EX on error
348                         @org_ids = ($user_obj->home_ou);
349         }
350
351         if( $self->api_name =~ /global/ ) {
352                 warn "performing global copy_tree search for $docid\n";
353                 return _build_volume_list( { record => $docid } );
354
355         } else {
356
357                 my @all_vols;
358                 for my $orgid (@org_ids) {
359                         my $vols = _build_volume_list( 
360                                         { record => $docid, owning_lib => $orgid } );
361                         warn "Volumes built for org $orgid\n";
362                         push( @all_vols, @$vols );
363                 }
364                 
365                 warn " $$ Finished copy_tree at " . time() . "\n";
366                 return \@all_vols;
367         }
368
369         return undef;
370 }
371
372
373 sub _build_volume_list {
374         my $search_hash = shift;
375
376         my      $session = OpenSRF::AppSession->create( "open-ils.storage" );
377         
378
379         my $request = $session->request( 
380                         "open-ils.storage.direct.asset.call_number.search.atomic", $search_hash );
381
382         my $vols = $request->gather(1);
383         my @volumes;
384
385         for my $volume (@$vols) {
386
387                 warn "Grabbing copies for volume: " . $volume->id . "\n";
388                 my $creq = $session->request(
389                         "open-ils.storage.direct.asset.copy.search.call_number", 
390                         $volume->id );
391                 my $copies = $creq->gather(1);
392
393                 $volume->copies($copies);
394
395                 push( @volumes, $volume );
396         }
397
398
399         $session->disconnect();
400         return \@volumes;
401
402 }
403
404
405
406
407 __PACKAGE__->register_method(
408         method  => "generic_edit_copies_volumes",
409         api_name        => "open-ils.cat.asset.volume.batch.update",
410 );
411
412 __PACKAGE__->register_method(
413         method  => "generic_edit_copies_volumes",
414         api_name        => "open-ils.cat.asset.volume.batch.delete",
415 );
416
417 __PACKAGE__->register_method(
418         method  => "generic_edit_copies_volumes",
419         api_name        => "open-ils.cat.asset.copy.batch.update",
420 );
421
422 __PACKAGE__->register_method(
423         method  => "generic_edit_copies_volumes",
424         api_name        => "open-ils.cat.asset.copy.batch.delete",
425 );
426
427
428 sub generic_edit_copies_volumes {
429
430         my( $self, $client, $user_session, $items ) = @_;
431
432         my $method = $self->api_name;
433         $method =~ s/open-ils\.cat/open-ils\.storage/og;
434         warn "our method is $method\n";
435
436         my $user_obj = 
437                 OpenILS::Application::AppUtils->check_user_session( $user_session ); #throws EX on error
438         
439         warn "updating editor info\n";
440
441         for my $item (@$items) {
442
443                 next unless $item;
444
445                 if( $method =~ /copy/ ) {
446                         new Fieldmapper::asset::copy($item);
447                 } else {
448                         new Fieldmapper::asset::call_number($item);
449                 }
450
451                 $item->editor( $user_obj->id );
452         }
453
454         my $session = OpenILS::Application::AppUtils->start_db_session;
455         my $request = $session->request( $method, @$items );
456
457         my $result = $request->recv();
458
459         if(!$request->complete) {
460                 OpenILS::Application::AppUtils->rollback_db_session($session);
461                 throw OpenSRF::EX::ERROR 
462                         ("No response from storage on $method");
463         }
464
465         if(UNIVERSAL::isa($result, "Error")) {
466                 OpenILS::Application::AppUtils->rollback_db_session($session);
467                 throw $result ($result->stringify);
468         }
469
470         OpenILS::Application::AppUtils->commit_db_session($session);
471
472         warn "looks like we succeeded\n";
473         return $result->content;
474 }
475
476
477 __PACKAGE__->register_method(
478         method  => "volume_tree_add",
479         api_name        => "open-ils.cat.asset.volume.tree.batch.add",
480 );
481
482 sub volume_tree_add {
483
484         my( $self, $client, $user_session, $volumes ) = @_;
485         return undef unless $volumes;
486
487         use Data::Dumper;
488         warn "Volumes:\n";
489         warn Dumper $volumes;
490
491         my $user_obj = 
492                 OpenILS::Application::AppUtils->check_user_session( $user_session ); #throws EX on error
493
494         warn "volume_tree_add creating new db session\n";
495
496         my $session = OpenILS::Application::AppUtils->start_db_session;
497
498         for my $volume (@$volumes) {
499
500                 new Fieldmapper::asset::call_number($volume);
501
502                 warn "Looping on volumes\n";
503
504
505
506                 my $new_copy_list = $volume->copies;
507                 my $id;
508
509                 warn "Searching for volume with ".$volume->owning_lib . " " .
510                         $volume->label . " " . $volume->record . "\n";
511
512                 my $cn_req = $session->request( 
513                                 'open-ils.storage.direct.asset.call_number.search' =>
514                       {       owning_lib      => $volume->owning_lib,
515                               label           => $volume->label,
516                               record          => $volume->record,
517                                 }); 
518
519                 $cn_req->wait_complete;
520                 my $cn = $cn_req->recv();
521                 
522                 if(!$cn_req->complete) {
523                         throw OpenSRF::EX::ERROR ("Error searching volumes on storage");
524                 }
525
526                 $cn_req->finish();
527
528                 if($cn) {
529
530                         if(UNIVERSAL::isa($cn,"Error")) {
531                                 throw $cn ($cn->stringify);
532                         }
533
534                         $volume = $cn->content;
535                         $id = $volume->id;
536                         $volume->editor( $user_obj->id );
537
538                 } else {
539
540                         $volume->creator( $user_obj->id );
541                         $volume->editor( $user_obj->id );
542
543                         warn "Attempting to create a new volume:\n";
544
545                         warn Dumper $volume;
546
547                         my $request = $session->request( 
548                                 "open-ils.storage.direct.asset.call_number.create", $volume );
549
550                         my $response = $request->recv();
551
552                         if(!$request->complete) { 
553                                 OpenILS::Application::AppUtils->rollback_db_session($session);
554                                 throw OpenSRF::EX::ERROR 
555                                         ("No response from storage on call_number.create");
556                         }
557                 
558                         if(UNIVERSAL::isa($response, "Error")) {
559                                 OpenILS::Application::AppUtils->rollback_db_session($session);
560                                 throw $response ($response->stringify);
561                         }
562
563                         $id = $response->content;
564
565                         if( $id == 0 ) {
566                                 OpenILS::Application::AppUtils->rollback_db_session($session);
567                                 throw OpenSRF::EX::ERROR (" * -> Error creating new volume");
568                         }
569
570                         $request->finish();
571         
572                         warn "received new volume id: $id\n";
573
574                 }
575
576
577                 for my $copy (@{$new_copy_list}) {
578
579                         new Fieldmapper::asset::copy($copy);
580
581                         warn "adding a copy for volume $id\n";
582
583                         $copy->call_number($id);
584                         $copy->creator( $user_obj->id );
585                         $copy->editor( $user_obj->id );
586
587                         warn Dumper $copy;
588
589                         my $req = $session->request(
590                                         "open-ils.storage.direct.asset.copy.create", $copy );
591                         my $resp = $req->recv();
592
593                         if(!$resp || ! ref($resp) ) { 
594                                 OpenILS::Application::AppUtils->rollback_db_session($session);
595                                 throw OpenSRF::EX::ERROR 
596                                         ("No response from storage on call_number.create");
597                         }
598         
599                         if(UNIVERSAL::isa($resp, "Error")) {
600                                 OpenILS::Application::AppUtils->rollback_db_session($session);
601                                 throw $resp ($resp->stringify);
602                         }
603                         
604                         my $cid = $resp->content;
605
606                         if(!$cid) {
607                                 OpenILS::Application::AppUtils->rollback_db_session($session);
608                                 throw OpenSRF::EX::ERROR ("Error adding copy to volume $id" );
609                         }
610
611                         warn "got new copy id $cid\n";
612
613                         $req->finish();
614                 }
615
616                 warn "completed adding copies for $id\n";
617
618
619         }
620
621         warn "committing volume tree add db session\n";
622         OpenILS::Application::AppUtils->commit_db_session($session);
623
624         return scalar(@$volumes);
625
626 }
627
628
629
630 __PACKAGE__->register_method(
631         method  => "volume_tree_delete",
632         api_name        => "open-ils.cat.asset.volume.tree.batch.delete",
633 );
634
635 sub volume_tree_delete {
636
637
638         my( $self, $client, $user_session, $volumes ) = @_;
639         return undef unless $volumes;
640
641         my $user_obj = 
642                 OpenILS::Application::AppUtils->check_user_session( $user_session ); #throws EX on error
643
644         my $session = OpenILS::Application::AppUtils->start_db_session;
645
646         for my $volume (@$volumes) {
647
648                 $volume->editor($user_obj->id);
649
650                 new Fieldmapper::asset::call_number($volume);
651
652                 for my $copy (@{$volume->copies}) {
653
654                         new Fieldmapper::asset::copy($copy);
655
656                         $copy->editor( $user_obj->id );
657
658                         warn "Deleting copy " . $copy->id . " from db\n";
659
660                         my $req = $session->request(
661                                         "open-ils.storage.direct.asset.copy.delete", $copy );
662
663                         my $resp = $req->recv();
664
665                         if( !$req->complete ) {
666                                 OpenILS::Application::AppUtils->rollback_db_session($session);
667                                 throw OpenSRF::EX::ERROR (
668                                                 "No response from storage on copy delete");
669                         }
670         
671                         if(UNIVERSAL::isa($resp, "Error")) {
672                                 OpenILS::Application::AppUtils->rollback_db_session($session);
673                                 throw $resp ($resp->stringify);
674                         }
675                         
676                         $req->finish();
677                 }
678
679                 warn "Deleting volume " . $volume->id . " from database\n";
680
681                 my $vol_req = $session->request(
682                                 "open-ils.storage.direct.asset.call_number.delete", $volume );
683                 my $vol_resp = $vol_req;
684
685                 if(!$vol_req->complete) {
686                         OpenILS::Application::AppUtils->rollback_db_session($session);
687                                 throw OpenSRF::EX::ERROR 
688                                         ("No response from storage on volume delete");
689                 }
690
691                 if( $vol_resp and UNIVERSAL::isa($vol_resp, "Error")) {
692                         OpenILS::Application::AppUtils->rollback_db_session($session);
693                         throw $vol_resp ($vol_resp->stringify);
694                 }
695
696                 $vol_req->finish();
697
698         }
699
700         warn "committing delete volume tree add db session\n";
701
702         OpenILS::Application::AppUtils->commit_db_session($session);
703
704         return scalar(@$volumes);
705
706 }
707
708
709
710
711
712 1;