1 package OpenILS::Application::Actor;
2 use base qw/OpenSRF::Application/;
3 use strict; use warnings;
5 $Data::Dumper::Indent = 0;
8 use Digest::MD5 qw(md5_hex);
10 use OpenSRF::EX qw(:try);
13 use OpenILS::Application::AppUtils;
15 use OpenILS::Utils::Fieldmapper;
16 use OpenILS::Application::Search::Actor;
17 use OpenILS::Utils::ModsParser;
18 use OpenSRF::Utils::Logger qw/$logger/;
19 use OpenSRF::Utils qw/:datetime/;
21 use OpenSRF::Utils::Cache;
24 use DateTime::Format::ISO8601;
26 use OpenILS::Application::Actor::Container;
28 use OpenILS::Utils::Editor;
30 use OpenILS::Application::Actor::UserGroups;
32 OpenILS::Application::Actor::Container->initialize();
33 OpenILS::Application::Actor::UserGroups->initialize();
36 my $apputils = "OpenILS::Application::AppUtils";
39 sub _d { warn "Patron:\n" . Dumper(shift()); }
44 my $set_user_settings;
47 __PACKAGE__->register_method(
48 method => "set_user_settings",
49 api_name => "open-ils.actor.patron.settings.update",
51 sub set_user_settings {
52 my( $self, $client, $user_session, $uid, $settings ) = @_;
54 $logger->debug("Setting user settings: $user_session, $uid, " . Dumper($settings));
56 my( $staff, $user, $evt ) =
57 $apputils->checkses_requestor( $user_session, $uid, 'UPDATE_USER' );
62 # [{ usr => $user->id, name => $_}, {value => $$settings{$_}}] } keys %$settings;
65 [{ usr => $user->id, name => $_}, {value => $$settings{$_}}] } keys %$settings;
67 $logger->activity("User " . $staff->id . " updating user $uid settings with: " . Dumper(\@params));
69 return $apputils->simplereq(
71 'open-ils.storage.direct.actor.user_setting.batch.merge', @params );
77 __PACKAGE__->register_method(
78 method => "set_ou_settings",
79 api_name => "open-ils.actor.org_unit.settings.update",
82 my( $self, $client, $user_session, $ouid, $settings ) = @_;
84 my( $staff, $evt ) = $apputils->checkses( $user_session );
86 $evt = $apputils->check_perms( $staff->id, $ouid, 'UPDATE_ORG_UNIT' );
91 map { [{ org_unit => $ouid, name => $_}, {value => $$settings{$_}}] } keys %$settings;
93 $logger->activity("Updating org unit [$ouid] settings with: " . Dumper($params));
95 return $apputils->simplereq(
97 'open-ils.storage.direct.actor.org_unit_setting.merge', @$params );
101 my $fetch_user_settings;
102 my $fetch_ou_settings;
104 __PACKAGE__->register_method(
105 method => "user_settings",
106 api_name => "open-ils.actor.patron.settings.retrieve",
109 my( $self, $client, $user_session, $uid ) = @_;
111 my( $staff, $user, $evt ) =
112 $apputils->checkses_requestor( $user_session, $uid, 'VIEW_USER' );
115 $logger->debug("User " . $staff->id . " fetching user $uid\n");
116 my $s = $apputils->simplereq(
118 'open-ils.storage.direct.actor.user_setting.search.usr.atomic',$uid );
120 return { map { ($_->name,$_->value) } @$s };
125 __PACKAGE__->register_method(
126 method => "ou_settings",
127 api_name => "open-ils.actor.org_unit.settings.retrieve",
130 my( $self, $client, $ouid ) = @_;
132 $logger->info("Fetching org unit settings for org $ouid");
134 my $s = $apputils->simplereq(
136 'open-ils.storage.direct.actor.org_unit_setting.search.org_unit.atomic', $ouid);
138 return { map { ($_->name,$_->value) } @$s };
141 __PACKAGE__->register_method (
142 method => "ou_setting_delete",
143 api_name => 'open-ils.actor.org_setting.delete',
145 Deletes a specific org unit setting for a specific location
146 @param authtoken The login session key
147 @param orgid The org unit whose setting we're changing
148 @param setting The name of the setting to delete
149 @return True value on success.
153 sub ou_setting_delete {
154 my( $self, $conn, $authtoken, $orgid, $setting ) = @_;
155 my( $reqr, $evt) = $U->checkses($authtoken);
157 $evt = $U->check_perms($reqr->id, $orgid, 'UPDATE_ORG_SETTING');
160 my $id = $U->storagereq(
161 'open-ils.storage.id_list.actor.org_unit_setting.search_where',
162 { name => $setting, org_unit => $orgid } );
164 $logger->debug("Retrieved setting $id in org unit setting delete");
166 my $s = $U->storagereq(
167 'open-ils.storage.direct.actor.org_unit_setting.delete', $id );
169 $logger->activity("User ".$reqr->id." deleted org unit setting $id") if $s;
175 __PACKAGE__->register_method(
176 method => "update_patron",
177 api_name => "open-ils.actor.patron.update",);
180 my( $self, $client, $user_session, $patron ) = @_;
182 my $session = $apputils->start_db_session();
185 $logger->info("Creating new patron...") if $patron->isnew;
186 $logger->info("Updating Patron: " . $patron->id) unless $patron->isnew;
188 my( $user_obj, $evt ) = $U->checkses($user_session);
191 # XXX does this user have permission to add/create users. Granularity?
192 # $new_patron is the patron in progress. $patron is the original patron
193 # passed in with the method. new_patron will change as the components
194 # of patron are added/updated.
198 # unflesh the real items on the patron
199 $patron->card( $patron->card->id ) if(ref($patron->card));
200 $patron->billing_address( $patron->billing_address->id )
201 if(ref($patron->billing_address));
202 $patron->mailing_address( $patron->mailing_address->id )
203 if(ref($patron->mailing_address));
205 # create/update the patron first so we can use his id
206 if($patron->isnew()) {
207 ( $new_patron, $evt ) = _add_patron($session, _clone_patron($patron), $user_obj);
209 } else { $new_patron = $patron; }
211 ( $new_patron, $evt ) = _add_update_addresses($session, $patron, $new_patron, $user_obj);
214 ( $new_patron, $evt ) = _add_update_cards($session, $patron, $new_patron, $user_obj);
217 ( $new_patron, $evt ) = _add_survey_responses($session, $patron, $new_patron, $user_obj);
220 # re-update the patron if anything has happened to him during this process
221 if($new_patron->ischanged()) {
222 ( $new_patron, $evt ) = _update_patron($session, $new_patron, $user_obj);
226 #$session = OpenSRF::AppSession->create("open-ils.storage"); # why did i put this here?
228 ($new_patron, $evt) = _create_stat_maps($session, $user_session, $patron, $new_patron, $user_obj);
231 ($new_patron, $evt) = _create_perm_maps($session, $user_session, $patron, $new_patron, $user_obj);
234 ($new_patron, $evt) = _create_standing_penalties($session, $user_session, $patron, $new_patron, $user_obj);
237 $logger->activity("user ".$user_obj->id." updating/creating user ".$new_patron->id);
238 $apputils->commit_db_session($session);
240 #warn "Patron Update/Create complete\n";
241 return flesh_user($new_patron->id());
247 __PACKAGE__->register_method(
248 method => "user_retrieve_fleshed_by_id",
249 api_name => "open-ils.actor.user.fleshed.retrieve",);
251 sub user_retrieve_fleshed_by_id {
252 my( $self, $client, $user_session, $user_id ) = @_;
254 my( $requestor, $target, $evt ) = $apputils->
255 checkses_requestor( $user_session, $user_id, 'VIEW_USER' );
258 return flesh_user($user_id);
262 # fleshes: card, cards, address, addresses, stat_cat_entries, standing_penalties
270 $session = OpenSRF::AppSession->create("open-ils.storage");
274 # grab the user with the given id
275 my $ureq = $session->request(
276 "open-ils.storage.direct.actor.user.retrieve", $id);
277 my $user = $ureq->gather(1);
279 if(!$user) { return undef; }
282 my $cards_req = $session->request(
283 "open-ils.storage.direct.actor.card.search.usr.atomic",
285 $user->cards( $cards_req->gather(1) );
287 for my $c(@{$user->cards}) {
288 if($c->id == $user->card || $c->id eq $user->card ) {
289 #warn "Setting my card to " . $c->id . "\n";
294 my $add_req = $session->request(
295 "open-ils.storage.direct.actor.user_address.search.usr.atomic",
297 $user->addresses( $add_req->gather(1) );
299 if( @{$user->addresses} ) {
300 if( ! grep { $_->id eq $user->billing_address } @{$user->addresses} ) {
301 my $ba = $session->request(
302 'open-ils.storage.direct.actor.user_address.retrieve',
303 $user->billing_address)->gather(1);
304 push( @{$user->addresses}, $ba );
307 if( ! grep { $_->id eq $user->mailing_address } @{$user->addresses} ) {
308 my $ba = $session->request(
309 'open-ils.storage.direct.actor.user_address.retrieve',
310 $user->mailing_address)->gather(1);
311 push( @{$user->addresses}, $ba );
316 for my $c(@{$user->addresses}) {
317 if($c->id eq $user->billing_address ) { $user->billing_address($c); }
318 if($c->id eq $user->mailing_address ) { $user->mailing_address($c); }
321 my $stat_req = $session->request(
322 "open-ils.storage.direct.actor.stat_cat_entry_user_map.search.target_usr.atomic",
324 $user->stat_cat_entries($stat_req->gather(1));
326 my $standing_penalties_req = $session->request(
327 "open-ils.storage.direct.actor.user_standing_penalty.search.usr.atomic",
329 $user->standing_penalties($standing_penalties_req->gather(1));
331 if($kill) { $session->disconnect(); }
332 $user->clear_passwd();
338 # clone and clear stuff that would break the database
342 my $new_patron = $patron->clone;
344 # Using the Fieldmapper clone method
345 #my $new_patron = Fieldmapper::actor::user->new();
347 #my $fmap = $Fieldmapper::fieldmap;
348 #no strict; # shallow clone, may be useful in the fieldmapper
350 # (keys %{$fmap->{"Fieldmapper::actor::user"}->{'fields'}}) {
351 # $new_patron->$field( $patron->$field() );
356 $new_patron->clear_billing_address();
357 $new_patron->clear_mailing_address();
358 $new_patron->clear_addresses();
359 $new_patron->clear_card();
360 $new_patron->clear_cards();
361 $new_patron->clear_id();
362 $new_patron->clear_isnew();
363 $new_patron->clear_ischanged();
364 $new_patron->clear_isdeleted();
365 $new_patron->clear_stat_cat_entries();
366 $new_patron->clear_permissions();
367 $new_patron->clear_standing_penalties();
377 my $user_obj = shift;
379 my $evt = $U->check_perms($user_obj->id, $patron->home_ou, 'CREATE_USER');
380 return (undef, $evt) if $evt;
382 my $ex = $session->request(
383 'open-ils.storage.direct.actor.user.search.usrname', $patron->usrrname())->gather(1);
385 return (undef, OpenILS::Event->new('USERNAME_EXISTS'));
388 $logger->info("Creating new user in the DB with username: ".$patron->usrname());
390 my $id = $session->request(
391 "open-ils.storage.direct.actor.user.create", $patron)->gather(1);
392 return (undef, $U->DB_UPDATE_FAILED($patron)) unless $id;
394 $logger->info("Successfully created new user [$id] in DB");
396 return ( $session->request(
397 "open-ils.storage.direct.actor.user.retrieve", $id)->gather(1), undef );
402 my( $session, $patron, $user_obj, $noperm) = @_;
404 $logger->info("Updating patron ".$patron->id." in DB");
407 my $evt = $U->check_perms($user_obj->id, $patron->home_ou, 'UPDATE_USER');
408 return (undef, $evt) if $evt;
411 # update the password by itself to avoid the password protection magic
412 if( $patron->passwd ) {
413 my $s = $session->request(
414 'open-ils.storage.direct.actor.user.remote_update',
415 {id => $patron->id}, {passwd => $patron->passwd})->gather(1);
416 return (undef, $U->DB_UPDATE_FAILED($patron)) unless defined($s);
417 $patron->clear_passwd;
420 if(!$patron->ident_type) {
421 $patron->clear_ident_type;
422 $patron->clear_ident_value;
425 if(!$patron->ident_type2) {
426 $patron->clear_ident_type2;
427 $patron->clear_ident_value2;
430 my $stat = $session->request(
431 "open-ils.storage.direct.actor.user.update",$patron )->gather(1);
432 return (undef, $U->DB_UPDATE_FAILED($patron)) unless defined($stat);
438 sub _add_update_addresses {
442 my $new_patron = shift;
446 my $current_id; # id of the address before creation
448 for my $address (@{$patron->addresses()}) {
450 $address->usr($new_patron->id());
452 if(ref($address) and $address->isnew()) {
454 $current_id = $address->id();
455 ($address, $evt) = _add_address($session,$address);
456 return (undef, $evt) if $evt;
458 if( $patron->billing_address() and
459 $patron->billing_address() == $current_id ) {
460 $new_patron->billing_address($address->id());
461 $new_patron->ischanged(1);
464 if( $patron->mailing_address() and
465 $patron->mailing_address() == $current_id ) {
466 $new_patron->mailing_address($address->id());
467 $new_patron->ischanged(1);
470 } elsif( ref($address) and $address->ischanged() ) {
472 $address->usr($new_patron->id());
473 ($address, $evt) = _update_address($session, $address);
474 return (undef, $evt) if $evt;
476 } elsif( ref($address) and $address->isdeleted() ) {
478 if( $address->id() == $new_patron->mailing_address() ) {
479 $new_patron->clear_mailing_address();
480 ($new_patron, $evt) = _update_patron($session, $new_patron);
481 return (undef, $evt) if $evt;
484 if( $address->id() == $new_patron->billing_address() ) {
485 $new_patron->clear_billing_address();
486 ($new_patron, $evt) = _update_patron($session, $new_patron);
487 return (undef, $evt) if $evt;
490 $evt = _delete_address($session, $address);
491 return (undef, $evt) if $evt;
495 return ( $new_patron, undef );
499 # adds an address to the db and returns the address with new id
501 my($session, $address) = @_;
502 $address->clear_id();
504 $logger->info("Creating new address at street ".$address->street1);
506 # put the address into the database
507 my $id = $session->request(
508 "open-ils.storage.direct.actor.user_address.create", $address )->gather(1);
509 return (undef, $U->DB_UPDATE_FAILED($address)) unless $id;
512 return ($address, undef);
516 sub _update_address {
517 my( $session, $address ) = @_;
519 $logger->info("Updating address ".$address->id." in the DB");
521 my $stat = $session->request(
522 "open-ils.storage.direct.actor.user_address.update", $address )->gather(1);
524 return (undef, $U->DB_UPDATE_FAILED($address)) unless defined($stat);
525 return ($address, undef);
530 sub _add_update_cards {
534 my $new_patron = shift;
538 my $virtual_id; #id of the card before creation
539 for my $card (@{$patron->cards()}) {
541 $card->usr($new_patron->id());
543 if(ref($card) and $card->isnew()) {
545 $virtual_id = $card->id();
546 ( $card, $evt ) = _add_card($session,$card);
547 return (undef, $evt) if $evt;
549 #if(ref($patron->card)) { $patron->card($patron->card->id); }
550 if($patron->card() == $virtual_id) {
551 $new_patron->card($card->id());
552 $new_patron->ischanged(1);
555 } elsif( ref($card) and $card->ischanged() ) {
556 $card->usr($new_patron->id());
557 $evt = _update_card($session, $card);
558 return (undef, $evt) if $evt;
562 return ( $new_patron, undef );
566 # adds an card to the db and returns the card with new id
568 my( $session, $card ) = @_;
571 $logger->info("Adding new patron card ".$card->barcode);
573 my $id = $session->request(
574 "open-ils.storage.direct.actor.card.create", $card )->gather(1);
575 return (undef, $U->DB_UPDATE_FAILED($card)) unless $id;
576 $logger->info("Successfully created patron card $id");
579 return ( $card, undef );
583 # returns event on error. returns undef otherwise
585 my( $session, $card ) = @_;
586 $logger->info("Updating patron card ".$card->id);
588 my $stat = $session->request(
589 "open-ils.storage.direct.actor.card.update", $card )->gather(1);
590 return $U->DB_UPDATE_FAILED($card) unless defined($stat);
597 # returns event on error. returns undef otherwise
598 sub _delete_address {
599 my( $session, $address ) = @_;
601 $logger->info("Deleting address ".$address->id." from DB");
603 my $stat = $session->request(
604 "open-ils.storage.direct.actor.user_address.delete", $address )->gather(1);
606 return $U->DB_UPDATE_FAILED($address) unless defined($stat);
612 sub _add_survey_responses {
613 my ($session, $patron, $new_patron) = @_;
615 $logger->info( "Updating survey responses for patron ".$new_patron->id );
617 my $responses = $patron->survey_responses;
621 $_->usr($new_patron->id) for (@$responses);
623 my $evt = $U->simplereq( "open-ils.circ",
624 "open-ils.circ.survey.submit.user_id", $responses );
626 return (undef, $evt) if defined($U->event_code($evt));
630 return ( $new_patron, undef );
634 sub _create_stat_maps {
636 my($session, $user_session, $patron, $new_patron) = @_;
638 my $maps = $patron->stat_cat_entries();
640 for my $map (@$maps) {
642 my $method = "open-ils.storage.direct.actor.stat_cat_entry_user_map.update";
644 if ($map->isdeleted()) {
645 $method = "open-ils.storage.direct.actor.stat_cat_entry_user_map.delete";
647 } elsif ($map->isnew()) {
648 $method = "open-ils.storage.direct.actor.stat_cat_entry_user_map.create";
653 $map->target_usr($new_patron->id);
656 $logger->info("Updating stat entry with method $method and map $map");
658 my $stat = $session->request($method, $map)->gather(1);
659 return (undef, $U->DB_UPDATE_FAILED($map)) unless defined($stat);
663 return ($new_patron, undef);
666 sub _create_perm_maps {
668 my($session, $user_session, $patron, $new_patron) = @_;
670 my $maps = $patron->permissions;
672 for my $map (@$maps) {
674 my $method = "open-ils.storage.direct.permission.usr_perm_map.update";
675 if ($map->isdeleted()) {
676 $method = "open-ils.storage.direct.permission.usr_perm_map.delete";
677 } elsif ($map->isnew()) {
678 $method = "open-ils.storage.direct.permission.usr_perm_map.create";
683 $map->usr($new_patron->id);
685 #warn( "Updating permissions with method $method and session $user_session and map $map" );
686 $logger->info( "Updating permissions with method $method and map $map" );
688 my $stat = $session->request($method, $map)->gather(1);
689 return (undef, $U->DB_UPDATE_FAILED($map)) unless defined($stat);
693 return ($new_patron, undef);
697 sub _create_standing_penalties {
699 my($session, $user_session, $patron, $new_patron) = @_;
701 my $maps = $patron->standing_penalties;
704 for my $map (@$maps) {
706 if ($map->isdeleted()) {
707 $method = "open-ils.storage.direct.actor.user_standing_penalty.delete";
708 } elsif ($map->isnew()) {
709 $method = "open-ils.storage.direct.actor.user_standing_penalty.create";
715 $map->usr($new_patron->id);
717 $logger->debug( "Updating standing penalty with method $method and session $user_session and map $map" );
719 my $stat = $session->request($method, $map)->gather(1);
720 return (undef, $U->DB_UPDATE_FAILED($map)) unless $stat;
723 return ($new_patron, undef);
728 __PACKAGE__->register_method(
729 method => "search_username",
730 api_name => "open-ils.actor.user.search.username",
733 sub search_username {
734 my($self, $client, $username) = @_;
735 my $users = OpenILS::Application::AppUtils->simple_scalar_request(
737 "open-ils.storage.direct.actor.user.search.usrname.atomic",
745 __PACKAGE__->register_method(
746 method => "user_retrieve_by_barcode",
747 api_name => "open-ils.actor.user.fleshed.retrieve_by_barcode",);
749 sub user_retrieve_by_barcode {
750 my($self, $client, $user_session, $barcode) = @_;
752 $logger->debug("Searching for user with barcode $barcode");
753 my ($user_obj, $evt) = $apputils->checkses($user_session);
757 my $session = OpenSRF::AppSession->create("open-ils.storage");
759 # find the card with the given barcode
760 my $creq = $session->request(
761 "open-ils.storage.direct.actor.card.search.barcode.atomic",
763 my $card = $creq->gather(1);
765 if(!$card || !$card->[0]) {
766 $session->disconnect();
767 return OpenILS::Event->new( 'ACTOR_USER_NOT_FOUND' );
771 my $user = flesh_user($card->usr(), $session);
773 $evt = $U->check_perms($user_obj->id, $user->home_ou, 'VIEW_USER');
776 $session->disconnect();
777 if(!$user) { return OpenILS::Event->new( 'ACTOR_USER_NOT_FOUND' ); }
784 __PACKAGE__->register_method(
785 method => "get_user_by_id",
786 api_name => "open-ils.actor.user.retrieve",);
789 my ($self, $client, $user_session, $id) = @_;
791 my $user_obj = $apputils->check_user_session( $user_session );
793 return $apputils->simple_scalar_request(
795 "open-ils.storage.direct.actor.user.retrieve",
801 __PACKAGE__->register_method(
802 method => "get_org_types",
803 api_name => "open-ils.actor.org_types.retrieve",);
807 my($self, $client) = @_;
809 return $org_types if $org_types;
811 $apputils->simple_scalar_request(
813 "open-ils.storage.direct.actor.org_unit_type.retrieve.all.atomic" );
818 __PACKAGE__->register_method(
819 method => "get_user_profiles",
820 api_name => "open-ils.actor.user.profiles.retrieve",
824 sub get_user_profiles {
825 return $user_profiles if $user_profiles;
827 return $user_profiles =
828 $apputils->simple_scalar_request(
830 "open-ils.storage.direct.actor.profile.retrieve.all.atomic");
835 __PACKAGE__->register_method(
836 method => "get_user_ident_types",
837 api_name => "open-ils.actor.user.ident_types.retrieve",
840 sub get_user_ident_types {
841 return $ident_types if $ident_types;
842 return $ident_types =
843 $apputils->simple_scalar_request(
845 "open-ils.storage.direct.config.identification_type.retrieve.all.atomic" );
851 __PACKAGE__->register_method(
852 method => "get_org_unit",
853 api_name => "open-ils.actor.org_unit.retrieve",
858 my( $self, $client, $user_session, $org_id ) = @_;
860 if(defined($user_session) && !defined($org_id)) {
862 OpenILS::Application::AppUtils->check_user_session( $user_session ); #throws EX on error
863 if(!defined($org_id)) {
864 $org_id = $user_obj->home_ou;
869 my $home_ou = OpenILS::Application::AppUtils->simple_scalar_request(
871 "open-ils.storage.direct.actor.org_unit.retrieve",
877 __PACKAGE__->register_method(
878 method => "search_org_unit",
879 api_name => "open-ils.actor.org_unit_list.search",
882 sub search_org_unit {
884 my( $self, $client, $field, $value ) = @_;
886 my $list = OpenILS::Application::AppUtils->simple_scalar_request(
888 "open-ils.storage.direct.actor.org_unit.search.$field.atomic",
897 __PACKAGE__->register_method(
898 method => "get_org_tree",
899 api_name => "open-ils.actor.org_tree.retrieve",
901 note => "Returns the entire org tree structure",
905 my( $self, $client) = @_;
908 $cache_client = OpenSRF::Utils::Cache->new("global", 0);
910 # see if it's in the cache
911 #warn "Getting ORG Tree\n";
912 my $tree = $cache_client->get_cache('orgtree');
914 #warn "Found orgtree in cache. returning...\n";
918 my $orglist = $apputils->simple_scalar_request(
920 "open-ils.storage.direct.actor.org_unit.retrieve.all.atomic" );
923 #warn "found org list\n";
926 $tree = $self->build_org_tree($orglist);
927 $cache_client->put_cache('orgtree', $tree);
933 # turns an org list into an org tree
936 my( $self, $orglist) = @_;
938 return $orglist unless (
939 ref($orglist) and @$orglist > 1 );
942 $a->ou_type <=> $b->ou_type ||
943 $a->name cmp $b->name } @$orglist;
945 for my $org (@list) {
947 next unless ($org and defined($org->parent_ou));
948 my ($parent) = grep { $_->id == $org->parent_ou } @list;
951 $parent->children([]) unless defined($parent->children);
952 push( @{$parent->children}, $org );
960 __PACKAGE__->register_method(
961 method => "get_org_descendants",
962 api_name => "open-ils.actor.org_tree.descendants.retrieve"
965 # depth is optional. org_unit is the id
966 sub get_org_descendants {
967 my( $self, $client, $org_unit, $depth ) = @_;
968 my $orglist = $apputils->simple_scalar_request(
970 "open-ils.storage.actor.org_unit.descendants.atomic",
972 return $self->build_org_tree($orglist);
976 __PACKAGE__->register_method(
977 method => "get_org_ancestors",
978 api_name => "open-ils.actor.org_tree.ancestors.retrieve"
981 # depth is optional. org_unit is the id
982 sub get_org_ancestors {
983 my( $self, $client, $org_unit, $depth ) = @_;
984 my $orglist = $apputils->simple_scalar_request(
986 "open-ils.storage.actor.org_unit.ancestors.atomic",
988 return $self->build_org_tree($orglist);
992 __PACKAGE__->register_method(
993 method => "get_standings",
994 api_name => "open-ils.actor.standings.retrieve"
999 return $user_standings if $user_standings;
1000 return $user_standings =
1001 $apputils->simple_scalar_request(
1003 "open-ils.storage.direct.config.standing.retrieve.all.atomic" );
1008 __PACKAGE__->register_method(
1009 method => "get_my_org_path",
1010 api_name => "open-ils.actor.org_unit.full_path.retrieve"
1013 sub get_my_org_path {
1014 my( $self, $client, $user_session, $org_id ) = @_;
1015 my $user_obj = $apputils->check_user_session($user_session);
1016 if(!defined($org_id)) { $org_id = $user_obj->home_ou; }
1018 return $apputils->simple_scalar_request(
1020 "open-ils.storage.actor.org_unit.full_path.atomic",
1025 __PACKAGE__->register_method(
1026 method => "patron_adv_search",
1027 api_name => "open-ils.actor.patron.search.advanced" );
1028 sub patron_adv_search {
1029 my( $self, $client, $auth, $search_hash, $search_limit, $search_sort ) = @_;
1030 my $e = OpenILS::Utils::Editor->new(authtoken=>$auth);
1031 return $e->event unless $e->checkauth;
1032 return $e->event unless $e->allowed('VIEW_USER');
1034 "open-ils.storage.actor.user.crazy_search",
1035 $search_hash, $search_limit, $search_sort);
1040 sub _verify_password {
1041 my($user_session, $password) = @_;
1042 my $user_obj = $apputils->check_user_session($user_session);
1044 #grab the user with password
1045 $user_obj = $apputils->simple_scalar_request(
1047 "open-ils.storage.direct.actor.user.retrieve",
1050 if($user_obj->passwd eq $password) {
1058 __PACKAGE__->register_method(
1059 method => "update_password",
1060 api_name => "open-ils.actor.user.password.update");
1062 __PACKAGE__->register_method(
1063 method => "update_password",
1064 api_name => "open-ils.actor.user.username.update");
1066 __PACKAGE__->register_method(
1067 method => "update_password",
1068 api_name => "open-ils.actor.user.email.update");
1070 sub update_password {
1071 my( $self, $client, $user_session, $new_value, $current_password ) = @_;
1075 my $user_obj = $apputils->check_user_session($user_session);
1077 if($self->api_name =~ /password/o) {
1079 #make sure they know the current password
1080 if(!_verify_password($user_session, md5_hex($current_password))) {
1081 return OpenILS::Event->new('INCORRECT_PASSWORD');
1084 $logger->debug("update_password setting new password $new_value");
1085 $user_obj->passwd($new_value);
1087 } elsif($self->api_name =~ /username/o) {
1088 my $users = search_username(undef, undef, $new_value);
1089 if( $users and $users->[0] ) {
1090 return OpenILS::Event->new('USERNAME_EXISTS');
1092 $user_obj->usrname($new_value);
1094 } elsif($self->api_name =~ /email/o) {
1095 #warn "Updating email to $new_value\n";
1096 $user_obj->email($new_value);
1099 my $session = $apputils->start_db_session();
1101 ( $user_obj, $evt ) = _update_patron($session, $user_obj, $user_obj, 1);
1102 return $evt if $evt;
1104 $apputils->commit_db_session($session);
1106 if($user_obj) { return 1; }
1111 __PACKAGE__->register_method(
1112 method => "check_user_perms",
1113 api_name => "open-ils.actor.user.perm.check",
1114 notes => <<" NOTES");
1115 Takes a login session, user id, an org id, and an array of perm type strings. For each
1116 perm type, if the user does *not* have the given permission it is added
1117 to a list which is returned from the method. If all permissions
1118 are allowed, an empty list is returned
1119 if the logged in user does not match 'user_id', then the logged in user must
1120 have VIEW_PERMISSION priveleges.
1123 sub check_user_perms {
1124 my( $self, $client, $login_session, $user_id, $org_id, $perm_types ) = @_;
1126 my( $staff, $evt ) = $apputils->checkses($login_session);
1127 return $evt if $evt;
1129 if($staff->id ne $user_id) {
1130 if( my $evt = $apputils->check_perms(
1131 $staff->id, $org_id, 'VIEW_PERMISSION') ) {
1137 for my $perm (@$perm_types) {
1138 if($apputils->check_perms($user_id, $org_id, $perm)) {
1139 push @not_allowed, $perm;
1143 return \@not_allowed
1146 __PACKAGE__->register_method(
1147 method => "check_user_perms2",
1148 api_name => "open-ils.actor.user.perm.check.multi_org",
1150 Checks the permissions on a list of perms and orgs for a user
1151 @param authtoken The login session key
1152 @param user_id The id of the user to check
1153 @param orgs The array of org ids
1154 @param perms The array of permission names
1155 @return An array of [ orgId, permissionName ] arrays that FAILED the check
1156 if the logged in user does not match 'user_id', then the logged in user must
1157 have VIEW_PERMISSION priveleges.
1160 sub check_user_perms2 {
1161 my( $self, $client, $authtoken, $user_id, $orgs, $perms ) = @_;
1163 my( $staff, $target, $evt ) = $apputils->checkses_requestor(
1164 $authtoken, $user_id, 'VIEW_PERMISSION' );
1165 return $evt if $evt;
1168 for my $org (@$orgs) {
1169 for my $perm (@$perms) {
1170 if($apputils->check_perms($user_id, $org, $perm)) {
1171 push @not_allowed, [ $org, $perm ];
1176 return \@not_allowed
1180 __PACKAGE__->register_method(
1181 method => 'check_user_perms3',
1182 api_name => 'open-ils.actor.user.perm.highest_org',
1184 Returns the highest org unit id at which a user has a given permission
1185 If the requestor does not match the target user, the requestor must have
1186 'VIEW_PERMISSION' rights at the home org unit of the target user
1187 @param authtoken The login session key
1188 @param userid The id of the user in question
1189 @param perm The permission to check
1190 @return The org unit highest in the org tree within which the user has
1191 the requested permission
1194 sub check_user_perms3 {
1195 my( $self, $client, $authtoken, $userid, $perm ) = @_;
1197 my( $staff, $target, $org, $evt );
1199 ( $staff, $target, $evt ) = $apputils->checkses_requestor(
1200 $authtoken, $userid, 'VIEW_PERMISSION' );
1201 return $evt if $evt;
1203 my $tree = $self->get_org_tree();
1204 return _find_highest_perm_org( $perm, $userid, $target->home_ou, $tree );
1208 sub _find_highest_perm_org {
1209 my ( $perm, $userid, $start_org, $org_tree ) = @_;
1210 my $org = $apputils->find_org($org_tree, $start_org );
1214 last if ($apputils->check_perms( $userid, $org->id, $perm )); # perm failed
1216 $org = $apputils->find_org( $org_tree, $org->parent_ou() );
1222 __PACKAGE__->register_method(
1223 method => 'check_user_perms4',
1224 api_name => 'open-ils.actor.user.perm.highest_org.batch',
1226 Returns the highest org unit id at which a user has a given permission
1227 If the requestor does not match the target user, the requestor must have
1228 'VIEW_PERMISSION' rights at the home org unit of the target user
1229 @param authtoken The login session key
1230 @param userid The id of the user in question
1231 @param perms An array of perm names to check
1232 @return An array of orgId's representing the org unit
1233 highest in the org tree within which the user has the requested permission
1234 The arrah of orgId's has matches the order of the perms array
1237 sub check_user_perms4 {
1238 my( $self, $client, $authtoken, $userid, $perms ) = @_;
1240 my( $staff, $target, $org, $evt );
1242 ( $staff, $target, $evt ) = $apputils->checkses_requestor(
1243 $authtoken, $userid, 'VIEW_PERMISSION' );
1244 return $evt if $evt;
1247 return [] unless ref($perms);
1248 my $tree = $self->get_org_tree();
1250 for my $p (@$perms) {
1251 push( @arr, _find_highest_perm_org( $p, $userid, $target->home_ou, $tree ) );
1259 __PACKAGE__->register_method(
1260 method => "user_fines_summary",
1261 api_name => "open-ils.actor.user.fines.summary",
1262 notes => <<" NOTES");
1263 Returns a short summary of the users total open fines, excluding voided fines
1264 Params are login_session, user_id
1265 Returns a 'mous' object.
1268 sub user_fines_summary {
1269 my( $self, $client, $login_session, $user_id ) = @_;
1271 my $user_obj = $apputils->check_user_session($login_session);
1272 if($user_obj->id ne $user_id) {
1273 if($apputils->check_user_perms($user_obj->id, $user_obj->home_ou, "VIEW_USER_FINES_SUMMARY")) {
1274 return OpenILS::Perm->new("VIEW_USER_FINES_SUMMARY");
1278 return $apputils->simple_scalar_request(
1280 "open-ils.storage.direct.money.open_user_summary.search.usr",
1288 __PACKAGE__->register_method(
1289 method => "user_transactions",
1290 api_name => "open-ils.actor.user.transactions",
1291 notes => <<" NOTES");
1292 Returns a list of open user transactions (mbts objects);
1293 Params are login_session, user_id
1294 Optional third parameter is the transactions type. defaults to all
1297 __PACKAGE__->register_method(
1298 method => "user_transactions",
1299 api_name => "open-ils.actor.user.transactions.have_charge",
1300 notes => <<" NOTES");
1301 Returns a list of all open user transactions (mbts objects) that have an initial charge
1302 Params are login_session, user_id
1303 Optional third parameter is the transactions type. defaults to all
1306 __PACKAGE__->register_method(
1307 method => "user_transactions",
1308 api_name => "open-ils.actor.user.transactions.have_balance",
1309 notes => <<" NOTES");
1310 Returns a list of all open user transactions (mbts objects) that have a balance
1311 Params are login_session, user_id
1312 Optional third parameter is the transactions type. defaults to all
1315 __PACKAGE__->register_method(
1316 method => "user_transactions",
1317 api_name => "open-ils.actor.user.transactions.fleshed",
1318 notes => <<" NOTES");
1319 Returns an object/hash of transaction, circ, title where transaction = an open
1320 user transactions (mbts objects), circ is the attached circluation, and title
1321 is the title the circ points to
1322 Params are login_session, user_id
1323 Optional third parameter is the transactions type. defaults to all
1326 __PACKAGE__->register_method(
1327 method => "user_transactions",
1328 api_name => "open-ils.actor.user.transactions.have_charge.fleshed",
1329 notes => <<" NOTES");
1330 Returns an object/hash of transaction, circ, title where transaction = an open
1331 user transactions that has an initial charge (mbts objects), circ is the
1332 attached circluation, and title is the title the circ points to
1333 Params are login_session, user_id
1334 Optional third parameter is the transactions type. defaults to all
1337 __PACKAGE__->register_method(
1338 method => "user_transactions",
1339 api_name => "open-ils.actor.user.transactions.have_balance.fleshed",
1340 notes => <<" NOTES");
1341 Returns an object/hash of transaction, circ, title where transaction = an open
1342 user transaction that has a balance (mbts objects), circ is the attached
1343 circluation, and title is the title the circ points to
1344 Params are login_session, user_id
1345 Optional third parameter is the transaction type. defaults to all
1348 __PACKAGE__->register_method(
1349 method => "user_transactions",
1350 api_name => "open-ils.actor.user.transactions.count",
1351 notes => <<" NOTES");
1352 Returns an object/hash of transaction, circ, title where transaction = an open
1353 user transactions (mbts objects), circ is the attached circluation, and title
1354 is the title the circ points to
1355 Params are login_session, user_id
1356 Optional third parameter is the transactions type. defaults to all
1359 __PACKAGE__->register_method(
1360 method => "user_transactions",
1361 api_name => "open-ils.actor.user.transactions.have_charge.count",
1362 notes => <<" NOTES");
1363 Returns an object/hash of transaction, circ, title where transaction = an open
1364 user transactions that has an initial charge (mbts objects), circ is the
1365 attached circluation, and title is the title the circ points to
1366 Params are login_session, user_id
1367 Optional third parameter is the transactions type. defaults to all
1370 __PACKAGE__->register_method(
1371 method => "user_transactions",
1372 api_name => "open-ils.actor.user.transactions.have_balance.count",
1373 notes => <<" NOTES");
1374 Returns an object/hash of transaction, circ, title where transaction = an open
1375 user transaction that has a balance (mbts objects), circ is the attached
1376 circluation, and title is the title the circ points to
1377 Params are login_session, user_id
1378 Optional third parameter is the transaction type. defaults to all
1381 __PACKAGE__->register_method(
1382 method => "user_transactions",
1383 api_name => "open-ils.actor.user.transactions.have_balance.total",
1384 notes => <<" NOTES");
1385 Returns an object/hash of transaction, circ, title where transaction = an open
1386 user transaction that has a balance (mbts objects), circ is the attached
1387 circluation, and title is the title the circ points to
1388 Params are login_session, user_id
1389 Optional third parameter is the transaction type. defaults to all
1394 sub user_transactions {
1395 my( $self, $client, $login_session, $user_id, $type ) = @_;
1397 my( $user_obj, $target, $evt ) = $apputils->checkses_requestor(
1398 $login_session, $user_id, 'VIEW_USER_TRANSACTIONS' );
1399 return $evt if $evt;
1401 my $api = $self->api_name();
1405 if(defined($type)) { @xact = (xact_type => $type);
1407 } else { @xact = (); }
1409 if($api =~ /have_charge/o) {
1411 $trans = $apputils->simple_scalar_request(
1413 "open-ils.storage.direct.money.open_billable_transaction_summary.search_where.atomic",
1414 { usr => $user_id, total_owed => { ">" => 0 }, @xact });
1416 } elsif($api =~ /have_balance/o) {
1418 $trans = $apputils->simple_scalar_request(
1420 "open-ils.storage.direct.money.open_billable_transaction_summary.search_where.atomic",
1421 { usr => $user_id, balance_owed => { "<>" => 0 }, @xact });
1425 $trans = $apputils->simple_scalar_request(
1427 "open-ils.storage.direct.money.open_billable_transaction_summary.search_where.atomic",
1428 { usr => $user_id, @xact });
1431 if($api =~ /total/o) {
1433 for my $t (@$trans) {
1434 $total += $t->balance_owed;
1437 $logger->debug("Total balance owed by user $user_id: $total");
1441 if($api =~ /count/o) { return scalar @$trans; }
1442 if($api !~ /fleshed/o) { return $trans; }
1445 for my $t (@$trans) {
1447 if( $t->xact_type ne 'circulation' ) {
1448 push @resp, {transaction => $t};
1452 my $circ = $apputils->simple_scalar_request(
1454 "open-ils.storage.direct.action.circulation.retrieve",
1459 my $title = $apputils->simple_scalar_request(
1461 "open-ils.storage.fleshed.biblio.record_entry.retrieve_by_copy",
1462 $circ->target_copy );
1466 my $u = OpenILS::Utils::ModsParser->new();
1467 $u->start_mods_batch($title->marc());
1468 my $mods = $u->finish_mods_batch();
1470 push @resp, {transaction => $t, circ => $circ, record => $mods };
1478 __PACKAGE__->register_method(
1479 method => "user_transaction_retrieve",
1480 api_name => "open-ils.actor.user.transaction.fleshed.retrieve",
1482 notes => <<" NOTES");
1483 Returns a fleshedtransaction record
1485 __PACKAGE__->register_method(
1486 method => "user_transaction_retrieve",
1487 api_name => "open-ils.actor.user.transaction.retrieve",
1489 notes => <<" NOTES");
1490 Returns a transaction record
1492 sub user_transaction_retrieve {
1493 my( $self, $client, $login_session, $bill_id ) = @_;
1495 my $trans = $apputils->simple_scalar_request(
1497 "open-ils.storage.direct.money.billable_transaction_summary.retrieve",
1501 my( $user_obj, $target, $evt ) = $apputils->checkses_requestor(
1502 $login_session, $trans->usr, 'VIEW_USER_TRANSACTIONS' );
1503 return $evt if $evt;
1505 my $api = $self->api_name();
1506 if($api !~ /fleshed/o) { return $trans; }
1508 if( $trans->xact_type ne 'circulation' ) {
1509 $logger->debug("Returning non-circ transaction");
1510 return {transaction => $trans};
1513 my $circ = $apputils->simple_scalar_request(
1515 "open-ils.storage.direct.action.circulation.retrieve",
1518 return {transaction => $trans} unless $circ;
1519 $logger->debug("Found the circ transaction");
1521 my $title = $apputils->simple_scalar_request(
1523 "open-ils.storage.fleshed.biblio.record_entry.retrieve_by_copy",
1524 $circ->target_copy );
1526 return {transaction => $trans, circ => $circ } unless $title;
1527 $logger->debug("Found the circ title");
1531 my $u = OpenILS::Utils::ModsParser->new();
1532 $u->start_mods_batch($title->marc());
1533 $mods = $u->finish_mods_batch();
1535 if ($title->id == -1) {
1536 my $copy = $apputils->simple_scalar_request(
1538 "open-ils.storage.direct.asset.copy.retrieve",
1539 $circ->target_copy );
1541 $mods = new Fieldmapper::metabib::virtual_record;
1543 $mods->title($copy->dummy_title);
1544 $mods->author($copy->dummy_author);
1548 $logger->debug("MODSized the circ title");
1550 return {transaction => $trans, circ => $circ, record => $mods };
1554 __PACKAGE__->register_method(
1555 method => "hold_request_count",
1556 api_name => "open-ils.actor.user.hold_requests.count",
1558 notes => <<" NOTES");
1559 Returns hold ready/total counts
1561 sub hold_request_count {
1562 my( $self, $client, $login_session, $userid ) = @_;
1564 my( $user_obj, $target, $evt ) = $apputils->checkses_requestor(
1565 $login_session, $userid, 'VIEW_HOLD' );
1566 return $evt if $evt;
1569 my $holds = $apputils->simple_scalar_request(
1571 "open-ils.storage.direct.action.hold_request.search_where.atomic",
1573 fulfillment_time => {"=" => undef } }
1577 for my $h (@$holds) {
1578 next unless $h->capture_time;
1580 my $copy = $apputils->simple_scalar_request(
1582 "open-ils.storage.direct.asset.copy.retrieve",
1586 if ($copy->status == 8) {
1591 return { total => scalar(@$holds), ready => scalar(@ready) };
1595 __PACKAGE__->register_method(
1596 method => "checkedout_count",
1597 api_name => "open-ils.actor.user.checked_out.count",
1599 notes => <<" NOTES");
1600 Returns a transaction record
1602 sub checkedout_count {
1603 my( $self, $client, $login_session, $userid ) = @_;
1605 my( $user_obj, $target, $evt ) = $apputils->checkses_requestor(
1606 $login_session, $userid, 'VIEW_CIRCULATIONS' );
1607 return $evt if $evt;
1610 my $circs = $apputils->simple_scalar_request(
1612 "open-ils.storage.direct.action.circulation.search_where.atomic",
1614 checkin_time => {"=" => undef } }
1617 my $parser = DateTime::Format::ISO8601->new;
1620 for my $c (@$circs) {
1621 my $due_dt = $parser->parse_datetime( clense_ISO8601( $c->due_date ) );
1622 my $due = $due_dt->epoch;
1624 if ($due < DateTime->today->epoch) {
1629 return { total => scalar(@$circs), overdue => scalar(@overdue) };
1632 __PACKAGE__->register_method(
1633 method => "user_transaction_history",
1634 api_name => "open-ils.actor.user.transactions.history",
1636 notes => <<" NOTES");
1637 Returns a list of billable transaction ids for a user, optionally by type
1639 __PACKAGE__->register_method(
1640 method => "user_transaction_history",
1641 api_name => "open-ils.actor.user.transactions.history.have_charge",
1643 notes => <<" NOTES");
1644 Returns a list of billable transaction ids for a user that have an initial charge, optionally by type
1646 sub user_transaction_history {
1647 my( $self, $client, $login_session, $user_id, $type ) = @_;
1649 my( $user_obj, $target, $evt ) = $apputils->checkses_requestor(
1650 $login_session, $user_id, 'VIEW_USER_TRANSACTIONS' );
1651 return $evt if $evt;
1653 my $api = $self->api_name();
1657 @xact = (xact_type => $type) if(defined($type));
1658 @charge = (total_owed => { ">" => 0}) if($api =~ /have_charge/);
1660 my $trans = $apputils->simple_scalar_request(
1662 "open-ils.storage.direct.money.billable_transaction_summary.search_where.atomic",
1663 { usr => $user_id, @xact, @charge }, { order_by => 'xact_start DESC' });
1665 return [ map { $_->id } @$trans ];
1669 __PACKAGE__->register_method(
1670 method => "user_perms",
1671 api_name => "open-ils.actor.permissions.user_perms.retrieve",
1673 notes => <<" NOTES");
1674 Returns a list of permissions
1677 my( $self, $client, $authtoken, $user ) = @_;
1679 my( $staff, $evt ) = $apputils->checkses($authtoken);
1680 return $evt if $evt;
1682 $user ||= $staff->id;
1684 if( $user != $staff->id and $evt = $apputils->check_perms( $staff->id, $staff->home_ou, 'VIEW_PERMISSION') ) {
1688 return $apputils->simple_scalar_request(
1690 "open-ils.storage.permission.user_perms.atomic",
1694 __PACKAGE__->register_method(
1695 method => "retrieve_perms",
1696 api_name => "open-ils.actor.permissions.retrieve",
1697 notes => <<" NOTES");
1698 Returns a list of permissions
1700 sub retrieve_perms {
1701 my( $self, $client ) = @_;
1702 return $apputils->simple_scalar_request(
1704 "open-ils.storage.direct.permission.perm_list.retrieve.all.atomic");
1707 __PACKAGE__->register_method(
1708 method => "retrieve_groups",
1709 api_name => "open-ils.actor.groups.retrieve",
1710 notes => <<" NOTES");
1711 Returns a list of user groupss
1713 sub retrieve_groups {
1714 my( $self, $client ) = @_;
1715 return $apputils->simple_scalar_request(
1717 "open-ils.storage.direct.permission.grp_tree.retrieve.all.atomic");
1720 __PACKAGE__->register_method(
1721 method => "retrieve_org_address",
1722 api_name => "open-ils.actor.org_unit.address.retrieve",
1723 notes => <<' NOTES');
1724 Returns an org_unit address by ID
1725 @param An org_address ID
1727 sub retrieve_org_address {
1728 my( $self, $client, $id ) = @_;
1729 return $apputils->simple_scalar_request(
1731 "open-ils.storage.direct.actor.org_address.retrieve",
1736 __PACKAGE__->register_method(
1737 method => "retrieve_groups_tree",
1738 api_name => "open-ils.actor.groups.tree.retrieve",
1739 notes => <<" NOTES");
1740 Returns a list of user groups
1742 sub retrieve_groups_tree {
1743 my( $self, $client ) = @_;
1744 my $groups = $apputils->simple_scalar_request(
1746 "open-ils.storage.direct.permission.grp_tree.retrieve.all.atomic");
1747 return $self->build_group_tree($groups);
1751 # turns an org list into an org tree
1752 sub build_group_tree {
1754 my( $self, $grplist) = @_;
1756 return $grplist unless (
1757 ref($grplist) and @$grplist > 1 );
1759 my @list = sort { $a->name cmp $b->name } @$grplist;
1762 for my $grp (@list) {
1764 if ($grp and !defined($grp->parent)) {
1768 my ($parent) = grep { $_->id == $grp->parent} @list;
1770 $parent->children([]) unless defined($parent->children);
1771 push( @{$parent->children}, $grp );
1779 __PACKAGE__->register_method(
1780 method => "add_user_to_groups",
1781 api_name => "open-ils.actor.user.set_groups",
1782 notes => <<" NOTES");
1783 Adds a user to one or more permission groups
1786 sub add_user_to_groups {
1787 my( $self, $client, $authtoken, $userid, $groups ) = @_;
1789 my( $requestor, $target, $evt ) = $apputils->checkses_requestor(
1790 $authtoken, $userid, 'CREATE_USER_GROUP_LINK' );
1791 return $evt if $evt;
1793 ( $requestor, $target, $evt ) = $apputils->checkses_requestor(
1794 $authtoken, $userid, 'REMOVE_USER_GROUP_LINK' );
1795 return $evt if $evt;
1797 $apputils->simplereq(
1799 'open-ils.storage.direct.permission.usr_grp_map.mass_delete', { usr => $userid } );
1801 for my $group (@$groups) {
1802 my $link = Fieldmapper::permission::usr_grp_map->new;
1804 $link->usr($userid);
1806 my $id = $apputils->simplereq(
1808 'open-ils.storage.direct.permission.usr_grp_map.create', $link );
1814 __PACKAGE__->register_method(
1815 method => "get_user_perm_groups",
1816 api_name => "open-ils.actor.user.get_groups",
1817 notes => <<" NOTES");
1818 Retrieve a user's permission groups.
1822 sub get_user_perm_groups {
1823 my( $self, $client, $authtoken, $userid ) = @_;
1825 my( $requestor, $target, $evt ) = $apputils->checkses_requestor(
1826 $authtoken, $userid, 'VIEW_PERM_GROUPS' );
1827 return $evt if $evt;
1829 return $apputils->simplereq(
1831 'open-ils.storage.direct.permission.usr_grp_map.search.usr.atomic', $userid );
1836 __PACKAGE__->register_method (
1837 method => 'register_workstation',
1838 api_name => 'open-ils.actor.workstation.register.override',
1839 signature => q/@see open-ils.actor.workstation.register/);
1841 __PACKAGE__->register_method (
1842 method => 'register_workstation',
1843 api_name => 'open-ils.actor.workstation.register',
1845 Registers a new workstion in the system
1846 @param authtoken The login session key
1847 @param name The name of the workstation id
1848 @param owner The org unit that owns this workstation
1849 @return The workstation id on success, WORKSTATION_NAME_EXISTS
1850 if the name is already in use.
1853 sub _register_workstation {
1854 my( $self, $connection, $authtoken, $name, $owner ) = @_;
1855 my( $requestor, $evt ) = $U->checkses($authtoken);
1856 return $evt if $evt;
1857 $evt = $U->check_perms($requestor->id, $owner, 'REGISTER_WORKSTATION');
1858 return $evt if $evt;
1860 my $ws = $U->storagereq(
1861 'open-ils.storage.direct.actor.workstation.search.name', $name );
1862 return OpenILS::Event->new('WORKSTATION_NAME_EXISTS') if $ws;
1864 $ws = Fieldmapper::actor::workstation->new;
1865 $ws->owning_lib($owner);
1868 my $id = $U->storagereq(
1869 'open-ils.storage.direct.actor.workstation.create', $ws );
1870 return $U->DB_UPDATE_FAILED($ws) unless $id;
1876 sub register_workstation {
1877 my( $self, $conn, $authtoken, $name, $owner ) = @_;
1879 my $e = OpenILS::Utils::Editor->new(authtoken=>$authtoken, xact=>1);
1880 return $e->event unless $e->checkauth;
1881 return $e->event unless $e->allowed('REGISTER_WORKSTATION'); # XXX rely on editor perms
1882 my $existing = $e->search_actor_workstation({name => $name});
1885 if( $self->api_name =~ /override/o ) {
1886 return $e->event unless $e->allowed('DELETE_WORKSTATION'); # XXX rely on editor perms
1887 return $e->event unless $e->delete_actor_workstation($$existing[0]);
1889 return OpenILS::Event->new('WORKSTATION_NAME_EXISTS')
1893 my $ws = Fieldmapper::actor::workstation->new;
1894 $ws->owning_lib($owner);
1896 $e->create_actor_workstation($ws) or return $e->event;
1898 return $ws->id; # note: editor sets the id on the new object for us
1902 __PACKAGE__->register_method (
1903 method => 'fetch_patron_note',
1904 api_name => 'open-ils.actor.note.retrieve.all',
1906 Returns a list of notes for a given user
1907 Requestor must have VIEW_USER permission if pub==false and
1908 @param authtoken The login session key
1909 @param args Hash of params including
1910 patronid : the patron's id
1911 pub : true if retrieving only public notes
1915 sub fetch_patron_note {
1916 my( $self, $conn, $authtoken, $args ) = @_;
1917 my $patronid = $$args{patronid};
1919 my($reqr, $evt) = $U->checkses($authtoken);
1922 ($patron, $evt) = $U->fetch_user($patronid);
1923 return $evt if $evt;
1926 if( $patronid ne $reqr->id ) {
1927 $evt = $U->check_perms($reqr->id, $patron->home_ou, 'VIEW_USER');
1928 return $evt if $evt;
1930 return $U->storagereq(
1931 'open-ils.storage.direct.actor.usr_note.search_where.atomic',
1932 { usr => $patronid, pub => 't' } );
1935 $evt = $U->check_perms($reqr->id, $patron->home_ou, 'VIEW_USER');
1936 return $evt if $evt;
1938 return $U->storagereq(
1939 'open-ils.storage.direct.actor.usr_note.search.usr.atomic', $patronid );
1942 __PACKAGE__->register_method (
1943 method => 'create_user_note',
1944 api_name => 'open-ils.actor.note.create',
1946 Creates a new note for the given user
1947 @param authtoken The login session key
1948 @param note The note object
1951 sub create_user_note {
1952 my( $self, $conn, $authtoken, $note ) = @_;
1953 my( $reqr, $patron, $evt ) =
1954 $U->checkses_requestor($authtoken, $note->usr, 'UPDATE_USER');
1955 return $evt if $evt;
1956 $logger->activity("user ".$reqr->id." creating note for user ".$note->usr);
1958 $note->pub('f') unless $note->pub;
1959 $note->creator($reqr->id);
1960 my $id = $U->storagereq(
1961 'open-ils.storage.direct.actor.usr_note.create', $note );
1962 return $U->DB_UPDATE_FAILED($note) unless $id;
1967 __PACKAGE__->register_method (
1968 method => 'delete_user_note',
1969 api_name => 'open-ils.actor.note.delete',
1971 Deletes a note for the given user
1972 @param authtoken The login session key
1973 @param noteid The note id
1976 sub delete_user_note {
1977 my( $self, $conn, $authtoken, $noteid ) = @_;
1979 my $note = $U->storagereq(
1980 'open-ils.storage.direct.actor.usr_note.retrieve', $noteid);
1981 return OpenILS::Event->new('ACTOR_USER_NOTE_NOT_FOUND') unless $note;
1983 my( $reqr, $patron, $evt ) =
1984 $U->checkses_requestor($authtoken, $note->usr, 'UPDATE_USER');
1985 return $evt if $evt;
1986 $logger->activity("user ".$reqr->id." deleting note [$noteid] for user ".$note->usr);
1988 my $stat = $U->storagereq(
1989 'open-ils.storage.direct.actor.usr_note.delete', $noteid );
1990 return $U->DB_UPDATE_FAILED($note) unless defined $stat;
1996 __PACKAGE__->register_method (
1997 method => 'create_closed_date',
1998 api_name => 'open-ils.actor.org_unit.closed_date.create',
2000 Creates a new closing entry for the given org_unit
2001 @param authtoken The login session key
2002 @param note The closed_date object
2005 sub create_closed_date {
2006 my( $self, $conn, $authtoken, $cd ) = @_;
2008 my( $user, $evt ) = $U->checkses($authtoken);
2009 return $evt if $evt;
2011 $evt = $U->check_perms($user->id, $cd->org_unit, 'CREATE_CLOSEING');
2012 return $evt if $evt;
2014 $logger->activity("user ".$user->id." creating library closing for ".$cd->org_unit);
2016 my $id = $U->storagereq(
2017 'open-ils.storage.direct.actor.org_unit.closed_date.create', $cd );
2018 return $U->DB_UPDATE_FAILED($cd) unless $id;
2023 __PACKAGE__->register_method (
2024 method => 'delete_closed_date',
2025 api_name => 'open-ils.actor.org_unit.closed_date.delete',
2027 Deletes a closing entry for the given org_unit
2028 @param authtoken The login session key
2029 @param noteid The close_date id
2032 sub delete_closed_date {
2033 my( $self, $conn, $authtoken, $cd ) = @_;
2035 my( $user, $evt ) = $U->checkses($authtoken);
2036 return $evt if $evt;
2039 ($cd_obj, $evt) = fetch_closed_date($cd);
2040 return $evt if $evt;
2042 $evt = $U->check_perms($user->id, $cd->org_unit, 'DELETE_CLOSEING');
2043 return $evt if $evt;
2045 $logger->activity("user ".$user->id." deleting library closing for ".$cd->org_unit);
2047 my $stat = $U->storagereq(
2048 'open-ils.storage.direct.actor.org_unit.closed_date.delete', $cd );
2049 return $U->DB_UPDATE_FAILED($cd) unless $stat;
2054 __PACKAGE__->register_method(
2055 method => 'usrname_exists',
2056 api_name => 'open-ils.actor.username.exists',
2058 Returns 1 if the requested username exists, returns 0 otherwise
2062 sub usrname_exists {
2063 my( $self, $conn, $usrname ) = @_;
2064 my $e = OpenILS::Utils::Editor->new;
2065 my $a = $e->search_actor_user({usrname => $usrname}, {idlist=>1});
2066 return 1 if $a and @$a;