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 $session = OpenSRF::AppSession->create("open-ils.storage");
206 $new_patron = _create_stat_maps($session, $user_session, $patron, $new_patron, $user_obj);
207 if(UNIVERSAL::isa($new_patron, "OpenILS::EX") ||
208 UNIVERSAL::isa($new_patron, "OpenILS::Perm")) {
209 $client->respond_complete($new_patron->ex);
213 $new_patron = _create_perm_maps($session, $user_session, $patron, $new_patron, $user_obj);
214 if(UNIVERSAL::isa($new_patron, "OpenILS::EX") ||
215 UNIVERSAL::isa($new_patron, "OpenILS::Perm")) {
216 $client->respond_complete($new_patron->ex);
220 $apputils->commit_db_session($session);
222 warn "Patron Update/Create complete\n";
223 return flesh_user($new_patron->id());
229 __PACKAGE__->register_method(
230 method => "user_retrieve_fleshed_by_id",
231 api_name => "open-ils.actor.user.fleshed.retrieve",);
233 sub user_retrieve_fleshed_by_id {
234 my( $self, $client, $user_session, $user_id ) = @_;
236 my( $requestor, $target, $evt ) = $apputils->
237 checkses_requestor( $user_session, $user_id, 'VIEW_USER' );
240 return flesh_user($user_id);
251 $session = OpenSRF::AppSession->create("open-ils.storage");
255 # grab the user with the given id
256 my $ureq = $session->request(
257 "open-ils.storage.direct.actor.user.retrieve", $id);
258 my $user = $ureq->gather(1);
260 if(!$user) { return undef; }
263 my $cards_req = $session->request(
264 "open-ils.storage.direct.actor.card.search.usr.atomic",
266 $user->cards( $cards_req->gather(1) );
268 for my $c(@{$user->cards}) {
269 if($c->id == $user->card || $c->id eq $user->card ) {
270 warn "Setting my card to " . $c->id . "\n";
275 my $add_req = $session->request(
276 "open-ils.storage.direct.actor.user_address.search.usr.atomic",
278 $user->addresses( $add_req->gather(1) );
280 for my $c(@{$user->addresses}) {
281 if($c->id eq $user->billing_address ) { $user->billing_address($c); }
282 if($c->id eq $user->mailing_address ) { $user->mailing_address($c); }
285 my $stat_req = $session->request(
286 "open-ils.storage.direct.actor.stat_cat_entry_user_map.search.target_usr.atomic",
288 $user->stat_cat_entries($stat_req->gather(1));
290 if($kill) { $session->disconnect(); }
291 $user->clear_passwd();
297 # clone and clear stuff that would break the database
301 my $new_patron = $patron->clone;
303 # Using the Fieldmapper clone method
304 #my $new_patron = Fieldmapper::actor::user->new();
306 #my $fmap = $Fieldmapper::fieldmap;
307 #no strict; # shallow clone, may be useful in the fieldmapper
309 # (keys %{$fmap->{"Fieldmapper::actor::user"}->{'fields'}}) {
310 # $new_patron->$field( $patron->$field() );
315 $new_patron->clear_billing_address();
316 $new_patron->clear_mailing_address();
317 $new_patron->clear_addresses();
318 $new_patron->clear_card();
319 $new_patron->clear_cards();
320 $new_patron->clear_id();
321 $new_patron->clear_isnew();
322 $new_patron->clear_ischanged();
323 $new_patron->clear_isdeleted();
324 $new_patron->clear_stat_cat_entries();
333 my $user_obj = shift;
336 if($apputils->check_user_perms(
337 $user_obj->id, $user_obj->home_ou, "CREATE_USER")) {
338 return OpenILS::Perm->new("CREATE_USER");
341 warn "Creating new patron\n";
344 my $req = $session->request(
345 "open-ils.storage.direct.actor.user.create",$patron);
346 my $id = $req->gather(1);
348 return OpenILS::EX->new("DUPLICATE_USER_USERNAME");
351 # retrieve the patron from the db to collect defaults
352 my $ureq = $session->request(
353 "open-ils.storage.direct.actor.user.retrieve",
356 warn "Created new patron with id $id\n";
358 return $ureq->gather(1);
363 my( $session, $patron, $user_obj) = @_;
366 if($patron->id ne $user_obj->id) {
367 if($apputils->check_user_perms(
368 $user_obj->id, $user_obj->home_ou, "UPDATE_USER")) {
369 return OpenILS::Perm->new("UPDATE_USER");
373 warn "updating patron " . Dumper($patron) . "\n";
375 my $req = $session->request(
376 "open-ils.storage.direct.actor.user.update",$patron );
377 my $status = $req->gather(1);
378 if(!defined($status)) {
379 throw OpenSRF::EX::ERROR
380 ("Unknown error updating patron");
386 sub _add_update_addresses {
389 my $new_patron = shift;
391 my $current_id; # id of the address before creation
393 for my $address (@{$patron->addresses()}) {
395 $address->usr($new_patron->id());
397 if(ref($address) and $address->isnew()) {
398 warn "Adding new address at street " . $address->street1() . "\n";
400 $current_id = $address->id();
401 $address = _add_address($session,$address);
403 if( $patron->billing_address() and
404 $patron->billing_address() == $current_id ) {
405 $new_patron->billing_address($address->id());
406 $new_patron->ischanged(1);
409 if( $patron->mailing_address() and
410 $patron->mailing_address() == $current_id ) {
411 $new_patron->mailing_address($address->id());
412 $new_patron->ischanged(1);
415 } elsif( ref($address) and $address->ischanged() ) {
416 warn "Updating address at street " . $address->street1();
417 $address->usr($new_patron->id());
418 _update_address($session,$address);
420 } elsif( ref($address) and $address->isdeleted() ) {
421 warn "Deleting address at street " . $address->street1();
423 if( $address->id() == $new_patron->mailing_address() ) {
424 $new_patron->clear_mailing_address();
425 _update_patron($session, $new_patron);
428 if( $address->id() == $new_patron->billing_address() ) {
429 $new_patron->clear_billing_address();
430 _update_patron($session, $new_patron);
433 _delete_address($session,$address);
441 # adds an address to the db and returns the address with new id
443 my($session, $address) = @_;
444 $address->clear_id();
447 warn "Adding Address:\n";
448 warn Dumper($address);
450 # put the address into the database
451 my $req = $session->request(
452 "open-ils.storage.direct.actor.user_address.create",
456 my $id = $req->gather(1);
458 throw OpenSRF::EX::ERROR
459 ("Unable to create new user address");
462 warn "Created address with id $id\n";
464 # update all the necessary id's
470 sub _update_address {
471 my( $session, $address ) = @_;
472 my $req = $session->request(
473 "open-ils.storage.direct.actor.user_address.update",
475 my $status = $req->gather(1);
476 if(!defined($status)) {
477 throw OpenSRF::EX::ERROR
478 ("Unknown error updating address");
485 sub _add_update_cards {
489 my $new_patron = shift;
491 my $virtual_id; #id of the card before creation
492 for my $card (@{$patron->cards()}) {
494 $card->usr($new_patron->id());
496 if(ref($card) and $card->isnew()) {
498 $virtual_id = $card->id();
499 $card = _add_card($session,$card);
500 if(UNIVERSAL::isa($card,"OpenILS::EX")) {
504 #if(ref($patron->card)) { $patron->card($patron->card->id); }
505 if($patron->card() == $virtual_id) {
506 $new_patron->card($card->id());
507 $new_patron->ischanged(1);
510 } elsif( ref($card) and $card->ischanged() ) {
511 $card->usr($new_patron->id());
512 _update_card($session, $card);
519 # adds an card to the db and returns the card with new id
521 my( $session, $card ) = @_;
524 warn "Adding card with barcode " . $card->barcode() . "\n";
525 my $req = $session->request(
526 "open-ils.storage.direct.actor.card.create",
529 my $id = $req->gather(1);
531 return OpenILS::EX->new("DUPLICATE_INVALID_USER_BARCODE");
535 warn "Created patron card with id $id\n";
541 my( $session, $card ) = @_;
544 my $req = $session->request(
545 "open-ils.storage.direct.actor.card.update",
547 my $status = $req->gather(1);
548 if(!defined($status)) {
549 throw OpenSRF::EX::ERROR
550 ("Unknown error updating card");
558 sub _delete_address {
559 my( $session, $address ) = @_;
561 warn "Deleting address " . $address->street1() . "\n";
563 my $req = $session->request(
564 "open-ils.storage.direct.actor.user_address.delete",
566 my $status = $req->gather(1);
567 if(!defined($status)) {
568 throw OpenSRF::EX::ERROR
569 ("Unknown error updating address");
571 warn "Delete address status is $status\n";
576 sub _add_survey_responses {
577 my ($session, $patron, $new_patron) = @_;
579 warn "updating responses for user " . $new_patron->id . "\n";
581 my $responses = $patron->survey_responses;
585 for my $resp( @$responses ) {
586 $resp->usr($new_patron->id);
589 my $status = $apputils->simple_scalar_request(
591 "open-ils.circ.survey.submit.user_id",
600 sub _create_stat_maps {
602 my($session, $user_session, $patron, $new_patron) = @_;
604 my $maps = $patron->stat_cat_entries();
606 for my $map (@$maps) {
608 next unless($map->isnew() || $map->ischanged());
610 my $method = "open-ils.storage.direct.actor.stat_cat_entry_user_map.update";
612 $method = "open-ils.storage.direct.actor.stat_cat_entry_user_map.create";
616 $map->target_usr($new_patron->id);
618 warn "Updating stat entry with method $method and session $user_session and map $map\n";
620 my $req = $session->request($method, $map);
621 my $status = $req->gather(1);
626 throw OpenSRF::EX::ERROR
627 ("Error updating stat map with method $method");
635 sub _create_perm_maps {
637 my($session, $user_session, $patron, $new_patron) = @_;
639 my $maps = $patron->permissions;
641 for my $map (@$maps) {
643 my $method = "open-ils.storage.direct.permission.usr_perm_map.update";
644 if ($map->isdeleted()) {
645 $method = "open-ils.storage.direct.permission.usr_perm_map.delete";
646 } elsif ($map->isnew()) {
647 $method = "open-ils.storage.direct.permission.usr_perm_map.create";
652 $map->usr($new_patron->id);
654 warn( "Updating permissions with method $method and session $user_session and map $map" );
655 $logger->debug( "Updating permissions with method $method and session $user_session and map $map" );
657 my $req = $session->request($method, $map);
658 my $status = $req->gather(1);
663 throw OpenSRF::EX::ERROR
664 ("Error updating permission map with method $method");
674 __PACKAGE__->register_method(
675 method => "search_username",
676 api_name => "open-ils.actor.user.search.username",
679 sub search_username {
680 my($self, $client, $username) = @_;
681 my $users = OpenILS::Application::AppUtils->simple_scalar_request(
683 "open-ils.storage.direct.actor.user.search.usrname.atomic",
691 __PACKAGE__->register_method(
692 method => "user_retrieve_by_barcode",
693 api_name => "open-ils.actor.user.fleshed.retrieve_by_barcode",);
695 sub user_retrieve_by_barcode {
696 my($self, $client, $user_session, $barcode) = @_;
698 $logger->debug("Searching for user with barcode $barcode");
699 #my $user_obj = $apputils->check_user_session( $user_session );
700 my ($user_obj, $evt) = $apputils->check_ses($user_session);
703 my $session = OpenSRF::AppSession->create("open-ils.storage");
705 # find the card with the given barcode
706 my $creq = $session->request(
707 "open-ils.storage.direct.actor.card.search.barcode.atomic",
709 my $card = $creq->gather(1);
711 if(!$card || !$card->[0]) {
712 $session->disconnect();
713 return OpenILS::Event->new( 'USER_NOT_FOUND' );
717 my $user = flesh_user($card->usr(), $session);
718 $session->disconnect();
719 if(!$user) { return OpenILS::Event->new( 'USER_NOT_FOUND' ); }
726 __PACKAGE__->register_method(
727 method => "get_user_by_id",
728 api_name => "open-ils.actor.user.retrieve",);
731 my ($self, $client, $user_session, $id) = @_;
733 my $user_obj = $apputils->check_user_session( $user_session );
735 return $apputils->simple_scalar_request(
737 "open-ils.storage.direct.actor.user.retrieve",
743 __PACKAGE__->register_method(
744 method => "get_org_types",
745 api_name => "open-ils.actor.org_types.retrieve",);
749 my($self, $client) = @_;
751 return $org_types if $org_types;
753 $apputils->simple_scalar_request(
755 "open-ils.storage.direct.actor.org_unit_type.retrieve.all.atomic" );
760 __PACKAGE__->register_method(
761 method => "get_user_profiles",
762 api_name => "open-ils.actor.user.profiles.retrieve",
766 sub get_user_profiles {
767 return $user_profiles if $user_profiles;
769 return $user_profiles =
770 $apputils->simple_scalar_request(
772 "open-ils.storage.direct.actor.profile.retrieve.all.atomic");
777 __PACKAGE__->register_method(
778 method => "get_user_ident_types",
779 api_name => "open-ils.actor.user.ident_types.retrieve",
782 sub get_user_ident_types {
783 return $ident_types if $ident_types;
784 return $ident_types =
785 $apputils->simple_scalar_request(
787 "open-ils.storage.direct.config.identification_type.retrieve.all.atomic" );
793 __PACKAGE__->register_method(
794 method => "get_org_unit",
795 api_name => "open-ils.actor.org_unit.retrieve",
800 my( $self, $client, $user_session, $org_id ) = @_;
802 if(defined($user_session) && !defined($org_id)) {
804 OpenILS::Application::AppUtils->check_user_session( $user_session ); #throws EX on error
805 if(!defined($org_id)) {
806 $org_id = $user_obj->home_ou;
811 my $home_ou = OpenILS::Application::AppUtils->simple_scalar_request(
813 "open-ils.storage.direct.actor.org_unit.retrieve",
822 __PACKAGE__->register_method(
823 method => "get_org_tree",
824 api_name => "open-ils.actor.org_tree.retrieve",
826 note => "Returns the entire org tree structure",
830 my( $self, $client) = @_;
833 $cache_client = OpenSRF::Utils::Cache->new("global", 0);
835 # see if it's in the cache
836 warn "Getting ORG Tree\n";
837 my $tree = $cache_client->get_cache('orgtree');
839 warn "Found orgtree in cache. returning...\n";
843 my $orglist = $apputils->simple_scalar_request(
845 "open-ils.storage.direct.actor.org_unit.retrieve.all.atomic" );
848 warn "found org list\n";
851 $tree = $self->build_org_tree($orglist);
852 $cache_client->put_cache('orgtree', $tree);
858 # turns an org list into an org tree
861 my( $self, $orglist) = @_;
863 return $orglist unless (
864 ref($orglist) and @$orglist > 1 );
867 $a->ou_type <=> $b->ou_type ||
868 $a->name cmp $b->name } @$orglist;
870 for my $org (@list) {
872 next unless ($org and defined($org->parent_ou));
873 my ($parent) = grep { $_->id == $org->parent_ou } @list;
876 $parent->children([]) unless defined($parent->children);
877 push( @{$parent->children}, $org );
885 __PACKAGE__->register_method(
886 method => "get_org_descendants",
887 api_name => "open-ils.actor.org_tree.descendants.retrieve"
890 # depth is optional. org_unit is the id
891 sub get_org_descendants {
892 my( $self, $client, $org_unit, $depth ) = @_;
893 my $orglist = $apputils->simple_scalar_request(
895 "open-ils.storage.actor.org_unit.descendants.atomic",
897 return $self->build_org_tree($orglist);
901 __PACKAGE__->register_method(
902 method => "get_org_ancestors",
903 api_name => "open-ils.actor.org_tree.ancestors.retrieve"
906 # depth is optional. org_unit is the id
907 sub get_org_ancestors {
908 my( $self, $client, $org_unit, $depth ) = @_;
909 my $orglist = $apputils->simple_scalar_request(
911 "open-ils.storage.actor.org_unit.ancestors.atomic",
913 return $self->build_org_tree($orglist);
917 __PACKAGE__->register_method(
918 method => "get_standings",
919 api_name => "open-ils.actor.standings.retrieve"
924 return $user_standings if $user_standings;
925 return $user_standings =
926 $apputils->simple_scalar_request(
928 "open-ils.storage.direct.config.standing.retrieve.all.atomic" );
933 __PACKAGE__->register_method(
934 method => "get_my_org_path",
935 api_name => "open-ils.actor.org_unit.full_path.retrieve"
938 sub get_my_org_path {
939 my( $self, $client, $user_session, $org_id ) = @_;
940 my $user_obj = $apputils->check_user_session($user_session);
941 if(!defined($org_id)) { $org_id = $user_obj->home_ou; }
943 return $apputils->simple_scalar_request(
945 "open-ils.storage.actor.org_unit.full_path.atomic",
950 __PACKAGE__->register_method(
951 method => "patron_adv_search",
952 api_name => "open-ils.actor.patron.search.advanced" );
954 sub patron_adv_search {
955 my( $self, $client, $staff_login, $search_hash ) = @_;
958 warn "patron adv with $staff_login and search " .
959 Dumper($search_hash) . "\n";
961 my $session = OpenSRF::AppSession->create("open-ils.storage");
962 my $req = $session->request(
963 "open-ils.storage.actor.user.crazy_search", $search_hash);
965 my $ans = $req->gather(1);
967 my %hash = map { ($_ =>1) } @$ans;
968 $ans = [ keys %hash ];
970 warn "Returning @$ans\n";
972 $session->disconnect();
979 sub _verify_password {
980 my($user_session, $password) = @_;
981 my $user_obj = $apputils->check_user_session($user_session);
983 #grab the user with password
984 $user_obj = $apputils->simple_scalar_request(
986 "open-ils.storage.direct.actor.user.retrieve",
989 if($user_obj->passwd eq $password) {
997 __PACKAGE__->register_method(
998 method => "update_password",
999 api_name => "open-ils.actor.user.password.update");
1001 __PACKAGE__->register_method(
1002 method => "update_password",
1003 api_name => "open-ils.actor.user.username.update");
1005 __PACKAGE__->register_method(
1006 method => "update_password",
1007 api_name => "open-ils.actor.user.email.update");
1009 sub update_password {
1010 my( $self, $client, $user_session, $new_value, $current_password ) = @_;
1012 warn "Updating user with method " .$self->api_name . "\n";
1013 my $user_obj = $apputils->check_user_session($user_session);
1015 if($self->api_name =~ /password/) {
1017 #make sure they know the current password
1018 if(!_verify_password($user_session, md5_hex($current_password))) {
1019 return OpenILS::EX->new("USER_WRONG_PASSWORD")->ex;
1022 $user_obj->passwd($new_value);
1024 elsif($self->api_name =~ /username/) {
1025 my $users = search_username(undef, undef, $new_value);
1026 if( $users and $users->[0] ) {
1027 return OpenILS::Event->new('USERNAME_EXISTS');
1029 $user_obj->usrname($new_value);
1032 elsif($self->api_name =~ /email/) {
1033 warn "Updating email to $new_value\n";
1034 $user_obj->email($new_value);
1037 my $session = $apputils->start_db_session();
1038 $user_obj = _update_patron($session, $user_obj, $user_obj);
1039 $apputils->commit_db_session($session);
1041 if($user_obj) { return 1; }
1046 __PACKAGE__->register_method(
1047 method => "check_user_perms",
1048 api_name => "open-ils.actor.user.perm.check",
1049 notes => <<" NOTES");
1050 Takes a login session, user id, an org id, and an array of perm type strings. For each
1051 perm type, if the user does *not* have the given permission it is added
1052 to a list which is returned from the method. If all permissions
1053 are allowed, an empty list is returned
1054 if the logged in user does not match 'user_id', then the logged in user must
1055 have VIEW_PERMISSION priveleges.
1058 sub check_user_perms {
1059 my( $self, $client, $login_session, $user_id, $org_id, $perm_types ) = @_;
1061 my( $staff, $evt ) = $apputils->checkses($login_session);
1062 return $evt if $evt;
1064 if($staff->id ne $user_id) {
1065 if( my $evt = $apputils->check_perms(
1066 $staff->id, $org_id, 'VIEW_PERMISSION') ) {
1072 for my $perm (@$perm_types) {
1073 if($apputils->check_perms($user_id, $org_id, $perm)) {
1074 push @not_allowed, $perm;
1078 return \@not_allowed
1081 __PACKAGE__->register_method(
1082 method => "check_user_perms2",
1083 api_name => "open-ils.actor.user.perm.check.multi_org",
1085 Checks the permissions on a list of perms and orgs for a user
1086 @param authtoken The login session key
1087 @param user_id The id of the user to check
1088 @param orgs The array of org ids
1089 @param perms The array of permission names
1090 @return An array of [ orgId, permissionName ] arrays that FAILED the check
1091 if the logged in user does not match 'user_id', then the logged in user must
1092 have VIEW_PERMISSION priveleges.
1095 sub check_user_perms2 {
1096 my( $self, $client, $authtoken, $user_id, $orgs, $perms ) = @_;
1098 my( $staff, $target, $evt ) = $apputils->checkses_requestor(
1099 $authtoken, $user_id, 'VIEW_PERMISSION' );
1100 return $evt if $evt;
1103 for my $org (@$orgs) {
1104 for my $perm (@$perms) {
1105 if($apputils->check_perms($user_id, $org, $perm)) {
1106 push @not_allowed, [ $org, $perm ];
1111 return \@not_allowed
1115 __PACKAGE__->register_method(
1116 method => 'check_user_perms3',
1117 api_name => 'open-ils.actor.user.perm.highest_org',
1119 Returns the highest org unit id at which a user has a given permission
1120 If the requestor does not match the target user, the requestor must have
1121 'VIEW_PERMISSION' rights at the home org unit of the target user
1122 @param authtoken The login session key
1123 @param userid The id of the user in question
1124 @param perm The permission to check
1125 @return The org unit highest in the org tree within which the user has
1126 the requested permission
1129 sub check_user_perms3 {
1130 my( $self, $client, $authtoken, $userid, $perm ) = @_;
1132 my( $staff, $target, $org, $evt );
1134 ( $staff, $target, $evt ) = $apputils->checkses_requestor(
1135 $authtoken, $userid, 'VIEW_PERMISSION' );
1136 return $evt if $evt;
1138 my $tree = $self->get_org_tree();
1139 return _find_highest_perm_org( $perm, $userid, $target->home_ou, $tree );
1143 sub _find_highest_perm_org {
1144 my ( $perm, $userid, $start_org, $org_tree ) = @_;
1145 my $org = $apputils->find_org($org_tree, $start_org );
1149 last if ($apputils->check_perms( $userid, $org->id, $perm )); # perm failed
1151 $org = $apputils->find_org( $org_tree, $org->parent_ou() );
1157 __PACKAGE__->register_method(
1158 method => 'check_user_perms4',
1159 api_name => 'open-ils.actor.user.perm.highest_org.batch',
1161 Returns the highest org unit id at which a user has a given permission
1162 If the requestor does not match the target user, the requestor must have
1163 'VIEW_PERMISSION' rights at the home org unit of the target user
1164 @param authtoken The login session key
1165 @param userid The id of the user in question
1166 @param perms An array of perm names to check
1167 @return An array of orgId's representing the org unit
1168 highest in the org tree within which the user has the requested permission
1169 The arrah of orgId's has matches the order of the perms array
1172 sub check_user_perms4 {
1173 my( $self, $client, $authtoken, $userid, $perms ) = @_;
1175 my( $staff, $target, $org, $evt );
1177 ( $staff, $target, $evt ) = $apputils->checkses_requestor(
1178 $authtoken, $userid, 'VIEW_PERMISSION' );
1179 return $evt if $evt;
1182 return [] unless ref($perms);
1183 my $tree = $self->get_org_tree();
1185 for my $p (@$perms) {
1186 push( @arr, _find_highest_perm_org( $p, $userid, $target->home_ou, $tree ) );
1194 __PACKAGE__->register_method(
1195 method => "user_fines_summary",
1196 api_name => "open-ils.actor.user.fines.summary",
1197 notes => <<" NOTES");
1198 Returns a short summary of the users total open fines, excluding voided fines
1199 Params are login_session, user_id
1200 Returns a 'mous' object.
1203 sub user_fines_summary {
1204 my( $self, $client, $login_session, $user_id ) = @_;
1206 my $user_obj = $apputils->check_user_session($login_session);
1207 if($user_obj->id ne $user_id) {
1208 if($apputils->check_user_perms($user_obj->id, $user_obj->home_ou, "VIEW_USER_FINES_SUMMARY")) {
1209 return OpenILS::Perm->new("VIEW_USER_FINES_SUMMARY");
1213 return $apputils->simple_scalar_request(
1215 "open-ils.storage.direct.money.open_user_summary.search.usr",
1223 __PACKAGE__->register_method(
1224 method => "user_transactions",
1225 api_name => "open-ils.actor.user.transactions",
1226 notes => <<" NOTES");
1227 Returns a list of open user transactions (mbts objects);
1228 Params are login_session, user_id
1229 Optional third parameter is the transactions type. defaults to all
1232 __PACKAGE__->register_method(
1233 method => "user_transactions",
1234 api_name => "open-ils.actor.user.transactions.have_charge",
1235 notes => <<" NOTES");
1236 Returns a list of all open user transactions (mbts objects) that have an initial charge
1237 Params are login_session, user_id
1238 Optional third parameter is the transactions type. defaults to all
1241 __PACKAGE__->register_method(
1242 method => "user_transactions",
1243 api_name => "open-ils.actor.user.transactions.have_balance",
1244 notes => <<" NOTES");
1245 Returns a list of all open user transactions (mbts objects) that have a balance
1246 Params are login_session, user_id
1247 Optional third parameter is the transactions type. defaults to all
1250 __PACKAGE__->register_method(
1251 method => "user_transactions",
1252 api_name => "open-ils.actor.user.transactions.fleshed",
1253 notes => <<" NOTES");
1254 Returns an object/hash of transaction, circ, title where transaction = an open
1255 user transactions (mbts objects), circ is the attached circluation, and title
1256 is the title the circ points to
1257 Params are login_session, user_id
1258 Optional third parameter is the transactions type. defaults to all
1261 __PACKAGE__->register_method(
1262 method => "user_transactions",
1263 api_name => "open-ils.actor.user.transactions.have_charge.fleshed",
1264 notes => <<" NOTES");
1265 Returns an object/hash of transaction, circ, title where transaction = an open
1266 user transactions that has an initial charge (mbts objects), circ is the
1267 attached circluation, and title is the title the circ points to
1268 Params are login_session, user_id
1269 Optional third parameter is the transactions type. defaults to all
1272 __PACKAGE__->register_method(
1273 method => "user_transactions",
1274 api_name => "open-ils.actor.user.transactions.have_balance.fleshed",
1275 notes => <<" NOTES");
1276 Returns an object/hash of transaction, circ, title where transaction = an open
1277 user transaction that has a balance (mbts objects), circ is the attached
1278 circluation, and title is the title the circ points to
1279 Params are login_session, user_id
1280 Optional third parameter is the transaction type. defaults to all
1285 sub user_transactions {
1286 my( $self, $client, $login_session, $user_id, $type ) = @_;
1288 my( $user_obj, $target, $evt ) = $apputils->checkses_requestor(
1289 $login_session, $user_id, 'VIEW_USER_TRANSACTIONS' );
1290 return $evt if $evt;
1292 my $api = $self->api_name();
1296 if(defined($type)) { @xact = (xact_type => $type);
1298 } else { @xact = (); }
1300 if($api =~ /have_charge/) {
1302 $trans = $apputils->simple_scalar_request(
1304 "open-ils.storage.direct.money.open_billable_transaction_summary.search_where.atomic",
1305 { usr => $user_id, total_owed => { ">" => 0 }, @xact });
1307 } elsif($api =~ /have_balance/) {
1309 $trans = $apputils->simple_scalar_request(
1311 "open-ils.storage.direct.money.open_billable_transaction_summary.search_where.atomic",
1312 { usr => $user_id, balance_owed => { ">" => 0 }, @xact });
1316 $trans = $apputils->simple_scalar_request(
1318 "open-ils.storage.direct.money.open_billable_transaction_summary.search_where.atomic",
1319 { usr => $user_id, @xact });
1322 if($api !~ /fleshed/) { return $trans; }
1327 for my $t (@$trans) {
1331 my $circ = $apputils->simple_scalar_request(
1333 "open-ils.storage.direct.action.circulation.retrieve",
1338 my $title = $apputils->simple_scalar_request(
1340 "open-ils.storage.fleshed.biblio.record_entry.retrieve_by_copy",
1341 $circ->target_copy );
1345 my $u = OpenILS::Utils::ModsParser->new();
1346 $u->start_mods_batch($title->marc());
1347 my $mods = $u->finish_mods_batch();
1349 push @resp, {transaction => $t, circ => $circ, record => $mods };
1359 __PACKAGE__->register_method(
1360 method => "user_perms",
1361 api_name => "open-ils.actor.permissions.user_perms.retrieve",
1363 notes => <<" NOTES");
1364 Returns a list of permissions
1367 my( $self, $client, $authtoken, $user ) = @_;
1369 my( $staff, $evt ) = $apputils->checkses($authtoken);
1370 return $evt if $evt;
1372 $user ||= $staff->id;
1374 if( $user != $staff->id and $evt = $apputils->check_perms( $staff->id, $staff->home_ou, 'VIEW_PERMISSION') ) {
1378 return $apputils->simple_scalar_request(
1380 "open-ils.storage.permission.user_perms.atomic",
1384 __PACKAGE__->register_method(
1385 method => "retrieve_perms",
1386 api_name => "open-ils.actor.permissions.retrieve",
1387 notes => <<" NOTES");
1388 Returns a list of permissions
1390 sub retrieve_perms {
1391 my( $self, $client ) = @_;
1392 return $apputils->simple_scalar_request(
1394 "open-ils.storage.direct.permission.perm_list.retrieve.all.atomic");
1397 __PACKAGE__->register_method(
1398 method => "retrieve_groups",
1399 api_name => "open-ils.actor.groups.retrieve",
1400 notes => <<" NOTES");
1401 Returns a list of user groupss
1403 sub retrieve_groups {
1404 my( $self, $client ) = @_;
1405 return $apputils->simple_scalar_request(
1407 "open-ils.storage.direct.permission.grp_tree.retrieve.all.atomic");
1410 __PACKAGE__->register_method(
1411 method => "retrieve_groups_tree",
1412 api_name => "open-ils.actor.groups.tree.retrieve",
1413 notes => <<" NOTES");
1414 Returns a list of user groups
1416 sub retrieve_groups_tree {
1417 my( $self, $client ) = @_;
1418 my $groups = $apputils->simple_scalar_request(
1420 "open-ils.storage.direct.permission.grp_tree.retrieve.all.atomic");
1421 return $self->build_group_tree($groups);
1425 # turns an org list into an org tree
1426 sub build_group_tree {
1428 my( $self, $grplist) = @_;
1430 return $grplist unless (
1431 ref($grplist) and @$grplist > 1 );
1433 my @list = sort { $a->name cmp $b->name } @$grplist;
1436 for my $grp (@list) {
1438 if ($grp and !defined($grp->parent)) {
1442 my ($parent) = grep { $_->id == $grp->parent} @list;
1444 $parent->children([]) unless defined($parent->children);
1445 push( @{$parent->children}, $grp );
1453 __PACKAGE__->register_method(
1454 method => "add_user_to_groups",
1455 api_name => "open-ils.actor.user.set_groups",
1456 notes => <<" NOTES");
1457 Adds a user to one or more permission groups
1460 sub add_user_to_groups {
1461 my( $self, $client, $authtoken, $userid, $groups ) = @_;
1463 my( $requestor, $target, $evt ) = $apputils->checkses_requestor(
1464 $authtoken, $userid, 'CREATE_USER_GROUP_LINK' );
1465 return $evt if $evt;
1467 ( $requestor, $target, $evt ) = $apputils->checkses_requestor(
1468 $authtoken, $userid, 'REMOVE_USER_GROUP_LINK' );
1469 return $evt if $evt;
1471 $apputils->simplereq(
1473 'open-ils.storage.direct.permission.usr_grp_map.mass_delete', { usr => $userid } );
1475 for my $group (@$groups) {
1476 my $link = Fieldmapper::permission::usr_grp_map->new;
1478 $link->usr($userid);
1480 my $id = $apputils->simplereq(
1482 'open-ils.storage.direct.permission.usr_grp_map.create', $link );
1488 __PACKAGE__->register_method(
1489 method => "get_user_perm_groups",
1490 api_name => "open-ils.actor.user.get_groups",
1491 notes => <<" NOTES");
1492 Retrieve a user's permission groups.
1496 sub get_user_perm_groups {
1497 my( $self, $client, $authtoken, $userid ) = @_;
1499 my( $requestor, $target, $evt ) = $apputils->checkses_requestor(
1500 $authtoken, $userid, 'VIEW_PERM_GROUPS' );
1501 return $evt if $evt;
1503 return $apputils->simplereq(
1505 'open-ils.storage.direct.permission.usr_grp_map.search.usr.atomic', $userid );