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;
13 use OpenILS::Utils::FlatXML;
15 use OpenSRF::Utils::SettingsClient;
16 use OpenSRF::Utils::Logger qw($logger);
18 my $apputils = "OpenILS::Application::AppUtils";
20 my $utils = "OpenILS::Application::Cat::Utils";
27 __PACKAGE__->register_method(
28 method => "retrieve_marc_template",
29 api_name => "open-ils.cat.biblio.marc_template.retrieve",
31 Returns a MARC 'record tree' based on a set of pre-defined templates.
32 Templates include : book
35 sub retrieve_marc_template {
36 my( $self, $client, $type ) = @_;
38 return $marctemplates{$type} if defined($marctemplates{$type});
40 my $xml = _load_marc_template($type);
42 my $nodes = OpenILS::Utils::FlatXML->new()->xml_to_nodeset( $xml );
43 $marctemplates{$type} = $utils->nodeset2tree( $nodes->nodeset );
44 return $marctemplates{$type};
47 sub _load_marc_template {
50 if(!$conf) { $conf = OpenSRF::Utils::SettingsClient->new; }
52 my $template = $conf->config_value(
53 "apps", "open-ils.cat","app_settings", "marctemplates", $type );
54 warn "Opening template file $template\n";
59 return join('', @xml);
65 __PACKAGE__->register_method(
66 method => "create_record_tree",
67 api_name => "open-ils.cat.biblio.record_tree.create",
69 Inserts a new MARC 'record tree' into the system
72 sub create_record_tree {
73 my( $self, $client, $login, $tree ) = @_;
75 my $user_obj = $apputils->check_user_session($login);
77 if($apputils->check_user_perms(
78 $user_obj->id, $user_obj->home_ou, "CREATE_MARC")) {
79 return OpenILS::Perm->new("CREATE_MARC");
82 warn "Creating a new record tree entry...";
83 my $meth = $self->method_lookup("open-ils.cat.biblio.record.tree.import");
84 my ($s) = $meth->run($login, $tree);
91 __PACKAGE__->register_method(
92 method => "biblio_record_tree_import",
93 api_name => "open-ils.cat.biblio.record.tree.import",
95 Takes a record tree and imports the record into the database. In this
96 case, the record tree is assumed to be a complete record (i.e. valid
97 MARC. The title control number is taken from (whichever comes first)
98 tags 001, 020, 022, 010, 035 and whichever does not already exist
100 user_session must have IMPORT_MARC permissions
104 sub biblio_record_tree_import {
105 my( $self, $client, $user_session, $tree) = @_;
106 my $user_obj = $apputils->check_user_session($user_session);
108 if($apputils->check_user_perms(
109 $user_obj->id, $user_obj->home_ou, "IMPORT_MARC")) {
110 return OpenILS::Perm->new("IMPORT_MARC");
113 my $nodeset = $utils->tree2nodeset($tree);
115 # copy the doc so that we can mangle the namespace.
116 my $marcxml = OpenILS::Utils::FlatXML->new()->nodeset_to_xml($nodeset);
117 my $copy_marcxml = XML::LibXML->new->parse_string($marcxml->toString);
119 $marcxml->documentElement->setNamespace( "http://www.loc.gov/MARC21/slim", "marc", 1 );
122 #warn "Importing MARC Doc:\n".$marcxml->toString(1)."\n";
123 #warn "Namespace: " . $marcxml->documentElement->firstChild->namespaceURI . "\n";
126 warn "Starting db session in import\n";
127 my $session = $apputils->start_db_session();
128 my $source = 2; # system local source
130 my $xpath = '//controlfield[@tag="001"]';
131 $tcn = $marcxml->documentElement->findvalue($xpath);
132 if(_tcn_exists($session, $tcn)) {$tcn = undef;}
133 my $tcn_source = "External";
137 $xpath = '//datafield[@tag="020"]';
138 $tcn = $marcxml->documentElement->findvalue($xpath);
139 $tcn_source = "ISBN";
140 if(_tcn_exists($session, $tcn)) {$tcn = undef;}
144 $xpath = '//datafield[@tag="022"]';
145 $tcn = $marcxml->documentElement->findvalue($xpath);
146 $tcn_source = "ISSN";
147 if(_tcn_exists($session, $tcn)) {$tcn = undef;}
151 $xpath = '//datafield[@tag="010"]';
152 $tcn = $marcxml->documentElement->findvalue($xpath);
153 $tcn_source = "LCCN";
154 if(_tcn_exists($session, $tcn)) {$tcn = undef;}
158 $xpath = '//datafield[@tag="035"]';
159 $tcn = $marcxml->documentElement->findvalue($xpath);
160 $tcn_source = "System";
161 if(_tcn_exists($session, $tcn)) {$tcn = undef;}
167 warn "Record import with tcn: $tcn and source $tcn_source\n";
169 my $record = Fieldmapper::biblio::record_entry->new;
171 $record->source($source);
172 $record->tcn_source($tcn_source);
173 $record->tcn_value($tcn);
174 $record->creator($user_obj->id);
175 $record->editor($user_obj->id);
176 $record->marc($copy_marcxml->toString);
179 my $req = $session->request(
180 "open-ils.storage.direct.biblio.record_entry.create", $record );
182 my $id = $req->gather(1);
184 if(!$id) { throw OpenSRF::EX::ERROR ("Unable to create new record_entry from import"); }
185 warn "received id: $id from record_entry create\n";
187 $apputils->commit_db_session($session);
189 $session = OpenSRF::AppSession->create("open-ils.storage");
191 my $wreq = $session->request("open-ils.worm.wormize.biblio", $id)->gather(1);
192 warn "Done worming record $id\n";
194 if(!$wreq) { throw OpenSRF::EX::ERROR ("Unable to wormize imported record"); }
196 return $self->biblio_record_tree_retrieve($client, $id);
204 if(!$tcn) {return 0;}
206 my $req = $session->request(
207 "open-ils.storage.direct.biblio.record_entry.search.tcn_value.atomic",
209 my $recs = $req->gather(1);
211 if($recs and $recs->[0]) {
212 $logger->debug("_tcn_exists is true for tcn : $tcn");
216 $logger->debug("_tcn_exists is false for tcn : $tcn");
222 __PACKAGE__->register_method(
223 method => "biblio_record_tree_retrieve",
224 api_name => "open-ils.cat.biblio.record.tree.retrieve",
227 sub biblio_record_tree_retrieve {
229 my( $self, $client, $recordid ) = @_;
231 my $name = "open-ils.storage.direct.biblio.record_entry.retrieve";
232 my $session = OpenSRF::AppSession->create( "open-ils.storage" );
233 my $request = $session->request( $name, $recordid );
234 my $marcxml = $request->gather(1);
237 throw OpenSRF::EX::ERROR
238 ("No record in database with id $recordid");
241 $session->disconnect();
244 warn "turning into nodeset\n";
245 my $nodes = OpenILS::Utils::FlatXML->new()->xml_to_nodeset( $marcxml->marc );
246 warn "turning nodeset into tree\n";
247 my $tree = $utils->nodeset2tree( $nodes->nodeset );
249 $tree->owner_doc( $marcxml->id() );
251 warn "returning tree\n";
256 __PACKAGE__->register_method(
257 method => "biblio_record_tree_commit",
258 api_name => "open-ils.cat.biblio.record.tree.commit",
259 argc => 3, #(session_id, biblio_tree )
260 notes => <<" NOTES");
261 Walks the tree and commits any changed nodes
262 adds any new nodes, and deletes any deleted nodes
263 The record to commit must already exist or this
267 sub biblio_record_tree_commit {
269 my( $self, $client, $user_session, $tree ) = @_;
271 throw OpenSRF::EX::InvalidArg
272 ("Not enough args to to open-ils.cat.biblio.record.tree.commit")
273 unless ( $user_session and $tree );
275 my $user_obj = $apputils->check_user_session($user_session);
277 if($apputils->check_user_perms(
278 $user_obj->id, $user_obj->home_ou, "UPDATE_MARC")) {
279 return OpenILS::Perm->new("UPDATE_MARC");
284 my $docid = $tree->owner_doc();
285 my $session = OpenILS::Application::AppUtils->start_db_session();
287 warn "Retrieving biblio record from storage for update\n";
289 my $req1 = $session->request(
290 "open-ils.storage.direct.biblio.record_entry.batch.retrieve", $docid );
291 my $biblio = $req1->gather(1);
293 warn "retrieved doc $docid\n";
296 # turn the tree into a nodeset
297 my $nodeset = $utils->tree2nodeset($tree);
298 $nodeset = $utils->clean_nodeset($nodeset);
300 if(!defined($docid)) { # be sure
301 for my $node (@$nodeset) {
302 $docid = $node->owner_doc();
303 last if defined($docid);
307 # turn the nodeset into a doc
308 my $marcxml = OpenILS::Utils::FlatXML->new()->nodeset_to_xml( $nodeset );
310 $biblio->marc( $marcxml->toString() );
312 warn "Starting db session\n";
314 my $x = _update_record_metadata( $session, { user => $user_obj, docid => $docid } );
315 OpenILS::Application::AppUtils->rollback_db_session($session) unless $x;
317 warn "Sending updated doc $docid to db\n";
318 my $req = $session->request( "open-ils.storage.direct.biblio.record_entry.update", $biblio );
321 my $status = $req->recv();
322 if( !$status || $status->isa("Error") || ! $status->content) {
323 OpenILS::Application::AppUtils->rollback_db_session($session);
324 if($status->isa("Error")) { throw $status ($status); }
325 throw OpenSRF::EX::ERROR ("Error updating biblio record");
329 # Send the doc to the wormer for wormizing
330 warn "Starting worm session\n";
335 my $wreq = $session->request( "open-ils.worm.wormize.biblio", $docid );
342 warn "wormizing failed, rolling back\n";
343 OpenILS::Application::AppUtils->rollback_db_session($session);
345 if($e) { throw $e ($e); }
346 throw OpenSRF::EX::ERROR ("Wormizing Failed for $docid" );
349 warn "Committing db session...\n";
350 OpenILS::Application::AppUtils->commit_db_session( $session );
352 $nodeset = OpenILS::Utils::FlatXML->new()->xmldoc_to_nodeset($marcxml);
353 $tree = $utils->nodeset2tree($nodeset->nodeset);
354 $tree->owner_doc($docid);
356 # $client->respond_complete($tree);
358 warn "Done wormizing\n";
361 #warn "Returning tree:\n";
370 __PACKAGE__->register_method(
371 method => "biblio_record_record_metadata",
372 api_name => "open-ils.cat.biblio.record.metadata.retrieve",
373 argc => 1, #(session_id, biblio_tree )
374 notes => "Walks the tree and commits any changed nodes " .
375 "adds any new nodes, and deletes any deleted nodes",
378 sub biblio_record_record_metadata {
379 my( $self, $client, @ids ) = @_;
381 if(!@ids){return undef;}
383 my $session = OpenSRF::AppSession->create("open-ils.storage");
384 my $request = $session->request(
385 "open-ils.storage.direct.biblio.record_entry.batch.retrieve", @ids );
389 while( my $response = $request->recv() ) {
392 throw OpenSRF::EX::ERROR ("No Response from Storage");
394 if($response->isa("Error")) {
395 throw $response ($response->stringify);
398 my $record_entry = $response->content;
400 my $creator = $record_entry->creator;
401 my $editor = $record_entry->editor;
403 ($creator, $editor) = _get_userid_by_id($creator, $editor);
405 $record_entry->creator($creator);
406 $record_entry->editor($editor);
408 push @$results, $record_entry;
413 $session->disconnect();
420 __PACKAGE__->register_method(
421 method => "biblio_record_marc_cn",
422 api_name => "open-ils.cat.biblio.record.marc_cn.retrieve",
423 argc => 1, #(bib id )
426 sub biblio_record_marc_cn {
427 my( $self, $client, $id ) = @_;
429 my $session = OpenSRF::AppSession->create("open-ils.storage");
431 ->request("open-ils.storage.direct.biblio.record_entry.retrieve", $id )
435 my $doc = XML::LibXML->new->parse_string($marc);
436 $doc->documentElement->setNamespace( "http://www.loc.gov/MARC21/slim", "marc", 1 );
439 for my $tag ( qw/050 055 060 070 080 082 086 088 090 092 096 098 099/ ) {
440 my @node = $doc->findnodes("//marc:datafield[\@tag='$tag']");
442 my $cn = $x->findvalue("marc:subfield[\@code='a' or \@code='b']");
443 push @res, {$tag => $cn} if ($cn);
451 sub _get_userid_by_id {
456 my $session = OpenSRF::AppSession->create( "open-ils.storage" );
457 my $request = $session->request(
458 "open-ils.storage.direct.actor.user.batch.retrieve.atomic", @ids );
460 $request->wait_complete;
461 my $response = $request->recv();
462 if(!$request->complete) { return undef; }
464 if($response->isa("Error")){
465 throw $response ($response);
468 for my $u (@{$response->content}) {
470 push @users, $u->usrname;
474 $session->disconnect;
480 sub _get_id_by_userid {
485 my $session = OpenSRF::AppSession->create( "open-ils.storage" );
486 my $request = $session->request(
487 "open-ils.storage.direct.actor.user.search.usrname.atomic", @users );
489 $request->wait_complete;
490 my $response = $request->recv();
491 if(!$request->complete) {
492 throw OpenSRF::EX::ERROR ("no response from storage on user retrieve");
495 if(UNIVERSAL::isa( $response, "Error")){
496 throw $response ($response);
499 for my $u (@{$response->content}) {
505 $session->disconnect;
512 # commits metadata objects to the db
513 sub _update_record_metadata {
515 my ($session, @docs ) = @_;
517 for my $doc (@docs) {
519 my $user_obj = $doc->{user};
520 my $docid = $doc->{docid};
522 warn "Updating metata for doc $docid\n";
524 my $request = $session->request(
525 "open-ils.storage.direct.biblio.record_entry.retrieve", $docid );
526 my $record = $request->gather(1);
528 warn "retrieved record\n";
529 my ($id) = _get_id_by_userid($user_obj->usrname);
531 warn "got $id from _get_id_by_userid\n";
532 $record->editor($id);
534 warn "Grabbed the record, updating and moving on\n";
536 $request = $session->request(
537 "open-ils.storage.direct.biblio.record_entry.update", $record );
541 warn "committing metarecord update\n";
548 __PACKAGE__->register_method(
549 method => "orgs_for_title",
550 api_name => "open-ils.cat.actor.org_unit.retrieve_by_title"
554 my( $self, $client, $record_id ) = @_;
556 my $vols = $apputils->simple_scalar_request(
558 "open-ils.storage.direct.asset.call_number.search.record.atomic",
561 my $orgs = { map {$_->owning_lib => 1 } @$vols };
562 return [ keys %$orgs ];
566 __PACKAGE__->register_method(
567 method => "retrieve_copies_",
568 api_name => "open-ils.cat.asset.copy_tree.retrieve_");
570 sub retrieve_copies_ {
571 my( $self, $conn, $authtoken, $docid, $orgs ) = @_;
575 __PACKAGE__->register_method(
576 method => "retrieve_copies",
577 api_name => "open-ils.cat.asset.copy_tree.retrieve");
579 __PACKAGE__->register_method(
580 method => "retrieve_copies",
581 api_name => "open-ils.cat.asset.copy_tree.global.retrieve");
583 # user_session may be null/undef
584 sub retrieve_copies {
586 my( $self, $client, $user_session, $docid, @org_ids ) = @_;
588 if(ref($org_ids[0])) { @org_ids = @{$org_ids[0]}; }
592 warn " $$ retrieving copy tree for orgs @org_ids and doc $docid at " . time() . "\n";
594 # grabbing copy trees should be available for everyone..
595 if(!@org_ids and $user_session) {
597 OpenILS::Application::AppUtils->check_user_session( $user_session ); #throws EX on error
598 @org_ids = ($user_obj->home_ou);
601 if( $self->api_name =~ /global/ ) {
602 warn "performing global copy_tree search for $docid\n";
603 return _build_volume_list( { record => $docid } );
608 for my $orgid (@org_ids) {
609 my $vols = _build_volume_list(
610 { record => $docid, owning_lib => $orgid } );
611 warn "Volumes built for org $orgid\n";
612 push( @all_vols, @$vols );
615 warn " $$ Finished copy_tree at " . time() . "\n";
623 sub _build_volume_list {
624 my $search_hash = shift;
626 my $session = OpenSRF::AppSession->create( "open-ils.storage" );
629 my $request = $session->request(
630 "open-ils.storage.direct.asset.call_number.search.atomic", $search_hash );
632 my $vols = $request->gather(1);
635 for my $volume (@$vols) {
637 warn "Grabbing copies for volume: " . $volume->id . "\n";
638 my $creq = $session->request(
639 "open-ils.storage.direct.asset.copy.search_where.atomic",
640 { call_number => $volume->id , deleted => 'f' });
641 #"open-ils.storage.direct.asset.copy.search.call_number.atomic", $volume->id );
643 my $copies = $creq->gather(1);
645 $copies = [ sort { $a->barcode cmp $b->barcode } @$copies ];
647 $volume->copies($copies);
649 push( @volumes, $volume );
653 $session->disconnect();
659 # -----------------------------------------------------------------
660 # Fleshed volume tree batch add/update. This does everything a
661 # volume tree could want, add, update, delete
662 # -----------------------------------------------------------------
663 __PACKAGE__->register_method(
664 method => "volume_tree_fleshed_update",
665 api_name => "open-ils.cat.asset.volume_tree.fleshed.batch.update",
667 sub volume_tree_fleshed_update {
669 my( $self, $client, $user_session, $volumes ) = @_;
670 return undef unless $volumes;
672 my $user_obj = $apputils->check_user_session($user_session);
675 my $session = $apputils->start_db_session();
676 warn "Looping on volumes in fleshed volume tree update\n";
678 # cycle through the volumes provided and update/create/delete where necessary
679 for my $volume (@$volumes) {
681 warn "updating volume " . $volume->id . "\n";
683 my $update_copy_list = $volume->copies;
686 if( $volume->isdeleted) {
687 my $status = _delete_volume($session, $volume, $user_obj);
689 throw OpenSRF::EX::ERROR
690 ("Volume delete failed for volume " . $volume->id);
692 if(UNIVERSAL::isa($status, "Fieldmapper::perm_ex")) { return $status; }
694 } elsif( $volume->isnew ) {
697 $volume->editor($user_obj->id);
698 $volume->creator($user_obj->id);
699 $volume = _add_volume($session, $volume, $user_obj);
702 if($volume and UNIVERSAL::isa($volume, "Fieldmapper::perm_ex")) { return $volume; }
704 } elsif( $volume->ischanged ) {
706 $volume->editor($user_obj->id);
707 my $stat = _update_volume($session, $volume, $user_obj);
708 if($stat and UNIVERSAL::isa($stat, "Fieldmapper::perm_ex")) { return $stat; }
712 if( ! $volume->isdeleted ) {
713 for my $copy (@{$update_copy_list}) {
715 $copy->editor($user_obj->id);
716 warn "updating copy for volume " . $volume->id . "\n";
721 $copy->call_number($volume->id);
722 $copy->creator($user_obj->id);
723 $copy = _fleshed_copy_update($session,$copy,$user_obj);
725 } elsif( $copy->ischanged ) {
726 $copy->call_number($volume->id);
727 $copy = _fleshed_copy_update($session, $copy, $user_obj);
729 } elsif( $copy->isdeleted ) {
730 warn "Deleting copy " . $copy->id . " for volume " . $volume->id . "\n";
731 my $status = _fleshed_copy_update($session, $copy, $user_obj);
732 warn "Copy delete returned a status of $status\n";
738 $apputils->commit_db_session($session);
739 return scalar(@$volumes);
744 my( $session, $volume, $user_obj ) = @_;
746 if($apputils->check_user_perms(
747 $user_obj->id, $user_obj->home_ou, "DELETE_VOLUME")) {
748 return OpenILS::Perm->new("DELETE_VOLUME"); }
750 #$volume = _find_volume($session, $volume);
751 warn "Deleting volume " . $volume->id . "\n";
753 my $copies = $session->request(
754 "open-ils.storage.direct.asset.copy.search_where.atomic",
755 { call_number => $volume->id, deleted => 'f' } )->gather(1);
756 #"open-ils.storage.direct.asset.copy.search.call_number.atomic",
759 throw OpenSRF::EX::ERROR
760 ("Cannot remove volume with copies attached");
763 my $req = $session->request(
764 "open-ils.storage.direct.asset.call_number.delete",
766 return $req->gather(1);
771 my($session, $volume, $user_obj) = @_;
772 if($apputils->check_user_perms(
773 $user_obj->id, $user_obj->home_ou, "UPDATE_VOLUME")) {
774 return OpenILS::Perm->new("UPDATE_VOLUME"); }
776 my $req = $session->request(
777 "open-ils.storage.direct.asset.call_number.update",
779 my $status = $req->gather(1);
784 my($session, $volume, $user_obj) = @_;
786 if($apputils->check_user_perms(
787 $user_obj->id, $user_obj->home_ou, "CREATE_VOLUME")) {
788 warn "User does not have priveleges to create new volumes\n";
789 return OpenILS::Perm->new("CREATE_VOLUME");
792 my $request = $session->request(
793 "open-ils.storage.direct.asset.call_number.create", $volume );
795 my $id = $request->gather(1);
798 OpenILS::Application::AppUtils->rollback_db_session($session);
799 throw OpenSRF::EX::ERROR (" * -> Error creating new volume");
803 warn "received new volume id: $id\n";
811 __PACKAGE__->register_method(
812 method => "fleshed_copy_update",
813 api_name => "open-ils.cat.asset.copy.fleshed.batch.update",
816 sub fleshed_copy_update {
817 my($self, $client, $user_session, $copies) = @_;
819 my $user_obj = $apputils->check_user_session($user_session);
820 my $session = $apputils->start_db_session();
822 for my $copy (@$copies) {
823 _fleshed_copy_update($session, $copy, $user_obj);
826 $apputils->commit_db_session($session);
833 my($session, $copy, $user_obj) = @_;
835 if($apputils->check_user_perms(
836 $user_obj->id, $user_obj->home_ou, "DELETE_COPY")) {
837 return OpenILS::Perm->new("DELETE_COPY"); }
839 warn "Deleting copy " . $copy->id . "\n";
840 my $request = $session->request(
841 "open-ils.storage.direct.asset.copy.delete",
843 return $request->gather(1);
847 my($session, $copy, $user_obj) = @_;
849 if($apputils->check_user_perms(
850 $user_obj->id, $user_obj->home_ou, "CREATE_COPY")) {
851 return OpenILS::Perm->new("CREATE_COPY"); }
853 my $request = $session->request(
854 "open-ils.storage.direct.asset.copy.create",
856 my $id = $request->gather(1);
859 throw OpenSRF::EX::ERROR
860 ("Unable to create new copy " . Dumper($copy));
863 warn "Created copy " . $copy->id . "\n";
870 my($session, $copy, $user_obj) = @_;
872 my $evt = $apputils->check_perms($user_obj->id, $copy->circ_lib, 'UPDATE_COPY');
873 return $evt if $evt; #XXX NOT YET HANDLED BY CALLER
875 my $status = $apputils->simplereq(
877 "open-ils.storage.direct.asset.copy.update", $copy );
878 $logger->debug("Successfully updated copy " . $copy->id );
883 # -----------------------------------------------------------------
884 # Creates/Updates/Deletes a fleshed asset.copy.
885 # adds/deletes copy stat_cat maps where necessary
886 # -----------------------------------------------------------------
887 sub _fleshed_copy_update {
888 my($session, $copy, $editor) = @_;
890 my $stat_cat_entries = $copy->stat_cat_entries;
891 $copy->editor($editor->id);
893 # in case we're fleshed
894 if(ref($copy->status)) {$copy->status( $copy->status->id ); }
895 if(ref($copy->location)) {$copy->location( $copy->location->id ); }
896 if(ref($copy->circ_lib)) {$copy->circ_lib( $copy->circ_lib->id ); }
898 warn "Updating copy " . Dumper($copy) . "\n";
900 if( $copy->isdeleted ) {
901 return _delete_copy($session, $copy, $editor);
902 } elsif( $copy->isnew ) {
903 $copy = _create_copy($session, $copy, $editor);
904 } elsif( $copy->ischanged ) {
905 _update_copy($session, $copy, $editor);
909 return 1 unless ( $stat_cat_entries and @$stat_cat_entries );
911 my $stat_maps = $session->request(
912 "open-ils.storage.direct.asset.stat_cat_entry_copy_map.search.owning_copy.atomic",
913 $copy->id )->gather(1);
915 if(!$copy->isnew) { _delete_stale_maps($session, $stat_maps, $copy); }
917 # go through the stat cat update/create process
918 for my $stat_entry (@{$stat_cat_entries}){
919 _copy_update_stat_cats( $session, $copy, $stat_maps, $stat_entry, $editor );
926 # -----------------------------------------------------------------
927 # Deletes stat maps attached to this copy in the database that
928 # are no longer attached to the current copy
929 # -----------------------------------------------------------------
930 sub _delete_stale_maps {
931 my( $session, $stat_maps, $copy) = @_;
933 warn "Deleting stale stat maps for copy " . $copy->id . "\n";
934 for my $map (@$stat_maps) {
935 # if there is no stat cat entry on the copy who's id matches the
936 # current map's id, remove the map from the database
937 if(! grep { $_->id == $map->stat_cat_entry } @{$copy->stat_cat_entries} ) {
938 my $req = $session->request(
939 "open-ils.storage.direct.asset.stat_cat_entry_copy_map.delete", $map );
948 # -----------------------------------------------------------------
949 # Searches the stat maps to see if '$entry' already exists on
950 # the given copy. If it does not, a new stat map is created
951 # for the given entry and copy
952 # -----------------------------------------------------------------
953 sub _copy_update_stat_cats {
954 my ( $session, $copy, $stat_maps, $entry, $editor ) = @_;
956 warn "Updating stat maps for copy " . $copy->id . "\n";
958 # see if this map already exists
959 for my $map (@$stat_maps) {
960 if( $map->stat_cat_entry == $entry->id ) {return;}
963 warn "Creating new stat map for stat " .
964 $entry->stat_cat . " and copy " . $copy->id . "\n";
967 my $new_map = Fieldmapper::asset::stat_cat_entry_copy_map->new();
969 $new_map->stat_cat( $entry->stat_cat );
970 $new_map->stat_cat_entry( $entry->id );
971 $new_map->owning_copy( $copy->id );
973 warn "New map is " . Dumper($new_map) . "\n";
975 my $request = $session->request(
976 "open-ils.storage.direct.asset.stat_cat_entry_copy_map.create",
978 my $status = $request->gather(1);
979 warn "created new map with id $status\n";