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 $apputils = "OpenILS::Application::AppUtils";
14 my $utils = "OpenILS::Application::Cat::Utils";
17 __PACKAGE__->register_method(
18 method => "biblio_record_tree_retrieve",
19 api_name => "open-ils.cat.biblio.record.tree.retrieve",
21 note => "Returns the tree associated with the nodeset of the given doc id"
24 sub biblio_record_tree_retrieve {
26 my( $self, $client, $recordid ) = @_;
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);
34 throw OpenSRF::EX::ERROR
35 ("No record in database with id $recordid");
38 $session->disconnect();
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 );
46 $tree->owner_doc( $marcxml->id() );
48 warn "returning tree\n";
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",
61 sub biblio_record_tree_commit {
63 my( $self, $client, $user_session, $tree ) = @_;
64 new Fieldmapper::biblio::record_node ($tree);
68 throw OpenSRF::EX::InvalidArg
69 ("Not enough args to to open-ils.cat.biblio.record.tree.commit")
70 unless ( $user_session and $tree );
73 OpenILS::Application::AppUtils->check_user_session( $user_session ); #throws EX on error
76 my $docid = $tree->owner_doc();
77 my $session = OpenILS::Application::AppUtils->start_db_session();
79 warn "Retrieving biblio record from storage for update\n";
81 my $req1 = $session->request(
82 "open-ils.storage.direct.biblio.record_entry.batch.retrieve",
84 my $biblio = $req1->gather(1);
86 warn "retrieved doc $docid\n";
89 # turn the tree into a nodeset
90 my $nodeset = $utils->tree2nodeset($tree);
91 $nodeset = $utils->clean_nodeset( $nodeset );
93 if(!defined($docid)) { # be sure
94 for my $node (@$nodeset) {
95 $docid = $node->owner_doc();
96 last if defined($docid);
100 # turn the nodeset into a doc
101 my $marcxml = OpenILS::Utils::FlatXML->new()->nodeset_to_xml( $nodeset );
103 $biblio->marc( $marcxml->toString() );
105 warn "Starting db session\n";
107 my $x = _update_record_metadata( $session, { user => $user_obj, docid => $docid } );
108 OpenILS::Application::AppUtils->rollback_db_session($session) unless $x;
110 warn "Sending updated doc $docid to db\n";
111 my $req = $session->request( "open-ils.storage.direct.biblio.record_entry.update", $biblio );
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");
122 # Send the doc to the wormer for wormizing
123 warn "Starting worm session\n";
128 my $wreq = $session->request( "open-ils.worm.wormize", $docid );
135 warn "wormizing failed, rolling back\n";
136 OpenILS::Application::AppUtils->rollback_db_session($session);
138 if($e) { throw $e ($e); }
139 throw OpenSRF::EX::ERROR ("Wormizing Failed for $docid" );
142 OpenILS::Application::AppUtils->commit_db_session( $session );
144 $nodeset = OpenILS::Utils::FlatXML->new()->xmldoc_to_nodeset($marcxml);
145 $tree = $utils->nodeset2tree($nodeset->nodeset);
146 $tree->owner_doc($docid);
148 $client->respond_complete($tree);
150 warn "Done wormizing\n";
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",
164 sub biblio_record_record_metadata {
165 my( $self, $client, @ids ) = @_;
167 if(!@ids){return undef;}
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 );
175 while( my $response = $request->recv() ) {
178 throw OpenSRF::EX::ERROR ("No Response from Storage");
180 if($response->isa("Error")) {
181 throw $response ($response->stringify);
184 my $record_entry = $response->content;
186 my $creator = $record_entry->creator;
187 my $editor = $record_entry->editor;
189 ($creator, $editor) = _get_userid_by_id($creator, $editor);
191 $record_entry->creator( $creator );
192 $record_entry->editor( $editor );
194 push @$results, $record_entry;
199 $session->disconnect();
207 sub _get_userid_by_id {
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 );
216 $request->wait_complete;
217 my $response = $request->recv();
218 if(!$request->complete) { return undef; }
220 if($response->isa("Error")){
221 throw $response ($response);
224 for my $u (@{$response->content}) {
226 push @users, $u->usrname;
230 $session->disconnect;
236 # open-ils.storage.direct.actor.user.search.usrid
238 sub _get_id_by_userid {
243 my $session = OpenSRF::AppSession->create( "open-ils.storage" );
244 my $request = $session->request(
245 "open-ils.storage.direct.actor.user.search.usrname", @users );
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");
253 if(UNIVERSAL::isa( $response, "Error")){
254 throw $response ($response);
257 for my $u (@{$response->content}) {
263 $session->disconnect;
270 # commits metadata objects to the db
271 sub _update_record_metadata {
273 my ($session, @docs ) = @_;
275 for my $doc (@docs) {
277 my $user_obj = $doc->{user};
278 my $docid = $doc->{docid};
280 warn "Updating metata for doc $docid\n";
282 my $request = $session->request(
283 "open-ils.storage.direct.biblio.record_entry.retrieve", $docid );
284 my $record = $request->gather(1);
286 warn "retrieved record\n";
287 my ($id) = _get_id_by_userid($user_obj->usrname);
289 warn "got $id from _get_id_by_userid\n";
290 $record->editor($id);
292 warn "Grabbed the record, updating and moving on\n";
294 $request = $session->request(
295 "open-ils.storage.direct.biblio.record_entry.update", $record );
299 warn "committing metarecord update\n";
306 __PACKAGE__->register_method(
307 method => "orgs_for_title",
308 api_name => "open-ils.cat.actor.org_unit.retrieve_by_title"
312 my( $self, $client, $record_id ) = @_;
314 my $vols = $apputils->simple_scalar_request(
316 "open-ils.storage.direct.asset.call_number.search.record",
319 my $orgs = { map {$_->owning_lib => 1 } @$vols };
320 return [ keys %$orgs ];
325 __PACKAGE__->register_method(
326 method => "retrieve_copies",
327 api_name => "open-ils.cat.asset.copy_tree.retrieve",
330 __PACKAGE__->register_method(
331 method => "retrieve_copies",
332 api_name => "open-ils.cat.asset.copy_tree.global.retrieve",
335 sub retrieve_copies {
337 my( $self, $client, $user_session, $docid, @org_ids ) = @_;
339 if(ref($org_ids[0])) { @org_ids = @{$org_ids[0]}; }
343 warn " $$ retrieving copy tree for doc $docid at " . time() . "\n";
347 OpenILS::Application::AppUtils->check_user_session( $user_session ); #throws EX on error
348 @org_ids = ($user_obj->home_ou);
351 if( $self->api_name =~ /global/ ) {
352 warn "performing global copy_tree search for $docid\n";
353 return _build_volume_list( { record => $docid } );
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 );
365 warn " $$ Finished copy_tree at " . time() . "\n";
373 sub _build_volume_list {
374 my $search_hash = shift;
376 my $session = OpenSRF::AppSession->create( "open-ils.storage" );
379 my $request = $session->request(
380 "open-ils.storage.direct.asset.call_number.search.atomic", $search_hash );
382 my $vols = $request->gather(1);
385 for my $volume (@$vols) {
387 warn "Grabbing copies for volume: " . $volume->id . "\n";
388 my $creq = $session->request(
389 "open-ils.storage.direct.asset.copy.search.call_number",
391 my $copies = $creq->gather(1);
393 $volume->copies($copies);
395 push( @volumes, $volume );
399 $session->disconnect();
407 __PACKAGE__->register_method(
408 method => "generic_edit_copies_volumes",
409 api_name => "open-ils.cat.asset.volume.batch.update",
412 __PACKAGE__->register_method(
413 method => "generic_edit_copies_volumes",
414 api_name => "open-ils.cat.asset.volume.batch.delete",
417 __PACKAGE__->register_method(
418 method => "generic_edit_copies_volumes",
419 api_name => "open-ils.cat.asset.copy.batch.update",
422 __PACKAGE__->register_method(
423 method => "generic_edit_copies_volumes",
424 api_name => "open-ils.cat.asset.copy.batch.delete",
428 sub generic_edit_copies_volumes {
430 my( $self, $client, $user_session, $items ) = @_;
432 my $method = $self->api_name;
433 $method =~ s/open-ils\.cat/open-ils\.storage/og;
434 warn "our method is $method\n";
437 OpenILS::Application::AppUtils->check_user_session( $user_session ); #throws EX on error
439 warn "updating editor info\n";
441 for my $item (@$items) {
445 if( $method =~ /copy/ ) {
446 new Fieldmapper::asset::copy($item);
448 new Fieldmapper::asset::call_number($item);
451 $item->editor( $user_obj->id );
454 my $session = OpenILS::Application::AppUtils->start_db_session;
455 my $request = $session->request( $method, @$items );
457 my $result = $request->recv();
459 if(!$request->complete) {
460 OpenILS::Application::AppUtils->rollback_db_session($session);
461 throw OpenSRF::EX::ERROR
462 ("No response from storage on $method");
465 if(UNIVERSAL::isa($result, "Error")) {
466 OpenILS::Application::AppUtils->rollback_db_session($session);
467 throw $result ($result->stringify);
470 OpenILS::Application::AppUtils->commit_db_session($session);
472 warn "looks like we succeeded\n";
473 return $result->content;
477 __PACKAGE__->register_method(
478 method => "volume_tree_add",
479 api_name => "open-ils.cat.asset.volume.tree.batch.add",
482 sub volume_tree_add {
484 my( $self, $client, $user_session, $volumes ) = @_;
485 return undef unless $volumes;
489 warn Dumper $volumes;
492 OpenILS::Application::AppUtils->check_user_session( $user_session ); #throws EX on error
494 warn "volume_tree_add creating new db session\n";
496 my $session = OpenILS::Application::AppUtils->start_db_session;
498 for my $volume (@$volumes) {
500 new Fieldmapper::asset::call_number($volume);
502 warn "Looping on volumes\n";
506 my $new_copy_list = $volume->copies;
509 warn "Searching for volume with ".$volume->owning_lib . " " .
510 $volume->label . " " . $volume->record . "\n";
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,
519 $cn_req->wait_complete;
520 my $cn = $cn_req->recv();
522 if(!$cn_req->complete) {
523 throw OpenSRF::EX::ERROR ("Error searching volumes on storage");
530 if(UNIVERSAL::isa($cn,"Error")) {
531 throw $cn ($cn->stringify);
534 $volume = $cn->content;
536 $volume->editor( $user_obj->id );
540 $volume->creator( $user_obj->id );
541 $volume->editor( $user_obj->id );
543 warn "Attempting to create a new volume:\n";
547 my $request = $session->request(
548 "open-ils.storage.direct.asset.call_number.create", $volume );
550 my $response = $request->recv();
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");
558 if(UNIVERSAL::isa($response, "Error")) {
559 OpenILS::Application::AppUtils->rollback_db_session($session);
560 throw $response ($response->stringify);
563 $id = $response->content;
566 OpenILS::Application::AppUtils->rollback_db_session($session);
567 throw OpenSRF::EX::ERROR (" * -> Error creating new volume");
572 warn "received new volume id: $id\n";
577 for my $copy (@{$new_copy_list}) {
579 new Fieldmapper::asset::copy($copy);
581 warn "adding a copy for volume $id\n";
583 $copy->call_number($id);
584 $copy->creator( $user_obj->id );
585 $copy->editor( $user_obj->id );
589 my $req = $session->request(
590 "open-ils.storage.direct.asset.copy.create", $copy );
591 my $resp = $req->recv();
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");
599 if(UNIVERSAL::isa($resp, "Error")) {
600 OpenILS::Application::AppUtils->rollback_db_session($session);
601 throw $resp ($resp->stringify);
604 my $cid = $resp->content;
607 OpenILS::Application::AppUtils->rollback_db_session($session);
608 throw OpenSRF::EX::ERROR ("Error adding copy to volume $id" );
611 warn "got new copy id $cid\n";
616 warn "completed adding copies for $id\n";
621 warn "committing volume tree add db session\n";
622 OpenILS::Application::AppUtils->commit_db_session($session);
624 return scalar(@$volumes);
630 __PACKAGE__->register_method(
631 method => "volume_tree_delete",
632 api_name => "open-ils.cat.asset.volume.tree.batch.delete",
635 sub volume_tree_delete {
638 my( $self, $client, $user_session, $volumes ) = @_;
639 return undef unless $volumes;
642 OpenILS::Application::AppUtils->check_user_session( $user_session ); #throws EX on error
644 my $session = OpenILS::Application::AppUtils->start_db_session;
646 for my $volume (@$volumes) {
648 $volume->editor($user_obj->id);
650 new Fieldmapper::asset::call_number($volume);
652 for my $copy (@{$volume->copies}) {
654 new Fieldmapper::asset::copy($copy);
656 $copy->editor( $user_obj->id );
658 warn "Deleting copy " . $copy->id . " from db\n";
660 my $req = $session->request(
661 "open-ils.storage.direct.asset.copy.delete", $copy );
663 my $resp = $req->recv();
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");
671 if(UNIVERSAL::isa($resp, "Error")) {
672 OpenILS::Application::AppUtils->rollback_db_session($session);
673 throw $resp ($resp->stringify);
679 warn "Deleting volume " . $volume->id . " from database\n";
681 my $vol_req = $session->request(
682 "open-ils.storage.direct.asset.call_number.delete", $volume );
683 my $vol_resp = $vol_req;
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");
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);
700 warn "committing delete volume tree add db session\n";
702 OpenILS::Application::AppUtils->commit_db_session($session);
704 return scalar(@$volumes);