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