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 object 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 = get_org_tree();
1139 $org = $apputils->find_org($tree, $target->home_ou );
1143 last if ($apputils->check_perms( $userid, $org->id, $perm )); # perm failed
1145 $org = $apputils->find_org( $tree, $org->parent_ou() );
1154 __PACKAGE__->register_method(
1155 method => "user_fines_summary",
1156 api_name => "open-ils.actor.user.fines.summary",
1157 notes => <<" NOTES");
1158 Returns a short summary of the users total open fines, excluding voided fines
1159 Params are login_session, user_id
1160 Returns a 'mous' object.
1163 sub user_fines_summary {
1164 my( $self, $client, $login_session, $user_id ) = @_;
1166 my $user_obj = $apputils->check_user_session($login_session);
1167 if($user_obj->id ne $user_id) {
1168 if($apputils->check_user_perms($user_obj->id, $user_obj->home_ou, "VIEW_USER_FINES_SUMMARY")) {
1169 return OpenILS::Perm->new("VIEW_USER_FINES_SUMMARY");
1173 return $apputils->simple_scalar_request(
1175 "open-ils.storage.direct.money.open_user_summary.search.usr",
1183 __PACKAGE__->register_method(
1184 method => "user_transactions",
1185 api_name => "open-ils.actor.user.transactions",
1186 notes => <<" NOTES");
1187 Returns a list of open user transactions (mbts objects);
1188 Params are login_session, user_id
1189 Optional third parameter is the transactions type. defaults to all
1192 __PACKAGE__->register_method(
1193 method => "user_transactions",
1194 api_name => "open-ils.actor.user.transactions.have_charge",
1195 notes => <<" NOTES");
1196 Returns a list of all open user transactions (mbts objects) that have an initial charge
1197 Params are login_session, user_id
1198 Optional third parameter is the transactions type. defaults to all
1201 __PACKAGE__->register_method(
1202 method => "user_transactions",
1203 api_name => "open-ils.actor.user.transactions.have_balance",
1204 notes => <<" NOTES");
1205 Returns a list of all open user transactions (mbts objects) that have a balance
1206 Params are login_session, user_id
1207 Optional third parameter is the transactions type. defaults to all
1210 __PACKAGE__->register_method(
1211 method => "user_transactions",
1212 api_name => "open-ils.actor.user.transactions.fleshed",
1213 notes => <<" NOTES");
1214 Returns an object/hash of transaction, circ, title where transaction = an open
1215 user transactions (mbts objects), circ is the attached circluation, and title
1216 is the title the circ points to
1217 Params are login_session, user_id
1218 Optional third parameter is the transactions type. defaults to all
1221 __PACKAGE__->register_method(
1222 method => "user_transactions",
1223 api_name => "open-ils.actor.user.transactions.have_charge.fleshed",
1224 notes => <<" NOTES");
1225 Returns an object/hash of transaction, circ, title where transaction = an open
1226 user transactions that has an initial charge (mbts objects), circ is the
1227 attached circluation, and title is the title the circ points to
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_balance.fleshed",
1235 notes => <<" NOTES");
1236 Returns an object/hash of transaction, circ, title where transaction = an open
1237 user transaction that has a balance (mbts objects), circ is the attached
1238 circluation, and title is the title the circ points to
1239 Params are login_session, user_id
1240 Optional third parameter is the transaction type. defaults to all
1245 sub user_transactions {
1246 my( $self, $client, $login_session, $user_id, $type ) = @_;
1248 my( $user_obj, $target, $evt ) = $apputils->checkses_requestor(
1249 $login_session, $user_id, 'VIEW_USER_TRANSACTIONS' );
1250 return $evt if $evt;
1252 my $api = $self->api_name();
1256 if(defined($type)) { @xact = (xact_type => $type);
1258 } else { @xact = (); }
1260 if($api =~ /have_charge/) {
1262 $trans = $apputils->simple_scalar_request(
1264 "open-ils.storage.direct.money.open_billable_transaction_summary.search_where.atomic",
1265 { usr => $user_id, total_owed => { ">" => 0 }, @xact });
1267 } elsif($api =~ /have_balance/) {
1269 $trans = $apputils->simple_scalar_request(
1271 "open-ils.storage.direct.money.open_billable_transaction_summary.search_where.atomic",
1272 { usr => $user_id, balance_owed => { ">" => 0 }, @xact });
1276 $trans = $apputils->simple_scalar_request(
1278 "open-ils.storage.direct.money.open_billable_transaction_summary.search_where.atomic",
1279 { usr => $user_id, @xact });
1282 if($api !~ /fleshed/) { return $trans; }
1287 for my $t (@$trans) {
1291 my $circ = $apputils->simple_scalar_request(
1293 "open-ils.storage.direct.action.circulation.retrieve",
1298 my $title = $apputils->simple_scalar_request(
1300 "open-ils.storage.fleshed.biblio.record_entry.retrieve_by_copy",
1301 $circ->target_copy );
1305 my $u = OpenILS::Utils::ModsParser->new();
1306 $u->start_mods_batch($title->marc());
1307 my $mods = $u->finish_mods_batch();
1309 push @resp, {transaction => $t, circ => $circ, record => $mods };
1319 __PACKAGE__->register_method(
1320 method => "user_perms",
1321 api_name => "open-ils.actor.permissions.user_perms.retrieve",
1323 notes => <<" NOTES");
1324 Returns a list of permissions
1327 my( $self, $client, $authtoken, $user ) = @_;
1329 my( $staff, $evt ) = $apputils->checkses($authtoken);
1330 return $evt if $evt;
1332 $user ||= $staff->id;
1334 if( $user != $staff->id and $evt = $apputils->check_perms( $staff->id, $staff->home_ou, 'VIEW_PERMISSION') ) {
1338 return $apputils->simple_scalar_request(
1340 "open-ils.storage.permission.user_perms.atomic",
1344 __PACKAGE__->register_method(
1345 method => "retrieve_perms",
1346 api_name => "open-ils.actor.permissions.retrieve",
1347 notes => <<" NOTES");
1348 Returns a list of permissions
1350 sub retrieve_perms {
1351 my( $self, $client ) = @_;
1352 return $apputils->simple_scalar_request(
1354 "open-ils.storage.direct.permission.perm_list.retrieve.all.atomic");
1357 __PACKAGE__->register_method(
1358 method => "retrieve_groups",
1359 api_name => "open-ils.actor.groups.retrieve",
1360 notes => <<" NOTES");
1361 Returns a list of user groupss
1363 sub retrieve_groups {
1364 my( $self, $client ) = @_;
1365 return $apputils->simple_scalar_request(
1367 "open-ils.storage.direct.permission.grp_tree.retrieve.all.atomic");
1370 __PACKAGE__->register_method(
1371 method => "retrieve_groups_tree",
1372 api_name => "open-ils.actor.groups.tree.retrieve",
1373 notes => <<" NOTES");
1374 Returns a list of user groups
1376 sub retrieve_groups_tree {
1377 my( $self, $client ) = @_;
1378 my $groups = $apputils->simple_scalar_request(
1380 "open-ils.storage.direct.permission.grp_tree.retrieve.all.atomic");
1381 return $self->build_group_tree($groups);
1385 # turns an org list into an org tree
1386 sub build_group_tree {
1388 my( $self, $grplist) = @_;
1390 return $grplist unless (
1391 ref($grplist) and @$grplist > 1 );
1393 my @list = sort { $a->name cmp $b->name } @$grplist;
1396 for my $grp (@list) {
1398 if ($grp and !defined($grp->parent)) {
1402 my ($parent) = grep { $_->id == $grp->parent} @list;
1404 $parent->children([]) unless defined($parent->children);
1405 push( @{$parent->children}, $grp );
1413 __PACKAGE__->register_method(
1414 method => "add_user_to_groups",
1415 api_name => "open-ils.actor.user.set_groups",
1416 notes => <<" NOTES");
1417 Adds a user to one or more permission groups
1420 sub add_user_to_groups {
1421 my( $self, $client, $authtoken, $userid, $groups ) = @_;
1423 my( $requestor, $target, $evt ) = $apputils->checkses_requestor(
1424 $authtoken, $userid, 'CREATE_USER_GROUP_LINK' );
1425 return $evt if $evt;
1427 ( $requestor, $target, $evt ) = $apputils->checkses_requestor(
1428 $authtoken, $userid, 'REMOVE_USER_GROUP_LINK' );
1429 return $evt if $evt;
1431 $apputils->simplereq(
1433 'open-ils.storage.direct.permission.usr_grp_map.mass_delete', { usr => $userid } );
1435 for my $group (@$groups) {
1436 my $link = Fieldmapper::permission::usr_grp_map->new;
1438 $link->usr($userid);
1440 my $id = $apputils->simplereq(
1442 'open-ils.storage.direct.permission.usr_grp_map.create', $link );
1448 __PACKAGE__->register_method(
1449 method => "get_user_perm_groups",
1450 api_name => "open-ils.actor.user.get_groups",
1451 notes => <<" NOTES");
1452 Retrieve a user's permission groups.
1456 sub get_user_perm_groups {
1457 my( $self, $client, $authtoken, $userid ) = @_;
1459 my( $requestor, $target, $evt ) = $apputils->checkses_requestor(
1460 $authtoken, $userid, 'VIEW_PERM_GROUPS' );
1461 return $evt if $evt;
1463 return $apputils->simplereq(
1465 'open-ils.storage.direct.permission.usr_grp_map.search.usr.atomic', $userid );