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