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";
15 __PACKAGE__->register_method(
16 method => "biblio_record_tree_retrieve",
17 api_name => "open-ils.cat.biblio.record.tree.retrieve",
19 note => "Returns the tree associated with the nodeset of the given doc id"
22 sub biblio_record_tree_retrieve {
24 my( $self, $client, $recordid ) = @_;
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);
32 throw OpenSRF::EX::ERROR
33 ("No record in database with id $recordid");
36 $session->disconnect();
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 );
44 $tree->owner_doc( $marcxml->id() );
46 warn "returning tree\n";
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",
59 sub biblio_record_tree_commit {
61 my( $self, $client, $user_session, $tree ) = @_;
62 new Fieldmapper::biblio::record_node ($tree);
66 throw OpenSRF::EX::InvalidArg
67 ("Not enough args to to open-ils.cat.biblio.record.tree.commit")
68 unless ( $user_session and $tree );
71 OpenILS::Application::AppUtils->check_user_session( $user_session ); #throws EX on error
74 my $docid = $tree->owner_doc();
75 my $session = OpenILS::Application::AppUtils->start_db_session();
77 warn "Retrieving biblio record from storage for update\n";
79 my $req1 = $session->request(
80 "open-ils.storage.direct.biblio.record_entry.batch.retrieve",
82 my $biblio = $req1->gather(1);
84 warn "retrieved doc $docid\n";
87 # turn the tree into a nodeset
88 my $nodeset = $utils->tree2nodeset($tree);
89 $nodeset = $utils->clean_nodeset( $nodeset );
91 if(!defined($docid)) { # be sure
92 for my $node (@$nodeset) {
93 $docid = $node->owner_doc();
94 last if defined($docid);
98 # turn the nodeset into a doc
99 my $marcxml = OpenILS::Utils::FlatXML->new()->nodeset_to_xml( $nodeset );
101 $biblio->marc( $marcxml->toString() );
103 warn "Starting db session\n";
105 my $x = _update_record_metadata( $session, { user => $user_obj, docid => $docid } );
106 OpenILS::Application::AppUtils->rollback_db_session($session) unless $x;
108 warn "Sending updated doc $docid to db\n";
109 my $req = $session->request( "open-ils.storage.direct.biblio.record_entry.update", $biblio );
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");
120 # Send the doc to the wormer for wormizing
121 warn "Starting worm session\n";
126 my $wreq = $session->request( "open-ils.worm.wormize", $docid );
133 warn "wormizing failed, rolling back\n";
134 OpenILS::Application::AppUtils->rollback_db_session($session);
136 if($e) { throw $e ($e); }
137 throw OpenSRF::EX::ERROR ("Wormizing Failed for $docid" );
140 OpenILS::Application::AppUtils->commit_db_session( $session );
142 $nodeset = OpenILS::Utils::FlatXML->new()->xmldoc_to_nodeset($marcxml);
143 $tree = $utils->nodeset2tree($nodeset->nodeset);
144 $tree->owner_doc($docid);
146 $client->respond_complete($tree);
148 warn "Done wormizing\n";
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",
162 sub biblio_record_record_metadata {
163 my( $self, $client, @ids ) = @_;
165 if(!@ids){return undef;}
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 );
173 while( my $response = $request->recv() ) {
176 throw OpenSRF::EX::ERROR ("No Response from Storage");
178 if($response->isa("Error")) {
179 throw $response ($response->stringify);
182 my $record_entry = $response->content;
184 my $creator = $record_entry->creator;
185 my $editor = $record_entry->editor;
187 ($creator, $editor) = _get_userid_by_id($creator, $editor);
189 $record_entry->creator( $creator );
190 $record_entry->editor( $editor );
192 push @$results, $record_entry;
197 $session->disconnect();
205 sub _get_userid_by_id {
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 );
214 $request->wait_complete;
215 my $response = $request->recv();
216 if(!$request->complete) { return undef; }
218 if($response->isa("Error")){
219 throw $response ($response);
222 for my $u (@{$response->content}) {
224 push @users, $u->usrname;
228 $session->disconnect;
234 # open-ils.storage.direct.actor.user.search.usrid
236 sub _get_id_by_userid {
241 my $session = OpenSRF::AppSession->create( "open-ils.storage" );
242 my $request = $session->request(
243 "open-ils.storage.direct.actor.user.search.usrname", @users );
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");
251 if(UNIVERSAL::isa( $response, "Error")){
252 throw $response ($response);
255 for my $u (@{$response->content}) {
261 $session->disconnect;
268 # commits metadata objects to the db
269 sub _update_record_metadata {
271 my ($session, @docs ) = @_;
273 for my $doc (@docs) {
275 my $user_obj = $doc->{user};
276 my $docid = $doc->{docid};
278 warn "Updating metata for doc $docid\n";
280 my $request = $session->request(
281 "open-ils.storage.direct.biblio.record_entry.retrieve", $docid );
282 my $record = $request->gather(1);
284 warn "retrieved record\n";
285 my ($id) = _get_id_by_userid($user_obj->usrname);
287 warn "got $id from _get_id_by_userid\n";
288 $record->editor($id);
290 warn "Grabbed the record, updating and moving on\n";
292 $request = $session->request(
293 "open-ils.storage.direct.biblio.record_entry.update", $record );
297 warn "committing metarecord update\n";
305 __PACKAGE__->register_method(
306 method => "retrieve_copies",
307 api_name => "open-ils.cat.asset.copy_tree.retrieve",
308 argc => 2, #(user_session, record_id)
310 Returns the copies for a given bib record and for the users home library
314 sub retrieve_copies {
316 my( $self, $client, $user_session, $docid, $home_ou ) = @_;
324 OpenILS::Application::AppUtils->check_user_session( $user_session ); #throws EX on error
325 $home_ou = $user_obj->home_ou;
328 my $session = OpenSRF::AppSession->create( "open-ils.storage" );
330 # ------------------------------------------------------
331 # grab the short name of the library location
332 my $request = $session->request(
333 "open-ils.storage.direct.actor.org_unit.retrieve", $home_ou );
335 my $org_unit = $request->recv();
337 throw OpenSRF::EX::ERROR
338 ("No response from storage for org unit search");
340 if($org_unit->isa("Error")) { throw $org_unit ($org_unit->stringify);}
341 my $location = $org_unit->content->shortname;
343 # ------------------------------------------------------
346 # ------------------------------------------------------
347 # grab all the volumes for the given record and location
348 my $search_hash = { record => $docid, owning_lib => $location };
352 $request = $session->request(
353 "open-ils.storage.direct.asset.call_number.search", $search_hash );
358 while( $volume = $request->recv() ) {
360 if($volume->isa("Error")) {
361 throw $volume ($volume->stringify);}
363 $volume = $volume->content;
365 warn "Grabbing copies for volume: " . $volume->id . "\n";
367 OpenILS::Application::AppUtils->simple_scalar_request( "open-ils.storage",
368 "open-ils.storage.direct.asset.copy.search.call_number", $volume->id );
370 $volume->copies($copies);
372 $client->respond( $volume );
374 #push @$results, $volume;
380 $session->disconnect();
390 __PACKAGE__->register_method(
391 method => "retrieve_copies_global",
392 api_name => "open-ils.cat.asset.copy_tree.global.retrieve",
393 argc => 2, #(user_session, record_id)
395 Returns all volumes and attached copies for a given bib record
399 sub retrieve_copies_global {
401 my( $self, $client, $user_session, $docid ) = @_;
405 my $session = OpenSRF::AppSession->create( "open-ils.storage" );
407 # ------------------------------------------------------
408 # grab all the volumes for the given record and location
409 my $request = $session->request(
410 "open-ils.storage.direct.asset.call_number.search.record", $docid );
412 my $volumes = $request->recv();
415 if($volumes->isa("Error")) {
416 throw $volumes ($volumes->stringify);}
418 $volumes = $volumes->content;
425 for my $volume (@$volumes) {
426 $vol_hash->{$volume->id} = $volume;
429 my @ii = keys %$vol_hash;
430 warn "Searching volumes @ii\n";
432 $request = $session->request(
433 "open-ils.storage.direct.asset.copy.search.call_number", keys %$vol_hash );
435 while( my $copylist = $request->recv ) {
437 if(UNIVERSAL::isa( $copylist, "Error")) {
438 throw $copylist ($copylist->stringify);
441 $copylist = $copylist->content;
444 for my $copy (@$copylist) {
445 $vol = $vol_hash->{$copy->call_number} unless $vol;
446 $vol->copies([]) unless $vol->copies();
447 push @{$vol->copies}, $copy;
449 $client->respond( $vol );
456 $session->disconnect();
466 __PACKAGE__->register_method(
467 method => "generic_edit_copies_volumes",
468 api_name => "open-ils.cat.asset.volume.batch.update",
471 __PACKAGE__->register_method(
472 method => "generic_edit_copies_volumes",
473 api_name => "open-ils.cat.asset.volume.batch.delete",
476 __PACKAGE__->register_method(
477 method => "generic_edit_copies_volumes",
478 api_name => "open-ils.cat.asset.copy.batch.update",
481 __PACKAGE__->register_method(
482 method => "generic_edit_copies_volumes",
483 api_name => "open-ils.cat.asset.copy.batch.delete",
487 sub generic_edit_copies_volumes {
489 my( $self, $client, $user_session, $items ) = @_;
491 my $method = $self->api_name;
492 $method =~ s/open-ils\.cat/open-ils\.storage/og;
493 warn "our method is $method\n";
496 OpenILS::Application::AppUtils->check_user_session( $user_session ); #throws EX on error
498 warn "updating editor info\n";
500 for my $item (@$items) {
504 if( $method =~ /copy/ ) {
505 new Fieldmapper::asset::copy($item);
507 new Fieldmapper::asset::call_number($item);
510 $item->editor( $user_obj->id );
513 my $session = OpenILS::Application::AppUtils->start_db_session;
514 my $request = $session->request( $method, @$items );
516 my $result = $request->recv();
518 if(!$request->complete) {
519 OpenILS::Application::AppUtils->rollback_db_session($session);
520 throw OpenSRF::EX::ERROR
521 ("No response from storage on $method");
524 if(UNIVERSAL::isa($result, "Error")) {
525 OpenILS::Application::AppUtils->rollback_db_session($session);
526 throw $result ($result->stringify);
529 OpenILS::Application::AppUtils->commit_db_session($session);
531 warn "looks like we succeeded\n";
532 return $result->content;
536 __PACKAGE__->register_method(
537 method => "volume_tree_add",
538 api_name => "open-ils.cat.asset.volume.tree.batch.add",
541 sub volume_tree_add {
543 my( $self, $client, $user_session, $volumes ) = @_;
544 return undef unless $volumes;
548 warn Dumper $volumes;
551 OpenILS::Application::AppUtils->check_user_session( $user_session ); #throws EX on error
553 warn "volume_tree_add creating new db session\n";
555 my $session = OpenILS::Application::AppUtils->start_db_session;
557 for my $volume (@$volumes) {
559 new Fieldmapper::asset::call_number($volume);
561 warn "Looping on volumes\n";
565 my $new_copy_list = $volume->copies;
568 warn "Searching for volume with ".$volume->owning_lib . " " .
569 $volume->label . " " . $volume->record . "\n";
571 my $cn_req = $session->request(
572 'open-ils.storage.direct.asset.call_number.search' =>
573 { owning_lib => $volume->owning_lib,
574 label => $volume->label,
575 record => $volume->record,
578 $cn_req->wait_complete;
579 my $cn = $cn_req->recv();
581 if(!$cn_req->complete) {
582 throw OpenSRF::EX::ERROR ("Error searching volumes on storage");
589 if(UNIVERSAL::isa($cn,"Error")) {
590 throw $cn ($cn->stringify);
593 $volume = $cn->content;
595 $volume->editor( $user_obj->id );
599 $volume->creator( $user_obj->id );
600 $volume->editor( $user_obj->id );
602 warn "Attempting to create a new volume:\n";
606 my $request = $session->request(
607 "open-ils.storage.direct.asset.call_number.create", $volume );
609 my $response = $request->recv();
611 if(!$request->complete) {
612 OpenILS::Application::AppUtils->rollback_db_session($session);
613 throw OpenSRF::EX::ERROR
614 ("No response from storage on call_number.create");
617 if(UNIVERSAL::isa($response, "Error")) {
618 OpenILS::Application::AppUtils->rollback_db_session($session);
619 throw $response ($response->stringify);
622 $id = $response->content;
625 OpenILS::Application::AppUtils->rollback_db_session($session);
626 throw OpenSRF::EX::ERROR (" * -> Error creating new volume");
631 warn "received new volume id: $id\n";
636 for my $copy (@{$new_copy_list}) {
638 new Fieldmapper::asset::copy($copy);
640 warn "adding a copy for volume $id\n";
642 $copy->call_number($id);
643 $copy->creator( $user_obj->id );
644 $copy->editor( $user_obj->id );
648 my $req = $session->request(
649 "open-ils.storage.direct.asset.copy.create", $copy );
650 my $resp = $req->recv();
652 if(!$resp || ! ref($resp) ) {
653 OpenILS::Application::AppUtils->rollback_db_session($session);
654 throw OpenSRF::EX::ERROR
655 ("No response from storage on call_number.create");
658 if(UNIVERSAL::isa($resp, "Error")) {
659 OpenILS::Application::AppUtils->rollback_db_session($session);
660 throw $resp ($resp->stringify);
663 my $cid = $resp->content;
666 OpenILS::Application::AppUtils->rollback_db_session($session);
667 throw OpenSRF::EX::ERROR ("Error adding copy to volume $id" );
670 warn "got new copy id $cid\n";
675 warn "completed adding copies for $id\n";
680 warn "committing volume tree add db session\n";
681 OpenILS::Application::AppUtils->commit_db_session($session);
683 return scalar(@$volumes);
689 __PACKAGE__->register_method(
690 method => "volume_tree_delete",
691 api_name => "open-ils.cat.asset.volume.tree.batch.delete",
694 sub volume_tree_delete {
697 my( $self, $client, $user_session, $volumes ) = @_;
698 return undef unless $volumes;
701 OpenILS::Application::AppUtils->check_user_session( $user_session ); #throws EX on error
703 my $session = OpenILS::Application::AppUtils->start_db_session;
705 for my $volume (@$volumes) {
707 $volume->editor($user_obj->id);
709 new Fieldmapper::asset::call_number($volume);
711 for my $copy (@{$volume->copies}) {
713 new Fieldmapper::asset::copy($copy);
715 $copy->editor( $user_obj->id );
717 warn "Deleting copy " . $copy->id . " from db\n";
719 my $req = $session->request(
720 "open-ils.storage.direct.asset.copy.delete", $copy );
722 my $resp = $req->recv();
724 if( !$req->complete ) {
725 OpenILS::Application::AppUtils->rollback_db_session($session);
726 throw OpenSRF::EX::ERROR (
727 "No response from storage on copy delete");
730 if(UNIVERSAL::isa($resp, "Error")) {
731 OpenILS::Application::AppUtils->rollback_db_session($session);
732 throw $resp ($resp->stringify);
738 warn "Deleting volume " . $volume->id . " from database\n";
740 my $vol_req = $session->request(
741 "open-ils.storage.direct.asset.call_number.delete", $volume );
742 my $vol_resp = $vol_req;
744 if(!$vol_req->complete) {
745 OpenILS::Application::AppUtils->rollback_db_session($session);
746 throw OpenSRF::EX::ERROR
747 ("No response from storage on volume delete");
750 if( $vol_resp and UNIVERSAL::isa($vol_resp, "Error")) {
751 OpenILS::Application::AppUtils->rollback_db_session($session);
752 throw $vol_resp ($vol_resp->stringify);
759 warn "committing delete volume tree add db session\n";
761 OpenILS::Application::AppUtils->commit_db_session($session);
763 return scalar(@$volumes);