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_where.atomic",
208 { tcn_value => $tcn, deleted => 'f' } );
209 #"open-ils.storage.direct.biblio.record_entry.search.tcn_value.atomic",
211 my $recs = $req->gather(1);
213 if($recs and $recs->[0]) {
214 $logger->debug("_tcn_exists is true for tcn : $tcn");
218 $logger->debug("_tcn_exists is false for tcn : $tcn");
224 __PACKAGE__->register_method(
225 method => "biblio_record_tree_retrieve",
226 api_name => "open-ils.cat.biblio.record.tree.retrieve",
229 sub biblio_record_tree_retrieve {
231 my( $self, $client, $recordid ) = @_;
233 my $name = "open-ils.storage.direct.biblio.record_entry.retrieve";
234 my $session = OpenSRF::AppSession->create( "open-ils.storage" );
235 my $request = $session->request( $name, $recordid );
236 my $marcxml = $request->gather(1);
239 throw OpenSRF::EX::ERROR
240 ("No record in database with id $recordid");
243 $session->disconnect();
246 warn "turning into nodeset\n";
247 my $nodes = OpenILS::Utils::FlatXML->new()->xml_to_nodeset( $marcxml->marc );
248 warn "turning nodeset into tree\n";
249 my $tree = $utils->nodeset2tree( $nodes->nodeset );
251 $tree->owner_doc( $marcxml->id() );
253 warn "returning tree\n";
258 __PACKAGE__->register_method(
259 method => "biblio_record_tree_commit",
260 api_name => "open-ils.cat.biblio.record.tree.commit",
261 argc => 3, #(session_id, biblio_tree )
262 notes => <<" NOTES");
263 Walks the tree and commits any changed nodes
264 adds any new nodes, and deletes any deleted nodes
265 The record to commit must already exist or this
269 sub biblio_record_tree_commit {
271 my( $self, $client, $user_session, $tree ) = @_;
273 throw OpenSRF::EX::InvalidArg
274 ("Not enough args to to open-ils.cat.biblio.record.tree.commit")
275 unless ( $user_session and $tree );
277 my $user_obj = $apputils->check_user_session($user_session);
279 if($apputils->check_user_perms(
280 $user_obj->id, $user_obj->home_ou, "UPDATE_MARC")) {
281 return OpenILS::Perm->new("UPDATE_MARC");
286 my $docid = $tree->owner_doc();
287 my $session = OpenILS::Application::AppUtils->start_db_session();
289 warn "Retrieving biblio record from storage for update\n";
291 my $req1 = $session->request(
292 "open-ils.storage.direct.biblio.record_entry.batch.retrieve", $docid );
293 my $biblio = $req1->gather(1);
295 warn "retrieved doc $docid\n";
298 # turn the tree into a nodeset
299 my $nodeset = $utils->tree2nodeset($tree);
300 $nodeset = $utils->clean_nodeset($nodeset);
302 if(!defined($docid)) { # be sure
303 for my $node (@$nodeset) {
304 $docid = $node->owner_doc();
305 last if defined($docid);
309 # turn the nodeset into a doc
310 my $marcxml = OpenILS::Utils::FlatXML->new()->nodeset_to_xml( $nodeset );
312 $biblio->marc( $marcxml->toString() );
314 warn "Starting db session\n";
316 my $x = _update_record_metadata( $session, { user => $user_obj, docid => $docid } );
317 OpenILS::Application::AppUtils->rollback_db_session($session) unless $x;
319 warn "Sending updated doc $docid to db\n";
320 my $req = $session->request( "open-ils.storage.direct.biblio.record_entry.update", $biblio );
323 my $status = $req->recv();
324 if( !$status || $status->isa("Error") || ! $status->content) {
325 OpenILS::Application::AppUtils->rollback_db_session($session);
326 if($status->isa("Error")) { throw $status ($status); }
327 throw OpenSRF::EX::ERROR ("Error updating biblio record");
331 # Send the doc to the wormer for wormizing
332 warn "Starting worm session\n";
337 my $wreq = $session->request( "open-ils.worm.wormize.biblio", $docid );
344 warn "wormizing failed, rolling back\n";
345 OpenILS::Application::AppUtils->rollback_db_session($session);
347 if($e) { throw $e ($e); }
348 throw OpenSRF::EX::ERROR ("Wormizing Failed for $docid" );
351 warn "Committing db session...\n";
352 OpenILS::Application::AppUtils->commit_db_session( $session );
354 $nodeset = OpenILS::Utils::FlatXML->new()->xmldoc_to_nodeset($marcxml);
355 $tree = $utils->nodeset2tree($nodeset->nodeset);
356 $tree->owner_doc($docid);
358 # $client->respond_complete($tree);
360 warn "Done wormizing\n";
363 #warn "Returning tree:\n";
372 __PACKAGE__->register_method(
373 method => "biblio_record_record_metadata",
374 api_name => "open-ils.cat.biblio.record.metadata.retrieve",
375 argc => 1, #(session_id, biblio_tree )
376 notes => "Walks the tree and commits any changed nodes " .
377 "adds any new nodes, and deletes any deleted nodes",
380 sub biblio_record_record_metadata {
381 my( $self, $client, @ids ) = @_;
383 if(!@ids){return undef;}
385 my $session = OpenSRF::AppSession->create("open-ils.storage");
386 my $request = $session->request(
387 "open-ils.storage.direct.biblio.record_entry.batch.retrieve", @ids );
391 while( my $response = $request->recv() ) {
394 throw OpenSRF::EX::ERROR ("No Response from Storage");
396 if($response->isa("Error")) {
397 throw $response ($response->stringify);
400 my $record_entry = $response->content;
402 my $creator = $record_entry->creator;
403 my $editor = $record_entry->editor;
405 ($creator, $editor) = _get_userid_by_id($creator, $editor);
407 $record_entry->creator($creator);
408 $record_entry->editor($editor);
410 push @$results, $record_entry;
415 $session->disconnect();
422 __PACKAGE__->register_method(
423 method => "biblio_record_marc_cn",
424 api_name => "open-ils.cat.biblio.record.marc_cn.retrieve",
425 argc => 1, #(bib id )
428 sub biblio_record_marc_cn {
429 my( $self, $client, $id ) = @_;
431 my $session = OpenSRF::AppSession->create("open-ils.storage");
433 ->request("open-ils.storage.direct.biblio.record_entry.retrieve", $id )
437 my $doc = XML::LibXML->new->parse_string($marc);
438 $doc->documentElement->setNamespace( "http://www.loc.gov/MARC21/slim", "marc", 1 );
441 for my $tag ( qw/050 055 060 070 080 082 086 088 090 092 096 098 099/ ) {
442 my @node = $doc->findnodes("//marc:datafield[\@tag='$tag']");
444 my $cn = $x->findvalue("marc:subfield[\@code='a' or \@code='b']");
445 push @res, {$tag => $cn} if ($cn);
453 sub _get_userid_by_id {
458 my $session = OpenSRF::AppSession->create( "open-ils.storage" );
459 my $request = $session->request(
460 "open-ils.storage.direct.actor.user.batch.retrieve.atomic", @ids );
462 $request->wait_complete;
463 my $response = $request->recv();
464 if(!$request->complete) { return undef; }
466 if($response->isa("Error")){
467 throw $response ($response);
470 for my $u (@{$response->content}) {
472 push @users, $u->usrname;
476 $session->disconnect;
482 sub _get_id_by_userid {
487 my $session = OpenSRF::AppSession->create( "open-ils.storage" );
488 my $request = $session->request(
489 "open-ils.storage.direct.actor.user.search.usrname.atomic", @users );
491 $request->wait_complete;
492 my $response = $request->recv();
493 if(!$request->complete) {
494 throw OpenSRF::EX::ERROR ("no response from storage on user retrieve");
497 if(UNIVERSAL::isa( $response, "Error")){
498 throw $response ($response);
501 for my $u (@{$response->content}) {
507 $session->disconnect;
514 # commits metadata objects to the db
515 sub _update_record_metadata {
517 my ($session, @docs ) = @_;
519 for my $doc (@docs) {
521 my $user_obj = $doc->{user};
522 my $docid = $doc->{docid};
524 warn "Updating metata for doc $docid\n";
526 my $request = $session->request(
527 "open-ils.storage.direct.biblio.record_entry.retrieve", $docid );
528 my $record = $request->gather(1);
530 warn "retrieved record\n";
531 my ($id) = _get_id_by_userid($user_obj->usrname);
533 warn "got $id from _get_id_by_userid\n";
534 $record->editor($id);
536 warn "Grabbed the record, updating and moving on\n";
538 $request = $session->request(
539 "open-ils.storage.direct.biblio.record_entry.update", $record );
543 warn "committing metarecord update\n";
550 __PACKAGE__->register_method(
551 method => "orgs_for_title",
552 api_name => "open-ils.cat.actor.org_unit.retrieve_by_title"
556 my( $self, $client, $record_id ) = @_;
558 my $vols = $apputils->simple_scalar_request(
560 "open-ils.storage.direct.asset.call_number.search_where.atomic",
561 { record => $record_id, deleted => 'f' });
562 #"open-ils.storage.direct.asset.call_number.search.record.atomic",
564 my $orgs = { map {$_->owning_lib => 1 } @$vols };
565 return [ keys %$orgs ];
569 __PACKAGE__->register_method(
570 method => "retrieve_copies_",
571 api_name => "open-ils.cat.asset.copy_tree.retrieve_");
573 sub retrieve_copies_ {
574 my( $self, $conn, $authtoken, $docid, $orgs ) = @_;
578 __PACKAGE__->register_method(
579 method => "retrieve_copies",
580 api_name => "open-ils.cat.asset.copy_tree.retrieve");
582 __PACKAGE__->register_method(
583 method => "retrieve_copies",
584 api_name => "open-ils.cat.asset.copy_tree.global.retrieve");
586 # user_session may be null/undef
587 sub retrieve_copies {
589 my( $self, $client, $user_session, $docid, @org_ids ) = @_;
591 if(ref($org_ids[0])) { @org_ids = @{$org_ids[0]}; }
595 warn " $$ retrieving copy tree for orgs @org_ids and doc $docid at " . time() . "\n";
597 # grabbing copy trees should be available for everyone..
598 if(!@org_ids and $user_session) {
600 OpenILS::Application::AppUtils->check_user_session( $user_session ); #throws EX on error
601 @org_ids = ($user_obj->home_ou);
604 if( $self->api_name =~ /global/ ) {
605 warn "performing global copy_tree search for $docid\n";
606 return _build_volume_list( { record => $docid } );
611 for my $orgid (@org_ids) {
612 my $vols = _build_volume_list(
613 { record => $docid, owning_lib => $orgid } );
614 warn "Volumes built for org $orgid\n";
615 push( @all_vols, @$vols );
618 warn " $$ Finished copy_tree at " . time() . "\n";
626 sub _build_volume_list {
627 my $search_hash = shift;
629 $search_hash->{deleted} = 'f';
631 my $session = OpenSRF::AppSession->create( "open-ils.storage" );
634 my $request = $session->request(
635 "open-ils.storage.direct.asset.call_number.search.atomic", $search_hash );
636 #"open-ils.storage.direct.asset.call_number.search.atomic", $search_hash );
638 my $vols = $request->gather(1);
641 for my $volume (@$vols) {
643 warn "Grabbing copies for volume: " . $volume->id . "\n";
644 my $creq = $session->request(
645 "open-ils.storage.direct.asset.copy.search_where.atomic",
646 { call_number => $volume->id , deleted => 'f' });
647 #"open-ils.storage.direct.asset.copy.search.call_number.atomic", $volume->id );
649 my $copies = $creq->gather(1);
651 $copies = [ sort { $a->barcode cmp $b->barcode } @$copies ];
653 $volume->copies($copies);
655 push( @volumes, $volume );
659 $session->disconnect();
665 # -----------------------------------------------------------------
666 # Fleshed volume tree batch add/update. This does everything a
667 # volume tree could want, add, update, delete
668 # -----------------------------------------------------------------
669 __PACKAGE__->register_method(
670 method => "volume_tree_fleshed_update",
671 api_name => "open-ils.cat.asset.volume_tree.fleshed.batch.update",
673 sub volume_tree_fleshed_update {
675 my( $self, $client, $user_session, $volumes ) = @_;
676 return undef unless $volumes;
678 my $user_obj = $apputils->check_user_session($user_session);
681 my $session = $apputils->start_db_session();
682 warn "Looping on volumes in fleshed volume tree update\n";
684 # cycle through the volumes provided and update/create/delete where necessary
685 for my $volume (@$volumes) {
687 warn "updating volume " . $volume->id . "\n";
689 my $update_copy_list = $volume->copies;
692 if( $volume->isdeleted) {
693 my $status = _delete_volume($session, $volume, $user_obj);
695 #throw OpenSRF::EX::ERROR
696 #("Volume delete failed for volume " . $volume->id);
698 if(UNIVERSAL::isa($status, "Fieldmapper::perm_ex")) { return $status; }
700 } elsif( $volume->isnew ) {
703 $volume->editor($user_obj->id);
704 $volume->creator($user_obj->id);
705 $volume = _add_volume($session, $volume, $user_obj);
708 if($volume and UNIVERSAL::isa($volume, "Fieldmapper::perm_ex")) { return $volume; }
710 } elsif( $volume->ischanged ) {
712 $volume->editor($user_obj->id);
713 my $stat = _update_volume($session, $volume, $user_obj);
714 if($stat and UNIVERSAL::isa($stat, "Fieldmapper::perm_ex")) { return $stat; }
718 if( ! $volume->isdeleted ) {
719 for my $copy (@{$update_copy_list}) {
721 $copy->editor($user_obj->id);
722 warn "updating copy for volume " . $volume->id . "\n";
727 $copy->call_number($volume->id);
728 $copy->creator($user_obj->id);
729 $copy = _fleshed_copy_update($session,$copy,$user_obj);
731 } elsif( $copy->ischanged ) {
732 $copy->call_number($volume->id);
733 $copy = _fleshed_copy_update($session, $copy, $user_obj);
735 } elsif( $copy->isdeleted ) {
736 warn "Deleting copy " . $copy->id . " for volume " . $volume->id . "\n";
737 my $status = _fleshed_copy_update($session, $copy, $user_obj);
738 warn "Copy delete returned a status of $status\n";
744 $apputils->commit_db_session($session);
745 return scalar(@$volumes);
750 my( $session, $volume, $user_obj ) = @_;
752 if($apputils->check_user_perms(
753 $user_obj->id, $user_obj->home_ou, "DELETE_VOLUME")) {
754 return OpenILS::Perm->new("DELETE_VOLUME"); }
756 #$volume = _find_volume($session, $volume);
757 warn "Deleting volume " . $volume->id . "\n";
759 my $copies = $session->request(
760 "open-ils.storage.direct.asset.copy.search_where.atomic",
761 { call_number => $volume->id, deleted => 'f' } )->gather(1);
762 #"open-ils.storage.direct.asset.copy.search.call_number.atomic",
765 throw OpenSRF::EX::ERROR
766 ("Cannot remove volume with copies attached");
769 my $req = $session->request(
770 "open-ils.storage.direct.asset.call_number.delete",
772 return $req->gather(1);
777 my($session, $volume, $user_obj) = @_;
778 if($apputils->check_user_perms(
779 $user_obj->id, $user_obj->home_ou, "UPDATE_VOLUME")) {
780 return OpenILS::Perm->new("UPDATE_VOLUME"); }
782 my $req = $session->request(
783 "open-ils.storage.direct.asset.call_number.update",
785 my $status = $req->gather(1);
790 my($session, $volume, $user_obj) = @_;
792 if($apputils->check_user_perms(
793 $user_obj->id, $user_obj->home_ou, "CREATE_VOLUME")) {
794 warn "User does not have priveleges to create new volumes\n";
795 return OpenILS::Perm->new("CREATE_VOLUME");
798 my $request = $session->request(
799 "open-ils.storage.direct.asset.call_number.create", $volume );
801 my $id = $request->gather(1);
804 OpenILS::Application::AppUtils->rollback_db_session($session);
805 throw OpenSRF::EX::ERROR (" * -> Error creating new volume");
809 warn "received new volume id: $id\n";
817 __PACKAGE__->register_method(
818 method => "fleshed_copy_update",
819 api_name => "open-ils.cat.asset.copy.fleshed.batch.update",
822 sub fleshed_copy_update {
823 my($self, $client, $user_session, $copies) = @_;
825 my $user_obj = $apputils->check_user_session($user_session);
826 my $session = $apputils->start_db_session();
828 for my $copy (@$copies) {
829 _fleshed_copy_update($session, $copy, $user_obj);
832 $apputils->commit_db_session($session);
839 my($session, $copy, $user_obj) = @_;
841 if($apputils->check_user_perms(
842 $user_obj->id, $user_obj->home_ou, "DELETE_COPY")) {
843 return OpenILS::Perm->new("DELETE_COPY"); }
845 warn "Deleting copy " . $copy->id . "\n";
846 my $request = $session->request(
847 "open-ils.storage.direct.asset.copy.delete",
849 return $request->gather(1);
853 my($session, $copy, $user_obj) = @_;
855 if($apputils->check_user_perms(
856 $user_obj->id, $user_obj->home_ou, "CREATE_COPY")) {
857 return OpenILS::Perm->new("CREATE_COPY"); }
859 my $request = $session->request(
860 "open-ils.storage.direct.asset.copy.create",
862 my $id = $request->gather(1);
865 throw OpenSRF::EX::ERROR
866 ("Unable to create new copy " . Dumper($copy));
869 warn "Created copy " . $copy->id . "\n";
876 my($session, $copy, $user_obj) = @_;
878 my $evt = $apputils->check_perms($user_obj->id, $copy->circ_lib, 'UPDATE_COPY');
879 return $evt if $evt; #XXX NOT YET HANDLED BY CALLER
881 my $status = $apputils->simplereq(
883 "open-ils.storage.direct.asset.copy.update", $copy );
884 $logger->debug("Successfully updated copy " . $copy->id );
889 # -----------------------------------------------------------------
890 # Creates/Updates/Deletes a fleshed asset.copy.
891 # adds/deletes copy stat_cat maps where necessary
892 # -----------------------------------------------------------------
893 sub _fleshed_copy_update {
894 my($session, $copy, $editor) = @_;
896 my $stat_cat_entries = $copy->stat_cat_entries;
897 $copy->editor($editor->id);
899 # in case we're fleshed
900 if(ref($copy->status)) {$copy->status( $copy->status->id ); }
901 if(ref($copy->location)) {$copy->location( $copy->location->id ); }
902 if(ref($copy->circ_lib)) {$copy->circ_lib( $copy->circ_lib->id ); }
904 warn "Updating copy " . Dumper($copy) . "\n";
906 if( $copy->isdeleted ) {
907 return _delete_copy($session, $copy, $editor);
908 } elsif( $copy->isnew ) {
909 $copy = _create_copy($session, $copy, $editor);
910 } elsif( $copy->ischanged ) {
911 _update_copy($session, $copy, $editor);
915 return 1 unless ( $stat_cat_entries and @$stat_cat_entries );
917 my $stat_maps = $session->request(
918 "open-ils.storage.direct.asset.stat_cat_entry_copy_map.search.owning_copy.atomic",
919 $copy->id )->gather(1);
921 if(!$copy->isnew) { _delete_stale_maps($session, $stat_maps, $copy); }
923 # go through the stat cat update/create process
924 for my $stat_entry (@{$stat_cat_entries}){
925 _copy_update_stat_cats( $session, $copy, $stat_maps, $stat_entry, $editor );
932 # -----------------------------------------------------------------
933 # Deletes stat maps attached to this copy in the database that
934 # are no longer attached to the current copy
935 # -----------------------------------------------------------------
936 sub _delete_stale_maps {
937 my( $session, $stat_maps, $copy) = @_;
939 warn "Deleting stale stat maps for copy " . $copy->id . "\n";
940 for my $map (@$stat_maps) {
941 # if there is no stat cat entry on the copy who's id matches the
942 # current map's id, remove the map from the database
943 if(! grep { $_->id == $map->stat_cat_entry } @{$copy->stat_cat_entries} ) {
944 my $req = $session->request(
945 "open-ils.storage.direct.asset.stat_cat_entry_copy_map.delete", $map );
954 # -----------------------------------------------------------------
955 # Searches the stat maps to see if '$entry' already exists on
956 # the given copy. If it does not, a new stat map is created
957 # for the given entry and copy
958 # -----------------------------------------------------------------
959 sub _copy_update_stat_cats {
960 my ( $session, $copy, $stat_maps, $entry, $editor ) = @_;
962 warn "Updating stat maps for copy " . $copy->id . "\n";
964 # see if this map already exists
965 for my $map (@$stat_maps) {
966 if( $map->stat_cat_entry == $entry->id ) {return;}
969 warn "Creating new stat map for stat " .
970 $entry->stat_cat . " and copy " . $copy->id . "\n";
973 my $new_map = Fieldmapper::asset::stat_cat_entry_copy_map->new();
975 $new_map->stat_cat( $entry->stat_cat );
976 $new_map->stat_cat_entry( $entry->id );
977 $new_map->owning_copy( $copy->id );
979 warn "New map is " . Dumper($new_map) . "\n";
981 my $request = $session->request(
982 "open-ils.storage.direct.asset.stat_cat_entry_copy_map.create",
984 my $status = $request->gather(1);
985 warn "created new map with id $status\n";