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());
81 $session = OpenSRF::AppSession->create("open-ils.storage");
85 # grab the user with the given card
86 my $ureq = $session->request(
87 "open-ils.storage.direct.actor.user.retrieve",
89 my $user = $ureq->gather(1);
92 my $cards_req = $session->request(
93 "open-ils.storage.direct.actor.card.search.usr",
95 $user->cards( $cards_req->gather(1) );
97 my $add_req = $session->request(
98 "open-ils.storage.direct.actor.user_address.search.usr",
100 $user->addresses( $add_req->gather(1) );
102 my $stat_req = $session->request(
103 "open-ils.storage.direct.actor.stat_cat_entry_user_map.search.target_usr",
105 $user->stat_cat_entries($stat_req->gather(1));
107 if($kill) { $session->disconnect(); }
108 $user->clear_passwd();
116 # clone and clear stuff that would break the database
120 my $new_patron = Fieldmapper::actor::user->new();
122 my $fmap = $Fieldmapper::fieldmap;
123 no strict; # shallow clone, may be useful in the fieldmapper
125 (keys %{$fmap->{"Fieldmapper::actor::user"}->{'fields'}}) {
126 $new_patron->$field( $patron->$field() );
131 $new_patron->clear_billing_address();
132 $new_patron->clear_mailing_address();
133 $new_patron->clear_addresses();
134 $new_patron->clear_card();
135 $new_patron->clear_cards();
136 $new_patron->clear_id();
137 $new_patron->clear_isnew();
138 $new_patron->clear_changed();
139 $new_patron->clear_deleted();
140 $new_patron->clear_stat_cat_entries();
150 warn "Creating new patron\n";
153 my $req = $session->request(
154 "open-ils.storage.direct.actor.user.create",$patron);
155 my $id = $req->gather(1);
156 if(!$id) { throw OpenSRF::EX::ERROR ("Unable to create new user"); }
157 warn "Created new patron with id $id\n";
159 # retrieve the patron from the db to collect defaults
160 my $ureq = $session->request(
161 "open-ils.storage.direct.actor.user.retrieve",
163 return $ureq->gather(1);
168 my( $session, $patron) = @_;
170 warn "updating patron " . Dumper($patron) . "\n";
172 my $req = $session->request(
173 "open-ils.storage.direct.actor.user.update",$patron );
174 my $status = $req->gather(1);
175 if(!defined($status)) {
176 throw OpenSRF::EX::ERROR
177 ("Unknown error updating patron");
183 sub _add_update_addresses {
186 my $new_patron = shift;
188 my $current_id; # id of the address before creation
190 for my $address (@{$patron->addresses()}) {
192 $address->usr($new_patron->id());
194 if(ref($address) and $address->isnew()) {
195 warn "Adding new address at street " . $address->street1() . "\n";
197 $current_id = $address->id();
198 $address = _add_address($session,$address);
200 if( $patron->billing_address() and
201 $patron->billing_address() == $current_id ) {
202 $new_patron->billing_address($address->id());
203 $new_patron->ischanged(1);
206 if( $patron->mailing_address() and
207 $patron->mailing_address() == $current_id ) {
208 $new_patron->mailing_address($address->id());
209 $new_patron->ischanged(1);
212 } elsif( ref($address) and $address->ischanged() ) {
213 warn "Updating address at street " . $address->street1();
214 $address->usr($new_patron->id());
215 _update_address($session,$address);
217 } elsif( ref($address) and $address->isdeleted() ) {
218 warn "Deleting address at street " . $address->street1();
220 if( $address->id() == $new_patron->mailing_address() ) {
221 $new_patron->clear_mailing_address();
222 _update_patron($session, $new_patron);
225 if( $address->id() == $new_patron->billing_address() ) {
226 $new_patron->clear_billing_address();
227 _update_patron($session, $new_patron);
230 _delete_address($session,$address);
238 # adds an address to the db and returns the address with new id
240 my($session, $address) = @_;
241 $address->clear_id();
243 # put the address into the database
244 my $req = $session->request(
245 "open-ils.storage.direct.actor.user_address.create",
249 my $id = $req->gather(1);
251 throw OpenSRF::EX::ERROR
252 ("Unable to create new user address");
255 warn "Created address with id $id\n";
257 # update all the necessary id's
263 sub _update_address {
264 my( $session, $address ) = @_;
265 my $req = $session->request(
266 "open-ils.storage.direct.actor.user_address.update",
268 my $status = $req->gather(1);
269 if(!defined($status)) {
270 throw OpenSRF::EX::ERROR
271 ("Unknown error updating address");
278 sub _add_update_cards {
282 my $new_patron = shift;
284 my $virtual_id; #id of the card before creation
285 for my $card (@{$patron->cards()}) {
287 $card->usr($new_patron->id());
289 if(ref($card) and $card->isnew()) {
291 $virtual_id = $card->id();
292 $card = _add_card($session,$card);
294 if($patron->card() == $virtual_id) {
295 $new_patron->card($card->id());
296 $new_patron->ischanged(1);
299 } elsif( ref($card) and $card->ischanged() ) {
300 $card->usr($new_patron->id());
301 _update_card($session, $card);
308 # adds an card to the db and returns the card with new id
310 my( $session, $card ) = @_;
313 warn "Adding card with barcode " . $card->barcode() . "\n";
314 my $req = $session->request(
315 "open-ils.storage.direct.actor.card.create",
318 my $id = $req->gather(1);
320 throw OpenSRF::EX::ERROR
321 ("Unknown error creating card");
325 warn "Created patron card with id $id\n";
331 my( $session, $card ) = @_;
334 my $req = $session->request(
335 "open-ils.storage.direct.actor.card.update",
337 my $status = $req->gather(1);
338 if(!defined($status)) {
339 throw OpenSRF::EX::ERROR
340 ("Unknown error updating card");
348 sub _delete_address {
349 my( $session, $address ) = @_;
351 warn "Deleting address " . $address->street1() . "\n";
353 my $req = $session->request(
354 "open-ils.storage.direct.actor.user_address.delete",
356 my $status = $req->gather(1);
357 if(!defined($status)) {
358 throw OpenSRF::EX::ERROR
359 ("Unknown error updating address");
361 warn "Delete address status is $status\n";
366 sub _add_survey_responses {
367 my ($session, $patron, $new_patron) = @_;
369 warn "updating responses for user " . $new_patron->id . "\n";
371 my $responses = $patron->survey_responses;
372 for my $resp( @$responses ) {
373 $resp->usr($new_patron->id);
376 my $status = $apputils->simple_scalar_request(
378 "open-ils.circ.survey.submit.user_id",
385 sub _create_stat_maps {
387 my($user_session, $patron, $new_patron) = @_;
388 my $maps = $patron->stat_cat_entries();
390 my $session = OpenSRF::AppSession->create("open-ils.circ");
392 for my $map (@$maps) {
394 next unless($map->isnew() || $map->ischanged());
396 my $method = "open-ils.circ.stat_cat.actor.user_map.update";
398 $method = "open-ils.circ.stat_cat.actor.user_map.create";
401 warn "Updating stat entry with method $method and
402 session $user_session and map $map\n";
404 my $req = $session->request($method, $user_session, $map);
405 my $status = $req->gather(1);
410 throw OpenSRF::EX::ERROR
411 ("Error updating stat map with method $method");
415 $session->disconnect();
421 __PACKAGE__->register_method(
422 method => "search_username",
423 api_name => "open-ils.actor.user.search.username",
426 sub search_username {
427 my($self, $client, $username) = @_;
428 my $users = OpenILS::Application::AppUtils->simple_scalar_request(
430 "open-ils.storage.direct.actor.user.search.usrname",
438 __PACKAGE__->register_method(
439 method => "user_retrieve_by_barcode",
440 api_name => "open-ils.actor.user.fleshed.retrieve_by_barcode",
443 sub user_retrieve_by_barcode {
444 my($self, $client, $barcode) = @_;
445 warn "Searching for user with barcode $barcode\n";
447 my $session = OpenSRF::AppSession->create("open-ils.storage");
449 # find the card with the given barcode
450 my $creq = $session->request(
451 "open-ils.storage.direct.actor.card.search.barcode",
453 my $card = $creq->gather(1);
455 my $user = flesh_user($card->usr(), $session);
456 $session->disconnect();
463 __PACKAGE__->register_method(
464 method => "get_user_by_id",
465 api_name => "open-ils.actor.user.retrieve",);
468 my ($self, $client, $user_session, $id) = @_;
470 my $user_obj = $apputils->check_user_session( $user_session );
472 return $apputils->simple_scalar_request(
474 "open-ils.storage.direct.actor.user.retrieve",
480 __PACKAGE__->register_method(
481 method => "get_org_types",
482 api_name => "open-ils.actor.org_types.retrieve",);
486 my($self, $client) = @_;
488 return $org_types if $org_types;
490 $apputils->simple_scalar_request(
492 "open-ils.storage.direct.actor.org_unit_type.retrieve.all.atomic" );
497 __PACKAGE__->register_method(
498 method => "get_user_profiles",
499 api_name => "open-ils.actor.user.profiles.retrieve",
503 sub get_user_profiles {
504 return $user_profiles if $user_profiles;
506 return $user_profiles =
507 $apputils->simple_scalar_request(
509 "open-ils.storage.direct.actor.profile.retrieve.all.atomic");
514 __PACKAGE__->register_method(
515 method => "get_user_ident_types",
516 api_name => "open-ils.actor.user.ident_types.retrieve",
519 sub get_user_ident_types {
520 return $ident_types if $ident_types;
521 return $ident_types =
522 $apputils->simple_scalar_request(
524 "open-ils.storage.direct.config.identification_type.retrieve.all.atomic" );
530 __PACKAGE__->register_method(
531 method => "get_org_unit",
532 api_name => "open-ils.actor.org_unit.retrieve",
537 my( $self, $client, $user_session ) = @_;
540 OpenILS::Application::AppUtils->check_user_session( $user_session ); #throws EX on error
542 my $home_ou = OpenILS::Application::AppUtils->simple_scalar_request(
544 "open-ils.storage.direct.actor.org_unit.retrieve",
545 $user_obj->home_ou );
553 __PACKAGE__->register_method(
554 method => "get_org_tree",
555 api_name => "open-ils.actor.org_tree.retrieve",
557 note => "Returns the entire org tree structure",
561 my( $self, $client) = @_;
563 # see if it's in the cache
564 warn "Getting ORG Tree\n";
565 my $tree = $cache_client->get_cache('orgtree');
567 warn "Found orgtree in cache. returning...\n";
571 my $orglist = $apputils->simple_scalar_request(
573 "open-ils.storage.direct.actor.org_unit.retrieve.all.atomic" );
575 $tree = $self->build_org_tree($orglist);
576 $cache_client->put_cache('orgtree', $tree);
582 # turns an org list into an org tree
585 my( $self, $orglist) = @_;
587 return $orglist unless (
588 ref($orglist) and @$orglist > 1 );
591 $a->ou_type <=> $b->ou_type ||
592 $a->name cmp $b->name } @$orglist;
594 for my $org (@list) {
596 next unless ($org and defined($org->parent_ou));
597 my ($parent) = grep { $_->id == $org->parent_ou } @list;
600 $parent->children([]) unless defined($parent->children);
601 push( @{$parent->children}, $org );
609 __PACKAGE__->register_method(
610 method => "get_org_descendants",
611 api_name => "open-ils.actor.org_tree.descendants.retrieve"
614 # depth is optional. org_unit is the id
615 sub get_org_descendants {
616 my( $self, $client, $org_unit, $depth ) = @_;
617 my $orglist = $apputils->simple_scalar_request(
619 "open-ils.storage.actor.org_unit.descendants.atomic",
621 return $self->build_org_tree($orglist);
625 __PACKAGE__->register_method(
626 method => "get_org_ancestors",
627 api_name => "open-ils.actor.org_tree.ancestors.retrieve"
630 # depth is optional. org_unit is the id
631 sub get_org_ancestors {
632 my( $self, $client, $org_unit, $depth ) = @_;
633 my $orglist = $apputils->simple_scalar_request(
635 "open-ils.storage.actor.org_unit.ancestors.atomic",
637 return $self->build_org_tree($orglist);
641 __PACKAGE__->register_method(
642 method => "get_standings",
643 api_name => "open-ils.actor.standings.retrieve"
648 return $user_standings if $user_standings;
649 return $user_standings =
650 $apputils->simple_scalar_request(
652 "open-ils.storage.direct.config.standing.retrieve.all.atomic" );
657 __PACKAGE__->register_method(
658 method => "get_my_org_path",
659 api_name => "open-ils.actor.org_unit.full_path.retrieve"
662 sub get_my_org_path {
663 my( $self, $client, $user_session, $org_id ) = @_;
664 my $user_obj = $apputils->check_user_session($user_session);
665 if(!defined($org_id)) { $org_id = $user_obj->home_ou; }
667 return $apputils->simple_scalar_request(
669 "open-ils.storage.actor.org_unit.full_path.atomic",
674 __PACKAGE__->register_method(
675 method => "patron_adv_search",
676 api_name => "open-ils.actor.patron.search.advanced" );
678 sub patron_adv_search {
679 my( $self, $client, $staff_login, $search_hash ) = @_;
682 warn "patron adv with $staff_login and search " .
683 Dumper($search_hash) . "\n";
685 my $session = OpenSRF::AppSession->create("open-ils.storage");
686 my $req = $session->request(
687 "open-ils.storage.actor.user.crazy_search", $search_hash);
689 my $ans = $req->gather(1);
690 $session->disconnect();
710 some old methods that may be good to keep around for now
713 my( $session, $card ) = @_;
715 warn "Deleting card with barcode " . $card->barcode() . "\n";
716 my $req = $session->request(
717 "open-ils.storage.direct.actor.card.delete",
719 my $status = $req->gather(1);
720 if(!defined($status)) {
721 throw OpenSRF::EX::ERROR
722 ("Unknown error updating card");
728 # deletes the patron and any attached addresses and cards
729 __PACKAGE__->register_method(
730 method => "delete_patron",
731 api_name => "open-ils.actor.patron.delete",
736 my( $self, $client, $patron ) = @_;
737 my $session = $apputils->start_db_session();
742 $patron->clear_mailing_address();
743 $patron->clear_billing_address();
744 $patron->ischanged(1);
746 _update_patron($session, $patron);
747 _delete_address($session,$_) for (@{$patron->addresses()});
748 _delete_card($session,$_) for (@{$patron->cards()});
749 _delete_patron($session,$patron);
750 $apputils->commit_db_session($session);
754 $err = "-*- Failure deleting user: $e";
755 $apputils->rollback_db_session($session);
759 if($err) { throw OpenSRF::EX::ERROR ($err); }
760 warn "Patron Delete complete\n";
765 my( $session, $patron ) = @_;
767 warn "Deleting patron " . $patron->usrname() . "\n";
769 my $req = $session->request(
770 "open-ils.storage.direct.actor.user.delete",
772 my $status = $req->gather(1);
773 if(!defined($status)) {
774 throw OpenSRF::EX::ERROR
775 ("Unknown error updating patron");