1 package OpenILS::Application::Actor;
2 use base qw/OpenSRF::Application/;
3 use strict; use warnings;
5 use OpenSRF::EX qw(:try);
6 use OpenILS::Application::AppUtils;
7 use OpenILS::Utils::Fieldmapper;
8 use OpenILS::Application::Search::Actor;
10 my $apputils = "OpenILS::Application::AppUtils";
11 sub _d { warn "Patron:\n" . Dumper(shift()); }
12 my $cache_client = OpenSRF::Utils::Cache->new( "global", 0 );
15 __PACKAGE__->register_method(
16 method => "update_patron",
17 api_name => "open-ils.actor.patron.update",
22 my( $self, $client, $user_session, $patron ) = @_;
24 my $session = $apputils->start_db_session();
27 warn $user_session . " " . $patron . "\n";
31 OpenILS::Application::AppUtils->check_user_session(
32 $user_session ); #throws EX on error
34 # XXX does this user have permission to add/create users. Granularity?
36 # $new_patron is the patron in progress. $patron is the original patron
37 # passed in with the method. new_patron will change as the components
38 # of patron are added/updated.
43 # create/update the patron first so we can use his id
44 if($patron->isnew()) {
45 $new_patron = _add_patron(
46 $session, _clone_patron($patron));
48 $new_patron = $patron;
51 $new_patron = _add_update_addresses($session, $patron, $new_patron);
52 $new_patron = _add_update_cards($session, $patron, $new_patron);
53 $new_patron = _add_survey_responses($session, $patron, $new_patron);
54 $new_patron = _create_stat_maps($user_session, $patron, $new_patron);
56 # re-update the patron if anything has happened to him during this process
57 if($new_patron->ischanged()) {
58 $new_patron = _update_patron($session, $new_patron);
60 $apputils->commit_db_session($session);
64 $err = "-*- Failure adding user: $e";
65 $apputils->rollback_db_session($session);
69 if($err) { throw OpenSRF::EX::ERROR ($err); }
70 warn "Patron Update/Create complete\n";
71 return flesh_user($new_patron->id());
75 __PACKAGE__->register_method(
76 method => "user_retrieve_fleshed_by_id",
77 api_name => "open-ils.actor.user.fleshed.retrieve",);
79 sub user_retrieve_fleshed_by_id {
80 my( $self, $client, $user_session, $user_id ) = @_;
81 my $user_obj = $apputils->check_user_session( $user_session );
82 return flesh_user($user_id);
93 $session = OpenSRF::AppSession->create("open-ils.storage");
97 # grab the user with the given card
98 my $ureq = $session->request(
99 "open-ils.storage.direct.actor.user.retrieve",
101 my $user = $ureq->gather(1);
104 my $cards_req = $session->request(
105 "open-ils.storage.direct.actor.card.search.usr",
107 $user->cards( $cards_req->gather(1) );
109 my $add_req = $session->request(
110 "open-ils.storage.direct.actor.user_address.search.usr",
112 $user->addresses( $add_req->gather(1) );
114 my $stat_req = $session->request(
115 "open-ils.storage.direct.actor.stat_cat_entry_user_map.search.target_usr",
117 $user->stat_cat_entries($stat_req->gather(1));
119 if($kill) { $session->disconnect(); }
120 $user->clear_passwd();
128 # clone and clear stuff that would break the database
132 my $new_patron = Fieldmapper::actor::user->new();
134 my $fmap = $Fieldmapper::fieldmap;
135 no strict; # shallow clone, may be useful in the fieldmapper
137 (keys %{$fmap->{"Fieldmapper::actor::user"}->{'fields'}}) {
138 $new_patron->$field( $patron->$field() );
143 $new_patron->clear_billing_address();
144 $new_patron->clear_mailing_address();
145 $new_patron->clear_addresses();
146 $new_patron->clear_card();
147 $new_patron->clear_cards();
148 $new_patron->clear_id();
149 $new_patron->clear_isnew();
150 $new_patron->clear_changed();
151 $new_patron->clear_deleted();
152 $new_patron->clear_stat_cat_entries();
162 warn "Creating new patron\n";
165 my $req = $session->request(
166 "open-ils.storage.direct.actor.user.create",$patron);
167 my $id = $req->gather(1);
168 if(!$id) { throw OpenSRF::EX::ERROR ("Unable to create new user"); }
169 warn "Created new patron with id $id\n";
171 # retrieve the patron from the db to collect defaults
172 my $ureq = $session->request(
173 "open-ils.storage.direct.actor.user.retrieve",
175 return $ureq->gather(1);
180 my( $session, $patron) = @_;
182 warn "updating patron " . Dumper($patron) . "\n";
184 my $req = $session->request(
185 "open-ils.storage.direct.actor.user.update",$patron );
186 my $status = $req->gather(1);
187 if(!defined($status)) {
188 throw OpenSRF::EX::ERROR
189 ("Unknown error updating patron");
195 sub _add_update_addresses {
198 my $new_patron = shift;
200 my $current_id; # id of the address before creation
202 for my $address (@{$patron->addresses()}) {
204 $address->usr($new_patron->id());
206 if(ref($address) and $address->isnew()) {
207 warn "Adding new address at street " . $address->street1() . "\n";
209 $current_id = $address->id();
210 $address = _add_address($session,$address);
212 if( $patron->billing_address() and
213 $patron->billing_address() == $current_id ) {
214 $new_patron->billing_address($address->id());
215 $new_patron->ischanged(1);
218 if( $patron->mailing_address() and
219 $patron->mailing_address() == $current_id ) {
220 $new_patron->mailing_address($address->id());
221 $new_patron->ischanged(1);
224 } elsif( ref($address) and $address->ischanged() ) {
225 warn "Updating address at street " . $address->street1();
226 $address->usr($new_patron->id());
227 _update_address($session,$address);
229 } elsif( ref($address) and $address->isdeleted() ) {
230 warn "Deleting address at street " . $address->street1();
232 if( $address->id() == $new_patron->mailing_address() ) {
233 $new_patron->clear_mailing_address();
234 _update_patron($session, $new_patron);
237 if( $address->id() == $new_patron->billing_address() ) {
238 $new_patron->clear_billing_address();
239 _update_patron($session, $new_patron);
242 _delete_address($session,$address);
250 # adds an address to the db and returns the address with new id
252 my($session, $address) = @_;
253 $address->clear_id();
255 # put the address into the database
256 my $req = $session->request(
257 "open-ils.storage.direct.actor.user_address.create",
261 my $id = $req->gather(1);
263 throw OpenSRF::EX::ERROR
264 ("Unable to create new user address");
267 warn "Created address with id $id\n";
269 # update all the necessary id's
275 sub _update_address {
276 my( $session, $address ) = @_;
277 my $req = $session->request(
278 "open-ils.storage.direct.actor.user_address.update",
280 my $status = $req->gather(1);
281 if(!defined($status)) {
282 throw OpenSRF::EX::ERROR
283 ("Unknown error updating address");
290 sub _add_update_cards {
294 my $new_patron = shift;
296 my $virtual_id; #id of the card before creation
297 for my $card (@{$patron->cards()}) {
299 $card->usr($new_patron->id());
301 if(ref($card) and $card->isnew()) {
303 $virtual_id = $card->id();
304 $card = _add_card($session,$card);
306 if($patron->card() == $virtual_id) {
307 $new_patron->card($card->id());
308 $new_patron->ischanged(1);
311 } elsif( ref($card) and $card->ischanged() ) {
312 $card->usr($new_patron->id());
313 _update_card($session, $card);
320 # adds an card to the db and returns the card with new id
322 my( $session, $card ) = @_;
325 warn "Adding card with barcode " . $card->barcode() . "\n";
326 my $req = $session->request(
327 "open-ils.storage.direct.actor.card.create",
330 my $id = $req->gather(1);
332 throw OpenSRF::EX::ERROR
333 ("Unknown error creating card");
337 warn "Created patron card with id $id\n";
343 my( $session, $card ) = @_;
346 my $req = $session->request(
347 "open-ils.storage.direct.actor.card.update",
349 my $status = $req->gather(1);
350 if(!defined($status)) {
351 throw OpenSRF::EX::ERROR
352 ("Unknown error updating card");
360 sub _delete_address {
361 my( $session, $address ) = @_;
363 warn "Deleting address " . $address->street1() . "\n";
365 my $req = $session->request(
366 "open-ils.storage.direct.actor.user_address.delete",
368 my $status = $req->gather(1);
369 if(!defined($status)) {
370 throw OpenSRF::EX::ERROR
371 ("Unknown error updating address");
373 warn "Delete address status is $status\n";
378 sub _add_survey_responses {
379 my ($session, $patron, $new_patron) = @_;
381 warn "updating responses for user " . $new_patron->id . "\n";
383 my $responses = $patron->survey_responses;
384 for my $resp( @$responses ) {
385 $resp->usr($new_patron->id);
388 my $status = $apputils->simple_scalar_request(
390 "open-ils.circ.survey.submit.user_id",
397 sub _create_stat_maps {
399 my($user_session, $patron, $new_patron) = @_;
400 my $maps = $patron->stat_cat_entries();
402 my $session = OpenSRF::AppSession->create("open-ils.circ");
404 for my $map (@$maps) {
406 next unless($map->isnew() || $map->ischanged());
408 my $method = "open-ils.circ.stat_cat.actor.user_map.update";
410 $method = "open-ils.circ.stat_cat.actor.user_map.create";
413 warn "Updating stat entry with method $method and
414 session $user_session and map $map\n";
416 my $req = $session->request($method, $user_session, $map);
417 my $status = $req->gather(1);
422 throw OpenSRF::EX::ERROR
423 ("Error updating stat map with method $method");
427 $session->disconnect();
433 __PACKAGE__->register_method(
434 method => "search_username",
435 api_name => "open-ils.actor.user.search.username",
438 sub search_username {
439 my($self, $client, $username) = @_;
440 my $users = OpenILS::Application::AppUtils->simple_scalar_request(
442 "open-ils.storage.direct.actor.user.search.usrname",
450 __PACKAGE__->register_method(
451 method => "user_retrieve_by_barcode",
452 api_name => "open-ils.actor.user.fleshed.retrieve_by_barcode",);
454 sub user_retrieve_by_barcode {
455 my($self, $client, $user_session, $barcode) = @_;
456 warn "Searching for user with barcode $barcode\n";
457 my $user_obj = $apputils->check_user_session( $user_session );
459 my $session = OpenSRF::AppSession->create("open-ils.storage");
461 # find the card with the given barcode
462 my $creq = $session->request(
463 "open-ils.storage.direct.actor.card.search.barcode",
465 my $card = $creq->gather(1);
467 my $user = flesh_user($card->usr(), $session);
468 $session->disconnect();
475 __PACKAGE__->register_method(
476 method => "get_user_by_id",
477 api_name => "open-ils.actor.user.retrieve",);
480 my ($self, $client, $user_session, $id) = @_;
482 my $user_obj = $apputils->check_user_session( $user_session );
484 return $apputils->simple_scalar_request(
486 "open-ils.storage.direct.actor.user.retrieve",
492 __PACKAGE__->register_method(
493 method => "get_org_types",
494 api_name => "open-ils.actor.org_types.retrieve",);
498 my($self, $client) = @_;
500 return $org_types if $org_types;
502 $apputils->simple_scalar_request(
504 "open-ils.storage.direct.actor.org_unit_type.retrieve.all.atomic" );
509 __PACKAGE__->register_method(
510 method => "get_user_profiles",
511 api_name => "open-ils.actor.user.profiles.retrieve",
515 sub get_user_profiles {
516 return $user_profiles if $user_profiles;
518 return $user_profiles =
519 $apputils->simple_scalar_request(
521 "open-ils.storage.direct.actor.profile.retrieve.all.atomic");
526 __PACKAGE__->register_method(
527 method => "get_user_ident_types",
528 api_name => "open-ils.actor.user.ident_types.retrieve",
531 sub get_user_ident_types {
532 return $ident_types if $ident_types;
533 return $ident_types =
534 $apputils->simple_scalar_request(
536 "open-ils.storage.direct.config.identification_type.retrieve.all.atomic" );
542 __PACKAGE__->register_method(
543 method => "get_org_unit",
544 api_name => "open-ils.actor.org_unit.retrieve",
549 my( $self, $client, $user_session ) = @_;
552 OpenILS::Application::AppUtils->check_user_session( $user_session ); #throws EX on error
554 my $home_ou = OpenILS::Application::AppUtils->simple_scalar_request(
556 "open-ils.storage.direct.actor.org_unit.retrieve",
557 $user_obj->home_ou );
565 __PACKAGE__->register_method(
566 method => "get_org_tree",
567 api_name => "open-ils.actor.org_tree.retrieve",
569 note => "Returns the entire org tree structure",
573 my( $self, $client) = @_;
575 # see if it's in the cache
576 warn "Getting ORG Tree\n";
577 my $tree = $cache_client->get_cache('orgtree');
579 warn "Found orgtree in cache. returning...\n";
583 my $orglist = $apputils->simple_scalar_request(
585 "open-ils.storage.direct.actor.org_unit.retrieve.all.atomic" );
587 $tree = $self->build_org_tree($orglist);
588 $cache_client->put_cache('orgtree', $tree);
594 # turns an org list into an org tree
597 my( $self, $orglist) = @_;
599 return $orglist unless (
600 ref($orglist) and @$orglist > 1 );
603 $a->ou_type <=> $b->ou_type ||
604 $a->name cmp $b->name } @$orglist;
606 for my $org (@list) {
608 next unless ($org and defined($org->parent_ou));
609 my ($parent) = grep { $_->id == $org->parent_ou } @list;
612 $parent->children([]) unless defined($parent->children);
613 push( @{$parent->children}, $org );
621 __PACKAGE__->register_method(
622 method => "get_org_descendants",
623 api_name => "open-ils.actor.org_tree.descendants.retrieve"
626 # depth is optional. org_unit is the id
627 sub get_org_descendants {
628 my( $self, $client, $org_unit, $depth ) = @_;
629 my $orglist = $apputils->simple_scalar_request(
631 "open-ils.storage.actor.org_unit.descendants.atomic",
633 return $self->build_org_tree($orglist);
637 __PACKAGE__->register_method(
638 method => "get_org_ancestors",
639 api_name => "open-ils.actor.org_tree.ancestors.retrieve"
642 # depth is optional. org_unit is the id
643 sub get_org_ancestors {
644 my( $self, $client, $org_unit, $depth ) = @_;
645 my $orglist = $apputils->simple_scalar_request(
647 "open-ils.storage.actor.org_unit.ancestors.atomic",
649 return $self->build_org_tree($orglist);
653 __PACKAGE__->register_method(
654 method => "get_standings",
655 api_name => "open-ils.actor.standings.retrieve"
660 return $user_standings if $user_standings;
661 return $user_standings =
662 $apputils->simple_scalar_request(
664 "open-ils.storage.direct.config.standing.retrieve.all.atomic" );
669 __PACKAGE__->register_method(
670 method => "get_my_org_path",
671 api_name => "open-ils.actor.org_unit.full_path.retrieve"
674 sub get_my_org_path {
675 my( $self, $client, $user_session, $org_id ) = @_;
676 my $user_obj = $apputils->check_user_session($user_session);
677 if(!defined($org_id)) { $org_id = $user_obj->home_ou; }
679 return $apputils->simple_scalar_request(
681 "open-ils.storage.actor.org_unit.full_path.atomic",
686 __PACKAGE__->register_method(
687 method => "patron_adv_search",
688 api_name => "open-ils.actor.patron.search.advanced" );
690 sub patron_adv_search {
691 my( $self, $client, $staff_login, $search_hash ) = @_;
694 warn "patron adv with $staff_login and search " .
695 Dumper($search_hash) . "\n";
697 my $session = OpenSRF::AppSession->create("open-ils.storage");
698 my $req = $session->request(
699 "open-ils.storage.actor.user.crazy_search", $search_hash);
701 my $ans = $req->gather(1);
702 $session->disconnect();
722 some old methods that may be good to keep around for now
725 my( $session, $card ) = @_;
727 warn "Deleting card with barcode " . $card->barcode() . "\n";
728 my $req = $session->request(
729 "open-ils.storage.direct.actor.card.delete",
731 my $status = $req->gather(1);
732 if(!defined($status)) {
733 throw OpenSRF::EX::ERROR
734 ("Unknown error updating card");
740 # deletes the patron and any attached addresses and cards
741 __PACKAGE__->register_method(
742 method => "delete_patron",
743 api_name => "open-ils.actor.patron.delete",
748 my( $self, $client, $patron ) = @_;
749 my $session = $apputils->start_db_session();
754 $patron->clear_mailing_address();
755 $patron->clear_billing_address();
756 $patron->ischanged(1);
758 _update_patron($session, $patron);
759 _delete_address($session,$_) for (@{$patron->addresses()});
760 _delete_card($session,$_) for (@{$patron->cards()});
761 _delete_patron($session,$patron);
762 $apputils->commit_db_session($session);
766 $err = "-*- Failure deleting user: $e";
767 $apputils->rollback_db_session($session);
771 if($err) { throw OpenSRF::EX::ERROR ($err); }
772 warn "Patron Delete complete\n";
777 my( $session, $patron ) = @_;
779 warn "Deleting patron " . $patron->usrname() . "\n";
781 my $req = $session->request(
782 "open-ils.storage.direct.actor.user.delete",
784 my $status = $req->gather(1);
785 if(!defined($status)) {
786 throw OpenSRF::EX::ERROR
787 ("Unknown error updating patron");