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);
10 use OpenILS::Utils::Fieldmapper;
12 my $utils = "OpenILS::Application::Cat::Utils";
16 OpenSRF::Application->method_lookup( "blah" );
18 warn "Child Init Failed: " . shift() . "\n";
23 __PACKAGE__->register_method(
24 method => "biblio_record_tree_retrieve",
25 api_name => "open-ils.cat.biblio.record.tree.retrieve",
27 note => "Returns the tree associated with the nodeset of the given doc id"
30 sub biblio_record_tree_retrieve {
32 my( $self, $client, $recordid ) = @_;
34 my $name = "open-ils.storage.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";
42 throw OpenSRF::EX::ERROR ("No record in database with id $recordid");
45 if( $response->isa("OpenSRF::EX")) {
46 throw $response ($response->stringify);
49 warn "grabbing content in retrieve\n";
50 my $marcxml = $response->content;
53 throw OpenSRF::EX::ERROR
54 ("No record in database with id $recordid");
58 $session->disconnect();
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 );
66 $tree->owner_doc( $marcxml->id() );
68 warn "returning tree\n";
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",
81 sub biblio_record_tree_commit {
83 my( $self, $client, $user_session, $tree ) = @_;
84 new Fieldmapper::biblio::record_node ($tree);
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 );
93 OpenILS::Application::AppUtils->check_user_session( $user_session ); #throws EX on error
96 my $docid = $tree->owner_doc();
98 # turn the tree into a nodeset
99 my $nodeset = $utils->tree2nodeset($tree);
100 $nodeset = $utils->clean_nodeset( $nodeset );
102 if(!defined($docid)) { # be sure
103 for my $node (@$nodeset) {
104 $docid = $node->owner_doc();
105 last if defined($docid);
109 # turn the nodeset into a doc
110 my $marcxml = OpenILS::Utils::FlatXML->new()->nodeset_to_xml( $nodeset );
112 my $biblio = Fieldmapper::biblio::record_marc->new();
113 $biblio->id( $docid );
114 $biblio->marc( $marcxml->toString() );
116 warn "Starting db session\n";
117 my $session = OpenILS::Application::AppUtils->start_db_session();
119 my $x = _update_record_metadata( $session, { user => $user_obj, docid => $docid } );
120 OpenILS::Application::AppUtils->rollback_db_session($session) unless $x;
122 warn "Sending updated doc $docid to db\n";
123 my $req = $session->request( "open-ils.storage.biblio.record_marc.update", $biblio );
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");
134 OpenILS::Application::AppUtils->commit_db_session( $session );
136 $nodeset = OpenILS::Utils::FlatXML->new()->xmldoc_to_nodeset($marcxml);
137 $tree = $utils->nodeset2tree($nodeset->nodeset);
138 $tree->owner_doc($docid);
140 $client->respond_complete($tree);
144 # Send the doc to the wormer for wormizing
145 warn "Starting worm session\n";
146 my $wses = OpenSRF::AppSession->create("open-ils.worm");
152 my $wreq = $wses->request(
153 "open-ils.worm.wormize.marc", $docid, $marcxml->toString );
154 warn "Calling worm receive\n";
156 $wreq->wait_complete;
157 $wresp = $wreq->recv();
159 if( $wresp && $wresp->can("content") and $wresp->content ) {
165 warn "Looping in worm call\n";
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);
180 OpenILS::Application::AppUtils->rollback_db_session($session);
182 throw OpenSRF::EX::ERROR ("Wormizing Failed for $docid" );
188 warn "Done wormizing\n";
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",
202 sub biblio_record_record_metadata {
203 my( $self, $client, @ids ) = @_;
205 if(!@ids){return undef;}
207 my $session = OpenSRF::AppSession->create("open-ils.storage");
208 my $request = $session->request(
209 "open-ils.storage.biblio.record_entry.batch.retrieve", @ids );
213 while( my $response = $request->recv() ) {
216 throw OpenSRF::EX::ERROR ("No Response from Storage");
218 if($response->isa("Error")) {
219 throw $response ($response->stringify);
222 my $record_entry = $response->content;
224 my $creator = $record_entry->creator;
225 my $editor = $record_entry->editor;
227 ($creator, $editor) = _get_userid_by_id($creator, $editor);
229 $record_entry->creator( $creator );
230 $record_entry->editor( $editor );
232 push @$results, $record_entry;
237 $session->disconnect();
245 sub _get_userid_by_id {
250 my $session = OpenSRF::AppSession->create( "open-ils.storage" );
251 my $request = $session->request(
252 "open-ils.storage.actor.user.batch.retrieve.atomic", @ids );
254 $request->wait_complete;
255 my $response = $request->recv();
256 if(!$request->complete) { return undef; }
258 if($response->isa("Error")){
259 throw $response ($response);
262 for my $u (@{$response->content}) {
264 push @users, $u->usrname;
268 $session->disconnect;
274 # open-ils.storage.actor.user.search.usrid
276 sub _get_id_by_userid {
281 my $session = OpenSRF::AppSession->create( "open-ils.storage" );
282 my $request = $session->request(
283 "open-ils.storage.actor.user.search.usrid", @users );
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");
291 if(UNIVERSAL::isa( $response, "Error")){
292 throw $response ($response);
295 for my $u (@{$response->content}) {
301 $session->disconnect;
308 # commits metadata objects to the db
309 sub _update_record_metadata {
311 my ($session, @docs ) = @_;
313 for my $doc (@docs) {
315 my $user_obj = $doc->{user};
316 my $docid = $doc->{docid};
318 warn "Updating metata for doc $docid\n";
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.biblio.record_entry.retrieve", $docid );
325 $user_request->wait_complete;
326 my $meta = $user_request->recv();
329 throw OpenSRF::EX::ERROR ("No meta info returned for biblio $docid");
331 if($meta->isa("Error")) {
332 throw $meta ($meta->stringify);
335 $meta = $meta->content;
336 my ($id) = _get_id_by_userid($user_obj->usrid);
337 warn "got $id from _get_id_by_userid\n";
340 $user_request->finish;
341 $user_session->disconnect;
342 $user_session->kill_me;
343 # -------------------------------------
345 warn "Grabbed the record, updating and moving on\n";
347 my $request = $session->request(
348 "open-ils.storage.biblio.record_entry.update", $meta );
350 my $response = $request->recv();
352 throw OpenSRF::EX::ERROR
353 ("Error commit record metadata for " . $meta->id);
356 if($response->isa("Error")){
357 throw $response ($response->stringify);
363 warn "committing metarecord update\n";
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)
376 Returns the copies for a given bib record and for the users home library
380 sub retrieve_copies {
382 my( $self, $client, $user_session, $docid, $home_ou ) = @_;
390 OpenILS::Application::AppUtils->check_user_session( $user_session ); #throws EX on error
391 $home_ou = $user_obj->home_ou;
394 my $session = OpenSRF::AppSession->create( "open-ils.storage" );
396 # ------------------------------------------------------
397 # grab the short name of the library location
398 my $request = $session->request(
399 "open-ils.storage.actor.org_unit.retrieve", $home_ou );
401 my $org_unit = $request->recv();
403 throw OpenSRF::EX::ERROR
404 ("No response from storage for org unit search");
406 if($org_unit->isa("Error")) { throw $org_unit ($org_unit->stringify);}
407 my $location = $org_unit->content->shortname;
409 # ------------------------------------------------------
412 # ------------------------------------------------------
413 # grab all the volumes for the given record and location
414 my $search_hash = { record => $docid, owning_lib => $location };
418 $request = $session->request(
419 "open-ils.storage.asset.call_number.search", $search_hash );
424 while( $volume = $request->recv() ) {
426 if($volume->isa("Error")) {
427 throw $volume ($volume->stringify);}
429 $volume = $volume->content;
431 warn "Grabbing copies for volume: " . $volume->id . "\n";
433 OpenILS::Application::AppUtils->simple_scalar_request( "open-ils.storage",
434 "open-ils.storage.asset.copy.search.call_number", $volume->id );
436 $volume->copies($copies);
438 $client->respond( $volume );
440 #push @$results, $volume;
446 $session->disconnect();
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)
462 Returns all volumes and attached copies for a given bib record
466 sub retrieve_copies_global {
468 my( $self, $client, $user_session, $docid ) = @_;
472 my $session = OpenSRF::AppSession->create( "open-ils.storage" );
474 # ------------------------------------------------------
475 # grab all the volumes for the given record and location
476 my $request = $session->request(
477 "open-ils.storage.asset.call_number.search.record", $docid );
479 my $volumes = $request->recv();
482 if($volumes->isa("Error")) {
483 throw $volumes ($volumes->stringify);}
485 $volumes = $volumes->content;
492 for my $volume (@$volumes) {
493 $vol_hash->{$volume->id} = $volume;
496 my @ii = keys %$vol_hash;
497 warn "Searching volumes @ii\n";
499 $request = $session->request(
500 "open-ils.storage.asset.copy.search.call_number", keys %$vol_hash );
502 while( my $copylist = $request->recv ) {
504 if(UNIVERSAL::isa( $copylist, "Error")) {
505 throw $copylist ($copylist->stringify);
508 warn "received copy list " . time() . "\n";
509 $copylist = $copylist->content;
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;
517 $client->respond( $vol );
524 $session->disconnect();
534 __PACKAGE__->register_method(
535 method => "generic_edit_copies_volumes",
536 api_name => "open-ils.cat.asset.volume.batch.update",
539 __PACKAGE__->register_method(
540 method => "generic_edit_copies_volumes",
541 api_name => "open-ils.cat.asset.volume.batch.delete",
544 __PACKAGE__->register_method(
545 method => "generic_edit_copies_volumes",
546 api_name => "open-ils.cat.asset.copy.batch.update",
549 __PACKAGE__->register_method(
550 method => "generic_edit_copies_volumes",
551 api_name => "open-ils.cat.asset.copy.batch.delete",
555 sub generic_edit_copies_volumes {
557 my( $self, $client, $user_session, $items ) = @_;
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";
568 OpenILS::Application::AppUtils->check_user_session( $user_session ); #throws EX on error
570 warn "updating editor info\n";
572 for my $item (@$items) {
576 if( $method =~ /copy/ ) {
577 new Fieldmapper::asset::copy($item);
579 new Fieldmapper::asset::call_number($item);
582 $item->editor( $user_obj->id );
585 my $session = OpenILS::Application::AppUtils->start_db_session;
586 my $request = $session->request( $method, @$items );
588 my $result = $request->recv();
590 if(!$request->complete) {
591 OpenILS::Application::AppUtils->rollback_db_session($session);
592 throw OpenSRF::EX::ERROR
593 ("No response from storage on $method");
596 if(UNIVERSAL::isa($result, "Error")) {
597 OpenILS::Application::AppUtils->rollback_db_session($session);
598 throw $result ($result->stringify);
601 OpenILS::Application::AppUtils->commit_db_session($session);
603 warn "looks like we succeeded\n";
604 return $result->content;
608 __PACKAGE__->register_method(
609 method => "volume_tree_add",
610 api_name => "open-ils.cat.asset.volume.tree.batch.add",
613 sub volume_tree_add {
615 my( $self, $client, $user_session, $volumes ) = @_;
616 return undef unless $volumes;
620 warn Dumper $volumes;
623 OpenILS::Application::AppUtils->check_user_session( $user_session ); #throws EX on error
625 warn "volume_tree_add creating new db session\n";
627 my $session = OpenILS::Application::AppUtils->start_db_session;
629 for my $volume (@$volumes) {
631 new Fieldmapper::asset::call_number($volume);
633 warn "Looping on volumes\n";
637 my $new_copy_list = $volume->copies;
640 warn "Searching for volume with ".$volume->owning_lib . " " .
641 $volume->label . " " . $volume->record . "\n";
643 my $cn_req = $session->request(
644 'open-ils.storage.asset.call_number.search' =>
645 { owning_lib => $volume->owning_lib,
646 label => $volume->label,
647 record => $volume->record,
650 $cn_req->wait_complete;
651 my $cn = $cn_req->recv();
653 if(!$cn_req->complete) {
654 throw OpenSRF::EX::ERROR ("Error searching volumes on storage");
661 if(UNIVERSAL::isa($cn,"Error")) {
662 throw $cn ($cn->stringify);
665 $volume = $cn->content;
667 $volume->editor( $user_obj->id );
671 $volume->creator( $user_obj->id );
672 $volume->editor( $user_obj->id );
674 warn "Attempting to create a new volume:\n";
678 my $request = $session->request(
679 "open-ils.storage.asset.call_number.create", $volume );
682 my $response = $request->recv();
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");
692 if(UNIVERSAL::isa($response, "Error")) {
693 OpenILS::Application::AppUtils->rollback_db_session($session);
694 throw $response ($response->stringify);
697 $id = $response->content;
701 OpenILS::Application::AppUtils->rollback_db_session($session);
702 throw OpenSRF::EX::ERROR (" * -> Error creating new volume");
707 warn "received new volume id: $id\n";
712 for my $copy (@{$new_copy_list}) {
714 new Fieldmapper::asset::copy($copy);
716 warn "adding a copy for volume $id\n";
718 $copy->call_number($id);
719 $copy->creator( $user_obj->id );
720 $copy->editor( $user_obj->id );
724 my $req = $session->request(
725 "open-ils.storage.asset.copy.create", $copy );
726 my $resp = $req->recv();
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");
734 if(UNIVERSAL::isa($resp, "Error")) {
735 OpenILS::Application::AppUtils->rollback_db_session($session);
736 throw $resp ($resp->stringify);
739 my $cid = $resp->content;
742 OpenILS::Application::AppUtils->rollback_db_session($session);
743 throw OpenSRF::EX::ERROR ("Error adding copy to volume $id" );
746 warn "got new copy id $cid\n";
751 warn "completed adding copies for $id\n";
756 warn "committing volume tree add db session\n";
757 OpenILS::Application::AppUtils->commit_db_session($session);
759 return scalar(@$volumes);
765 __PACKAGE__->register_method(
766 method => "volume_tree_delete",
767 api_name => "open-ils.cat.asset.volume.tree.batch.delete",
770 sub volume_tree_delete {
773 my( $self, $client, $user_session, $volumes ) = @_;
774 return undef unless $volumes;
777 OpenILS::Application::AppUtils->check_user_session( $user_session ); #throws EX on error
779 my $session = OpenILS::Application::AppUtils->start_db_session;
781 for my $volume (@$volumes) {
783 $volume->editor($user_obj->id);
785 new Fieldmapper::asset::call_number($volume);
787 for my $copy (@{$volume->copies}) {
789 new Fieldmapper::asset::copy($copy);
791 $copy->editor( $user_obj->id );
793 warn "Deleting copy " . $copy->id . " from db\n";
795 my $req = $session->request(
796 "open-ils.storage.asset.copy.delete", $copy );
798 my $resp = $req->recv();
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");
806 if(UNIVERSAL::isa($resp, "Error")) {
807 OpenILS::Application::AppUtils->rollback_db_session($session);
808 throw $resp ($resp->stringify);
814 warn "Deleting volume " . $volume->id . " from database\n";
816 my $vol_req = $session->request(
817 "open-ils.storage.asset.call_number.delete", $volume );
818 my $vol_resp = $vol_req;
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");
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);
835 warn "committing delete volume tree add db session\n";
837 OpenILS::Application::AppUtils->commit_db_session($session);
839 return scalar(@$volumes);