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 $logger->info("Creating new user in the DB with username: ".$patron->usrname());
384 my $id = $session->request(
385 "open-ils.storage.direct.actor.user.create", $patron)->gather(1);
386 return (undef, $U->DB_UPDATE_FAILED($patron)) unless $id;
388 $logger->info("Successfully created new user [$id] in DB");
390 return ( $session->request(
391 "open-ils.storage.direct.actor.user.retrieve", $id)->gather(1), undef );
396 my( $session, $patron, $user_obj, $noperm) = @_;
398 $logger->info("Updating patron ".$patron->id." in DB");
401 my $evt = $U->check_perms($user_obj->id, $patron->home_ou, 'UPDATE_USER');
402 return (undef, $evt) if $evt;
405 # update the password by itself to avoid the password protection magic
406 if( $patron->passwd ) {
407 my $s = $session->request(
408 'open-ils.storage.direct.actor.user.remote_update',
409 {id => $patron->id}, {passwd => $patron->passwd})->gather(1);
410 return (undef, $U->DB_UPDATE_FAILED($patron)) unless defined($s);
411 $patron->clear_passwd;
414 if(!$patron->ident_type) {
415 $patron->clear_ident_type;
416 $patron->clear_ident_value;
419 if(!$patron->ident_type2) {
420 $patron->clear_ident_type2;
421 $patron->clear_ident_value2;
424 my $stat = $session->request(
425 "open-ils.storage.direct.actor.user.update",$patron )->gather(1);
426 return (undef, $U->DB_UPDATE_FAILED($patron)) unless defined($stat);
432 sub _add_update_addresses {
436 my $new_patron = shift;
440 my $current_id; # id of the address before creation
442 for my $address (@{$patron->addresses()}) {
444 $address->usr($new_patron->id());
446 if(ref($address) and $address->isnew()) {
448 $current_id = $address->id();
449 ($address, $evt) = _add_address($session,$address);
450 return (undef, $evt) if $evt;
452 if( $patron->billing_address() and
453 $patron->billing_address() == $current_id ) {
454 $new_patron->billing_address($address->id());
455 $new_patron->ischanged(1);
458 if( $patron->mailing_address() and
459 $patron->mailing_address() == $current_id ) {
460 $new_patron->mailing_address($address->id());
461 $new_patron->ischanged(1);
464 } elsif( ref($address) and $address->ischanged() ) {
466 $address->usr($new_patron->id());
467 ($address, $evt) = _update_address($session, $address);
468 return (undef, $evt) if $evt;
470 } elsif( ref($address) and $address->isdeleted() ) {
472 if( $address->id() == $new_patron->mailing_address() ) {
473 $new_patron->clear_mailing_address();
474 ($new_patron, $evt) = _update_patron($session, $new_patron);
475 return (undef, $evt) if $evt;
478 if( $address->id() == $new_patron->billing_address() ) {
479 $new_patron->clear_billing_address();
480 ($new_patron, $evt) = _update_patron($session, $new_patron);
481 return (undef, $evt) if $evt;
484 $evt = _delete_address($session, $address);
485 return (undef, $evt) if $evt;
489 return ( $new_patron, undef );
493 # adds an address to the db and returns the address with new id
495 my($session, $address) = @_;
496 $address->clear_id();
498 $logger->info("Creating new address at street ".$address->street1);
500 # put the address into the database
501 my $id = $session->request(
502 "open-ils.storage.direct.actor.user_address.create", $address )->gather(1);
503 return (undef, $U->DB_UPDATE_FAILED($address)) unless $id;
506 return ($address, undef);
510 sub _update_address {
511 my( $session, $address ) = @_;
513 $logger->info("Updating address ".$address->id." in the DB");
515 my $stat = $session->request(
516 "open-ils.storage.direct.actor.user_address.update", $address )->gather(1);
518 return (undef, $U->DB_UPDATE_FAILED($address)) unless defined($stat);
519 return ($address, undef);
524 sub _add_update_cards {
528 my $new_patron = shift;
532 my $virtual_id; #id of the card before creation
533 for my $card (@{$patron->cards()}) {
535 $card->usr($new_patron->id());
537 if(ref($card) and $card->isnew()) {
539 $virtual_id = $card->id();
540 ( $card, $evt ) = _add_card($session,$card);
541 return (undef, $evt) if $evt;
543 #if(ref($patron->card)) { $patron->card($patron->card->id); }
544 if($patron->card() == $virtual_id) {
545 $new_patron->card($card->id());
546 $new_patron->ischanged(1);
549 } elsif( ref($card) and $card->ischanged() ) {
550 $card->usr($new_patron->id());
551 $evt = _update_card($session, $card);
552 return (undef, $evt) if $evt;
556 return ( $new_patron, undef );
560 # adds an card to the db and returns the card with new id
562 my( $session, $card ) = @_;
565 $logger->info("Adding new patron card ".$card->barcode);
567 my $id = $session->request(
568 "open-ils.storage.direct.actor.card.create", $card )->gather(1);
569 return (undef, $U->DB_UPDATE_FAILED($card)) unless $id;
570 $logger->info("Successfully created patron card $id");
573 return ( $card, undef );
577 # returns event on error. returns undef otherwise
579 my( $session, $card ) = @_;
580 $logger->info("Updating patron card ".$card->id);
582 my $stat = $session->request(
583 "open-ils.storage.direct.actor.card.update", $card )->gather(1);
584 return $U->DB_UPDATE_FAILED($card) unless defined($stat);
591 # returns event on error. returns undef otherwise
592 sub _delete_address {
593 my( $session, $address ) = @_;
595 $logger->info("Deleting address ".$address->id." from DB");
597 my $stat = $session->request(
598 "open-ils.storage.direct.actor.user_address.delete", $address )->gather(1);
600 return $U->DB_UPDATE_FAILED($address) unless defined($stat);
606 sub _add_survey_responses {
607 my ($session, $patron, $new_patron) = @_;
609 $logger->info( "Updating survey responses for patron ".$new_patron->id );
611 my $responses = $patron->survey_responses;
615 $_->usr($new_patron->id) for (@$responses);
617 my $evt = $U->simplereq( "open-ils.circ",
618 "open-ils.circ.survey.submit.user_id", $responses );
620 return (undef, $evt) if defined($U->event_code($evt));
624 return ( $new_patron, undef );
628 sub _create_stat_maps {
630 my($session, $user_session, $patron, $new_patron) = @_;
632 my $maps = $patron->stat_cat_entries();
634 for my $map (@$maps) {
636 my $method = "open-ils.storage.direct.actor.stat_cat_entry_user_map.update";
638 if ($map->isdeleted()) {
639 $method = "open-ils.storage.direct.actor.stat_cat_entry_user_map.delete";
641 } elsif ($map->isnew()) {
642 $method = "open-ils.storage.direct.actor.stat_cat_entry_user_map.create";
647 $map->target_usr($new_patron->id);
650 $logger->info("Updating stat entry with method $method and map $map");
652 my $stat = $session->request($method, $map)->gather(1);
653 return (undef, $U->DB_UPDATE_FAILED($map)) unless defined($stat);
657 return ($new_patron, undef);
660 sub _create_perm_maps {
662 my($session, $user_session, $patron, $new_patron) = @_;
664 my $maps = $patron->permissions;
666 for my $map (@$maps) {
668 my $method = "open-ils.storage.direct.permission.usr_perm_map.update";
669 if ($map->isdeleted()) {
670 $method = "open-ils.storage.direct.permission.usr_perm_map.delete";
671 } elsif ($map->isnew()) {
672 $method = "open-ils.storage.direct.permission.usr_perm_map.create";
677 $map->usr($new_patron->id);
679 #warn( "Updating permissions with method $method and session $user_session and map $map" );
680 $logger->info( "Updating permissions with method $method and map $map" );
682 my $stat = $session->request($method, $map)->gather(1);
683 return (undef, $U->DB_UPDATE_FAILED($map)) unless defined($stat);
687 return ($new_patron, undef);
691 sub _create_standing_penalties {
693 my($session, $user_session, $patron, $new_patron) = @_;
695 my $maps = $patron->standing_penalties;
698 for my $map (@$maps) {
700 if ($map->isdeleted()) {
701 $method = "open-ils.storage.direct.actor.user_standing_penalty.delete";
702 } elsif ($map->isnew()) {
703 $method = "open-ils.storage.direct.actor.user_standing_penalty.create";
709 $map->usr($new_patron->id);
711 $logger->debug( "Updating standing penalty with method $method and session $user_session and map $map" );
713 my $stat = $session->request($method, $map)->gather(1);
714 return (undef, $U->DB_UPDATE_FAILED($map)) unless $stat;
717 return ($new_patron, undef);
722 __PACKAGE__->register_method(
723 method => "search_username",
724 api_name => "open-ils.actor.user.search.username",
727 sub search_username {
728 my($self, $client, $username) = @_;
729 my $users = OpenILS::Application::AppUtils->simple_scalar_request(
731 "open-ils.storage.direct.actor.user.search.usrname.atomic",
739 __PACKAGE__->register_method(
740 method => "user_retrieve_by_barcode",
741 api_name => "open-ils.actor.user.fleshed.retrieve_by_barcode",);
743 sub user_retrieve_by_barcode {
744 my($self, $client, $user_session, $barcode) = @_;
746 $logger->debug("Searching for user with barcode $barcode");
747 my ($user_obj, $evt) = $apputils->checkses($user_session);
751 my $session = OpenSRF::AppSession->create("open-ils.storage");
753 # find the card with the given barcode
754 my $creq = $session->request(
755 "open-ils.storage.direct.actor.card.search.barcode.atomic",
757 my $card = $creq->gather(1);
759 if(!$card || !$card->[0]) {
760 $session->disconnect();
761 return OpenILS::Event->new( 'ACTOR_USER_NOT_FOUND' );
765 my $user = flesh_user($card->usr(), $session);
767 $evt = $U->check_perms($user_obj->id, $user->home_ou, 'VIEW_USER');
770 $session->disconnect();
771 if(!$user) { return OpenILS::Event->new( 'ACTOR_USER_NOT_FOUND' ); }
778 __PACKAGE__->register_method(
779 method => "get_user_by_id",
780 api_name => "open-ils.actor.user.retrieve",);
783 my ($self, $client, $user_session, $id) = @_;
785 my $user_obj = $apputils->check_user_session( $user_session );
787 return $apputils->simple_scalar_request(
789 "open-ils.storage.direct.actor.user.retrieve",
795 __PACKAGE__->register_method(
796 method => "get_org_types",
797 api_name => "open-ils.actor.org_types.retrieve",);
801 my($self, $client) = @_;
803 return $org_types if $org_types;
805 $apputils->simple_scalar_request(
807 "open-ils.storage.direct.actor.org_unit_type.retrieve.all.atomic" );
812 __PACKAGE__->register_method(
813 method => "get_user_profiles",
814 api_name => "open-ils.actor.user.profiles.retrieve",
818 sub get_user_profiles {
819 return $user_profiles if $user_profiles;
821 return $user_profiles =
822 $apputils->simple_scalar_request(
824 "open-ils.storage.direct.actor.profile.retrieve.all.atomic");
829 __PACKAGE__->register_method(
830 method => "get_user_ident_types",
831 api_name => "open-ils.actor.user.ident_types.retrieve",
834 sub get_user_ident_types {
835 return $ident_types if $ident_types;
836 return $ident_types =
837 $apputils->simple_scalar_request(
839 "open-ils.storage.direct.config.identification_type.retrieve.all.atomic" );
845 __PACKAGE__->register_method(
846 method => "get_org_unit",
847 api_name => "open-ils.actor.org_unit.retrieve",
852 my( $self, $client, $user_session, $org_id ) = @_;
854 if(defined($user_session) && !defined($org_id)) {
856 OpenILS::Application::AppUtils->check_user_session( $user_session ); #throws EX on error
857 if(!defined($org_id)) {
858 $org_id = $user_obj->home_ou;
863 my $home_ou = OpenILS::Application::AppUtils->simple_scalar_request(
865 "open-ils.storage.direct.actor.org_unit.retrieve",
871 __PACKAGE__->register_method(
872 method => "search_org_unit",
873 api_name => "open-ils.actor.org_unit_list.search",
876 sub search_org_unit {
878 my( $self, $client, $field, $value ) = @_;
880 my $list = OpenILS::Application::AppUtils->simple_scalar_request(
882 "open-ils.storage.direct.actor.org_unit.search.$field.atomic",
891 __PACKAGE__->register_method(
892 method => "get_org_tree",
893 api_name => "open-ils.actor.org_tree.retrieve",
895 note => "Returns the entire org tree structure",
899 my( $self, $client) = @_;
902 $cache_client = OpenSRF::Utils::Cache->new("global", 0);
904 # see if it's in the cache
905 #warn "Getting ORG Tree\n";
906 my $tree = $cache_client->get_cache('orgtree');
908 #warn "Found orgtree in cache. returning...\n";
912 my $orglist = $apputils->simple_scalar_request(
914 "open-ils.storage.direct.actor.org_unit.retrieve.all.atomic" );
917 #warn "found org list\n";
920 $tree = $self->build_org_tree($orglist);
921 $cache_client->put_cache('orgtree', $tree);
927 # turns an org list into an org tree
930 my( $self, $orglist) = @_;
932 return $orglist unless (
933 ref($orglist) and @$orglist > 1 );
936 $a->ou_type <=> $b->ou_type ||
937 $a->name cmp $b->name } @$orglist;
939 for my $org (@list) {
941 next unless ($org and defined($org->parent_ou));
942 my ($parent) = grep { $_->id == $org->parent_ou } @list;
945 $parent->children([]) unless defined($parent->children);
946 push( @{$parent->children}, $org );
954 __PACKAGE__->register_method(
955 method => "get_org_descendants",
956 api_name => "open-ils.actor.org_tree.descendants.retrieve"
959 # depth is optional. org_unit is the id
960 sub get_org_descendants {
961 my( $self, $client, $org_unit, $depth ) = @_;
962 my $orglist = $apputils->simple_scalar_request(
964 "open-ils.storage.actor.org_unit.descendants.atomic",
966 return $self->build_org_tree($orglist);
970 __PACKAGE__->register_method(
971 method => "get_org_ancestors",
972 api_name => "open-ils.actor.org_tree.ancestors.retrieve"
975 # depth is optional. org_unit is the id
976 sub get_org_ancestors {
977 my( $self, $client, $org_unit, $depth ) = @_;
978 my $orglist = $apputils->simple_scalar_request(
980 "open-ils.storage.actor.org_unit.ancestors.atomic",
982 return $self->build_org_tree($orglist);
986 __PACKAGE__->register_method(
987 method => "get_standings",
988 api_name => "open-ils.actor.standings.retrieve"
993 return $user_standings if $user_standings;
994 return $user_standings =
995 $apputils->simple_scalar_request(
997 "open-ils.storage.direct.config.standing.retrieve.all.atomic" );
1002 __PACKAGE__->register_method(
1003 method => "get_my_org_path",
1004 api_name => "open-ils.actor.org_unit.full_path.retrieve"
1007 sub get_my_org_path {
1008 my( $self, $client, $user_session, $org_id ) = @_;
1009 my $user_obj = $apputils->check_user_session($user_session);
1010 if(!defined($org_id)) { $org_id = $user_obj->home_ou; }
1012 return $apputils->simple_scalar_request(
1014 "open-ils.storage.actor.org_unit.full_path.atomic",
1019 __PACKAGE__->register_method(
1020 method => "patron_adv_search",
1021 api_name => "open-ils.actor.patron.search.advanced" );
1022 sub patron_adv_search {
1023 my( $self, $client, $auth, $search_hash, $search_limit, $search_sort ) = @_;
1024 my $e = OpenILS::Utils::Editor->new(authtoken=>$auth);
1025 return $e->event unless $e->checkauth;
1026 return $e->event unless $e->allowed('VIEW_USER');
1028 "open-ils.storage.actor.user.crazy_search",
1029 $search_hash, $search_limit, $search_sort);
1034 sub _verify_password {
1035 my($user_session, $password) = @_;
1036 my $user_obj = $apputils->check_user_session($user_session);
1038 #grab the user with password
1039 $user_obj = $apputils->simple_scalar_request(
1041 "open-ils.storage.direct.actor.user.retrieve",
1044 if($user_obj->passwd eq $password) {
1052 __PACKAGE__->register_method(
1053 method => "update_password",
1054 api_name => "open-ils.actor.user.password.update");
1056 __PACKAGE__->register_method(
1057 method => "update_password",
1058 api_name => "open-ils.actor.user.username.update");
1060 __PACKAGE__->register_method(
1061 method => "update_password",
1062 api_name => "open-ils.actor.user.email.update");
1064 sub update_password {
1065 my( $self, $client, $user_session, $new_value, $current_password ) = @_;
1069 my $user_obj = $apputils->check_user_session($user_session);
1071 if($self->api_name =~ /password/o) {
1073 #make sure they know the current password
1074 if(!_verify_password($user_session, md5_hex($current_password))) {
1075 return OpenILS::Event->new('INCORRECT_PASSWORD');
1078 $logger->debug("update_password setting new password $new_value");
1079 $user_obj->passwd($new_value);
1081 } elsif($self->api_name =~ /username/o) {
1082 my $users = search_username(undef, undef, $new_value);
1083 if( $users and $users->[0] ) {
1084 return OpenILS::Event->new('USERNAME_EXISTS');
1086 $user_obj->usrname($new_value);
1088 } elsif($self->api_name =~ /email/o) {
1089 #warn "Updating email to $new_value\n";
1090 $user_obj->email($new_value);
1093 my $session = $apputils->start_db_session();
1095 ( $user_obj, $evt ) = _update_patron($session, $user_obj, $user_obj, 1);
1096 return $evt if $evt;
1098 $apputils->commit_db_session($session);
1100 if($user_obj) { return 1; }
1105 __PACKAGE__->register_method(
1106 method => "check_user_perms",
1107 api_name => "open-ils.actor.user.perm.check",
1108 notes => <<" NOTES");
1109 Takes a login session, user id, an org id, and an array of perm type strings. For each
1110 perm type, if the user does *not* have the given permission it is added
1111 to a list which is returned from the method. If all permissions
1112 are allowed, an empty list is returned
1113 if the logged in user does not match 'user_id', then the logged in user must
1114 have VIEW_PERMISSION priveleges.
1117 sub check_user_perms {
1118 my( $self, $client, $login_session, $user_id, $org_id, $perm_types ) = @_;
1120 my( $staff, $evt ) = $apputils->checkses($login_session);
1121 return $evt if $evt;
1123 if($staff->id ne $user_id) {
1124 if( my $evt = $apputils->check_perms(
1125 $staff->id, $org_id, 'VIEW_PERMISSION') ) {
1131 for my $perm (@$perm_types) {
1132 if($apputils->check_perms($user_id, $org_id, $perm)) {
1133 push @not_allowed, $perm;
1137 return \@not_allowed
1140 __PACKAGE__->register_method(
1141 method => "check_user_perms2",
1142 api_name => "open-ils.actor.user.perm.check.multi_org",
1144 Checks the permissions on a list of perms and orgs for a user
1145 @param authtoken The login session key
1146 @param user_id The id of the user to check
1147 @param orgs The array of org ids
1148 @param perms The array of permission names
1149 @return An array of [ orgId, permissionName ] arrays that FAILED the check
1150 if the logged in user does not match 'user_id', then the logged in user must
1151 have VIEW_PERMISSION priveleges.
1154 sub check_user_perms2 {
1155 my( $self, $client, $authtoken, $user_id, $orgs, $perms ) = @_;
1157 my( $staff, $target, $evt ) = $apputils->checkses_requestor(
1158 $authtoken, $user_id, 'VIEW_PERMISSION' );
1159 return $evt if $evt;
1162 for my $org (@$orgs) {
1163 for my $perm (@$perms) {
1164 if($apputils->check_perms($user_id, $org, $perm)) {
1165 push @not_allowed, [ $org, $perm ];
1170 return \@not_allowed
1174 __PACKAGE__->register_method(
1175 method => 'check_user_perms3',
1176 api_name => 'open-ils.actor.user.perm.highest_org',
1178 Returns the highest org unit id at which a user has a given permission
1179 If the requestor does not match the target user, the requestor must have
1180 'VIEW_PERMISSION' rights at the home org unit of the target user
1181 @param authtoken The login session key
1182 @param userid The id of the user in question
1183 @param perm The permission to check
1184 @return The org unit highest in the org tree within which the user has
1185 the requested permission
1188 sub check_user_perms3 {
1189 my( $self, $client, $authtoken, $userid, $perm ) = @_;
1191 my( $staff, $target, $org, $evt );
1193 ( $staff, $target, $evt ) = $apputils->checkses_requestor(
1194 $authtoken, $userid, 'VIEW_PERMISSION' );
1195 return $evt if $evt;
1197 my $tree = $self->get_org_tree();
1198 return _find_highest_perm_org( $perm, $userid, $target->home_ou, $tree );
1202 sub _find_highest_perm_org {
1203 my ( $perm, $userid, $start_org, $org_tree ) = @_;
1204 my $org = $apputils->find_org($org_tree, $start_org );
1208 last if ($apputils->check_perms( $userid, $org->id, $perm )); # perm failed
1210 $org = $apputils->find_org( $org_tree, $org->parent_ou() );
1216 __PACKAGE__->register_method(
1217 method => 'check_user_perms4',
1218 api_name => 'open-ils.actor.user.perm.highest_org.batch',
1220 Returns the highest org unit id at which a user has a given permission
1221 If the requestor does not match the target user, the requestor must have
1222 'VIEW_PERMISSION' rights at the home org unit of the target user
1223 @param authtoken The login session key
1224 @param userid The id of the user in question
1225 @param perms An array of perm names to check
1226 @return An array of orgId's representing the org unit
1227 highest in the org tree within which the user has the requested permission
1228 The arrah of orgId's has matches the order of the perms array
1231 sub check_user_perms4 {
1232 my( $self, $client, $authtoken, $userid, $perms ) = @_;
1234 my( $staff, $target, $org, $evt );
1236 ( $staff, $target, $evt ) = $apputils->checkses_requestor(
1237 $authtoken, $userid, 'VIEW_PERMISSION' );
1238 return $evt if $evt;
1241 return [] unless ref($perms);
1242 my $tree = $self->get_org_tree();
1244 for my $p (@$perms) {
1245 push( @arr, _find_highest_perm_org( $p, $userid, $target->home_ou, $tree ) );
1253 __PACKAGE__->register_method(
1254 method => "user_fines_summary",
1255 api_name => "open-ils.actor.user.fines.summary",
1256 notes => <<" NOTES");
1257 Returns a short summary of the users total open fines, excluding voided fines
1258 Params are login_session, user_id
1259 Returns a 'mous' object.
1262 sub user_fines_summary {
1263 my( $self, $client, $login_session, $user_id ) = @_;
1265 my $user_obj = $apputils->check_user_session($login_session);
1266 if($user_obj->id ne $user_id) {
1267 if($apputils->check_user_perms($user_obj->id, $user_obj->home_ou, "VIEW_USER_FINES_SUMMARY")) {
1268 return OpenILS::Perm->new("VIEW_USER_FINES_SUMMARY");
1272 return $apputils->simple_scalar_request(
1274 "open-ils.storage.direct.money.open_user_summary.search.usr",
1282 __PACKAGE__->register_method(
1283 method => "user_transactions",
1284 api_name => "open-ils.actor.user.transactions",
1285 notes => <<" NOTES");
1286 Returns a list of open user transactions (mbts objects);
1287 Params are login_session, user_id
1288 Optional third parameter is the transactions type. defaults to all
1291 __PACKAGE__->register_method(
1292 method => "user_transactions",
1293 api_name => "open-ils.actor.user.transactions.have_charge",
1294 notes => <<" NOTES");
1295 Returns a list of all open user transactions (mbts objects) that have an initial charge
1296 Params are login_session, user_id
1297 Optional third parameter is the transactions type. defaults to all
1300 __PACKAGE__->register_method(
1301 method => "user_transactions",
1302 api_name => "open-ils.actor.user.transactions.have_balance",
1303 notes => <<" NOTES");
1304 Returns a list of all open user transactions (mbts objects) that have a balance
1305 Params are login_session, user_id
1306 Optional third parameter is the transactions type. defaults to all
1309 __PACKAGE__->register_method(
1310 method => "user_transactions",
1311 api_name => "open-ils.actor.user.transactions.fleshed",
1312 notes => <<" NOTES");
1313 Returns an object/hash of transaction, circ, title where transaction = an open
1314 user transactions (mbts objects), circ is the attached circluation, and title
1315 is the title the circ points to
1316 Params are login_session, user_id
1317 Optional third parameter is the transactions type. defaults to all
1320 __PACKAGE__->register_method(
1321 method => "user_transactions",
1322 api_name => "open-ils.actor.user.transactions.have_charge.fleshed",
1323 notes => <<" NOTES");
1324 Returns an object/hash of transaction, circ, title where transaction = an open
1325 user transactions that has an initial charge (mbts objects), circ is the
1326 attached circluation, and title is the title the circ points to
1327 Params are login_session, user_id
1328 Optional third parameter is the transactions type. defaults to all
1331 __PACKAGE__->register_method(
1332 method => "user_transactions",
1333 api_name => "open-ils.actor.user.transactions.have_balance.fleshed",
1334 notes => <<" NOTES");
1335 Returns an object/hash of transaction, circ, title where transaction = an open
1336 user transaction that has a balance (mbts objects), circ is the attached
1337 circluation, and title is the title the circ points to
1338 Params are login_session, user_id
1339 Optional third parameter is the transaction type. defaults to all
1342 __PACKAGE__->register_method(
1343 method => "user_transactions",
1344 api_name => "open-ils.actor.user.transactions.count",
1345 notes => <<" NOTES");
1346 Returns an object/hash of transaction, circ, title where transaction = an open
1347 user transactions (mbts objects), circ is the attached circluation, and title
1348 is the title the circ points to
1349 Params are login_session, user_id
1350 Optional third parameter is the transactions type. defaults to all
1353 __PACKAGE__->register_method(
1354 method => "user_transactions",
1355 api_name => "open-ils.actor.user.transactions.have_charge.count",
1356 notes => <<" NOTES");
1357 Returns an object/hash of transaction, circ, title where transaction = an open
1358 user transactions that has an initial charge (mbts objects), circ is the
1359 attached circluation, and title is the title the circ points to
1360 Params are login_session, user_id
1361 Optional third parameter is the transactions type. defaults to all
1364 __PACKAGE__->register_method(
1365 method => "user_transactions",
1366 api_name => "open-ils.actor.user.transactions.have_balance.count",
1367 notes => <<" NOTES");
1368 Returns an object/hash of transaction, circ, title where transaction = an open
1369 user transaction that has a balance (mbts objects), circ is the attached
1370 circluation, and title is the title the circ points to
1371 Params are login_session, user_id
1372 Optional third parameter is the transaction type. defaults to all
1375 __PACKAGE__->register_method(
1376 method => "user_transactions",
1377 api_name => "open-ils.actor.user.transactions.have_balance.total",
1378 notes => <<" NOTES");
1379 Returns an object/hash of transaction, circ, title where transaction = an open
1380 user transaction that has a balance (mbts objects), circ is the attached
1381 circluation, and title is the title the circ points to
1382 Params are login_session, user_id
1383 Optional third parameter is the transaction type. defaults to all
1388 sub user_transactions {
1389 my( $self, $client, $login_session, $user_id, $type ) = @_;
1391 my( $user_obj, $target, $evt ) = $apputils->checkses_requestor(
1392 $login_session, $user_id, 'VIEW_USER_TRANSACTIONS' );
1393 return $evt if $evt;
1395 my $api = $self->api_name();
1399 if(defined($type)) { @xact = (xact_type => $type);
1401 } else { @xact = (); }
1403 if($api =~ /have_charge/o) {
1405 $trans = $apputils->simple_scalar_request(
1407 "open-ils.storage.direct.money.open_billable_transaction_summary.search_where.atomic",
1408 { usr => $user_id, total_owed => { ">" => 0 }, @xact });
1410 } elsif($api =~ /have_balance/o) {
1412 $trans = $apputils->simple_scalar_request(
1414 "open-ils.storage.direct.money.open_billable_transaction_summary.search_where.atomic",
1415 { usr => $user_id, balance_owed => { "<>" => 0 }, @xact });
1419 $trans = $apputils->simple_scalar_request(
1421 "open-ils.storage.direct.money.open_billable_transaction_summary.search_where.atomic",
1422 { usr => $user_id, @xact });
1425 if($api =~ /total/o) {
1427 for my $t (@$trans) {
1428 $total += $t->balance_owed;
1431 $logger->debug("Total balance owed by user $user_id: $total");
1435 if($api =~ /count/o) { return scalar @$trans; }
1436 if($api !~ /fleshed/o) { return $trans; }
1439 for my $t (@$trans) {
1441 if( $t->xact_type ne 'circulation' ) {
1442 push @resp, {transaction => $t};
1446 my $circ = $apputils->simple_scalar_request(
1448 "open-ils.storage.direct.action.circulation.retrieve",
1453 my $title = $apputils->simple_scalar_request(
1455 "open-ils.storage.fleshed.biblio.record_entry.retrieve_by_copy",
1456 $circ->target_copy );
1460 my $u = OpenILS::Utils::ModsParser->new();
1461 $u->start_mods_batch($title->marc());
1462 my $mods = $u->finish_mods_batch();
1464 push @resp, {transaction => $t, circ => $circ, record => $mods };
1472 __PACKAGE__->register_method(
1473 method => "user_transaction_retrieve",
1474 api_name => "open-ils.actor.user.transaction.fleshed.retrieve",
1476 notes => <<" NOTES");
1477 Returns a fleshedtransaction record
1479 __PACKAGE__->register_method(
1480 method => "user_transaction_retrieve",
1481 api_name => "open-ils.actor.user.transaction.retrieve",
1483 notes => <<" NOTES");
1484 Returns a transaction record
1486 sub user_transaction_retrieve {
1487 my( $self, $client, $login_session, $bill_id ) = @_;
1489 my $trans = $apputils->simple_scalar_request(
1491 "open-ils.storage.direct.money.billable_transaction_summary.retrieve",
1495 my( $user_obj, $target, $evt ) = $apputils->checkses_requestor(
1496 $login_session, $trans->usr, 'VIEW_USER_TRANSACTIONS' );
1497 return $evt if $evt;
1499 my $api = $self->api_name();
1500 if($api !~ /fleshed/o) { return $trans; }
1502 if( $trans->xact_type ne 'circulation' ) {
1503 $logger->debug("Returning non-circ transaction");
1504 return {transaction => $trans};
1507 my $circ = $apputils->simple_scalar_request(
1509 "open-ils.storage.direct.action.circulation.retrieve",
1512 return {transaction => $trans} unless $circ;
1513 $logger->debug("Found the circ transaction");
1515 my $title = $apputils->simple_scalar_request(
1517 "open-ils.storage.fleshed.biblio.record_entry.retrieve_by_copy",
1518 $circ->target_copy );
1520 return {transaction => $trans, circ => $circ } unless $title;
1521 $logger->debug("Found the circ title");
1525 my $u = OpenILS::Utils::ModsParser->new();
1526 $u->start_mods_batch($title->marc());
1527 $mods = $u->finish_mods_batch();
1529 if ($title->id == -1) {
1530 my $copy = $apputils->simple_scalar_request(
1532 "open-ils.storage.direct.asset.copy.retrieve",
1533 $circ->target_copy );
1535 $mods = new Fieldmapper::metabib::virtual_record;
1537 $mods->title($copy->dummy_title);
1538 $mods->author($copy->dummy_author);
1542 $logger->debug("MODSized the circ title");
1544 return {transaction => $trans, circ => $circ, record => $mods };
1548 __PACKAGE__->register_method(
1549 method => "hold_request_count",
1550 api_name => "open-ils.actor.user.hold_requests.count",
1552 notes => <<" NOTES");
1553 Returns hold ready/total counts
1555 sub hold_request_count {
1556 my( $self, $client, $login_session, $userid ) = @_;
1558 my( $user_obj, $target, $evt ) = $apputils->checkses_requestor(
1559 $login_session, $userid, 'VIEW_HOLD' );
1560 return $evt if $evt;
1563 my $holds = $apputils->simple_scalar_request(
1565 "open-ils.storage.direct.action.hold_request.search_where.atomic",
1567 fulfillment_time => {"=" => undef } }
1571 for my $h (@$holds) {
1572 next unless $h->capture_time;
1574 my $copy = $apputils->simple_scalar_request(
1576 "open-ils.storage.direct.asset.copy.retrieve",
1580 if ($copy->status == 8) {
1585 return { total => scalar(@$holds), ready => scalar(@ready) };
1589 __PACKAGE__->register_method(
1590 method => "checkedout_count",
1591 api_name => "open-ils.actor.user.checked_out.count",
1593 notes => <<" NOTES");
1594 Returns a transaction record
1596 sub checkedout_count {
1597 my( $self, $client, $login_session, $userid ) = @_;
1599 my( $user_obj, $target, $evt ) = $apputils->checkses_requestor(
1600 $login_session, $userid, 'VIEW_CIRCULATIONS' );
1601 return $evt if $evt;
1604 my $circs = $apputils->simple_scalar_request(
1606 "open-ils.storage.direct.action.circulation.search_where.atomic",
1608 checkin_time => {"=" => undef } }
1611 my $parser = DateTime::Format::ISO8601->new;
1614 for my $c (@$circs) {
1615 my $due_dt = $parser->parse_datetime( clense_ISO8601( $c->due_date ) );
1616 my $due = $due_dt->epoch;
1618 if ($due < DateTime->today->epoch) {
1623 return { total => scalar(@$circs), overdue => scalar(@overdue) };
1626 __PACKAGE__->register_method(
1627 method => "user_transaction_history",
1628 api_name => "open-ils.actor.user.transactions.history",
1630 notes => <<" NOTES");
1631 Returns a list of billable transaction ids for a user, optionally by type
1633 __PACKAGE__->register_method(
1634 method => "user_transaction_history",
1635 api_name => "open-ils.actor.user.transactions.history.have_charge",
1637 notes => <<" NOTES");
1638 Returns a list of billable transaction ids for a user that have an initial charge, optionally by type
1640 sub user_transaction_history {
1641 my( $self, $client, $login_session, $user_id, $type ) = @_;
1643 my( $user_obj, $target, $evt ) = $apputils->checkses_requestor(
1644 $login_session, $user_id, 'VIEW_USER_TRANSACTIONS' );
1645 return $evt if $evt;
1647 my $api = $self->api_name();
1651 @xact = (xact_type => $type) if(defined($type));
1652 @charge = (total_owed => { ">" => 0}) if($api =~ /have_charge/);
1654 my $trans = $apputils->simple_scalar_request(
1656 "open-ils.storage.direct.money.billable_transaction_summary.search_where.atomic",
1657 { usr => $user_id, @xact, @charge }, { order_by => 'xact_start DESC' });
1659 return [ map { $_->id } @$trans ];
1663 __PACKAGE__->register_method(
1664 method => "user_perms",
1665 api_name => "open-ils.actor.permissions.user_perms.retrieve",
1667 notes => <<" NOTES");
1668 Returns a list of permissions
1671 my( $self, $client, $authtoken, $user ) = @_;
1673 my( $staff, $evt ) = $apputils->checkses($authtoken);
1674 return $evt if $evt;
1676 $user ||= $staff->id;
1678 if( $user != $staff->id and $evt = $apputils->check_perms( $staff->id, $staff->home_ou, 'VIEW_PERMISSION') ) {
1682 return $apputils->simple_scalar_request(
1684 "open-ils.storage.permission.user_perms.atomic",
1688 __PACKAGE__->register_method(
1689 method => "retrieve_perms",
1690 api_name => "open-ils.actor.permissions.retrieve",
1691 notes => <<" NOTES");
1692 Returns a list of permissions
1694 sub retrieve_perms {
1695 my( $self, $client ) = @_;
1696 return $apputils->simple_scalar_request(
1698 "open-ils.storage.direct.permission.perm_list.retrieve.all.atomic");
1701 __PACKAGE__->register_method(
1702 method => "retrieve_groups",
1703 api_name => "open-ils.actor.groups.retrieve",
1704 notes => <<" NOTES");
1705 Returns a list of user groupss
1707 sub retrieve_groups {
1708 my( $self, $client ) = @_;
1709 return $apputils->simple_scalar_request(
1711 "open-ils.storage.direct.permission.grp_tree.retrieve.all.atomic");
1714 __PACKAGE__->register_method(
1715 method => "retrieve_org_address",
1716 api_name => "open-ils.actor.org_unit.address.retrieve",
1717 notes => <<' NOTES');
1718 Returns an org_unit address by ID
1719 @param An org_address ID
1721 sub retrieve_org_address {
1722 my( $self, $client, $id ) = @_;
1723 return $apputils->simple_scalar_request(
1725 "open-ils.storage.direct.actor.org_address.retrieve",
1730 __PACKAGE__->register_method(
1731 method => "retrieve_groups_tree",
1732 api_name => "open-ils.actor.groups.tree.retrieve",
1733 notes => <<" NOTES");
1734 Returns a list of user groups
1736 sub retrieve_groups_tree {
1737 my( $self, $client ) = @_;
1738 my $groups = $apputils->simple_scalar_request(
1740 "open-ils.storage.direct.permission.grp_tree.retrieve.all.atomic");
1741 return $self->build_group_tree($groups);
1745 # turns an org list into an org tree
1746 sub build_group_tree {
1748 my( $self, $grplist) = @_;
1750 return $grplist unless (
1751 ref($grplist) and @$grplist > 1 );
1753 my @list = sort { $a->name cmp $b->name } @$grplist;
1756 for my $grp (@list) {
1758 if ($grp and !defined($grp->parent)) {
1762 my ($parent) = grep { $_->id == $grp->parent} @list;
1764 $parent->children([]) unless defined($parent->children);
1765 push( @{$parent->children}, $grp );
1773 __PACKAGE__->register_method(
1774 method => "add_user_to_groups",
1775 api_name => "open-ils.actor.user.set_groups",
1776 notes => <<" NOTES");
1777 Adds a user to one or more permission groups
1780 sub add_user_to_groups {
1781 my( $self, $client, $authtoken, $userid, $groups ) = @_;
1783 my( $requestor, $target, $evt ) = $apputils->checkses_requestor(
1784 $authtoken, $userid, 'CREATE_USER_GROUP_LINK' );
1785 return $evt if $evt;
1787 ( $requestor, $target, $evt ) = $apputils->checkses_requestor(
1788 $authtoken, $userid, 'REMOVE_USER_GROUP_LINK' );
1789 return $evt if $evt;
1791 $apputils->simplereq(
1793 'open-ils.storage.direct.permission.usr_grp_map.mass_delete', { usr => $userid } );
1795 for my $group (@$groups) {
1796 my $link = Fieldmapper::permission::usr_grp_map->new;
1798 $link->usr($userid);
1800 my $id = $apputils->simplereq(
1802 'open-ils.storage.direct.permission.usr_grp_map.create', $link );
1808 __PACKAGE__->register_method(
1809 method => "get_user_perm_groups",
1810 api_name => "open-ils.actor.user.get_groups",
1811 notes => <<" NOTES");
1812 Retrieve a user's permission groups.
1816 sub get_user_perm_groups {
1817 my( $self, $client, $authtoken, $userid ) = @_;
1819 my( $requestor, $target, $evt ) = $apputils->checkses_requestor(
1820 $authtoken, $userid, 'VIEW_PERM_GROUPS' );
1821 return $evt if $evt;
1823 return $apputils->simplereq(
1825 'open-ils.storage.direct.permission.usr_grp_map.search.usr.atomic', $userid );
1830 __PACKAGE__->register_method (
1831 method => 'register_workstation',
1832 api_name => 'open-ils.actor.workstation.register.override',
1833 signature => q/@see open-ils.actor.workstation.register/);
1835 __PACKAGE__->register_method (
1836 method => 'register_workstation',
1837 api_name => 'open-ils.actor.workstation.register',
1839 Registers a new workstion in the system
1840 @param authtoken The login session key
1841 @param name The name of the workstation id
1842 @param owner The org unit that owns this workstation
1843 @return The workstation id on success, WORKSTATION_NAME_EXISTS
1844 if the name is already in use.
1847 sub _register_workstation {
1848 my( $self, $connection, $authtoken, $name, $owner ) = @_;
1849 my( $requestor, $evt ) = $U->checkses($authtoken);
1850 return $evt if $evt;
1851 $evt = $U->check_perms($requestor->id, $owner, 'REGISTER_WORKSTATION');
1852 return $evt if $evt;
1854 my $ws = $U->storagereq(
1855 'open-ils.storage.direct.actor.workstation.search.name', $name );
1856 return OpenILS::Event->new('WORKSTATION_NAME_EXISTS') if $ws;
1858 $ws = Fieldmapper::actor::workstation->new;
1859 $ws->owning_lib($owner);
1862 my $id = $U->storagereq(
1863 'open-ils.storage.direct.actor.workstation.create', $ws );
1864 return $U->DB_UPDATE_FAILED($ws) unless $id;
1870 sub register_workstation {
1871 my( $self, $conn, $authtoken, $name, $owner ) = @_;
1873 my $e = OpenILS::Utils::Editor->new(authtoken=>$authtoken, xact=>1);
1874 return $e->event unless $e->checkauth;
1875 return $e->event unless $e->allowed('REGISTER_WORKSTATION'); # XXX rely on editor perms
1876 my $existing = $e->search_actor_workstation({name => $name});
1879 if( $self->api_name =~ /override/o ) {
1880 return $e->event unless $e->allowed('DELETE_WORKSTATION'); # XXX rely on editor perms
1881 return $e->event unless $e->delete_actor_workstation($$existing[0]);
1883 return OpenILS::Event->new('WORKSTATION_NAME_EXISTS')
1887 my $ws = Fieldmapper::actor::workstation->new;
1888 $ws->owning_lib($owner);
1890 $e->create_actor_workstation($ws) or return $e->event;
1891 return $ws->id; # note: editor sets the id on the new object for us
1895 __PACKAGE__->register_method (
1896 method => 'fetch_patron_note',
1897 api_name => 'open-ils.actor.note.retrieve.all',
1899 Returns a list of notes for a given user
1900 Requestor must have VIEW_USER permission if pub==false and
1901 @param authtoken The login session key
1902 @param args Hash of params including
1903 patronid : the patron's id
1904 pub : true if retrieving only public notes
1908 sub fetch_patron_note {
1909 my( $self, $conn, $authtoken, $args ) = @_;
1910 my $patronid = $$args{patronid};
1912 my($reqr, $evt) = $U->checkses($authtoken);
1915 ($patron, $evt) = $U->fetch_user($patronid);
1916 return $evt if $evt;
1919 if( $patronid ne $reqr->id ) {
1920 $evt = $U->check_perms($reqr->id, $patron->home_ou, 'VIEW_USER');
1921 return $evt if $evt;
1923 return $U->storagereq(
1924 'open-ils.storage.direct.actor.usr_note.search_where.atomic',
1925 { usr => $patronid, pub => 't' } );
1928 $evt = $U->check_perms($reqr->id, $patron->home_ou, 'VIEW_USER');
1929 return $evt if $evt;
1931 return $U->storagereq(
1932 'open-ils.storage.direct.actor.usr_note.search.usr.atomic', $patronid );
1935 __PACKAGE__->register_method (
1936 method => 'create_user_note',
1937 api_name => 'open-ils.actor.note.create',
1939 Creates a new note for the given user
1940 @param authtoken The login session key
1941 @param note The note object
1944 sub create_user_note {
1945 my( $self, $conn, $authtoken, $note ) = @_;
1946 my( $reqr, $patron, $evt ) =
1947 $U->checkses_requestor($authtoken, $note->usr, 'UPDATE_USER');
1948 return $evt if $evt;
1949 $logger->activity("user ".$reqr->id." creating note for user ".$note->usr);
1951 $note->pub('f') unless $note->pub;
1952 $note->creator($reqr->id);
1953 my $id = $U->storagereq(
1954 'open-ils.storage.direct.actor.usr_note.create', $note );
1955 return $U->DB_UPDATE_FAILED($note) unless $id;
1960 __PACKAGE__->register_method (
1961 method => 'delete_user_note',
1962 api_name => 'open-ils.actor.note.delete',
1964 Deletes a note for the given user
1965 @param authtoken The login session key
1966 @param noteid The note id
1969 sub delete_user_note {
1970 my( $self, $conn, $authtoken, $noteid ) = @_;
1972 my $note = $U->storagereq(
1973 'open-ils.storage.direct.actor.usr_note.retrieve', $noteid);
1974 return OpenILS::Event->new('ACTOR_USER_NOTE_NOT_FOUND') unless $note;
1976 my( $reqr, $patron, $evt ) =
1977 $U->checkses_requestor($authtoken, $note->usr, 'UPDATE_USER');
1978 return $evt if $evt;
1979 $logger->activity("user ".$reqr->id." deleting note [$noteid] for user ".$note->usr);
1981 my $stat = $U->storagereq(
1982 'open-ils.storage.direct.actor.usr_note.delete', $noteid );
1983 return $U->DB_UPDATE_FAILED($note) unless defined $stat;
1989 __PACKAGE__->register_method (
1990 method => 'create_closed_date',
1991 api_name => 'open-ils.actor.org_unit.closed_date.create',
1993 Creates a new closing entry for the given org_unit
1994 @param authtoken The login session key
1995 @param note The closed_date object
1998 sub create_closed_date {
1999 my( $self, $conn, $authtoken, $cd ) = @_;
2001 my( $user, $evt ) = $U->checkses($authtoken);
2002 return $evt if $evt;
2004 $evt = $U->check_perms($user->id, $cd->org_unit, 'CREATE_CLOSEING');
2005 return $evt if $evt;
2007 $logger->activity("user ".$user->id." creating library closing for ".$cd->org_unit);
2009 my $id = $U->storagereq(
2010 'open-ils.storage.direct.actor.org_unit.closed_date.create', $cd );
2011 return $U->DB_UPDATE_FAILED($cd) unless $id;
2016 __PACKAGE__->register_method (
2017 method => 'delete_closed_date',
2018 api_name => 'open-ils.actor.org_unit.closed_date.delete',
2020 Deletes a closing entry for the given org_unit
2021 @param authtoken The login session key
2022 @param noteid The close_date id
2025 sub delete_closed_date {
2026 my( $self, $conn, $authtoken, $cd ) = @_;
2028 my( $user, $evt ) = $U->checkses($authtoken);
2029 return $evt if $evt;
2032 ($cd_obj, $evt) = fetch_closed_date($cd);
2033 return $evt if $evt;
2035 $evt = $U->check_perms($user->id, $cd->org_unit, 'DELETE_CLOSEING');
2036 return $evt if $evt;
2038 $logger->activity("user ".$user->id." deleting library closing for ".$cd->org_unit);
2040 my $stat = $U->storagereq(
2041 'open-ils.storage.direct.actor.org_unit.closed_date.delete', $cd );
2042 return $U->DB_UPDATE_FAILED($cd) unless $stat;
2047 #__PACKAGE__->register_method(