1 package OpenILS::Application::Actor;
2 use base qw/OpenSRF::Application/;
3 use strict; use warnings;
7 use Digest::MD5 qw(md5_hex);
9 use OpenSRF::EX qw(:try);
13 use OpenILS::Application::AppUtils;
14 use OpenILS::Utils::Fieldmapper;
15 use OpenILS::Application::Search::Actor;
16 use OpenILS::Utils::ModsParser;
17 use OpenSRF::Utils::Logger;
18 my $logger = "OpenSRF::Utils::Logger";
20 use OpenSRF::Utils::Cache;
23 use OpenILS::Application::Actor::Container;
25 OpenILS::Application::Actor::Container->initialize();
28 my $apputils = "OpenILS::Application::AppUtils";
30 sub _d { warn "Patron:\n" . Dumper(shift()); }
35 my $set_user_settings;
38 __PACKAGE__->register_method(
39 method => "set_user_settings",
40 api_name => "open-ils.actor.patron.settings.update",
42 sub set_user_settings {
43 my( $self, $client, $user_session, $uid, $settings ) = @_;
45 $logger->debug("Setting user settings: $user_session, $uid, " . Dumper($settings));
47 my( $staff, $user, $evt ) =
48 $apputils->checkses_requestor( $user_session, $uid, 'UPDATE_USER' );
53 [{ usr => $user->id, name => $_}, {value => $$settings{$_}}] } keys %$settings;
55 $logger->activity("User " . $staff->id . " updating user $uid settings with: " . Dumper($params));
57 return $apputils->simplereq(
59 'open-ils.storage.direct.actor.user_setting.batch.merge', $params );
65 __PACKAGE__->register_method(
66 method => "set_ou_settings",
67 api_name => "open-ils.actor.org_unit.settings.update",
70 my( $self, $client, $user_session, $ouid, $settings ) = @_;
72 my( $staff, $evt ) = $apputils->checkses( $user_session );
74 $evt = $apputils->check_perms( $staff->id, $ouid, 'UPDATE_ORG_UNIT' );
79 map { [{ org_unit => $ouid, name => $_}, {value => $$settings{$_}}] } keys %$settings;
81 $logger->activity("Updating org unit [$ouid] settings with: " . Dumper($params));
83 return $apputils->simplereq(
85 'open-ils.storage.direct.actor.org_unit_setting.merge', @$params );
89 my $fetch_user_settings;
90 my $fetch_ou_settings;
92 __PACKAGE__->register_method(
93 method => "user_settings",
94 api_name => "open-ils.actor.patron.settings.retrieve",
97 my( $self, $client, $user_session, $uid ) = @_;
99 my( $staff, $user, $evt ) =
100 $apputils->checkses_requestor( $user_session, $uid, 'VIEW_USER' );
103 $logger->debug("User " . $staff->id . " fetching user $uid\n");
104 my $s = $apputils->simplereq(
106 'open-ils.storage.direct.actor.user_setting.search.usr.atomic',$uid );
108 return { map { ($_->name,$_->value) } @$s };
113 __PACKAGE__->register_method(
114 method => "ou_settings",
115 api_name => "open-ils.actor.org_unit.settings.retrieve",
118 my( $self, $client, $ouid ) = @_;
120 my $s = $apputils->simplereq(
122 'open-ils.storage.direct.actor.org_unit_setting.search.org_unit.atomic', $ouid);
124 return { map { ($_->name,$_->value) } @$s };
129 __PACKAGE__->register_method(
130 method => "update_patron",
131 api_name => "open-ils.actor.patron.update",);
134 my( $self, $client, $user_session, $patron ) = @_;
136 my $session = $apputils->start_db_session();
139 warn $user_session . " " . $patron . "\n";
143 OpenILS::Application::AppUtils->check_user_session(
144 $user_session ); #throws EX on error
146 # XXX does this user have permission to add/create users. Granularity?
147 # $new_patron is the patron in progress. $patron is the original patron
148 # passed in with the method. new_patron will change as the components
149 # of patron are added/updated.
153 if(ref($patron->card)) { $patron->card( $patron->card->id ); }
154 if(ref($patron->billing_address)) { $patron->billing_address( $patron->billing_address->id ); }
155 if(ref($patron->mailing_address)) { $patron->mailing_address( $patron->mailing_address->id ); }
157 # create/update the patron first so we can use his id
158 if($patron->isnew()) {
160 $new_patron = _add_patron($session, _clone_patron($patron), $user_obj);
162 if(UNIVERSAL::isa($new_patron, "OpenILS::EX") ||
163 UNIVERSAL::isa($new_patron, "OpenILS::Perm")) {
164 $client->respond_complete($new_patron->ex);
168 } else { $new_patron = $patron; }
170 $new_patron = _add_update_addresses($session, $patron, $new_patron, $user_obj);
172 if(UNIVERSAL::isa($new_patron, "OpenILS::EX") ||
173 UNIVERSAL::isa($new_patron, "OpenILS::Perm")) {
174 $client->respond_complete($new_patron->ex);
178 $new_patron = _add_update_cards($session, $patron, $new_patron, $user_obj);
180 if(UNIVERSAL::isa($new_patron, "OpenILS::EX") ||
181 UNIVERSAL::isa($new_patron, "OpenILS::Perm")) {
182 $client->respond_complete($new_patron->ex);
186 $new_patron = _add_survey_responses($session, $patron, $new_patron, $user_obj);
187 if(UNIVERSAL::isa($new_patron, "OpenILS::EX") ||
188 UNIVERSAL::isa($new_patron, "OpenILS::Perm")) {
189 $client->respond_complete($new_patron->ex);
194 # re-update the patron if anything has happened to him during this process
195 if($new_patron->ischanged()) {
196 $new_patron = _update_patron($session, $new_patron, $user_obj);
198 if(UNIVERSAL::isa($new_patron, "OpenILS::EX") ||
199 UNIVERSAL::isa($new_patron, "OpenILS::Perm")) {
200 $client->respond_complete($new_patron->ex);
205 $apputils->commit_db_session($session);
207 $session = OpenSRF::AppSession->create("open-ils.storage");
208 $new_patron = _create_stat_maps($session, $user_session, $patron, $new_patron, $user_obj);
209 if(UNIVERSAL::isa($new_patron, "OpenILS::EX") ||
210 UNIVERSAL::isa($new_patron, "OpenILS::Perm")) {
211 $client->respond_complete($new_patron->ex);
216 warn "Patron Update/Create complete\n";
217 return flesh_user($new_patron->id());
223 __PACKAGE__->register_method(
224 method => "user_retrieve_fleshed_by_id",
225 api_name => "open-ils.actor.user.fleshed.retrieve",);
227 sub user_retrieve_fleshed_by_id {
228 my( $self, $client, $user_session, $user_id ) = @_;
229 my $user_obj = $apputils->check_user_session( $user_session );
231 if(!defined($user_id)) { $user_id = $user_obj->id; }
233 if( $user_obj->id ne $user_id ) {
234 if($apputils->check_user_perms($user_obj->id, $user_obj->home_ou, "VIEW_USER")) {
235 return OpenILS::Perm->new("VIEW_USER");
239 return flesh_user($user_id);
250 $session = OpenSRF::AppSession->create("open-ils.storage");
254 # grab the user with the given id
255 my $ureq = $session->request(
256 "open-ils.storage.direct.actor.user.retrieve", $id);
257 my $user = $ureq->gather(1);
259 if(!$user) { return undef; }
262 my $cards_req = $session->request(
263 "open-ils.storage.direct.actor.card.search.usr.atomic",
265 $user->cards( $cards_req->gather(1) );
267 for my $c(@{$user->cards}) {
268 if($c->id == $user->card || $c->id eq $user->card ) {
269 warn "Setting my card to " . $c->id . "\n";
274 my $add_req = $session->request(
275 "open-ils.storage.direct.actor.user_address.search.usr.atomic",
277 $user->addresses( $add_req->gather(1) );
279 for my $c(@{$user->addresses}) {
280 if($c->id == $user->billing_address || $c->id eq $user->billing_address ) {
281 warn "Setting my address to " . $c->id . "\n";
282 $user->billing_address($c);
286 for my $c(@{$user->addresses}) {
287 if($c->id == $user->mailing_address || $c->id eq $user->mailing_address ) {
288 warn "Setting my address to " . $c->id . "\n";
289 $user->mailing_address($c);
293 my $stat_req = $session->request(
294 "open-ils.storage.direct.actor.stat_cat_entry_user_map.search.target_usr.atomic",
296 $user->stat_cat_entries($stat_req->gather(1));
298 if($kill) { $session->disconnect(); }
299 $user->clear_passwd();
307 # clone and clear stuff that would break the database
311 my $new_patron = $patron->clone;
313 # Using the Fieldmapper clone method
314 #my $new_patron = Fieldmapper::actor::user->new();
316 #my $fmap = $Fieldmapper::fieldmap;
317 #no strict; # shallow clone, may be useful in the fieldmapper
319 # (keys %{$fmap->{"Fieldmapper::actor::user"}->{'fields'}}) {
320 # $new_patron->$field( $patron->$field() );
325 $new_patron->clear_billing_address();
326 $new_patron->clear_mailing_address();
327 $new_patron->clear_addresses();
328 $new_patron->clear_card();
329 $new_patron->clear_cards();
330 $new_patron->clear_id();
331 $new_patron->clear_isnew();
332 $new_patron->clear_ischanged();
333 $new_patron->clear_isdeleted();
334 $new_patron->clear_stat_cat_entries();
343 my $user_obj = shift;
346 if($apputils->check_user_perms(
347 $user_obj->id, $user_obj->home_ou, "CREATE_USER")) {
348 return OpenILS::Perm->new("CREATE_USER");
351 warn "Creating new patron\n";
354 my $req = $session->request(
355 "open-ils.storage.direct.actor.user.create",$patron);
356 my $id = $req->gather(1);
358 return OpenILS::EX->new("DUPLICATE_USER_USERNAME");
361 # retrieve the patron from the db to collect defaults
362 my $ureq = $session->request(
363 "open-ils.storage.direct.actor.user.retrieve",
366 warn "Created new patron with id $id\n";
368 return $ureq->gather(1);
373 my( $session, $patron, $user_obj) = @_;
376 if($patron->id ne $user_obj->id) {
377 if($apputils->check_user_perms(
378 $user_obj->id, $user_obj->home_ou, "UPDATE_USER")) {
379 return OpenILS::Perm->new("UPDATE_USER");
383 warn "updating patron " . Dumper($patron) . "\n";
385 my $req = $session->request(
386 "open-ils.storage.direct.actor.user.update",$patron );
387 my $status = $req->gather(1);
388 if(!defined($status)) {
389 throw OpenSRF::EX::ERROR
390 ("Unknown error updating patron");
396 sub _add_update_addresses {
399 my $new_patron = shift;
401 my $current_id; # id of the address before creation
403 for my $address (@{$patron->addresses()}) {
405 $address->usr($new_patron->id());
407 if(ref($address) and $address->isnew()) {
408 warn "Adding new address at street " . $address->street1() . "\n";
410 $current_id = $address->id();
411 $address = _add_address($session,$address);
413 if( $patron->billing_address() and
414 $patron->billing_address() == $current_id ) {
415 $new_patron->billing_address($address->id());
416 $new_patron->ischanged(1);
419 if( $patron->mailing_address() and
420 $patron->mailing_address() == $current_id ) {
421 $new_patron->mailing_address($address->id());
422 $new_patron->ischanged(1);
425 } elsif( ref($address) and $address->ischanged() ) {
426 warn "Updating address at street " . $address->street1();
427 $address->usr($new_patron->id());
428 _update_address($session,$address);
430 } elsif( ref($address) and $address->isdeleted() ) {
431 warn "Deleting address at street " . $address->street1();
433 if( $address->id() == $new_patron->mailing_address() ) {
434 $new_patron->clear_mailing_address();
435 _update_patron($session, $new_patron);
438 if( $address->id() == $new_patron->billing_address() ) {
439 $new_patron->clear_billing_address();
440 _update_patron($session, $new_patron);
443 _delete_address($session,$address);
451 # adds an address to the db and returns the address with new id
453 my($session, $address) = @_;
454 $address->clear_id();
457 warn "Adding Address:\n";
458 warn Dumper($address);
460 # put the address into the database
461 my $req = $session->request(
462 "open-ils.storage.direct.actor.user_address.create",
466 my $id = $req->gather(1);
468 throw OpenSRF::EX::ERROR
469 ("Unable to create new user address");
472 warn "Created address with id $id\n";
474 # update all the necessary id's
480 sub _update_address {
481 my( $session, $address ) = @_;
482 my $req = $session->request(
483 "open-ils.storage.direct.actor.user_address.update",
485 my $status = $req->gather(1);
486 if(!defined($status)) {
487 throw OpenSRF::EX::ERROR
488 ("Unknown error updating address");
495 sub _add_update_cards {
499 my $new_patron = shift;
501 my $virtual_id; #id of the card before creation
502 for my $card (@{$patron->cards()}) {
504 $card->usr($new_patron->id());
506 if(ref($card) and $card->isnew()) {
508 $virtual_id = $card->id();
509 $card = _add_card($session,$card);
510 if(UNIVERSAL::isa($card,"OpenILS::EX")) {
514 #if(ref($patron->card)) { $patron->card($patron->card->id); }
515 if($patron->card() == $virtual_id) {
516 $new_patron->card($card->id());
517 $new_patron->ischanged(1);
520 } elsif( ref($card) and $card->ischanged() ) {
521 $card->usr($new_patron->id());
522 _update_card($session, $card);
529 # adds an card to the db and returns the card with new id
531 my( $session, $card ) = @_;
534 warn "Adding card with barcode " . $card->barcode() . "\n";
535 my $req = $session->request(
536 "open-ils.storage.direct.actor.card.create",
539 my $id = $req->gather(1);
541 return OpenILS::EX->new("DUPLICATE_INVALID_USER_BARCODE");
545 warn "Created patron card with id $id\n";
551 my( $session, $card ) = @_;
554 my $req = $session->request(
555 "open-ils.storage.direct.actor.card.update",
557 my $status = $req->gather(1);
558 if(!defined($status)) {
559 throw OpenSRF::EX::ERROR
560 ("Unknown error updating card");
568 sub _delete_address {
569 my( $session, $address ) = @_;
571 warn "Deleting address " . $address->street1() . "\n";
573 my $req = $session->request(
574 "open-ils.storage.direct.actor.user_address.delete",
576 my $status = $req->gather(1);
577 if(!defined($status)) {
578 throw OpenSRF::EX::ERROR
579 ("Unknown error updating address");
581 warn "Delete address status is $status\n";
586 sub _add_survey_responses {
587 my ($session, $patron, $new_patron) = @_;
589 warn "updating responses for user " . $new_patron->id . "\n";
591 my $responses = $patron->survey_responses;
595 for my $resp( @$responses ) {
596 $resp->usr($new_patron->id);
599 my $status = $apputils->simple_scalar_request(
601 "open-ils.circ.survey.submit.user_id",
610 sub _create_stat_maps {
612 my($session, $user_session, $patron, $new_patron) = @_;
614 my $maps = $patron->stat_cat_entries();
616 for my $map (@$maps) {
618 next unless($map->isnew() || $map->ischanged());
620 my $method = "open-ils.storage.direct.actor.stat_cat_entry_user_map.update";
622 $method = "open-ils.storage.direct.actor.stat_cat_entry_user_map.create";
626 $map->target_usr($new_patron->id);
628 warn "Updating stat entry with method $method and session $user_session and map $map\n";
630 my $req = $session->request($method, $map);
631 my $status = $req->gather(1);
636 throw OpenSRF::EX::ERROR
637 ("Error updating stat map with method $method");
647 __PACKAGE__->register_method(
648 method => "search_username",
649 api_name => "open-ils.actor.user.search.username",
652 sub search_username {
653 my($self, $client, $username) = @_;
654 my $users = OpenILS::Application::AppUtils->simple_scalar_request(
656 "open-ils.storage.direct.actor.user.search.usrname.atomic",
664 __PACKAGE__->register_method(
665 method => "user_retrieve_by_barcode",
666 api_name => "open-ils.actor.user.fleshed.retrieve_by_barcode",);
668 sub user_retrieve_by_barcode {
669 my($self, $client, $user_session, $barcode) = @_;
671 $logger->debug("Searching for user with barcode $barcode");
672 #my $user_obj = $apputils->check_user_session( $user_session );
673 my ($user_obj, $evt) = $apputils->check_ses($user_session);
676 my $session = OpenSRF::AppSession->create("open-ils.storage");
678 # find the card with the given barcode
679 my $creq = $session->request(
680 "open-ils.storage.direct.actor.card.search.barcode.atomic",
682 my $card = $creq->gather(1);
684 if(!$card || !$card->[0]) {
685 $session->disconnect();
686 return OpenILS::Event->new( 'USER_NOT_FOUND' );
690 my $user = flesh_user($card->usr(), $session);
691 $session->disconnect();
692 if(!$user) { return OpenILS::Event->new( 'USER_NOT_FOUND' ); }
699 __PACKAGE__->register_method(
700 method => "get_user_by_id",
701 api_name => "open-ils.actor.user.retrieve",);
704 my ($self, $client, $user_session, $id) = @_;
706 my $user_obj = $apputils->check_user_session( $user_session );
708 return $apputils->simple_scalar_request(
710 "open-ils.storage.direct.actor.user.retrieve",
716 __PACKAGE__->register_method(
717 method => "get_org_types",
718 api_name => "open-ils.actor.org_types.retrieve",);
722 my($self, $client) = @_;
724 return $org_types if $org_types;
726 $apputils->simple_scalar_request(
728 "open-ils.storage.direct.actor.org_unit_type.retrieve.all.atomic" );
733 __PACKAGE__->register_method(
734 method => "get_user_profiles",
735 api_name => "open-ils.actor.user.profiles.retrieve",
739 sub get_user_profiles {
740 return $user_profiles if $user_profiles;
742 return $user_profiles =
743 $apputils->simple_scalar_request(
745 "open-ils.storage.direct.actor.profile.retrieve.all.atomic");
750 __PACKAGE__->register_method(
751 method => "get_user_ident_types",
752 api_name => "open-ils.actor.user.ident_types.retrieve",
755 sub get_user_ident_types {
756 return $ident_types if $ident_types;
757 return $ident_types =
758 $apputils->simple_scalar_request(
760 "open-ils.storage.direct.config.identification_type.retrieve.all.atomic" );
766 __PACKAGE__->register_method(
767 method => "get_org_unit",
768 api_name => "open-ils.actor.org_unit.retrieve",
773 my( $self, $client, $user_session, $org_id ) = @_;
775 if(defined($user_session) && !defined($org_id)) {
777 OpenILS::Application::AppUtils->check_user_session( $user_session ); #throws EX on error
778 if(!defined($org_id)) {
779 $org_id = $user_obj->home_ou;
784 my $home_ou = OpenILS::Application::AppUtils->simple_scalar_request(
786 "open-ils.storage.direct.actor.org_unit.retrieve",
795 __PACKAGE__->register_method(
796 method => "get_org_tree",
797 api_name => "open-ils.actor.org_tree.retrieve",
799 note => "Returns the entire org tree structure",
803 my( $self, $client) = @_;
806 $cache_client = OpenSRF::Utils::Cache->new("global", 0);
808 # see if it's in the cache
809 warn "Getting ORG Tree\n";
810 my $tree = $cache_client->get_cache('orgtree');
812 warn "Found orgtree in cache. returning...\n";
816 my $orglist = $apputils->simple_scalar_request(
818 "open-ils.storage.direct.actor.org_unit.retrieve.all.atomic" );
821 warn "found org list\n";
824 $tree = $self->build_org_tree($orglist);
825 $cache_client->put_cache('orgtree', $tree);
831 # turns an org list into an org tree
834 my( $self, $orglist) = @_;
836 return $orglist unless (
837 ref($orglist) and @$orglist > 1 );
840 $a->ou_type <=> $b->ou_type ||
841 $a->name cmp $b->name } @$orglist;
843 for my $org (@list) {
845 next unless ($org and defined($org->parent_ou));
846 my ($parent) = grep { $_->id == $org->parent_ou } @list;
849 $parent->children([]) unless defined($parent->children);
850 push( @{$parent->children}, $org );
858 __PACKAGE__->register_method(
859 method => "get_org_descendants",
860 api_name => "open-ils.actor.org_tree.descendants.retrieve"
863 # depth is optional. org_unit is the id
864 sub get_org_descendants {
865 my( $self, $client, $org_unit, $depth ) = @_;
866 my $orglist = $apputils->simple_scalar_request(
868 "open-ils.storage.actor.org_unit.descendants.atomic",
870 return $self->build_org_tree($orglist);
874 __PACKAGE__->register_method(
875 method => "get_org_ancestors",
876 api_name => "open-ils.actor.org_tree.ancestors.retrieve"
879 # depth is optional. org_unit is the id
880 sub get_org_ancestors {
881 my( $self, $client, $org_unit, $depth ) = @_;
882 my $orglist = $apputils->simple_scalar_request(
884 "open-ils.storage.actor.org_unit.ancestors.atomic",
886 return $self->build_org_tree($orglist);
890 __PACKAGE__->register_method(
891 method => "get_standings",
892 api_name => "open-ils.actor.standings.retrieve"
897 return $user_standings if $user_standings;
898 return $user_standings =
899 $apputils->simple_scalar_request(
901 "open-ils.storage.direct.config.standing.retrieve.all.atomic" );
906 __PACKAGE__->register_method(
907 method => "get_my_org_path",
908 api_name => "open-ils.actor.org_unit.full_path.retrieve"
911 sub get_my_org_path {
912 my( $self, $client, $user_session, $org_id ) = @_;
913 my $user_obj = $apputils->check_user_session($user_session);
914 if(!defined($org_id)) { $org_id = $user_obj->home_ou; }
916 return $apputils->simple_scalar_request(
918 "open-ils.storage.actor.org_unit.full_path.atomic",
923 __PACKAGE__->register_method(
924 method => "patron_adv_search",
925 api_name => "open-ils.actor.patron.search.advanced" );
927 sub patron_adv_search {
928 my( $self, $client, $staff_login, $search_hash ) = @_;
931 warn "patron adv with $staff_login and search " .
932 Dumper($search_hash) . "\n";
934 my $session = OpenSRF::AppSession->create("open-ils.storage");
935 my $req = $session->request(
936 "open-ils.storage.actor.user.crazy_search", $search_hash);
938 my $ans = $req->gather(1);
940 my %hash = map { ($_ =>1) } @$ans;
941 $ans = [ keys %hash ];
943 warn "Returning @$ans\n";
945 $session->disconnect();
952 sub _verify_password {
953 my($user_session, $password) = @_;
954 my $user_obj = $apputils->check_user_session($user_session);
956 #grab the user with password
957 $user_obj = $apputils->simple_scalar_request(
959 "open-ils.storage.direct.actor.user.retrieve",
962 if($user_obj->passwd eq $password) {
970 __PACKAGE__->register_method(
971 method => "update_password",
972 api_name => "open-ils.actor.user.password.update");
974 __PACKAGE__->register_method(
975 method => "update_password",
976 api_name => "open-ils.actor.user.username.update");
978 __PACKAGE__->register_method(
979 method => "update_password",
980 api_name => "open-ils.actor.user.email.update");
982 sub update_password {
983 my( $self, $client, $user_session, $new_value, $current_password ) = @_;
985 warn "Updating user with method " .$self->api_name . "\n";
986 my $user_obj = $apputils->check_user_session($user_session);
988 if($self->api_name =~ /password/) {
990 #make sure they know the current password
991 if(!_verify_password($user_session, md5_hex($current_password))) {
992 return OpenILS::EX->new("USER_WRONG_PASSWORD")->ex;
995 $user_obj->passwd($new_value);
997 elsif($self->api_name =~ /username/) {
998 my $users = search_username(undef, undef, $new_value);
999 if( $users and $users->[0] ) {
1000 return OpenILS::Event->new('USERNAME_EXISTS');
1002 $user_obj->usrname($new_value);
1005 elsif($self->api_name =~ /email/) {
1006 warn "Updating email to $new_value\n";
1007 $user_obj->email($new_value);
1010 my $session = $apputils->start_db_session();
1011 $user_obj = _update_patron($session, $user_obj, $user_obj);
1012 $apputils->commit_db_session($session);
1014 if($user_obj) { return 1; }
1019 __PACKAGE__->register_method(
1020 method => "check_user_perms",
1021 api_name => "open-ils.actor.user.perm.check",
1022 notes => <<" NOTES");
1023 Takes a login session, user id, an org id, and an array of perm type strings. For each
1024 perm type, if the user does *not* have the given permission it is added
1025 to a list which is returned from the method. If all permissions
1026 are allowed, an empty list is returned
1027 if the logged in user does not match 'user_id', then the logged in user must
1028 have VIEW_PERMISSION priveleges.
1031 sub check_user_perms {
1032 my( $self, $client, $login_session, $user_id, $org_id, $perm_types ) = @_;
1034 my( $staff, $evt ) = $apputils->checkses($login_session);
1035 return $evt if $evt;
1037 if($staff->id ne $user_id) {
1038 if( my $evt = $apputils->check_perms(
1039 $staff->id, $org_id, 'VIEW_PERMISSION') ) {
1045 for my $perm (@$perm_types) {
1046 if($apputils->check_user_perms($user_id, $org_id, $perm)) {
1047 push @not_allowed, $perm;
1051 return \@not_allowed
1056 __PACKAGE__->register_method(
1057 method => "user_fines_summary",
1058 api_name => "open-ils.actor.user.fines.summary",
1059 notes => <<" NOTES");
1060 Returns a short summary of the users total open fines, excluding voided fines
1061 Params are login_session, user_id
1062 Returns a 'mous' object.
1065 sub user_fines_summary {
1066 my( $self, $client, $login_session, $user_id ) = @_;
1068 my $user_obj = $apputils->check_user_session($login_session);
1069 if($user_obj->id ne $user_id) {
1070 if($apputils->check_user_perms($user_obj->id, $user_obj->home_ou, "VIEW_USER_FINES_SUMMARY")) {
1071 return OpenILS::Perm->new("VIEW_USER_FINES_SUMMARY");
1075 return $apputils->simple_scalar_request(
1077 "open-ils.storage.direct.money.open_user_summary.search.usr",
1085 __PACKAGE__->register_method(
1086 method => "user_transactions",
1087 api_name => "open-ils.actor.user.transactions",
1088 notes => <<" NOTES");
1089 Returns a list of open user transactions (mbts objects);
1090 Params are login_session, user_id
1091 Optional third parameter is the transactions type. defaults to all
1094 __PACKAGE__->register_method(
1095 method => "user_transactions",
1096 api_name => "open-ils.actor.user.transactions.have_charge",
1097 notes => <<" NOTES");
1098 Returns a list of all open user transactions (mbts objects) that have an initial charge
1099 Params are login_session, user_id
1100 Optional third parameter is the transactions type. defaults to all
1103 __PACKAGE__->register_method(
1104 method => "user_transactions",
1105 api_name => "open-ils.actor.user.transactions.have_balance",
1106 notes => <<" NOTES");
1107 Returns a list of all open user transactions (mbts objects) that have a balance
1108 Params are login_session, user_id
1109 Optional third parameter is the transactions type. defaults to all
1112 __PACKAGE__->register_method(
1113 method => "user_transactions",
1114 api_name => "open-ils.actor.user.transactions.fleshed",
1115 notes => <<" NOTES");
1116 Returns an object/hash of transaction, circ, title where transaction = an open
1117 user transactions (mbts objects), circ is the attached circluation, and title
1118 is the title the circ points to
1119 Params are login_session, user_id
1120 Optional third parameter is the transactions type. defaults to all
1123 __PACKAGE__->register_method(
1124 method => "user_transactions",
1125 api_name => "open-ils.actor.user.transactions.have_charge.fleshed",
1126 notes => <<" NOTES");
1127 Returns an object/hash of transaction, circ, title where transaction = an open
1128 user transactions that has an initial charge (mbts objects), circ is the
1129 attached circluation, and title is the title the circ points to
1130 Params are login_session, user_id
1131 Optional third parameter is the transactions type. defaults to all
1134 __PACKAGE__->register_method(
1135 method => "user_transactions",
1136 api_name => "open-ils.actor.user.transactions.have_balance.fleshed",
1137 notes => <<" NOTES");
1138 Returns an object/hash of transaction, circ, title where transaction = an open
1139 user transaction that has a balance (mbts objects), circ is the attached
1140 circluation, and title is the title the circ points to
1141 Params are login_session, user_id
1142 Optional third parameter is the transaction type. defaults to all
1147 sub user_transactions {
1148 my( $self, $client, $login_session, $user_id, $type ) = @_;
1150 my( $user_obj, $target, $evt ) = $apputils->checkses_requestor(
1151 $login_session, $user_id, 'VIEW_USER_TRANSACTIONS' );
1152 return $evt if $evt;
1154 my $api = $self->api_name();
1158 if(defined($type)) { @xact = (xact_type => $type);
1160 } else { @xact = (); }
1162 if($api =~ /have_charge/) {
1164 $trans = $apputils->simple_scalar_request(
1166 "open-ils.storage.direct.money.open_billable_transaction_summary.search_where.atomic",
1167 { usr => $user_id, total_owed => { ">" => 0 }, @xact });
1169 } elsif($api =~ /have_balance/) {
1171 $trans = $apputils->simple_scalar_request(
1173 "open-ils.storage.direct.money.open_billable_transaction_summary.search_where.atomic",
1174 { usr => $user_id, balance_owed => { ">" => 0 }, @xact });
1178 $trans = $apputils->simple_scalar_request(
1180 "open-ils.storage.direct.money.open_billable_transaction_summary.search_where.atomic",
1181 { usr => $user_id, @xact });
1184 if($api !~ /fleshed/) { return $trans; }
1189 for my $t (@$trans) {
1193 my $circ = $apputils->simple_scalar_request(
1195 "open-ils.storage.direct.action.circulation.retrieve",
1200 my $title = $apputils->simple_scalar_request(
1202 "open-ils.storage.fleshed.biblio.record_entry.retrieve_by_copy",
1203 $circ->target_copy );
1207 my $u = OpenILS::Utils::ModsParser->new();
1208 $u->start_mods_batch($title->marc());
1209 my $mods = $u->finish_mods_batch();
1211 push @resp, {transaction => $t, circ => $circ, record => $mods };
1221 __PACKAGE__->register_method(
1222 method => "retrieve_groups",
1223 api_name => "open-ils.actor.groups.retrieve",
1224 notes => <<" NOTES");
1225 Returns a list of user groupss
1227 sub retrieve_groups {
1228 my( $self, $client ) = @_;
1229 return $apputils->simple_scalar_request(
1231 "open-ils.storage.direct.permission.grp_tree.retrieve.all.atomic");
1234 __PACKAGE__->register_method(
1235 method => "retrieve_groups_tree",
1236 api_name => "open-ils.actor.groups.tree.retrieve",
1237 notes => <<" NOTES");
1238 Returns a list of user groups
1240 sub retrieve_groups_tree {
1241 my( $self, $client ) = @_;
1242 my $groups = $apputils->simple_scalar_request(
1244 "open-ils.storage.direct.permission.grp_tree.retrieve.all.atomic");
1245 return $self->build_group_tree($groups);
1249 # turns an org list into an org tree
1250 sub build_group_tree {
1252 my( $self, $grplist) = @_;
1254 return $grplist unless (
1255 ref($grplist) and @$grplist > 1 );
1257 my @list = sort { $a->name cmp $b->name } @$grplist;
1260 for my $grp (@list) {
1262 if ($grp and !defined($grp->parent)) {
1266 my ($parent) = grep { $_->id == $grp->parent} @list;
1268 $parent->children([]) unless defined($parent->children);
1269 push( @{$parent->children}, $grp );
1277 __PACKAGE__->register_method(
1278 method => "add_user_to_groups",
1279 api_name => "open-ils.actor.user.set_groups",
1280 notes => <<" NOTES");
1281 Adds a user to one or more permission groups
1284 sub add_user_to_groups {
1285 my( $self, $client, $authtoken, $userid, $groups ) = @_;
1287 my( $requestor, $target, $evt ) = $apputils->checkses_requestor(
1288 $authtoken, $userid, 'CREATE_USER_GROUP_LINK' );
1289 return $evt if $evt;
1291 ( $requestor, $target, $evt ) = $apputils->checkses_requestor(
1292 $authtoken, $userid, 'REMOVE_USER_GROUP_LINK' );
1293 return $evt if $evt;
1295 $apputils->simplereq(
1297 'open-ils.storage.direct.permission.usr_grp_map.mass_delete', { usr => $userid } );
1299 for my $group (@$groups) {
1300 my $link = Fieldmapper::permission::usr_grp_map->new;
1302 $link->usr($userid);
1304 my $id = $apputils->simplereq(
1306 'open-ils.storage.direct.permission.usr_grp_map.create', $link );
1312 __PACKAGE__->register_method(
1313 method => "get_user_perm_groups",
1314 api_name => "open-ils.actor.user.get_groups",
1315 notes => <<" NOTES");
1316 Retrieve a user's permission groups.
1320 sub get_user_perm_groups {
1321 my( $self, $client, $authtoken, $userid ) = @_;
1323 my( $requestor, $target, $evt ) = $apputils->checkses_requestor(
1324 $authtoken, $userid, 'VIEW_PERM_GROUPS' );
1325 return $evt if $evt;
1327 return $apputils->simplereq(
1329 'open-ils.storage.direct.permission.usr_grp_map.search.usr.atomic', $userid );
1375 some old methods that may be good to keep around for now
1378 my( $session, $card ) = @_;
1380 warn "Deleting card with barcode " . $card->barcode() . "\n";
1381 my $req = $session->request(
1382 "open-ils.storage.direct.actor.card.delete",
1384 my $status = $req->gather(1);
1385 if(!defined($status)) {
1386 throw OpenSRF::EX::ERROR
1387 ("Unknown error updating card");
1393 # deletes the patron and any attached addresses and cards
1394 __PACKAGE__->register_method(
1395 method => "delete_patron",
1396 api_name => "open-ils.actor.patron.delete",
1401 my( $self, $client, $patron ) = @_;
1402 my $session = $apputils->start_db_session();
1407 $patron->clear_mailing_address();
1408 $patron->clear_billing_address();
1409 $patron->ischanged(1);
1411 _update_patron($session, $patron);
1412 _delete_address($session,$_) for (@{$patron->addresses()});
1413 _delete_card($session,$_) for (@{$patron->cards()});
1414 _delete_patron($session,$patron);
1415 $apputils->commit_db_session($session);
1417 } catch Error with {
1419 $err = "-*- Failure deleting user: $e";
1420 $apputils->rollback_db_session($session);
1424 if($err) { throw OpenSRF::EX::ERROR ($err); }
1425 warn "Patron Delete complete\n";
1429 sub _delete_patron {
1430 my( $session, $patron ) = @_;
1432 warn "Deleting patron " . $patron->usrname() . "\n";
1434 my $req = $session->request(
1435 "open-ils.storage.direct.actor.user.delete",
1437 my $status = $req->gather(1);
1438 if(!defined($status)) {
1439 throw OpenSRF::EX::ERROR
1440 ("Unknown error updating patron");