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});
39 $marctemplates{$type} = _load_marc_template($type);
40 return $marctemplates{$type};
43 sub _load_marc_template {
46 if(!$conf) { $conf = OpenSRF::Utils::SettingsClient->new; }
48 my $template = $conf->config_value(
49 "apps", "open-ils.cat","app_settings", "marctemplates", $type );
50 warn "Opening template file $template\n";
52 open( F, $template ) or
53 throw OpenSRF::EX::ERROR ("Unable to open MARC template file: $template : $@");
57 my $xml = join('', @xml);
59 return XML::LibXML->new->parse_string($xml)->documentElement->toString;
64 __PACKAGE__->register_method(
65 method => "create_record_tree",
66 api_name => "open-ils.cat.biblio.record_tree.create",
68 Inserts a new MARC 'record tree' into the system
71 sub create_record_tree {
72 my( $self, $client, $login, $tree ) = @_;
74 my $user_obj = $apputils->check_user_session($login);
76 if($apputils->check_user_perms(
77 $user_obj->id, $user_obj->home_ou, "CREATE_MARC")) {
78 return OpenILS::Perm->new("CREATE_MARC");
81 warn "Creating a new record tree entry...";
82 my $meth = $self->method_lookup("open-ils.cat.biblio.record.tree.import");
83 my ($s) = $meth->run($login, $tree);
90 __PACKAGE__->register_method(
91 method => "biblio_record_tree_import",
92 api_name => "open-ils.cat.biblio.record.tree.import",
94 Takes a record tree and imports the record into the database. In this
95 case, the record tree is assumed to be a complete record (i.e. valid
96 MARC. The title control number is taken from (whichever comes first)
97 tags 001, 020, 022, 010, 035 and whichever does not already exist
99 user_session must have IMPORT_MARC permissions
103 sub biblio_record_tree_import {
104 my( $self, $client, $user_session, $tree) = @_;
105 my $user_obj = $apputils->check_user_session($user_session);
107 if($apputils->check_user_perms(
108 $user_obj->id, $user_obj->home_ou, "IMPORT_MARC")) {
109 return OpenILS::Perm->new("IMPORT_MARC");
112 my $nodeset = $utils->tree2nodeset($tree);
114 # copy the doc so that we can mangle the namespace.
115 my $marcxml = OpenILS::Utils::FlatXML->new()->nodeset_to_xml($nodeset);
116 my $copy_marcxml = XML::LibXML->new->parse_string($marcxml->toString);
118 $marcxml->documentElement->setNamespace( "http://www.loc.gov/MARC21/slim", "marc", 1 );
121 #warn "Importing MARC Doc:\n".$marcxml->toString(1)."\n";
122 #warn "Namespace: " . $marcxml->documentElement->firstChild->namespaceURI . "\n";
125 warn "Starting db session in import\n";
126 my $session = $apputils->start_db_session();
127 my $source = 2; # system local source
129 my $xpath = '//controlfield[@tag="001"]';
130 $tcn = $marcxml->documentElement->findvalue($xpath);
131 if(_tcn_exists($session, $tcn)) {$tcn = undef;}
132 my $tcn_source = "External";
136 $xpath = '//datafield[@tag="020"]';
137 $tcn = $marcxml->documentElement->findvalue($xpath);
138 $tcn_source = "ISBN";
139 if(_tcn_exists($session, $tcn)) {$tcn = undef;}
143 $xpath = '//datafield[@tag="022"]';
144 $tcn = $marcxml->documentElement->findvalue($xpath);
145 $tcn_source = "ISSN";
146 if(_tcn_exists($session, $tcn)) {$tcn = undef;}
150 $xpath = '//datafield[@tag="010"]';
151 $tcn = $marcxml->documentElement->findvalue($xpath);
152 $tcn_source = "LCCN";
153 if(_tcn_exists($session, $tcn)) {$tcn = undef;}
157 $xpath = '//datafield[@tag="035"]';
158 $tcn = $marcxml->documentElement->findvalue($xpath);
159 $tcn_source = "System";
160 if(_tcn_exists($session, $tcn)) {$tcn = undef;}
166 warn "Record import with tcn: $tcn and source $tcn_source\n";
168 my $record = Fieldmapper::biblio::record_entry->new;
170 $record->source($source);
171 $record->tcn_source($tcn_source);
172 $record->tcn_value($tcn);
173 $record->creator($user_obj->id);
174 $record->editor($user_obj->id);
175 $record->marc($copy_marcxml->toString);
178 my $req = $session->request(
179 "open-ils.storage.direct.biblio.record_entry.create", $record );
181 my $id = $req->gather(1);
183 if(!$id) { throw OpenSRF::EX::ERROR ("Unable to create new record_entry from import"); }
184 warn "received id: $id from record_entry create\n";
186 $apputils->commit_db_session($session);
188 $session = OpenSRF::AppSession->create("open-ils.storage");
190 my $wreq = $session->request("open-ils.worm.wormize.biblio", $id)->gather(1);
191 warn "Done worming record $id\n";
193 if(!$wreq) { throw OpenSRF::EX::ERROR ("Unable to wormize imported record"); }
195 return $self->biblio_record_tree_retrieve($client, $id);
203 if(!$tcn) {return 0;}
205 my $req = $session->request(
206 "open-ils.storage.direct.biblio.record_entry.search_where.atomic",
207 { tcn_value => $tcn, deleted => 'f' } );
208 #"open-ils.storage.direct.biblio.record_entry.search.tcn_value.atomic",
210 my $recs = $req->gather(1);
212 if($recs and $recs->[0]) {
213 $logger->debug("_tcn_exists is true for tcn : $tcn");
217 $logger->debug("_tcn_exists is false for tcn : $tcn");
223 __PACKAGE__->register_method(
224 method => "biblio_record_tree_retrieve",
225 api_name => "open-ils.cat.biblio.record.tree.retrieve",
228 sub biblio_record_tree_retrieve {
230 my( $self, $client, $recordid ) = @_;
232 my $name = "open-ils.storage.direct.biblio.record_entry.retrieve";
233 my $session = OpenSRF::AppSession->create( "open-ils.storage" );
234 my $request = $session->request( $name, $recordid );
235 my $marcxml = $request->gather(1);
238 throw OpenSRF::EX::ERROR
239 ("No record in database with id $recordid");
242 $session->disconnect();
245 warn "turning into nodeset\n";
246 my $nodes = OpenILS::Utils::FlatXML->new()->xml_to_nodeset( $marcxml->marc );
247 warn "turning nodeset into tree\n";
248 my $tree = $utils->nodeset2tree( $nodes->nodeset );
250 $tree->owner_doc( $marcxml->id() );
252 warn "returning tree\n";
257 __PACKAGE__->register_method(
258 method => "biblio_record_tree_commit",
259 api_name => "open-ils.cat.biblio.record.tree.commit",
260 argc => 3, #(session_id, biblio_tree )
261 notes => <<" NOTES");
262 Walks the tree and commits any changed nodes
263 adds any new nodes, and deletes any deleted nodes
264 The record to commit must already exist or this
268 sub biblio_record_tree_commit {
270 my( $self, $client, $user_session, $tree ) = @_;
272 throw OpenSRF::EX::InvalidArg
273 ("Not enough args to to open-ils.cat.biblio.record.tree.commit")
274 unless ( $user_session and $tree );
276 my $user_obj = $apputils->check_user_session($user_session);
278 if($apputils->check_user_perms(
279 $user_obj->id, $user_obj->home_ou, "UPDATE_MARC")) {
280 return OpenILS::Perm->new("UPDATE_MARC");
285 my $docid = $tree->owner_doc();
286 my $session = OpenILS::Application::AppUtils->start_db_session();
288 warn "Retrieving biblio record from storage for update\n";
290 my $req1 = $session->request(
291 "open-ils.storage.direct.biblio.record_entry.batch.retrieve", $docid );
292 my $biblio = $req1->gather(1);
294 warn "retrieved doc $docid\n";
297 # turn the tree into a nodeset
298 my $nodeset = $utils->tree2nodeset($tree);
299 $nodeset = $utils->clean_nodeset($nodeset);
301 if(!defined($docid)) { # be sure
302 for my $node (@$nodeset) {
303 $docid = $node->owner_doc();
304 last if defined($docid);
308 # turn the nodeset into a doc
309 my $marcxml = OpenILS::Utils::FlatXML->new()->nodeset_to_xml( $nodeset );
311 $biblio->marc( $marcxml->toString() );
313 warn "Starting db session\n";
315 my $x = _update_record_metadata( $session, { user => $user_obj, docid => $docid } );
316 OpenILS::Application::AppUtils->rollback_db_session($session) unless $x;
318 warn "Sending updated doc $docid to db\n";
319 my $req = $session->request( "open-ils.storage.direct.biblio.record_entry.update", $biblio );
322 my $status = $req->recv();
323 if( !$status || $status->isa("Error") || ! $status->content) {
324 OpenILS::Application::AppUtils->rollback_db_session($session);
325 if($status->isa("Error")) { throw $status ($status); }
326 throw OpenSRF::EX::ERROR ("Error updating biblio record");
330 # Send the doc to the wormer for wormizing
331 warn "Starting worm session\n";
336 my $wreq = $session->request( "open-ils.worm.wormize.biblio", $docid );
343 warn "wormizing failed, rolling back\n";
344 OpenILS::Application::AppUtils->rollback_db_session($session);
346 if($e) { throw $e ($e); }
347 throw OpenSRF::EX::ERROR ("Wormizing Failed for $docid" );
350 warn "Committing db session...\n";
351 OpenILS::Application::AppUtils->commit_db_session( $session );
353 $nodeset = OpenILS::Utils::FlatXML->new()->xmldoc_to_nodeset($marcxml);
354 $tree = $utils->nodeset2tree($nodeset->nodeset);
355 $tree->owner_doc($docid);
357 # $client->respond_complete($tree);
359 warn "Done wormizing\n";
362 #warn "Returning tree:\n";
371 __PACKAGE__->register_method(
372 method => "biblio_record_record_metadata",
373 api_name => "open-ils.cat.biblio.record.metadata.retrieve",
374 argc => 1, #(session_id, biblio_tree )
375 notes => "Walks the tree and commits any changed nodes " .
376 "adds any new nodes, and deletes any deleted nodes",
379 sub biblio_record_record_metadata {
380 my( $self, $client, @ids ) = @_;
382 if(!@ids){return undef;}
384 my $session = OpenSRF::AppSession->create("open-ils.storage");
385 my $request = $session->request(
386 "open-ils.storage.direct.biblio.record_entry.batch.retrieve", @ids );
390 while( my $response = $request->recv() ) {
393 throw OpenSRF::EX::ERROR ("No Response from Storage");
395 if($response->isa("Error")) {
396 throw $response ($response->stringify);
399 my $record_entry = $response->content;
401 my $creator = $record_entry->creator;
402 my $editor = $record_entry->editor;
404 ($creator, $editor) = _get_userid_by_id($creator, $editor);
406 $record_entry->creator($creator);
407 $record_entry->editor($editor);
409 push @$results, $record_entry;
414 $session->disconnect();
421 __PACKAGE__->register_method(
422 method => "biblio_record_marc_cn",
423 api_name => "open-ils.cat.biblio.record.marc_cn.retrieve",
424 argc => 1, #(bib id )
427 sub biblio_record_marc_cn {
428 my( $self, $client, $id ) = @_;
430 my $session = OpenSRF::AppSession->create("open-ils.storage");
432 ->request("open-ils.storage.direct.biblio.record_entry.retrieve", $id )
436 my $doc = XML::LibXML->new->parse_string($marc);
437 $doc->documentElement->setNamespace( "http://www.loc.gov/MARC21/slim", "marc", 1 );
440 for my $tag ( qw/050 055 060 070 080 082 086 088 090 092 096 098 099/ ) {
441 my @node = $doc->findnodes("//marc:datafield[\@tag='$tag']");
443 my $cn = $x->findvalue("marc:subfield[\@code='a' or \@code='b']");
444 push @res, {$tag => $cn} if ($cn);
452 sub _get_userid_by_id {
457 my $session = OpenSRF::AppSession->create( "open-ils.storage" );
458 my $request = $session->request(
459 "open-ils.storage.direct.actor.user.batch.retrieve.atomic", @ids );
461 $request->wait_complete;
462 my $response = $request->recv();
463 if(!$request->complete) { return undef; }
465 if($response->isa("Error")){
466 throw $response ($response);
469 for my $u (@{$response->content}) {
471 push @users, $u->usrname;
475 $session->disconnect;
481 sub _get_id_by_userid {
486 my $session = OpenSRF::AppSession->create( "open-ils.storage" );
487 my $request = $session->request(
488 "open-ils.storage.direct.actor.user.search.usrname.atomic", @users );
490 $request->wait_complete;
491 my $response = $request->recv();
492 if(!$request->complete) {
493 throw OpenSRF::EX::ERROR ("no response from storage on user retrieve");
496 if(UNIVERSAL::isa( $response, "Error")){
497 throw $response ($response);
500 for my $u (@{$response->content}) {
506 $session->disconnect;
513 # commits metadata objects to the db
514 sub _update_record_metadata {
516 my ($session, @docs ) = @_;
518 for my $doc (@docs) {
520 my $user_obj = $doc->{user};
521 my $docid = $doc->{docid};
523 warn "Updating metata for doc $docid\n";
525 my $request = $session->request(
526 "open-ils.storage.direct.biblio.record_entry.retrieve", $docid );
527 my $record = $request->gather(1);
529 warn "retrieved record\n";
530 my ($id) = _get_id_by_userid($user_obj->usrname);
532 warn "got $id from _get_id_by_userid\n";
533 $record->editor($id);
535 warn "Grabbed the record, updating and moving on\n";
537 $request = $session->request(
538 "open-ils.storage.direct.biblio.record_entry.update", $record );
542 warn "committing metarecord update\n";
549 __PACKAGE__->register_method(
550 method => "orgs_for_title",
551 api_name => "open-ils.cat.actor.org_unit.retrieve_by_title"
555 my( $self, $client, $record_id ) = @_;
557 my $vols = $apputils->simple_scalar_request(
559 "open-ils.storage.direct.asset.call_number.search_where.atomic",
560 { record => $record_id, deleted => 'f' });
561 #"open-ils.storage.direct.asset.call_number.search.record.atomic",
563 my $orgs = { map {$_->owning_lib => 1 } @$vols };
564 return [ keys %$orgs ];
568 __PACKAGE__->register_method(
569 method => "retrieve_copies_",
570 api_name => "open-ils.cat.asset.copy_tree.retrieve_");
572 sub retrieve_copies_ {
573 my( $self, $conn, $authtoken, $docid, $orgs ) = @_;
577 __PACKAGE__->register_method(
578 method => "retrieve_copies",
579 api_name => "open-ils.cat.asset.copy_tree.retrieve");
581 __PACKAGE__->register_method(
582 method => "retrieve_copies",
583 api_name => "open-ils.cat.asset.copy_tree.global.retrieve");
585 # user_session may be null/undef
586 sub retrieve_copies {
588 my( $self, $client, $user_session, $docid, @org_ids ) = @_;
590 if(ref($org_ids[0])) { @org_ids = @{$org_ids[0]}; }
594 warn " $$ retrieving copy tree for orgs @org_ids and doc $docid at " . time() . "\n";
596 # grabbing copy trees should be available for everyone..
597 if(!@org_ids and $user_session) {
599 OpenILS::Application::AppUtils->check_user_session( $user_session ); #throws EX on error
600 @org_ids = ($user_obj->home_ou);
603 if( $self->api_name =~ /global/ ) {
604 warn "performing global copy_tree search for $docid\n";
605 return _build_volume_list( { record => $docid } );
610 for my $orgid (@org_ids) {
611 my $vols = _build_volume_list(
612 { record => $docid, owning_lib => $orgid } );
613 warn "Volumes built for org $orgid\n";
614 push( @all_vols, @$vols );
617 warn " $$ Finished copy_tree at " . time() . "\n";
625 sub _build_volume_list {
626 my $search_hash = shift;
628 $search_hash->{deleted} = 'f';
630 my $session = OpenSRF::AppSession->create( "open-ils.storage" );
633 my $request = $session->request(
634 "open-ils.storage.direct.asset.call_number.search.atomic", $search_hash );
635 #"open-ils.storage.direct.asset.call_number.search.atomic", $search_hash );
637 my $vols = $request->gather(1);
640 for my $volume (@$vols) {
642 warn "Grabbing copies for volume: " . $volume->id . "\n";
643 my $creq = $session->request(
644 "open-ils.storage.direct.asset.copy.search_where.atomic",
645 { call_number => $volume->id , deleted => 'f' });
646 #"open-ils.storage.direct.asset.copy.search.call_number.atomic", $volume->id );
648 my $copies = $creq->gather(1);
650 $copies = [ sort { $a->barcode cmp $b->barcode } @$copies ];
652 $volume->copies($copies);
654 push( @volumes, $volume );
658 $session->disconnect();
664 # -----------------------------------------------------------------
665 # Fleshed volume tree batch add/update. This does everything a
666 # volume tree could want, add, update, delete
667 # -----------------------------------------------------------------
668 __PACKAGE__->register_method(
669 method => "volume_tree_fleshed_update",
670 api_name => "open-ils.cat.asset.volume_tree.fleshed.batch.update",
672 sub volume_tree_fleshed_update {
674 my( $self, $client, $user_session, $volumes ) = @_;
675 return undef unless $volumes;
677 my $user_obj = $apputils->check_user_session($user_session);
680 my $session = $apputils->start_db_session();
681 warn "Looping on volumes in fleshed volume tree update\n";
683 # cycle through the volumes provided and update/create/delete where necessary
684 for my $volume (@$volumes) {
686 warn "updating volume " . $volume->id . "\n";
688 my $update_copy_list = $volume->copies;
691 if( $volume->isdeleted) {
692 my $status = _delete_volume($session, $volume, $user_obj);
694 #throw OpenSRF::EX::ERROR
695 #("Volume delete failed for volume " . $volume->id);
697 if(UNIVERSAL::isa($status, "Fieldmapper::perm_ex")) { return $status; }
699 } elsif( $volume->isnew ) {
702 $volume->editor($user_obj->id);
703 $volume->creator($user_obj->id);
704 $volume = _add_volume($session, $volume, $user_obj);
707 if($volume and UNIVERSAL::isa($volume, "Fieldmapper::perm_ex")) { return $volume; }
709 } elsif( $volume->ischanged ) {
711 $volume->editor($user_obj->id);
712 my $stat = _update_volume($session, $volume, $user_obj);
713 if($stat and UNIVERSAL::isa($stat, "Fieldmapper::perm_ex")) { return $stat; }
717 if( ! $volume->isdeleted ) {
718 for my $copy (@{$update_copy_list}) {
720 $copy->editor($user_obj->id);
721 warn "updating copy for volume " . $volume->id . "\n";
726 $copy->call_number($volume->id);
727 $copy->creator($user_obj->id);
728 $copy = _fleshed_copy_update($session,$copy,$user_obj);
730 } elsif( $copy->ischanged ) {
731 $copy->call_number($volume->id);
732 $copy = _fleshed_copy_update($session, $copy, $user_obj);
734 } elsif( $copy->isdeleted ) {
735 warn "Deleting copy " . $copy->id . " for volume " . $volume->id . "\n";
736 my $status = _fleshed_copy_update($session, $copy, $user_obj);
737 warn "Copy delete returned a status of $status\n";
743 $apputils->commit_db_session($session);
744 return scalar(@$volumes);
749 my( $session, $volume, $user_obj ) = @_;
751 if($apputils->check_user_perms(
752 $user_obj->id, $user_obj->home_ou, "DELETE_VOLUME")) {
753 return OpenILS::Perm->new("DELETE_VOLUME"); }
755 #$volume = _find_volume($session, $volume);
756 warn "Deleting volume " . $volume->id . "\n";
758 my $copies = $session->request(
759 "open-ils.storage.direct.asset.copy.search_where.atomic",
760 { call_number => $volume->id, deleted => 'f' } )->gather(1);
761 #"open-ils.storage.direct.asset.copy.search.call_number.atomic",
764 throw OpenSRF::EX::ERROR
765 ("Cannot remove volume with copies attached");
768 my $req = $session->request(
769 "open-ils.storage.direct.asset.call_number.delete",
771 return $req->gather(1);
776 my($session, $volume, $user_obj) = @_;
777 if($apputils->check_user_perms(
778 $user_obj->id, $user_obj->home_ou, "UPDATE_VOLUME")) {
779 return OpenILS::Perm->new("UPDATE_VOLUME"); }
781 my $req = $session->request(
782 "open-ils.storage.direct.asset.call_number.update",
784 my $status = $req->gather(1);
789 my($session, $volume, $user_obj) = @_;
791 if($apputils->check_user_perms(
792 $user_obj->id, $user_obj->home_ou, "CREATE_VOLUME")) {
793 warn "User does not have priveleges to create new volumes\n";
794 return OpenILS::Perm->new("CREATE_VOLUME");
797 my $request = $session->request(
798 "open-ils.storage.direct.asset.call_number.create", $volume );
800 my $id = $request->gather(1);
803 OpenILS::Application::AppUtils->rollback_db_session($session);
804 throw OpenSRF::EX::ERROR (" * -> Error creating new volume");
808 warn "received new volume id: $id\n";
816 __PACKAGE__->register_method(
817 method => "fleshed_copy_update",
818 api_name => "open-ils.cat.asset.copy.fleshed.batch.update",
821 sub fleshed_copy_update {
822 my($self, $client, $user_session, $copies) = @_;
824 my $user_obj = $apputils->check_user_session($user_session);
825 my $session = $apputils->start_db_session();
827 for my $copy (@$copies) {
828 _fleshed_copy_update($session, $copy, $user_obj);
831 $apputils->commit_db_session($session);
838 my($session, $copy, $user_obj) = @_;
840 if($apputils->check_user_perms(
841 $user_obj->id, $user_obj->home_ou, "DELETE_COPY")) {
842 return OpenILS::Perm->new("DELETE_COPY"); }
844 warn "Deleting copy " . $copy->id . "\n";
845 my $request = $session->request(
846 "open-ils.storage.direct.asset.copy.delete",
848 return $request->gather(1);
852 my($session, $copy, $user_obj) = @_;
854 if($apputils->check_user_perms(
855 $user_obj->id, $user_obj->home_ou, "CREATE_COPY")) {
856 return OpenILS::Perm->new("CREATE_COPY"); }
858 my $request = $session->request(
859 "open-ils.storage.direct.asset.copy.create",
861 my $id = $request->gather(1);
864 throw OpenSRF::EX::ERROR
865 ("Unable to create new copy " . Dumper($copy));
868 warn "Created copy " . $copy->id . "\n";
875 my($session, $copy, $user_obj) = @_;
877 my $evt = $apputils->check_perms($user_obj->id, $copy->circ_lib, 'UPDATE_COPY');
878 return $evt if $evt; #XXX NOT YET HANDLED BY CALLER
880 my $status = $apputils->simplereq(
882 "open-ils.storage.direct.asset.copy.update", $copy );
883 $logger->debug("Successfully updated copy " . $copy->id );
888 # -----------------------------------------------------------------
889 # Creates/Updates/Deletes a fleshed asset.copy.
890 # adds/deletes copy stat_cat maps where necessary
891 # -----------------------------------------------------------------
892 sub _fleshed_copy_update {
893 my($session, $copy, $editor) = @_;
895 my $stat_cat_entries = $copy->stat_cat_entries;
896 $copy->editor($editor->id);
898 # in case we're fleshed
899 if(ref($copy->status)) {$copy->status( $copy->status->id ); }
900 if(ref($copy->location)) {$copy->location( $copy->location->id ); }
901 if(ref($copy->circ_lib)) {$copy->circ_lib( $copy->circ_lib->id ); }
903 warn "Updating copy " . Dumper($copy) . "\n";
905 if( $copy->isdeleted ) {
906 return _delete_copy($session, $copy, $editor);
907 } elsif( $copy->isnew ) {
908 $copy = _create_copy($session, $copy, $editor);
909 } elsif( $copy->ischanged ) {
910 _update_copy($session, $copy, $editor);
914 return 1 unless ( $stat_cat_entries and @$stat_cat_entries );
916 my $stat_maps = $session->request(
917 "open-ils.storage.direct.asset.stat_cat_entry_copy_map.search.owning_copy.atomic",
918 $copy->id )->gather(1);
920 if(!$copy->isnew) { _delete_stale_maps($session, $stat_maps, $copy); }
922 # go through the stat cat update/create process
923 for my $stat_entry (@{$stat_cat_entries}){
924 _copy_update_stat_cats( $session, $copy, $stat_maps, $stat_entry, $editor );
931 # -----------------------------------------------------------------
932 # Deletes stat maps attached to this copy in the database that
933 # are no longer attached to the current copy
934 # -----------------------------------------------------------------
935 sub _delete_stale_maps {
936 my( $session, $stat_maps, $copy) = @_;
938 warn "Deleting stale stat maps for copy " . $copy->id . "\n";
939 for my $map (@$stat_maps) {
940 # if there is no stat cat entry on the copy who's id matches the
941 # current map's id, remove the map from the database
942 if(! grep { $_->id == $map->stat_cat_entry } @{$copy->stat_cat_entries} ) {
943 my $req = $session->request(
944 "open-ils.storage.direct.asset.stat_cat_entry_copy_map.delete", $map );
953 # -----------------------------------------------------------------
954 # Searches the stat maps to see if '$entry' already exists on
955 # the given copy. If it does not, a new stat map is created
956 # for the given entry and copy
957 # -----------------------------------------------------------------
958 sub _copy_update_stat_cats {
959 my ( $session, $copy, $stat_maps, $entry, $editor ) = @_;
961 warn "Updating stat maps for copy " . $copy->id . "\n";
963 # see if this map already exists
964 for my $map (@$stat_maps) {
965 if( $map->stat_cat_entry == $entry->id ) {return;}
968 warn "Creating new stat map for stat " .
969 $entry->stat_cat . " and copy " . $copy->id . "\n";
972 my $new_map = Fieldmapper::asset::stat_cat_entry_copy_map->new();
974 $new_map->stat_cat( $entry->stat_cat );
975 $new_map->stat_cat_entry( $entry->id );
976 $new_map->owning_copy( $copy->id );
978 warn "New map is " . Dumper($new_map) . "\n";
980 my $request = $session->request(
981 "open-ils.storage.direct.asset.stat_cat_entry_copy_map.create",
983 my $status = $request->gather(1);
984 warn "created new map with id $status\n";