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);
14 use OpenILS::Application::AppUtils;
16 use OpenILS::Utils::Fieldmapper;
17 use OpenILS::Application::Search::Actor;
18 use OpenILS::Utils::ModsParser;
19 use OpenSRF::Utils::Logger qw/$logger/;
20 use OpenSRF::Utils qw/:datetime/;
22 use OpenSRF::Utils::Cache;
25 use DateTime::Format::ISO8601;
27 use OpenILS::Application::Actor::Container;
29 use OpenILS::Utils::Editor;
31 use OpenILS::Application::Actor::UserGroups;
33 OpenILS::Application::Actor::Container->initialize();
34 OpenILS::Application::Actor::UserGroups->initialize();
37 my $apputils = "OpenILS::Application::AppUtils";
40 sub _d { warn "Patron:\n" . Dumper(shift()); }
45 my $set_user_settings;
48 __PACKAGE__->register_method(
49 method => "set_user_settings",
50 api_name => "open-ils.actor.patron.settings.update",
52 sub set_user_settings {
53 my( $self, $client, $user_session, $uid, $settings ) = @_;
55 $logger->debug("Setting user settings: $user_session, $uid, " . Dumper($settings));
57 my( $staff, $user, $evt ) =
58 $apputils->checkses_requestor( $user_session, $uid, 'UPDATE_USER' );
63 # [{ usr => $user->id, name => $_}, {value => $$settings{$_}}] } keys %$settings;
66 [{ usr => $user->id, name => $_}, {value => $$settings{$_}}] } keys %$settings;
68 $logger->activity("User " . $staff->id . " updating user $uid settings with: " . Dumper(\@params));
70 return $apputils->simplereq(
72 'open-ils.storage.direct.actor.user_setting.batch.merge', @params );
78 __PACKAGE__->register_method(
79 method => "set_ou_settings",
80 api_name => "open-ils.actor.org_unit.settings.update",
83 my( $self, $client, $user_session, $ouid, $settings ) = @_;
85 my( $staff, $evt ) = $apputils->checkses( $user_session );
87 $evt = $apputils->check_perms( $staff->id, $ouid, 'UPDATE_ORG_UNIT' );
92 map { [{ org_unit => $ouid, name => $_}, {value => $$settings{$_}}] } keys %$settings;
94 $logger->activity("Updating org unit [$ouid] settings with: " . Dumper($params));
96 return $apputils->simplereq(
98 'open-ils.storage.direct.actor.org_unit_setting.merge', @$params );
102 my $fetch_user_settings;
103 my $fetch_ou_settings;
105 __PACKAGE__->register_method(
106 method => "user_settings",
107 api_name => "open-ils.actor.patron.settings.retrieve",
110 my( $self, $client, $user_session, $uid ) = @_;
112 my( $staff, $user, $evt ) =
113 $apputils->checkses_requestor( $user_session, $uid, 'VIEW_USER' );
116 $logger->debug("User " . $staff->id . " fetching user $uid\n");
117 my $s = $apputils->simplereq(
119 'open-ils.storage.direct.actor.user_setting.search.usr.atomic',$uid );
121 return { map { ($_->name,$_->value) } @$s };
126 __PACKAGE__->register_method(
127 method => "ou_settings",
128 api_name => "open-ils.actor.org_unit.settings.retrieve",
131 my( $self, $client, $ouid ) = @_;
133 $logger->info("Fetching org unit settings for org $ouid");
135 my $s = $apputils->simplereq(
137 'open-ils.storage.direct.actor.org_unit_setting.search.org_unit.atomic', $ouid);
139 return { map { ($_->name,$_->value) } @$s };
142 __PACKAGE__->register_method (
143 method => "ou_setting_delete",
144 api_name => 'open-ils.actor.org_setting.delete',
146 Deletes a specific org unit setting for a specific location
147 @param authtoken The login session key
148 @param orgid The org unit whose setting we're changing
149 @param setting The name of the setting to delete
150 @return True value on success.
154 sub ou_setting_delete {
155 my( $self, $conn, $authtoken, $orgid, $setting ) = @_;
156 my( $reqr, $evt) = $U->checkses($authtoken);
158 $evt = $U->check_perms($reqr->id, $orgid, 'UPDATE_ORG_SETTING');
161 my $id = $U->storagereq(
162 'open-ils.storage.id_list.actor.org_unit_setting.search_where',
163 { name => $setting, org_unit => $orgid } );
165 $logger->debug("Retrieved setting $id in org unit setting delete");
167 my $s = $U->storagereq(
168 'open-ils.storage.direct.actor.org_unit_setting.delete', $id );
170 $logger->activity("User ".$reqr->id." deleted org unit setting $id") if $s;
176 __PACKAGE__->register_method(
177 method => "update_patron",
178 api_name => "open-ils.actor.patron.update",);
181 my( $self, $client, $user_session, $patron ) = @_;
183 my $session = $apputils->start_db_session();
186 $logger->info("Creating new patron...") if $patron->isnew;
187 $logger->info("Updating Patron: " . $patron->id) unless $patron->isnew;
189 my( $user_obj, $evt ) = $U->checkses($user_session);
192 # XXX does this user have permission to add/create users. Granularity?
193 # $new_patron is the patron in progress. $patron is the original patron
194 # passed in with the method. new_patron will change as the components
195 # of patron are added/updated.
199 # unflesh the real items on the patron
200 $patron->card( $patron->card->id ) if(ref($patron->card));
201 $patron->billing_address( $patron->billing_address->id )
202 if(ref($patron->billing_address));
203 $patron->mailing_address( $patron->mailing_address->id )
204 if(ref($patron->mailing_address));
206 # create/update the patron first so we can use his id
207 if($patron->isnew()) {
208 ( $new_patron, $evt ) = _add_patron($session, _clone_patron($patron), $user_obj);
210 } else { $new_patron = $patron; }
212 ( $new_patron, $evt ) = _add_update_addresses($session, $patron, $new_patron, $user_obj);
215 ( $new_patron, $evt ) = _add_update_cards($session, $patron, $new_patron, $user_obj);
218 ( $new_patron, $evt ) = _add_survey_responses($session, $patron, $new_patron, $user_obj);
221 # re-update the patron if anything has happened to him during this process
222 if($new_patron->ischanged()) {
223 ( $new_patron, $evt ) = _update_patron($session, $new_patron, $user_obj);
227 #$session = OpenSRF::AppSession->create("open-ils.storage"); # why did i put this here?
229 ($new_patron, $evt) = _create_stat_maps($session, $user_session, $patron, $new_patron, $user_obj);
232 ($new_patron, $evt) = _create_perm_maps($session, $user_session, $patron, $new_patron, $user_obj);
235 ($new_patron, $evt) = _create_standing_penalties($session, $user_session, $patron, $new_patron, $user_obj);
238 $logger->activity("user ".$user_obj->id." updating/creating user ".$new_patron->id);
239 $apputils->commit_db_session($session);
241 #warn "Patron Update/Create complete\n";
242 return flesh_user($new_patron->id());
248 __PACKAGE__->register_method(
249 method => "user_retrieve_fleshed_by_id",
250 api_name => "open-ils.actor.user.fleshed.retrieve",);
252 sub user_retrieve_fleshed_by_id {
253 my( $self, $client, $user_session, $user_id ) = @_;
255 my( $requestor, $target, $evt ) = $apputils->
256 checkses_requestor( $user_session, $user_id, 'VIEW_USER' );
259 return flesh_user($user_id);
263 # fleshes: card, cards, address, addresses, stat_cat_entries, standing_penalties
271 $session = OpenSRF::AppSession->create("open-ils.storage");
275 # grab the user with the given id
276 my $ureq = $session->request(
277 "open-ils.storage.direct.actor.user.retrieve", $id);
278 my $user = $ureq->gather(1);
280 if(!$user) { return undef; }
283 my $cards_req = $session->request(
284 "open-ils.storage.direct.actor.card.search.usr.atomic",
286 $user->cards( $cards_req->gather(1) );
288 for my $c(@{$user->cards}) {
289 if($c->id == $user->card || $c->id eq $user->card ) {
290 #warn "Setting my card to " . $c->id . "\n";
295 my $add_req = $session->request(
296 "open-ils.storage.direct.actor.user_address.search.usr.atomic",
298 $user->addresses( $add_req->gather(1) );
300 if( @{$user->addresses} ) {
301 if( ! grep { $_->id eq $user->billing_address } @{$user->addresses} ) {
302 my $ba = $session->request(
303 'open-ils.storage.direct.actor.user_address.retrieve',
304 $user->billing_address)->gather(1);
305 push( @{$user->addresses}, $ba );
308 if( ! grep { $_->id eq $user->mailing_address } @{$user->addresses} ) {
309 my $ba = $session->request(
310 'open-ils.storage.direct.actor.user_address.retrieve',
311 $user->mailing_address)->gather(1);
312 push( @{$user->addresses}, $ba );
317 for my $c(@{$user->addresses}) {
318 if($c->id eq $user->billing_address ) { $user->billing_address($c); }
319 if($c->id eq $user->mailing_address ) { $user->mailing_address($c); }
322 my $stat_req = $session->request(
323 "open-ils.storage.direct.actor.stat_cat_entry_user_map.search.target_usr.atomic",
325 $user->stat_cat_entries($stat_req->gather(1));
327 my $standing_penalties_req = $session->request(
328 "open-ils.storage.direct.actor.user_standing_penalty.search.usr.atomic",
330 $user->standing_penalties($standing_penalties_req->gather(1));
332 if($kill) { $session->disconnect(); }
333 $user->clear_passwd();
339 # clone and clear stuff that would break the database
343 my $new_patron = $patron->clone;
345 # Using the Fieldmapper clone method
346 #my $new_patron = Fieldmapper::actor::user->new();
348 #my $fmap = $Fieldmapper::fieldmap;
349 #no strict; # shallow clone, may be useful in the fieldmapper
351 # (keys %{$fmap->{"Fieldmapper::actor::user"}->{'fields'}}) {
352 # $new_patron->$field( $patron->$field() );
357 $new_patron->clear_billing_address();
358 $new_patron->clear_mailing_address();
359 $new_patron->clear_addresses();
360 $new_patron->clear_card();
361 $new_patron->clear_cards();
362 $new_patron->clear_id();
363 $new_patron->clear_isnew();
364 $new_patron->clear_ischanged();
365 $new_patron->clear_isdeleted();
366 $new_patron->clear_stat_cat_entries();
367 $new_patron->clear_permissions();
368 $new_patron->clear_standing_penalties();
378 my $user_obj = shift;
380 my $evt = $U->check_perms($user_obj->id, $patron->home_ou, 'CREATE_USER');
381 return (undef, $evt) if $evt;
383 $logger->info("Creating new user in the DB with username: ".$patron->usrname());
385 my $id = $session->request(
386 "open-ils.storage.direct.actor.user.create", $patron)->gather(1);
387 return (undef, $U->DB_UPDATE_FAILED($patron)) unless $id;
389 $logger->info("Successfully created new user [$id] in DB");
391 return ( $session->request(
392 "open-ils.storage.direct.actor.user.retrieve", $id)->gather(1), undef );
397 my( $session, $patron, $user_obj) = @_;
399 $logger->info("Updating patron ".$patron->id." in DB");
400 my $evt = $U->check_perms($user_obj->id, $patron->home_ou, 'UPDATE_USER');
401 return (undef, $evt) if $evt;
403 $patron->clear_passwd unless $patron->passwd;
405 if(!$patron->ident_type) {
406 $patron->clear_ident_type;
407 $patron->clear_ident_value;
410 if(!$patron->ident_type2) {
411 $patron->clear_ident_type2;
412 $patron->clear_ident_value2;
415 my $stat = $session->request(
416 "open-ils.storage.direct.actor.user.update",$patron )->gather(1);
417 return (undef, $U->DB_UPDATE_FAILED($patron)) unless defined($stat);
423 sub _add_update_addresses {
427 my $new_patron = shift;
431 my $current_id; # id of the address before creation
433 for my $address (@{$patron->addresses()}) {
435 $address->usr($new_patron->id());
437 if(ref($address) and $address->isnew()) {
439 $current_id = $address->id();
440 ($address, $evt) = _add_address($session,$address);
441 return (undef, $evt) if $evt;
443 if( $patron->billing_address() and
444 $patron->billing_address() == $current_id ) {
445 $new_patron->billing_address($address->id());
446 $new_patron->ischanged(1);
449 if( $patron->mailing_address() and
450 $patron->mailing_address() == $current_id ) {
451 $new_patron->mailing_address($address->id());
452 $new_patron->ischanged(1);
455 } elsif( ref($address) and $address->ischanged() ) {
457 $address->usr($new_patron->id());
458 ($address, $evt) = _update_address($session, $address);
459 return (undef, $evt) if $evt;
461 } elsif( ref($address) and $address->isdeleted() ) {
463 if( $address->id() == $new_patron->mailing_address() ) {
464 $new_patron->clear_mailing_address();
465 ($new_patron, $evt) = _update_patron($session, $new_patron);
466 return (undef, $evt) if $evt;
469 if( $address->id() == $new_patron->billing_address() ) {
470 $new_patron->clear_billing_address();
471 ($new_patron, $evt) = _update_patron($session, $new_patron);
472 return (undef, $evt) if $evt;
475 $evt = _delete_address($session, $address);
476 return (undef, $evt) if $evt;
480 return ( $new_patron, undef );
484 # adds an address to the db and returns the address with new id
486 my($session, $address) = @_;
487 $address->clear_id();
489 $logger->info("Creating new address at street ".$address->street1);
491 # put the address into the database
492 my $id = $session->request(
493 "open-ils.storage.direct.actor.user_address.create", $address )->gather(1);
494 return (undef, $U->DB_UPDATE_FAILED($address)) unless $id;
497 return ($address, undef);
501 sub _update_address {
502 my( $session, $address ) = @_;
504 $logger->info("Updating address ".$address->id." in the DB");
506 my $stat = $session->request(
507 "open-ils.storage.direct.actor.user_address.update", $address )->gather(1);
509 return (undef, $U->DB_UPDATE_FAILED($address)) unless defined($stat);
510 return ($address, undef);
515 sub _add_update_cards {
519 my $new_patron = shift;
523 my $virtual_id; #id of the card before creation
524 for my $card (@{$patron->cards()}) {
526 $card->usr($new_patron->id());
528 if(ref($card) and $card->isnew()) {
530 $virtual_id = $card->id();
531 ( $card, $evt ) = _add_card($session,$card);
532 return (undef, $evt) if $evt;
534 #if(ref($patron->card)) { $patron->card($patron->card->id); }
535 if($patron->card() == $virtual_id) {
536 $new_patron->card($card->id());
537 $new_patron->ischanged(1);
540 } elsif( ref($card) and $card->ischanged() ) {
541 $card->usr($new_patron->id());
542 $evt = _update_card($session, $card);
543 return (undef, $evt) if $evt;
547 return ( $new_patron, undef );
551 # adds an card to the db and returns the card with new id
553 my( $session, $card ) = @_;
556 $logger->info("Adding new patron card ".$card->barcode);
558 my $id = $session->request(
559 "open-ils.storage.direct.actor.card.create", $card )->gather(1);
560 return (undef, $U->DB_UPDATE_FAILED($card)) unless $id;
561 $logger->info("Successfully created patron card $id");
564 return ( $card, undef );
568 # returns event on error. returns undef otherwise
570 my( $session, $card ) = @_;
571 $logger->info("Updating patron card ".$card->id);
573 my $stat = $session->request(
574 "open-ils.storage.direct.actor.card.update", $card )->gather(1);
575 return $U->DB_UPDATE_FAILED($card) unless defined($stat);
582 # returns event on error. returns undef otherwise
583 sub _delete_address {
584 my( $session, $address ) = @_;
586 $logger->info("Deleting address ".$address->id." from DB");
588 my $stat = $session->request(
589 "open-ils.storage.direct.actor.user_address.delete", $address )->gather(1);
591 return $U->DB_UPDATE_FAILED($address) unless defined($stat);
597 sub _add_survey_responses {
598 my ($session, $patron, $new_patron) = @_;
600 $logger->info( "Updating survey responses for patron ".$new_patron->id );
602 my $responses = $patron->survey_responses;
606 $_->usr($new_patron->id) for (@$responses);
608 my $evt = $U->simplereq( "open-ils.circ",
609 "open-ils.circ.survey.submit.user_id", $responses );
611 return (undef, $evt) if defined($U->event_code($evt));
615 return ( $new_patron, undef );
619 sub _create_stat_maps {
621 my($session, $user_session, $patron, $new_patron) = @_;
623 my $maps = $patron->stat_cat_entries();
625 for my $map (@$maps) {
627 my $method = "open-ils.storage.direct.actor.stat_cat_entry_user_map.update";
629 if ($map->isdeleted()) {
630 $method = "open-ils.storage.direct.actor.stat_cat_entry_user_map.delete";
632 } elsif ($map->isnew()) {
633 $method = "open-ils.storage.direct.actor.stat_cat_entry_user_map.create";
638 $map->target_usr($new_patron->id);
641 $logger->info("Updating stat entry with method $method and map $map");
643 my $stat = $session->request($method, $map)->gather(1);
644 return (undef, $U->DB_UPDATE_FAILED($map)) unless defined($stat);
648 return ($new_patron, undef);
651 sub _create_perm_maps {
653 my($session, $user_session, $patron, $new_patron) = @_;
655 my $maps = $patron->permissions;
657 for my $map (@$maps) {
659 my $method = "open-ils.storage.direct.permission.usr_perm_map.update";
660 if ($map->isdeleted()) {
661 $method = "open-ils.storage.direct.permission.usr_perm_map.delete";
662 } elsif ($map->isnew()) {
663 $method = "open-ils.storage.direct.permission.usr_perm_map.create";
668 $map->usr($new_patron->id);
670 #warn( "Updating permissions with method $method and session $user_session and map $map" );
671 $logger->info( "Updating permissions with method $method and map $map" );
673 my $stat = $session->request($method, $map)->gather(1);
674 return (undef, $U->DB_UPDATE_FAILED($map)) unless defined($stat);
678 return ($new_patron, undef);
682 sub _create_standing_penalties {
684 my($session, $user_session, $patron, $new_patron) = @_;
686 my $maps = $patron->standing_penalties;
689 for my $map (@$maps) {
691 if ($map->isdeleted()) {
692 $method = "open-ils.storage.direct.actor.user_standing_penalty.delete";
693 } elsif ($map->isnew()) {
694 $method = "open-ils.storage.direct.actor.user_standing_penalty.create";
700 $map->usr($new_patron->id);
702 $logger->debug( "Updating standing penalty with method $method and session $user_session and map $map" );
704 my $stat = $session->request($method, $map)->gather(1);
705 return (undef, $U->DB_UPDATE_FAILED($map)) unless $stat;
708 return ($new_patron, undef);
713 __PACKAGE__->register_method(
714 method => "search_username",
715 api_name => "open-ils.actor.user.search.username",
718 sub search_username {
719 my($self, $client, $username) = @_;
720 my $users = OpenILS::Application::AppUtils->simple_scalar_request(
722 "open-ils.storage.direct.actor.user.search.usrname.atomic",
730 __PACKAGE__->register_method(
731 method => "user_retrieve_by_barcode",
732 api_name => "open-ils.actor.user.fleshed.retrieve_by_barcode",);
734 sub user_retrieve_by_barcode {
735 my($self, $client, $user_session, $barcode) = @_;
737 $logger->debug("Searching for user with barcode $barcode");
738 my ($user_obj, $evt) = $apputils->checkses($user_session);
742 my $session = OpenSRF::AppSession->create("open-ils.storage");
744 # find the card with the given barcode
745 my $creq = $session->request(
746 "open-ils.storage.direct.actor.card.search.barcode.atomic",
748 my $card = $creq->gather(1);
750 if(!$card || !$card->[0]) {
751 $session->disconnect();
752 return OpenILS::Event->new( 'ACTOR_USER_NOT_FOUND' );
756 my $user = flesh_user($card->usr(), $session);
758 $evt = $U->check_perms($user_obj->id, $user->home_ou, 'VIEW_USER');
761 $session->disconnect();
762 if(!$user) { return OpenILS::Event->new( 'ACTOR_USER_NOT_FOUND' ); }
769 __PACKAGE__->register_method(
770 method => "get_user_by_id",
771 api_name => "open-ils.actor.user.retrieve",);
774 my ($self, $client, $user_session, $id) = @_;
776 my $user_obj = $apputils->check_user_session( $user_session );
778 return $apputils->simple_scalar_request(
780 "open-ils.storage.direct.actor.user.retrieve",
786 __PACKAGE__->register_method(
787 method => "get_org_types",
788 api_name => "open-ils.actor.org_types.retrieve",);
792 my($self, $client) = @_;
794 return $org_types if $org_types;
796 $apputils->simple_scalar_request(
798 "open-ils.storage.direct.actor.org_unit_type.retrieve.all.atomic" );
803 __PACKAGE__->register_method(
804 method => "get_user_profiles",
805 api_name => "open-ils.actor.user.profiles.retrieve",
809 sub get_user_profiles {
810 return $user_profiles if $user_profiles;
812 return $user_profiles =
813 $apputils->simple_scalar_request(
815 "open-ils.storage.direct.actor.profile.retrieve.all.atomic");
820 __PACKAGE__->register_method(
821 method => "get_user_ident_types",
822 api_name => "open-ils.actor.user.ident_types.retrieve",
825 sub get_user_ident_types {
826 return $ident_types if $ident_types;
827 return $ident_types =
828 $apputils->simple_scalar_request(
830 "open-ils.storage.direct.config.identification_type.retrieve.all.atomic" );
836 __PACKAGE__->register_method(
837 method => "get_org_unit",
838 api_name => "open-ils.actor.org_unit.retrieve",
843 my( $self, $client, $user_session, $org_id ) = @_;
845 if(defined($user_session) && !defined($org_id)) {
847 OpenILS::Application::AppUtils->check_user_session( $user_session ); #throws EX on error
848 if(!defined($org_id)) {
849 $org_id = $user_obj->home_ou;
854 my $home_ou = OpenILS::Application::AppUtils->simple_scalar_request(
856 "open-ils.storage.direct.actor.org_unit.retrieve",
862 __PACKAGE__->register_method(
863 method => "search_org_unit",
864 api_name => "open-ils.actor.org_unit_list.search",
867 sub search_org_unit {
869 my( $self, $client, $field, $value ) = @_;
871 my $list = OpenILS::Application::AppUtils->simple_scalar_request(
873 "open-ils.storage.direct.actor.org_unit.search.$field.atomic",
882 __PACKAGE__->register_method(
883 method => "get_org_tree",
884 api_name => "open-ils.actor.org_tree.retrieve",
886 note => "Returns the entire org tree structure",
890 my( $self, $client) = @_;
893 $cache_client = OpenSRF::Utils::Cache->new("global", 0);
895 # see if it's in the cache
896 #warn "Getting ORG Tree\n";
897 my $tree = $cache_client->get_cache('orgtree');
899 #warn "Found orgtree in cache. returning...\n";
903 my $orglist = $apputils->simple_scalar_request(
905 "open-ils.storage.direct.actor.org_unit.retrieve.all.atomic" );
908 #warn "found org list\n";
911 $tree = $self->build_org_tree($orglist);
912 $cache_client->put_cache('orgtree', $tree);
918 # turns an org list into an org tree
921 my( $self, $orglist) = @_;
923 return $orglist unless (
924 ref($orglist) and @$orglist > 1 );
927 $a->ou_type <=> $b->ou_type ||
928 $a->name cmp $b->name } @$orglist;
930 for my $org (@list) {
932 next unless ($org and defined($org->parent_ou));
933 my ($parent) = grep { $_->id == $org->parent_ou } @list;
936 $parent->children([]) unless defined($parent->children);
937 push( @{$parent->children}, $org );
945 __PACKAGE__->register_method(
946 method => "get_org_descendants",
947 api_name => "open-ils.actor.org_tree.descendants.retrieve"
950 # depth is optional. org_unit is the id
951 sub get_org_descendants {
952 my( $self, $client, $org_unit, $depth ) = @_;
953 my $orglist = $apputils->simple_scalar_request(
955 "open-ils.storage.actor.org_unit.descendants.atomic",
957 return $self->build_org_tree($orglist);
961 __PACKAGE__->register_method(
962 method => "get_org_ancestors",
963 api_name => "open-ils.actor.org_tree.ancestors.retrieve"
966 # depth is optional. org_unit is the id
967 sub get_org_ancestors {
968 my( $self, $client, $org_unit, $depth ) = @_;
969 my $orglist = $apputils->simple_scalar_request(
971 "open-ils.storage.actor.org_unit.ancestors.atomic",
973 return $self->build_org_tree($orglist);
977 __PACKAGE__->register_method(
978 method => "get_standings",
979 api_name => "open-ils.actor.standings.retrieve"
984 return $user_standings if $user_standings;
985 return $user_standings =
986 $apputils->simple_scalar_request(
988 "open-ils.storage.direct.config.standing.retrieve.all.atomic" );
993 __PACKAGE__->register_method(
994 method => "get_my_org_path",
995 api_name => "open-ils.actor.org_unit.full_path.retrieve"
998 sub get_my_org_path {
999 my( $self, $client, $user_session, $org_id ) = @_;
1000 my $user_obj = $apputils->check_user_session($user_session);
1001 if(!defined($org_id)) { $org_id = $user_obj->home_ou; }
1003 return $apputils->simple_scalar_request(
1005 "open-ils.storage.actor.org_unit.full_path.atomic",
1010 __PACKAGE__->register_method(
1011 method => "patron_adv_search",
1012 api_name => "open-ils.actor.patron.search.advanced" );
1013 sub patron_adv_search {
1014 my( $self, $client, $auth, $search_hash, $search_limit, $search_sort ) = @_;
1015 my $e = OpenILS::Utils::Editor->new(authtoken=>$auth);
1016 return $e->event unless $e->checkauth;
1017 return $e->event unless $e->allowed('VIEW_USER');
1019 "open-ils.storage.actor.user.crazy_search",
1020 $search_hash, $search_limit, $search_sort);
1025 sub _verify_password {
1026 my($user_session, $password) = @_;
1027 my $user_obj = $apputils->check_user_session($user_session);
1029 #grab the user with password
1030 $user_obj = $apputils->simple_scalar_request(
1032 "open-ils.storage.direct.actor.user.retrieve",
1035 if($user_obj->passwd eq $password) {
1043 __PACKAGE__->register_method(
1044 method => "update_password",
1045 api_name => "open-ils.actor.user.password.update");
1047 __PACKAGE__->register_method(
1048 method => "update_password",
1049 api_name => "open-ils.actor.user.username.update");
1051 __PACKAGE__->register_method(
1052 method => "update_password",
1053 api_name => "open-ils.actor.user.email.update");
1055 sub update_password {
1056 my( $self, $client, $user_session, $new_value, $current_password ) = @_;
1060 #warn "Updating user with method " .$self->api_name . "\n";
1061 my $user_obj = $apputils->check_user_session($user_session);
1063 if($self->api_name =~ /password/o) {
1065 #make sure they know the current password
1066 if(!_verify_password($user_session, md5_hex($current_password))) {
1067 return OpenILS::EX->new("USER_WRONG_PASSWORD")->ex;
1070 $user_obj->passwd($new_value);
1072 elsif($self->api_name =~ /username/o) {
1073 my $users = search_username(undef, undef, $new_value);
1074 if( $users and $users->[0] ) {
1075 return OpenILS::Event->new('USERNAME_EXISTS');
1077 $user_obj->usrname($new_value);
1080 elsif($self->api_name =~ /email/o) {
1081 #warn "Updating email to $new_value\n";
1082 $user_obj->email($new_value);
1085 my $session = $apputils->start_db_session();
1087 ( $user_obj, $evt ) = _update_patron($session, $user_obj, $user_obj);
1088 return $evt if $evt;
1090 $apputils->commit_db_session($session);
1092 if($user_obj) { return 1; }
1097 __PACKAGE__->register_method(
1098 method => "check_user_perms",
1099 api_name => "open-ils.actor.user.perm.check",
1100 notes => <<" NOTES");
1101 Takes a login session, user id, an org id, and an array of perm type strings. For each
1102 perm type, if the user does *not* have the given permission it is added
1103 to a list which is returned from the method. If all permissions
1104 are allowed, an empty list is returned
1105 if the logged in user does not match 'user_id', then the logged in user must
1106 have VIEW_PERMISSION priveleges.
1109 sub check_user_perms {
1110 my( $self, $client, $login_session, $user_id, $org_id, $perm_types ) = @_;
1112 my( $staff, $evt ) = $apputils->checkses($login_session);
1113 return $evt if $evt;
1115 if($staff->id ne $user_id) {
1116 if( my $evt = $apputils->check_perms(
1117 $staff->id, $org_id, 'VIEW_PERMISSION') ) {
1123 for my $perm (@$perm_types) {
1124 if($apputils->check_perms($user_id, $org_id, $perm)) {
1125 push @not_allowed, $perm;
1129 return \@not_allowed
1132 __PACKAGE__->register_method(
1133 method => "check_user_perms2",
1134 api_name => "open-ils.actor.user.perm.check.multi_org",
1136 Checks the permissions on a list of perms and orgs for a user
1137 @param authtoken The login session key
1138 @param user_id The id of the user to check
1139 @param orgs The array of org ids
1140 @param perms The array of permission names
1141 @return An array of [ orgId, permissionName ] arrays that FAILED the check
1142 if the logged in user does not match 'user_id', then the logged in user must
1143 have VIEW_PERMISSION priveleges.
1146 sub check_user_perms2 {
1147 my( $self, $client, $authtoken, $user_id, $orgs, $perms ) = @_;
1149 my( $staff, $target, $evt ) = $apputils->checkses_requestor(
1150 $authtoken, $user_id, 'VIEW_PERMISSION' );
1151 return $evt if $evt;
1154 for my $org (@$orgs) {
1155 for my $perm (@$perms) {
1156 if($apputils->check_perms($user_id, $org, $perm)) {
1157 push @not_allowed, [ $org, $perm ];
1162 return \@not_allowed
1166 __PACKAGE__->register_method(
1167 method => 'check_user_perms3',
1168 api_name => 'open-ils.actor.user.perm.highest_org',
1170 Returns the highest org unit id at which a user has a given permission
1171 If the requestor does not match the target user, the requestor must have
1172 'VIEW_PERMISSION' rights at the home org unit of the target user
1173 @param authtoken The login session key
1174 @param userid The id of the user in question
1175 @param perm The permission to check
1176 @return The org unit highest in the org tree within which the user has
1177 the requested permission
1180 sub check_user_perms3 {
1181 my( $self, $client, $authtoken, $userid, $perm ) = @_;
1183 my( $staff, $target, $org, $evt );
1185 ( $staff, $target, $evt ) = $apputils->checkses_requestor(
1186 $authtoken, $userid, 'VIEW_PERMISSION' );
1187 return $evt if $evt;
1189 my $tree = $self->get_org_tree();
1190 return _find_highest_perm_org( $perm, $userid, $target->home_ou, $tree );
1194 sub _find_highest_perm_org {
1195 my ( $perm, $userid, $start_org, $org_tree ) = @_;
1196 my $org = $apputils->find_org($org_tree, $start_org );
1200 last if ($apputils->check_perms( $userid, $org->id, $perm )); # perm failed
1202 $org = $apputils->find_org( $org_tree, $org->parent_ou() );
1208 __PACKAGE__->register_method(
1209 method => 'check_user_perms4',
1210 api_name => 'open-ils.actor.user.perm.highest_org.batch',
1212 Returns the highest org unit id at which a user has a given permission
1213 If the requestor does not match the target user, the requestor must have
1214 'VIEW_PERMISSION' rights at the home org unit of the target user
1215 @param authtoken The login session key
1216 @param userid The id of the user in question
1217 @param perms An array of perm names to check
1218 @return An array of orgId's representing the org unit
1219 highest in the org tree within which the user has the requested permission
1220 The arrah of orgId's has matches the order of the perms array
1223 sub check_user_perms4 {
1224 my( $self, $client, $authtoken, $userid, $perms ) = @_;
1226 my( $staff, $target, $org, $evt );
1228 ( $staff, $target, $evt ) = $apputils->checkses_requestor(
1229 $authtoken, $userid, 'VIEW_PERMISSION' );
1230 return $evt if $evt;
1233 return [] unless ref($perms);
1234 my $tree = $self->get_org_tree();
1236 for my $p (@$perms) {
1237 push( @arr, _find_highest_perm_org( $p, $userid, $target->home_ou, $tree ) );
1245 __PACKAGE__->register_method(
1246 method => "user_fines_summary",
1247 api_name => "open-ils.actor.user.fines.summary",
1248 notes => <<" NOTES");
1249 Returns a short summary of the users total open fines, excluding voided fines
1250 Params are login_session, user_id
1251 Returns a 'mous' object.
1254 sub user_fines_summary {
1255 my( $self, $client, $login_session, $user_id ) = @_;
1257 my $user_obj = $apputils->check_user_session($login_session);
1258 if($user_obj->id ne $user_id) {
1259 if($apputils->check_user_perms($user_obj->id, $user_obj->home_ou, "VIEW_USER_FINES_SUMMARY")) {
1260 return OpenILS::Perm->new("VIEW_USER_FINES_SUMMARY");
1264 return $apputils->simple_scalar_request(
1266 "open-ils.storage.direct.money.open_user_summary.search.usr",
1274 __PACKAGE__->register_method(
1275 method => "user_transactions",
1276 api_name => "open-ils.actor.user.transactions",
1277 notes => <<" NOTES");
1278 Returns a list of open user transactions (mbts objects);
1279 Params are login_session, user_id
1280 Optional third parameter is the transactions type. defaults to all
1283 __PACKAGE__->register_method(
1284 method => "user_transactions",
1285 api_name => "open-ils.actor.user.transactions.have_charge",
1286 notes => <<" NOTES");
1287 Returns a list of all open user transactions (mbts objects) that have an initial charge
1288 Params are login_session, user_id
1289 Optional third parameter is the transactions type. defaults to all
1292 __PACKAGE__->register_method(
1293 method => "user_transactions",
1294 api_name => "open-ils.actor.user.transactions.have_balance",
1295 notes => <<" NOTES");
1296 Returns a list of all open user transactions (mbts objects) that have a balance
1297 Params are login_session, user_id
1298 Optional third parameter is the transactions type. defaults to all
1301 __PACKAGE__->register_method(
1302 method => "user_transactions",
1303 api_name => "open-ils.actor.user.transactions.fleshed",
1304 notes => <<" NOTES");
1305 Returns an object/hash of transaction, circ, title where transaction = an open
1306 user transactions (mbts objects), circ is the attached circluation, and title
1307 is the title the circ points to
1308 Params are login_session, user_id
1309 Optional third parameter is the transactions type. defaults to all
1312 __PACKAGE__->register_method(
1313 method => "user_transactions",
1314 api_name => "open-ils.actor.user.transactions.have_charge.fleshed",
1315 notes => <<" NOTES");
1316 Returns an object/hash of transaction, circ, title where transaction = an open
1317 user transactions that has an initial charge (mbts objects), circ is the
1318 attached circluation, and title is the title the circ points to
1319 Params are login_session, user_id
1320 Optional third parameter is the transactions type. defaults to all
1323 __PACKAGE__->register_method(
1324 method => "user_transactions",
1325 api_name => "open-ils.actor.user.transactions.have_balance.fleshed",
1326 notes => <<" NOTES");
1327 Returns an object/hash of transaction, circ, title where transaction = an open
1328 user transaction that has a balance (mbts objects), circ is the attached
1329 circluation, and title is the title the circ points to
1330 Params are login_session, user_id
1331 Optional third parameter is the transaction type. defaults to all
1334 __PACKAGE__->register_method(
1335 method => "user_transactions",
1336 api_name => "open-ils.actor.user.transactions.count",
1337 notes => <<" NOTES");
1338 Returns an object/hash of transaction, circ, title where transaction = an open
1339 user transactions (mbts objects), circ is the attached circluation, and title
1340 is the title the circ points to
1341 Params are login_session, user_id
1342 Optional third parameter is the transactions type. defaults to all
1345 __PACKAGE__->register_method(
1346 method => "user_transactions",
1347 api_name => "open-ils.actor.user.transactions.have_charge.count",
1348 notes => <<" NOTES");
1349 Returns an object/hash of transaction, circ, title where transaction = an open
1350 user transactions that has an initial charge (mbts objects), circ is the
1351 attached circluation, and title is the title the circ points to
1352 Params are login_session, user_id
1353 Optional third parameter is the transactions type. defaults to all
1356 __PACKAGE__->register_method(
1357 method => "user_transactions",
1358 api_name => "open-ils.actor.user.transactions.have_balance.count",
1359 notes => <<" NOTES");
1360 Returns an object/hash of transaction, circ, title where transaction = an open
1361 user transaction that has a balance (mbts objects), circ is the attached
1362 circluation, and title is the title the circ points to
1363 Params are login_session, user_id
1364 Optional third parameter is the transaction type. defaults to all
1367 __PACKAGE__->register_method(
1368 method => "user_transactions",
1369 api_name => "open-ils.actor.user.transactions.have_balance.total",
1370 notes => <<" NOTES");
1371 Returns an object/hash of transaction, circ, title where transaction = an open
1372 user transaction that has a balance (mbts objects), circ is the attached
1373 circluation, and title is the title the circ points to
1374 Params are login_session, user_id
1375 Optional third parameter is the transaction type. defaults to all
1380 sub user_transactions {
1381 my( $self, $client, $login_session, $user_id, $type ) = @_;
1383 my( $user_obj, $target, $evt ) = $apputils->checkses_requestor(
1384 $login_session, $user_id, 'VIEW_USER_TRANSACTIONS' );
1385 return $evt if $evt;
1387 my $api = $self->api_name();
1391 if(defined($type)) { @xact = (xact_type => $type);
1393 } else { @xact = (); }
1395 if($api =~ /have_charge/o) {
1397 $trans = $apputils->simple_scalar_request(
1399 "open-ils.storage.direct.money.open_billable_transaction_summary.search_where.atomic",
1400 { usr => $user_id, total_owed => { ">" => 0 }, @xact });
1402 } elsif($api =~ /have_balance/o) {
1404 $trans = $apputils->simple_scalar_request(
1406 "open-ils.storage.direct.money.open_billable_transaction_summary.search_where.atomic",
1407 { usr => $user_id, balance_owed => { "<>" => 0 }, @xact });
1411 $trans = $apputils->simple_scalar_request(
1413 "open-ils.storage.direct.money.open_billable_transaction_summary.search_where.atomic",
1414 { usr => $user_id, @xact });
1417 if($api =~ /total/o) {
1419 for my $t (@$trans) {
1420 $total += $t->balance_owed;
1423 $logger->debug("Total balance owed by user $user_id: $total");
1427 if($api =~ /count/o) { return scalar @$trans; }
1428 if($api !~ /fleshed/o) { return $trans; }
1431 for my $t (@$trans) {
1433 if( $t->xact_type ne 'circulation' ) {
1434 push @resp, {transaction => $t};
1438 my $circ = $apputils->simple_scalar_request(
1440 "open-ils.storage.direct.action.circulation.retrieve",
1445 my $title = $apputils->simple_scalar_request(
1447 "open-ils.storage.fleshed.biblio.record_entry.retrieve_by_copy",
1448 $circ->target_copy );
1452 my $u = OpenILS::Utils::ModsParser->new();
1453 $u->start_mods_batch($title->marc());
1454 my $mods = $u->finish_mods_batch();
1456 push @resp, {transaction => $t, circ => $circ, record => $mods };
1464 __PACKAGE__->register_method(
1465 method => "user_transaction_retrieve",
1466 api_name => "open-ils.actor.user.transaction.fleshed.retrieve",
1468 notes => <<" NOTES");
1469 Returns a fleshedtransaction record
1471 __PACKAGE__->register_method(
1472 method => "user_transaction_retrieve",
1473 api_name => "open-ils.actor.user.transaction.retrieve",
1475 notes => <<" NOTES");
1476 Returns a transaction record
1478 sub user_transaction_retrieve {
1479 my( $self, $client, $login_session, $bill_id ) = @_;
1481 my $trans = $apputils->simple_scalar_request(
1483 "open-ils.storage.direct.money.billable_transaction_summary.retrieve",
1487 my( $user_obj, $target, $evt ) = $apputils->checkses_requestor(
1488 $login_session, $trans->usr, 'VIEW_USER_TRANSACTIONS' );
1489 return $evt if $evt;
1491 my $api = $self->api_name();
1492 if($api !~ /fleshed/o) { return $trans; }
1494 if( $trans->xact_type ne 'circulation' ) {
1495 $logger->debug("Returning non-circ transaction");
1496 return {transaction => $trans};
1499 my $circ = $apputils->simple_scalar_request(
1501 "open-ils.storage.direct.action.circulation.retrieve",
1504 return {transaction => $trans} unless $circ;
1505 $logger->debug("Found the circ transaction");
1507 my $title = $apputils->simple_scalar_request(
1509 "open-ils.storage.fleshed.biblio.record_entry.retrieve_by_copy",
1510 $circ->target_copy );
1512 return {transaction => $trans, circ => $circ } unless $title;
1513 $logger->debug("Found the circ title");
1517 my $u = OpenILS::Utils::ModsParser->new();
1518 $u->start_mods_batch($title->marc());
1519 $mods = $u->finish_mods_batch();
1521 if ($title->id == -1) {
1522 my $copy = $apputils->simple_scalar_request(
1524 "open-ils.storage.direct.asset.copy.retrieve",
1525 $circ->target_copy );
1527 $mods = new Fieldmapper::metabib::virtual_record;
1529 $mods->title($copy->dummy_title);
1530 $mods->author($copy->dummy_author);
1534 $logger->debug("MODSized the circ title");
1536 return {transaction => $trans, circ => $circ, record => $mods };
1540 __PACKAGE__->register_method(
1541 method => "hold_request_count",
1542 api_name => "open-ils.actor.user.hold_requests.count",
1544 notes => <<" NOTES");
1545 Returns hold ready/total counts
1547 sub hold_request_count {
1548 my( $self, $client, $login_session, $userid ) = @_;
1550 my( $user_obj, $target, $evt ) = $apputils->checkses_requestor(
1551 $login_session, $userid, 'VIEW_HOLD' );
1552 return $evt if $evt;
1555 my $holds = $apputils->simple_scalar_request(
1557 "open-ils.storage.direct.action.hold_request.search_where.atomic",
1559 fulfillment_time => {"=" => undef } }
1563 for my $h (@$holds) {
1564 next unless $h->capture_time;
1566 my $copy = $apputils->simple_scalar_request(
1568 "open-ils.storage.direct.asset.copy.retrieve",
1572 if ($copy->status == 8) {
1577 return { total => scalar(@$holds), ready => scalar(@ready) };
1581 __PACKAGE__->register_method(
1582 method => "checkedout_count",
1583 api_name => "open-ils.actor.user.checked_out.count",
1585 notes => <<" NOTES");
1586 Returns a transaction record
1588 sub checkedout_count {
1589 my( $self, $client, $login_session, $userid ) = @_;
1591 my( $user_obj, $target, $evt ) = $apputils->checkses_requestor(
1592 $login_session, $userid, 'VIEW_CIRCULATIONS' );
1593 return $evt if $evt;
1596 my $circs = $apputils->simple_scalar_request(
1598 "open-ils.storage.direct.action.circulation.search_where.atomic",
1600 checkin_time => {"=" => undef } }
1603 my $parser = DateTime::Format::ISO8601->new;
1606 for my $c (@$circs) {
1607 my $due_dt = $parser->parse_datetime( clense_ISO8601( $c->due_date ) );
1608 my $due = $due_dt->epoch;
1610 if ($due < DateTime->today->epoch) {
1615 return { total => scalar(@$circs), overdue => scalar(@overdue) };
1618 __PACKAGE__->register_method(
1619 method => "user_transaction_history",
1620 api_name => "open-ils.actor.user.transactions.history",
1622 notes => <<" NOTES");
1623 Returns a list of billable transaction ids for a user, optionally by type
1625 __PACKAGE__->register_method(
1626 method => "user_transaction_history",
1627 api_name => "open-ils.actor.user.transactions.history.have_charge",
1629 notes => <<" NOTES");
1630 Returns a list of billable transaction ids for a user that have an initial charge, optionally by type
1632 sub user_transaction_history {
1633 my( $self, $client, $login_session, $user_id, $type ) = @_;
1635 my( $user_obj, $target, $evt ) = $apputils->checkses_requestor(
1636 $login_session, $user_id, 'VIEW_USER_TRANSACTIONS' );
1637 return $evt if $evt;
1639 my $api = $self->api_name();
1643 @xact = (xact_type => $type) if(defined($type));
1644 @charge = (total_owed => { ">" => 0}) if($api =~ /have_charge/);
1646 my $trans = $apputils->simple_scalar_request(
1648 "open-ils.storage.direct.money.billable_transaction_summary.search_where.atomic",
1649 { usr => $user_id, @xact, @charge }, { order_by => 'xact_start DESC' });
1651 return [ map { $_->id } @$trans ];
1655 __PACKAGE__->register_method(
1656 method => "user_perms",
1657 api_name => "open-ils.actor.permissions.user_perms.retrieve",
1659 notes => <<" NOTES");
1660 Returns a list of permissions
1663 my( $self, $client, $authtoken, $user ) = @_;
1665 my( $staff, $evt ) = $apputils->checkses($authtoken);
1666 return $evt if $evt;
1668 $user ||= $staff->id;
1670 if( $user != $staff->id and $evt = $apputils->check_perms( $staff->id, $staff->home_ou, 'VIEW_PERMISSION') ) {
1674 return $apputils->simple_scalar_request(
1676 "open-ils.storage.permission.user_perms.atomic",
1680 __PACKAGE__->register_method(
1681 method => "retrieve_perms",
1682 api_name => "open-ils.actor.permissions.retrieve",
1683 notes => <<" NOTES");
1684 Returns a list of permissions
1686 sub retrieve_perms {
1687 my( $self, $client ) = @_;
1688 return $apputils->simple_scalar_request(
1690 "open-ils.storage.direct.permission.perm_list.retrieve.all.atomic");
1693 __PACKAGE__->register_method(
1694 method => "retrieve_groups",
1695 api_name => "open-ils.actor.groups.retrieve",
1696 notes => <<" NOTES");
1697 Returns a list of user groupss
1699 sub retrieve_groups {
1700 my( $self, $client ) = @_;
1701 return $apputils->simple_scalar_request(
1703 "open-ils.storage.direct.permission.grp_tree.retrieve.all.atomic");
1706 __PACKAGE__->register_method(
1707 method => "retrieve_org_address",
1708 api_name => "open-ils.actor.org_unit.address.retrieve",
1709 notes => <<' NOTES');
1710 Returns an org_unit address by ID
1711 @param An org_address ID
1713 sub retrieve_org_address {
1714 my( $self, $client, $id ) = @_;
1715 return $apputils->simple_scalar_request(
1717 "open-ils.storage.direct.actor.org_address.retrieve",
1722 __PACKAGE__->register_method(
1723 method => "retrieve_groups_tree",
1724 api_name => "open-ils.actor.groups.tree.retrieve",
1725 notes => <<" NOTES");
1726 Returns a list of user groups
1728 sub retrieve_groups_tree {
1729 my( $self, $client ) = @_;
1730 my $groups = $apputils->simple_scalar_request(
1732 "open-ils.storage.direct.permission.grp_tree.retrieve.all.atomic");
1733 return $self->build_group_tree($groups);
1737 # turns an org list into an org tree
1738 sub build_group_tree {
1740 my( $self, $grplist) = @_;
1742 return $grplist unless (
1743 ref($grplist) and @$grplist > 1 );
1745 my @list = sort { $a->name cmp $b->name } @$grplist;
1748 for my $grp (@list) {
1750 if ($grp and !defined($grp->parent)) {
1754 my ($parent) = grep { $_->id == $grp->parent} @list;
1756 $parent->children([]) unless defined($parent->children);
1757 push( @{$parent->children}, $grp );
1765 __PACKAGE__->register_method(
1766 method => "add_user_to_groups",
1767 api_name => "open-ils.actor.user.set_groups",
1768 notes => <<" NOTES");
1769 Adds a user to one or more permission groups
1772 sub add_user_to_groups {
1773 my( $self, $client, $authtoken, $userid, $groups ) = @_;
1775 my( $requestor, $target, $evt ) = $apputils->checkses_requestor(
1776 $authtoken, $userid, 'CREATE_USER_GROUP_LINK' );
1777 return $evt if $evt;
1779 ( $requestor, $target, $evt ) = $apputils->checkses_requestor(
1780 $authtoken, $userid, 'REMOVE_USER_GROUP_LINK' );
1781 return $evt if $evt;
1783 $apputils->simplereq(
1785 'open-ils.storage.direct.permission.usr_grp_map.mass_delete', { usr => $userid } );
1787 for my $group (@$groups) {
1788 my $link = Fieldmapper::permission::usr_grp_map->new;
1790 $link->usr($userid);
1792 my $id = $apputils->simplereq(
1794 'open-ils.storage.direct.permission.usr_grp_map.create', $link );
1800 __PACKAGE__->register_method(
1801 method => "get_user_perm_groups",
1802 api_name => "open-ils.actor.user.get_groups",
1803 notes => <<" NOTES");
1804 Retrieve a user's permission groups.
1808 sub get_user_perm_groups {
1809 my( $self, $client, $authtoken, $userid ) = @_;
1811 my( $requestor, $target, $evt ) = $apputils->checkses_requestor(
1812 $authtoken, $userid, 'VIEW_PERM_GROUPS' );
1813 return $evt if $evt;
1815 return $apputils->simplereq(
1817 'open-ils.storage.direct.permission.usr_grp_map.search.usr.atomic', $userid );
1822 __PACKAGE__->register_method (
1823 method => 'register_workstation',
1824 api_name => 'open-ils.actor.workstation.register',
1826 Registers a new workstion in the system
1827 @param authtoken The login session key
1828 @param name The name of the workstation id
1829 @param owner The org unit that owns this workstation
1830 @return The workstation id on success, WORKSTATION_NAME_EXISTS
1831 if the name is already in use.
1834 sub register_workstation {
1835 my( $self, $connection, $authtoken, $name, $owner ) = @_;
1836 my( $requestor, $evt ) = $U->checkses($authtoken);
1837 return $evt if $evt;
1838 $evt = $U->check_perms($requestor->id, $owner, 'REGISTER_WORKSTATION');
1839 return $evt if $evt;
1841 my $ws = $U->storagereq(
1842 'open-ils.storage.direct.actor.workstation.search.name', $name );
1843 return OpenILS::Event->new('WORKSTATION_NAME_EXISTS') if $ws;
1845 $ws = Fieldmapper::actor::workstation->new;
1846 $ws->owning_lib($owner);
1849 my $id = $U->storagereq(
1850 'open-ils.storage.direct.actor.workstation.create', $ws );
1851 return $U->DB_UPDATE_FAILED($ws) unless $id;
1858 __PACKAGE__->register_method (
1859 method => 'fetch_patron_note',
1860 api_name => 'open-ils.actor.note.retrieve.all',
1862 Returns a list of notes for a given user
1863 Requestor must have VIEW_USER permission if pub==false and
1864 @param authtoken The login session key
1865 @param args Hash of params including
1866 patronid : the patron's id
1867 pub : true if retrieving only public notes
1871 sub fetch_patron_note {
1872 my( $self, $conn, $authtoken, $args ) = @_;
1873 my $patronid = $$args{patronid};
1875 my($reqr, $evt) = $U->checkses($authtoken);
1878 ($patron, $evt) = $U->fetch_user($patronid);
1879 return $evt if $evt;
1882 if( $patronid ne $reqr->id ) {
1883 $evt = $U->check_perms($reqr->id, $patron->home_ou, 'VIEW_USER');
1884 return $evt if $evt;
1886 return $U->storagereq(
1887 'open-ils.storage.direct.actor.usr_note.search_where.atomic',
1888 { usr => $patronid, pub => 't' } );
1891 $evt = $U->check_perms($reqr->id, $patron->home_ou, 'VIEW_USER');
1892 return $evt if $evt;
1894 return $U->storagereq(
1895 'open-ils.storage.direct.actor.usr_note.search.usr.atomic', $patronid );
1898 __PACKAGE__->register_method (
1899 method => 'create_user_note',
1900 api_name => 'open-ils.actor.note.create',
1902 Creates a new note for the given user
1903 @param authtoken The login session key
1904 @param note The note object
1907 sub create_user_note {
1908 my( $self, $conn, $authtoken, $note ) = @_;
1909 my( $reqr, $patron, $evt ) =
1910 $U->checkses_requestor($authtoken, $note->usr, 'UPDATE_USER');
1911 return $evt if $evt;
1912 $logger->activity("user ".$reqr->id." creating note for user ".$note->usr);
1914 $note->pub('f') unless $note->pub;
1915 $note->creator($reqr->id);
1916 my $id = $U->storagereq(
1917 'open-ils.storage.direct.actor.usr_note.create', $note );
1918 return $U->DB_UPDATE_FAILED($note) unless $id;
1923 __PACKAGE__->register_method (
1924 method => 'delete_user_note',
1925 api_name => 'open-ils.actor.note.delete',
1927 Deletes a note for the given user
1928 @param authtoken The login session key
1929 @param noteid The note id
1932 sub delete_user_note {
1933 my( $self, $conn, $authtoken, $noteid ) = @_;
1935 my $note = $U->storagereq(
1936 'open-ils.storage.direct.actor.usr_note.retrieve', $noteid);
1937 return OpenILS::Event->new('USER_NOTE_NOT_FOUND') unless $note;
1939 my( $reqr, $patron, $evt ) =
1940 $U->checkses_requestor($authtoken, $note->usr, 'UPDATE_USER');
1941 return $evt if $evt;
1942 $logger->activity("user ".$reqr->id." deleting note [$noteid] for user ".$note->usr);
1944 my $stat = $U->storagereq(
1945 'open-ils.storage.direct.actor.usr_note.delete', $noteid );
1946 return $U->DB_UPDATE_FAILED($note) unless defined $stat;
1952 __PACKAGE__->register_method (
1953 method => 'create_closed_date',
1954 api_name => 'open-ils.actor.org_unit.closed_date.create',
1956 Creates a new closing entry for the given org_unit
1957 @param authtoken The login session key
1958 @param note The closed_date object
1961 sub create_closed_date {
1962 my( $self, $conn, $authtoken, $cd ) = @_;
1964 my( $user, $evt ) = $U->checkses($authtoken);
1965 return $evt if $evt;
1967 $evt = $U->check_perms($user->id, $cd->org_unit, 'CREATE_CLOSEING');
1968 return $evt if $evt;
1970 $logger->activity("user ".$user->id." creating library closing for ".$cd->org_unit);
1972 my $id = $U->storagereq(
1973 'open-ils.storage.direct.actor.org_unit.closed_date.create', $cd );
1974 return $U->DB_UPDATE_FAILED($cd) unless $id;
1979 __PACKAGE__->register_method (
1980 method => 'delete_closed_date',
1981 api_name => 'open-ils.actor.org_unit.closed_date.delete',
1983 Deletes a closing entry for the given org_unit
1984 @param authtoken The login session key
1985 @param noteid The close_date id
1988 sub delete_closed_date {
1989 my( $self, $conn, $authtoken, $cd ) = @_;
1991 my( $user, $evt ) = $U->checkses($authtoken);
1992 return $evt if $evt;
1995 ($cd_obj, $evt) = fetch_closed_date($cd);
1996 return $evt if $evt;
1998 $evt = $U->check_perms($user->id, $cd->org_unit, 'DELETE_CLOSEING');
1999 return $evt if $evt;
2001 $logger->activity("user ".$user->id." deleting library closing for ".$cd->org_unit);
2003 my $stat = $U->storagereq(
2004 'open-ils.storage.direct.actor.org_unit.closed_date.delete', $cd );
2005 return $U->DB_UPDATE_FAILED($cd) unless $stat;
2010 #__PACKAGE__->register_method(