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;
30 OpenILS::Application::Actor::Container->initialize();
33 my $apputils = "OpenILS::Application::AppUtils";
36 sub _d { warn "Patron:\n" . Dumper(shift()); }
41 my $set_user_settings;
44 __PACKAGE__->register_method(
45 method => "set_user_settings",
46 api_name => "open-ils.actor.patron.settings.update",
48 sub set_user_settings {
49 my( $self, $client, $user_session, $uid, $settings ) = @_;
51 $logger->debug("Setting user settings: $user_session, $uid, " . Dumper($settings));
53 my( $staff, $user, $evt ) =
54 $apputils->checkses_requestor( $user_session, $uid, 'UPDATE_USER' );
59 # [{ usr => $user->id, name => $_}, {value => $$settings{$_}}] } keys %$settings;
62 [{ usr => $user->id, name => $_}, {value => $$settings{$_}}] } keys %$settings;
64 $logger->activity("User " . $staff->id . " updating user $uid settings with: " . Dumper(\@params));
66 return $apputils->simplereq(
68 'open-ils.storage.direct.actor.user_setting.batch.merge', @params );
74 __PACKAGE__->register_method(
75 method => "set_ou_settings",
76 api_name => "open-ils.actor.org_unit.settings.update",
79 my( $self, $client, $user_session, $ouid, $settings ) = @_;
81 my( $staff, $evt ) = $apputils->checkses( $user_session );
83 $evt = $apputils->check_perms( $staff->id, $ouid, 'UPDATE_ORG_UNIT' );
88 map { [{ org_unit => $ouid, name => $_}, {value => $$settings{$_}}] } keys %$settings;
90 $logger->activity("Updating org unit [$ouid] settings with: " . Dumper($params));
92 return $apputils->simplereq(
94 'open-ils.storage.direct.actor.org_unit_setting.merge', @$params );
98 my $fetch_user_settings;
99 my $fetch_ou_settings;
101 __PACKAGE__->register_method(
102 method => "user_settings",
103 api_name => "open-ils.actor.patron.settings.retrieve",
106 my( $self, $client, $user_session, $uid ) = @_;
108 my( $staff, $user, $evt ) =
109 $apputils->checkses_requestor( $user_session, $uid, 'VIEW_USER' );
112 $logger->debug("User " . $staff->id . " fetching user $uid\n");
113 my $s = $apputils->simplereq(
115 'open-ils.storage.direct.actor.user_setting.search.usr.atomic',$uid );
117 return { map { ($_->name,$_->value) } @$s };
122 __PACKAGE__->register_method(
123 method => "ou_settings",
124 api_name => "open-ils.actor.org_unit.settings.retrieve",
127 my( $self, $client, $ouid ) = @_;
129 my $s = $apputils->simplereq(
131 'open-ils.storage.direct.actor.org_unit_setting.search.org_unit.atomic', $ouid);
133 return { map { ($_->name,$_->value) } @$s };
136 __PACKAGE__->register_method (
137 method => "ou_setting_delete",
138 api_name => 'open-ils.actor.org_setting.delete',
140 Deletes a specific org unit setting for a specific location
141 @param authtoken The login session key
142 @param orgid The org unit whose setting we're changing
143 @param setting The name of the setting to delete
144 @return True value on success.
148 sub ou_setting_delete {
149 my( $self, $conn, $authtoken, $orgid, $setting ) = @_;
150 my( $reqr, $evt) = $U->checkses($authtoken);
152 $evt = $U->check_perms($reqr->id, $orgid, 'UPDATE_ORG_SETTING');
155 my $id = $U->storagereq(
156 'open-ils.storage.id_list.actor.org_unit_setting.search_where',
157 { name => $setting, org_unit => $orgid } );
159 $logger->debug("Retrieved setting $id in org unit setting delete");
161 my $s = $U->storagereq(
162 'open-ils.storage.direct.actor.org_unit_setting.delete', $id );
164 $logger->activity("User ".$reqr->id." deleted org unit setting $id") if $s;
170 __PACKAGE__->register_method(
171 method => "update_patron",
172 api_name => "open-ils.actor.patron.update",);
175 my( $self, $client, $user_session, $patron ) = @_;
177 my $session = $apputils->start_db_session();
180 $logger->info("Creating new patron...") if $patron->isnew;
181 $logger->info("Updating Patron: " . $patron->id) unless $patron->isnew;
183 my( $user_obj, $evt ) = $U->checkses($user_session);
186 # XXX does this user have permission to add/create users. Granularity?
187 # $new_patron is the patron in progress. $patron is the original patron
188 # passed in with the method. new_patron will change as the components
189 # of patron are added/updated.
193 # unflesh the real items on the patron
194 $patron->card( $patron->card->id ) if(ref($patron->card));
195 $patron->billing_address( $patron->billing_address->id )
196 if(ref($patron->billing_address));
197 $patron->mailing_address( $patron->mailing_address->id )
198 if(ref($patron->mailing_address));
200 # create/update the patron first so we can use his id
201 if($patron->isnew()) {
202 ( $new_patron, $evt ) = _add_patron($session, _clone_patron($patron), $user_obj);
204 } else { $new_patron = $patron; }
206 ( $new_patron, $evt ) = _add_update_addresses($session, $patron, $new_patron, $user_obj);
209 ( $new_patron, $evt ) = _add_update_cards($session, $patron, $new_patron, $user_obj);
212 ( $new_patron, $evt ) = _add_survey_responses($session, $patron, $new_patron, $user_obj);
215 # re-update the patron if anything has happened to him during this process
216 if($new_patron->ischanged()) {
217 ( $new_patron, $evt ) = _update_patron($session, $new_patron, $user_obj);
221 #$session = OpenSRF::AppSession->create("open-ils.storage"); # why did i put this here?
223 ($new_patron, $evt) = _create_stat_maps($session, $user_session, $patron, $new_patron, $user_obj);
226 ($new_patron, $evt) = _create_perm_maps($session, $user_session, $patron, $new_patron, $user_obj);
229 ($new_patron, $evt) = _create_standing_penalties($session, $user_session, $patron, $new_patron, $user_obj);
232 $logger->activity("user ".$user_obj->id." updating/creating user ".$new_patron->id);
233 $apputils->commit_db_session($session);
235 #warn "Patron Update/Create complete\n";
236 return flesh_user($new_patron->id());
242 __PACKAGE__->register_method(
243 method => "user_retrieve_fleshed_by_id",
244 api_name => "open-ils.actor.user.fleshed.retrieve",);
246 sub user_retrieve_fleshed_by_id {
247 my( $self, $client, $user_session, $user_id ) = @_;
249 my( $requestor, $target, $evt ) = $apputils->
250 checkses_requestor( $user_session, $user_id, 'VIEW_USER' );
253 return flesh_user($user_id);
257 # fleshes: card, cards, address, addresses, stat_cat_entries, standing_penalties
265 $session = OpenSRF::AppSession->create("open-ils.storage");
269 # grab the user with the given id
270 my $ureq = $session->request(
271 "open-ils.storage.direct.actor.user.retrieve", $id);
272 my $user = $ureq->gather(1);
274 if(!$user) { return undef; }
277 my $cards_req = $session->request(
278 "open-ils.storage.direct.actor.card.search.usr.atomic",
280 $user->cards( $cards_req->gather(1) );
282 for my $c(@{$user->cards}) {
283 if($c->id == $user->card || $c->id eq $user->card ) {
284 #warn "Setting my card to " . $c->id . "\n";
289 my $add_req = $session->request(
290 "open-ils.storage.direct.actor.user_address.search.usr.atomic",
292 $user->addresses( $add_req->gather(1) );
294 for my $c(@{$user->addresses}) {
295 if($c->id eq $user->billing_address ) { $user->billing_address($c); }
296 if($c->id eq $user->mailing_address ) { $user->mailing_address($c); }
299 my $stat_req = $session->request(
300 "open-ils.storage.direct.actor.stat_cat_entry_user_map.search.target_usr.atomic",
302 $user->stat_cat_entries($stat_req->gather(1));
304 my $standing_penalties_req = $session->request(
305 "open-ils.storage.direct.actor.user_standing_penalty.search.usr.atomic",
307 $user->standing_penalties($standing_penalties_req->gather(1));
309 if($kill) { $session->disconnect(); }
310 $user->clear_passwd();
316 # clone and clear stuff that would break the database
320 my $new_patron = $patron->clone;
322 # Using the Fieldmapper clone method
323 #my $new_patron = Fieldmapper::actor::user->new();
325 #my $fmap = $Fieldmapper::fieldmap;
326 #no strict; # shallow clone, may be useful in the fieldmapper
328 # (keys %{$fmap->{"Fieldmapper::actor::user"}->{'fields'}}) {
329 # $new_patron->$field( $patron->$field() );
334 $new_patron->clear_billing_address();
335 $new_patron->clear_mailing_address();
336 $new_patron->clear_addresses();
337 $new_patron->clear_card();
338 $new_patron->clear_cards();
339 $new_patron->clear_id();
340 $new_patron->clear_isnew();
341 $new_patron->clear_ischanged();
342 $new_patron->clear_isdeleted();
343 $new_patron->clear_stat_cat_entries();
344 $new_patron->clear_permissions();
345 $new_patron->clear_standing_penalties();
355 my $user_obj = shift;
357 my $evt = $U->check_perms($user_obj->id, $patron->home_ou, 'CREATE_USER');
358 return (undef, $evt) if $evt;
360 $logger->info("Creating new user in the DB with username: ".$patron->usrname());
362 my $id = $session->request(
363 "open-ils.storage.direct.actor.user.create", $patron)->gather(1);
364 return (undef, $U->DB_UPDATE_FAILED($patron)) unless $id;
366 $logger->info("Successfully created new user [$id] in DB");
368 return ( $session->request(
369 "open-ils.storage.direct.actor.user.retrieve", $id)->gather(1), undef );
374 my( $session, $patron, $user_obj) = @_;
376 $logger->info("Updating patron ".$patron->id." in DB");
377 my $evt = $U->check_perms($user_obj->id, $patron->home_ou, 'UPDATE_USER');
378 return (undef, $evt) if $evt;
380 $patron->clear_passwd unless $patron->passwd;
382 if(!$patron->ident_type) {
383 $patron->clear_ident_type;
384 $patron->clear_ident_value;
387 if(!$patron->ident_type2) {
388 $patron->clear_ident_type2;
389 $patron->clear_ident_value2;
392 my $stat = $session->request(
393 "open-ils.storage.direct.actor.user.update",$patron )->gather(1);
394 return (undef, $U->DB_UPDATE_FAILED($patron)) unless defined($stat);
400 sub _add_update_addresses {
404 my $new_patron = shift;
408 my $current_id; # id of the address before creation
410 for my $address (@{$patron->addresses()}) {
412 $address->usr($new_patron->id());
414 if(ref($address) and $address->isnew()) {
416 $current_id = $address->id();
417 ($address, $evt) = _add_address($session,$address);
418 return (undef, $evt) if $evt;
420 if( $patron->billing_address() and
421 $patron->billing_address() == $current_id ) {
422 $new_patron->billing_address($address->id());
423 $new_patron->ischanged(1);
426 if( $patron->mailing_address() and
427 $patron->mailing_address() == $current_id ) {
428 $new_patron->mailing_address($address->id());
429 $new_patron->ischanged(1);
432 } elsif( ref($address) and $address->ischanged() ) {
434 $address->usr($new_patron->id());
435 ($address, $evt) = _update_address($session, $address);
436 return (undef, $evt) if $evt;
438 } elsif( ref($address) and $address->isdeleted() ) {
440 if( $address->id() == $new_patron->mailing_address() ) {
441 $new_patron->clear_mailing_address();
442 ($new_patron, $evt) = _update_patron($session, $new_patron);
443 return (undef, $evt) if $evt;
446 if( $address->id() == $new_patron->billing_address() ) {
447 $new_patron->clear_billing_address();
448 ($new_patron, $evt) = _update_patron($session, $new_patron);
449 return (undef, $evt) if $evt;
452 $evt = _delete_address($session, $address);
453 return (undef, $evt) if $evt;
457 return ( $new_patron, undef );
461 # adds an address to the db and returns the address with new id
463 my($session, $address) = @_;
464 $address->clear_id();
466 $logger->info("Creating new address at street ".$address->street1);
468 # put the address into the database
469 my $id = $session->request(
470 "open-ils.storage.direct.actor.user_address.create", $address )->gather(1);
471 return (undef, $U->DB_UPDATE_FAILED($address)) unless $id;
474 return ($address, undef);
478 sub _update_address {
479 my( $session, $address ) = @_;
481 $logger->info("Updating address ".$address->id." in the DB");
483 my $stat = $session->request(
484 "open-ils.storage.direct.actor.user_address.update", $address )->gather(1);
486 return (undef, $U->DB_UPDATE_FAILED($address)) unless defined($stat);
487 return ($address, undef);
492 sub _add_update_cards {
496 my $new_patron = shift;
500 my $virtual_id; #id of the card before creation
501 for my $card (@{$patron->cards()}) {
503 $card->usr($new_patron->id());
505 if(ref($card) and $card->isnew()) {
507 $virtual_id = $card->id();
508 ( $card, $evt ) = _add_card($session,$card);
509 return (undef, $evt) if $evt;
511 #if(ref($patron->card)) { $patron->card($patron->card->id); }
512 if($patron->card() == $virtual_id) {
513 $new_patron->card($card->id());
514 $new_patron->ischanged(1);
517 } elsif( ref($card) and $card->ischanged() ) {
518 $card->usr($new_patron->id());
519 $evt = _update_card($session, $card);
520 return (undef, $evt) if $evt;
524 return ( $new_patron, undef );
528 # adds an card to the db and returns the card with new id
530 my( $session, $card ) = @_;
533 $logger->info("Adding new patron card ".$card->barcode);
535 my $id = $session->request(
536 "open-ils.storage.direct.actor.card.create", $card )->gather(1);
537 return (undef, $U->DB_UPDATE_FAILED($card)) unless $id;
538 $logger->info("Successfully created patron card $id");
541 return ( $card, undef );
545 # returns event on error. returns undef otherwise
547 my( $session, $card ) = @_;
548 $logger->info("Updating patron card ".$card->id);
550 my $stat = $session->request(
551 "open-ils.storage.direct.actor.card.update", $card )->gather(1);
552 return $U->DB_UPDATE_FAILED($card) unless defined($stat);
559 # returns event on error. returns undef otherwise
560 sub _delete_address {
561 my( $session, $address ) = @_;
563 $logger->info("Deleting address ".$address->id." from DB");
565 my $stat = $session->request(
566 "open-ils.storage.direct.actor.user_address.delete", $address )->gather(1);
568 return $U->DB_UPDATE_FAILED($address) unless defined($stat);
574 sub _add_survey_responses {
575 my ($session, $patron, $new_patron) = @_;
577 $logger->info( "Updating survey responses for patron ".$new_patron->id );
579 my $responses = $patron->survey_responses;
583 $_->usr($new_patron->id) for (@$responses);
585 my $evt = $U->simplereq( "open-ils.circ",
586 "open-ils.circ.survey.submit.user_id", $responses );
588 return (undef, $evt) if defined($U->event_code($evt));
592 return ( $new_patron, undef );
596 sub _create_stat_maps {
598 my($session, $user_session, $patron, $new_patron) = @_;
600 my $maps = $patron->stat_cat_entries();
602 for my $map (@$maps) {
604 my $method = "open-ils.storage.direct.actor.stat_cat_entry_user_map.update";
606 if ($map->isdeleted()) {
607 $method = "open-ils.storage.direct.actor.stat_cat_entry_user_map.delete";
609 } elsif ($map->isnew()) {
610 $method = "open-ils.storage.direct.actor.stat_cat_entry_user_map.create";
615 $map->target_usr($new_patron->id);
618 $logger->info("Updating stat entry with method $method and map $map");
620 my $stat = $session->request($method, $map)->gather(1);
621 return (undef, $U->DB_UPDATE_FAILED($map)) unless defined($stat);
625 return ($new_patron, undef);
628 sub _create_perm_maps {
630 my($session, $user_session, $patron, $new_patron) = @_;
632 my $maps = $patron->permissions;
634 for my $map (@$maps) {
636 my $method = "open-ils.storage.direct.permission.usr_perm_map.update";
637 if ($map->isdeleted()) {
638 $method = "open-ils.storage.direct.permission.usr_perm_map.delete";
639 } elsif ($map->isnew()) {
640 $method = "open-ils.storage.direct.permission.usr_perm_map.create";
645 $map->usr($new_patron->id);
647 #warn( "Updating permissions with method $method and session $user_session and map $map" );
648 $logger->info( "Updating permissions with method $method and map $map" );
650 my $stat = $session->request($method, $map)->gather(1);
651 return (undef, $U->DB_UPDATE_FAILED($map)) unless defined($stat);
655 return ($new_patron, undef);
659 sub _create_standing_penalties {
661 my($session, $user_session, $patron, $new_patron) = @_;
663 my $maps = $patron->standing_penalties;
666 for my $map (@$maps) {
668 if ($map->isdeleted()) {
669 $method = "open-ils.storage.direct.actor.user_standing_penalty.delete";
670 } elsif ($map->isnew()) {
671 $method = "open-ils.storage.direct.actor.user_standing_penalty.create";
677 $map->usr($new_patron->id);
679 $logger->debug( "Updating standing penalty with method $method and session $user_session and map $map" );
681 my $stat = $session->request($method, $map)->gather(1);
682 return (undef, $U->DB_UPDATE_FAILED($map)) unless $stat;
685 return ($new_patron, undef);
690 __PACKAGE__->register_method(
691 method => "search_username",
692 api_name => "open-ils.actor.user.search.username",
695 sub search_username {
696 my($self, $client, $username) = @_;
697 my $users = OpenILS::Application::AppUtils->simple_scalar_request(
699 "open-ils.storage.direct.actor.user.search.usrname.atomic",
707 __PACKAGE__->register_method(
708 method => "user_retrieve_by_barcode",
709 api_name => "open-ils.actor.user.fleshed.retrieve_by_barcode",);
711 sub user_retrieve_by_barcode {
712 my($self, $client, $user_session, $barcode) = @_;
714 $logger->debug("Searching for user with barcode $barcode");
715 my ($user_obj, $evt) = $apputils->checkses($user_session);
719 my $session = OpenSRF::AppSession->create("open-ils.storage");
721 # find the card with the given barcode
722 my $creq = $session->request(
723 "open-ils.storage.direct.actor.card.search.barcode.atomic",
725 my $card = $creq->gather(1);
727 if(!$card || !$card->[0]) {
728 $session->disconnect();
729 return OpenILS::Event->new( 'USER_NOT_FOUND' );
733 my $user = flesh_user($card->usr(), $session);
735 $evt = $U->check_perms($user_obj->id, $user->home_ou, 'VIEW_USER');
738 $session->disconnect();
739 if(!$user) { return OpenILS::Event->new( 'USER_NOT_FOUND' ); }
746 __PACKAGE__->register_method(
747 method => "get_user_by_id",
748 api_name => "open-ils.actor.user.retrieve",);
751 my ($self, $client, $user_session, $id) = @_;
753 my $user_obj = $apputils->check_user_session( $user_session );
755 return $apputils->simple_scalar_request(
757 "open-ils.storage.direct.actor.user.retrieve",
763 __PACKAGE__->register_method(
764 method => "get_org_types",
765 api_name => "open-ils.actor.org_types.retrieve",);
769 my($self, $client) = @_;
771 return $org_types if $org_types;
773 $apputils->simple_scalar_request(
775 "open-ils.storage.direct.actor.org_unit_type.retrieve.all.atomic" );
780 __PACKAGE__->register_method(
781 method => "get_user_profiles",
782 api_name => "open-ils.actor.user.profiles.retrieve",
786 sub get_user_profiles {
787 return $user_profiles if $user_profiles;
789 return $user_profiles =
790 $apputils->simple_scalar_request(
792 "open-ils.storage.direct.actor.profile.retrieve.all.atomic");
797 __PACKAGE__->register_method(
798 method => "get_user_ident_types",
799 api_name => "open-ils.actor.user.ident_types.retrieve",
802 sub get_user_ident_types {
803 return $ident_types if $ident_types;
804 return $ident_types =
805 $apputils->simple_scalar_request(
807 "open-ils.storage.direct.config.identification_type.retrieve.all.atomic" );
813 __PACKAGE__->register_method(
814 method => "get_org_unit",
815 api_name => "open-ils.actor.org_unit.retrieve",
820 my( $self, $client, $user_session, $org_id ) = @_;
822 if(defined($user_session) && !defined($org_id)) {
824 OpenILS::Application::AppUtils->check_user_session( $user_session ); #throws EX on error
825 if(!defined($org_id)) {
826 $org_id = $user_obj->home_ou;
831 my $home_ou = OpenILS::Application::AppUtils->simple_scalar_request(
833 "open-ils.storage.direct.actor.org_unit.retrieve",
839 __PACKAGE__->register_method(
840 method => "search_org_unit",
841 api_name => "open-ils.actor.org_unit_list.search",
844 sub search_org_unit {
846 my( $self, $client, $field, $value ) = @_;
848 my $list = OpenILS::Application::AppUtils->simple_scalar_request(
850 "open-ils.storage.direct.actor.org_unit.search.$field.atomic",
859 __PACKAGE__->register_method(
860 method => "get_org_tree",
861 api_name => "open-ils.actor.org_tree.retrieve",
863 note => "Returns the entire org tree structure",
867 my( $self, $client) = @_;
870 $cache_client = OpenSRF::Utils::Cache->new("global", 0);
872 # see if it's in the cache
873 #warn "Getting ORG Tree\n";
874 my $tree = $cache_client->get_cache('orgtree');
876 #warn "Found orgtree in cache. returning...\n";
880 my $orglist = $apputils->simple_scalar_request(
882 "open-ils.storage.direct.actor.org_unit.retrieve.all.atomic" );
885 #warn "found org list\n";
888 $tree = $self->build_org_tree($orglist);
889 $cache_client->put_cache('orgtree', $tree);
895 # turns an org list into an org tree
898 my( $self, $orglist) = @_;
900 return $orglist unless (
901 ref($orglist) and @$orglist > 1 );
904 $a->ou_type <=> $b->ou_type ||
905 $a->name cmp $b->name } @$orglist;
907 for my $org (@list) {
909 next unless ($org and defined($org->parent_ou));
910 my ($parent) = grep { $_->id == $org->parent_ou } @list;
913 $parent->children([]) unless defined($parent->children);
914 push( @{$parent->children}, $org );
922 __PACKAGE__->register_method(
923 method => "get_org_descendants",
924 api_name => "open-ils.actor.org_tree.descendants.retrieve"
927 # depth is optional. org_unit is the id
928 sub get_org_descendants {
929 my( $self, $client, $org_unit, $depth ) = @_;
930 my $orglist = $apputils->simple_scalar_request(
932 "open-ils.storage.actor.org_unit.descendants.atomic",
934 return $self->build_org_tree($orglist);
938 __PACKAGE__->register_method(
939 method => "get_org_ancestors",
940 api_name => "open-ils.actor.org_tree.ancestors.retrieve"
943 # depth is optional. org_unit is the id
944 sub get_org_ancestors {
945 my( $self, $client, $org_unit, $depth ) = @_;
946 my $orglist = $apputils->simple_scalar_request(
948 "open-ils.storage.actor.org_unit.ancestors.atomic",
950 return $self->build_org_tree($orglist);
954 __PACKAGE__->register_method(
955 method => "get_standings",
956 api_name => "open-ils.actor.standings.retrieve"
961 return $user_standings if $user_standings;
962 return $user_standings =
963 $apputils->simple_scalar_request(
965 "open-ils.storage.direct.config.standing.retrieve.all.atomic" );
970 __PACKAGE__->register_method(
971 method => "get_my_org_path",
972 api_name => "open-ils.actor.org_unit.full_path.retrieve"
975 sub get_my_org_path {
976 my( $self, $client, $user_session, $org_id ) = @_;
977 my $user_obj = $apputils->check_user_session($user_session);
978 if(!defined($org_id)) { $org_id = $user_obj->home_ou; }
980 return $apputils->simple_scalar_request(
982 "open-ils.storage.actor.org_unit.full_path.atomic",
987 __PACKAGE__->register_method(
988 method => "patron_adv_search",
989 api_name => "open-ils.actor.patron.search.advanced" );
991 sub patron_adv_search {
992 my( $self, $client, $staff_login, $search_hash ) = @_;
994 #warn "patron adv with $staff_login and search " .
995 #Dumper($search_hash) . "\n";
997 my $session = OpenSRF::AppSession->create("open-ils.storage");
998 my $req = $session->request(
999 "open-ils.storage.actor.user.crazy_search", $search_hash);
1001 my $ans = $req->gather(1);
1003 my %hash = map { ($_ =>1) } @$ans;
1004 $ans = [ keys %hash ];
1006 #warn "Returning @$ans\n";
1008 $session->disconnect();
1015 sub _verify_password {
1016 my($user_session, $password) = @_;
1017 my $user_obj = $apputils->check_user_session($user_session);
1019 #grab the user with password
1020 $user_obj = $apputils->simple_scalar_request(
1022 "open-ils.storage.direct.actor.user.retrieve",
1025 if($user_obj->passwd eq $password) {
1033 __PACKAGE__->register_method(
1034 method => "update_password",
1035 api_name => "open-ils.actor.user.password.update");
1037 __PACKAGE__->register_method(
1038 method => "update_password",
1039 api_name => "open-ils.actor.user.username.update");
1041 __PACKAGE__->register_method(
1042 method => "update_password",
1043 api_name => "open-ils.actor.user.email.update");
1045 sub update_password {
1046 my( $self, $client, $user_session, $new_value, $current_password ) = @_;
1050 #warn "Updating user with method " .$self->api_name . "\n";
1051 my $user_obj = $apputils->check_user_session($user_session);
1053 if($self->api_name =~ /password/o) {
1055 #make sure they know the current password
1056 if(!_verify_password($user_session, md5_hex($current_password))) {
1057 return OpenILS::EX->new("USER_WRONG_PASSWORD")->ex;
1060 $user_obj->passwd($new_value);
1062 elsif($self->api_name =~ /username/o) {
1063 my $users = search_username(undef, undef, $new_value);
1064 if( $users and $users->[0] ) {
1065 return OpenILS::Event->new('USERNAME_EXISTS');
1067 $user_obj->usrname($new_value);
1070 elsif($self->api_name =~ /email/o) {
1071 #warn "Updating email to $new_value\n";
1072 $user_obj->email($new_value);
1075 my $session = $apputils->start_db_session();
1077 ( $user_obj, $evt ) = _update_patron($session, $user_obj, $user_obj);
1078 return $evt if $evt;
1080 $apputils->commit_db_session($session);
1082 if($user_obj) { return 1; }
1087 __PACKAGE__->register_method(
1088 method => "check_user_perms",
1089 api_name => "open-ils.actor.user.perm.check",
1090 notes => <<" NOTES");
1091 Takes a login session, user id, an org id, and an array of perm type strings. For each
1092 perm type, if the user does *not* have the given permission it is added
1093 to a list which is returned from the method. If all permissions
1094 are allowed, an empty list is returned
1095 if the logged in user does not match 'user_id', then the logged in user must
1096 have VIEW_PERMISSION priveleges.
1099 sub check_user_perms {
1100 my( $self, $client, $login_session, $user_id, $org_id, $perm_types ) = @_;
1102 my( $staff, $evt ) = $apputils->checkses($login_session);
1103 return $evt if $evt;
1105 if($staff->id ne $user_id) {
1106 if( my $evt = $apputils->check_perms(
1107 $staff->id, $org_id, 'VIEW_PERMISSION') ) {
1113 for my $perm (@$perm_types) {
1114 if($apputils->check_perms($user_id, $org_id, $perm)) {
1115 push @not_allowed, $perm;
1119 return \@not_allowed
1122 __PACKAGE__->register_method(
1123 method => "check_user_perms2",
1124 api_name => "open-ils.actor.user.perm.check.multi_org",
1126 Checks the permissions on a list of perms and orgs for a user
1127 @param authtoken The login session key
1128 @param user_id The id of the user to check
1129 @param orgs The array of org ids
1130 @param perms The array of permission names
1131 @return An array of [ orgId, permissionName ] arrays that FAILED the check
1132 if the logged in user does not match 'user_id', then the logged in user must
1133 have VIEW_PERMISSION priveleges.
1136 sub check_user_perms2 {
1137 my( $self, $client, $authtoken, $user_id, $orgs, $perms ) = @_;
1139 my( $staff, $target, $evt ) = $apputils->checkses_requestor(
1140 $authtoken, $user_id, 'VIEW_PERMISSION' );
1141 return $evt if $evt;
1144 for my $org (@$orgs) {
1145 for my $perm (@$perms) {
1146 if($apputils->check_perms($user_id, $org, $perm)) {
1147 push @not_allowed, [ $org, $perm ];
1152 return \@not_allowed
1156 __PACKAGE__->register_method(
1157 method => 'check_user_perms3',
1158 api_name => 'open-ils.actor.user.perm.highest_org',
1160 Returns the highest org unit id at which a user has a given permission
1161 If the requestor does not match the target user, the requestor must have
1162 'VIEW_PERMISSION' rights at the home org unit of the target user
1163 @param authtoken The login session key
1164 @param userid The id of the user in question
1165 @param perm The permission to check
1166 @return The org unit highest in the org tree within which the user has
1167 the requested permission
1170 sub check_user_perms3 {
1171 my( $self, $client, $authtoken, $userid, $perm ) = @_;
1173 my( $staff, $target, $org, $evt );
1175 ( $staff, $target, $evt ) = $apputils->checkses_requestor(
1176 $authtoken, $userid, 'VIEW_PERMISSION' );
1177 return $evt if $evt;
1179 my $tree = $self->get_org_tree();
1180 return _find_highest_perm_org( $perm, $userid, $target->home_ou, $tree );
1184 sub _find_highest_perm_org {
1185 my ( $perm, $userid, $start_org, $org_tree ) = @_;
1186 my $org = $apputils->find_org($org_tree, $start_org );
1190 last if ($apputils->check_perms( $userid, $org->id, $perm )); # perm failed
1192 $org = $apputils->find_org( $org_tree, $org->parent_ou() );
1198 __PACKAGE__->register_method(
1199 method => 'check_user_perms4',
1200 api_name => 'open-ils.actor.user.perm.highest_org.batch',
1202 Returns the highest org unit id at which a user has a given permission
1203 If the requestor does not match the target user, the requestor must have
1204 'VIEW_PERMISSION' rights at the home org unit of the target user
1205 @param authtoken The login session key
1206 @param userid The id of the user in question
1207 @param perms An array of perm names to check
1208 @return An array of orgId's representing the org unit
1209 highest in the org tree within which the user has the requested permission
1210 The arrah of orgId's has matches the order of the perms array
1213 sub check_user_perms4 {
1214 my( $self, $client, $authtoken, $userid, $perms ) = @_;
1216 my( $staff, $target, $org, $evt );
1218 ( $staff, $target, $evt ) = $apputils->checkses_requestor(
1219 $authtoken, $userid, 'VIEW_PERMISSION' );
1220 return $evt if $evt;
1223 return [] unless ref($perms);
1224 my $tree = $self->get_org_tree();
1226 for my $p (@$perms) {
1227 push( @arr, _find_highest_perm_org( $p, $userid, $target->home_ou, $tree ) );
1235 __PACKAGE__->register_method(
1236 method => "user_fines_summary",
1237 api_name => "open-ils.actor.user.fines.summary",
1238 notes => <<" NOTES");
1239 Returns a short summary of the users total open fines, excluding voided fines
1240 Params are login_session, user_id
1241 Returns a 'mous' object.
1244 sub user_fines_summary {
1245 my( $self, $client, $login_session, $user_id ) = @_;
1247 my $user_obj = $apputils->check_user_session($login_session);
1248 if($user_obj->id ne $user_id) {
1249 if($apputils->check_user_perms($user_obj->id, $user_obj->home_ou, "VIEW_USER_FINES_SUMMARY")) {
1250 return OpenILS::Perm->new("VIEW_USER_FINES_SUMMARY");
1254 return $apputils->simple_scalar_request(
1256 "open-ils.storage.direct.money.open_user_summary.search.usr",
1264 __PACKAGE__->register_method(
1265 method => "user_transactions",
1266 api_name => "open-ils.actor.user.transactions",
1267 notes => <<" NOTES");
1268 Returns a list of open user transactions (mbts objects);
1269 Params are login_session, user_id
1270 Optional third parameter is the transactions type. defaults to all
1273 __PACKAGE__->register_method(
1274 method => "user_transactions",
1275 api_name => "open-ils.actor.user.transactions.have_charge",
1276 notes => <<" NOTES");
1277 Returns a list of all open user transactions (mbts objects) that have an initial charge
1278 Params are login_session, user_id
1279 Optional third parameter is the transactions type. defaults to all
1282 __PACKAGE__->register_method(
1283 method => "user_transactions",
1284 api_name => "open-ils.actor.user.transactions.have_balance",
1285 notes => <<" NOTES");
1286 Returns a list of all open user transactions (mbts objects) that have a balance
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.fleshed",
1294 notes => <<" NOTES");
1295 Returns an object/hash of transaction, circ, title where transaction = an open
1296 user transactions (mbts objects), circ is the attached circluation, and title
1297 is the title the circ points to
1298 Params are login_session, user_id
1299 Optional third parameter is the transactions type. defaults to all
1302 __PACKAGE__->register_method(
1303 method => "user_transactions",
1304 api_name => "open-ils.actor.user.transactions.have_charge.fleshed",
1305 notes => <<" NOTES");
1306 Returns an object/hash of transaction, circ, title where transaction = an open
1307 user transactions that has an initial charge (mbts objects), circ is the
1308 attached circluation, and title is the title the circ points to
1309 Params are login_session, user_id
1310 Optional third parameter is the transactions type. defaults to all
1313 __PACKAGE__->register_method(
1314 method => "user_transactions",
1315 api_name => "open-ils.actor.user.transactions.have_balance.fleshed",
1316 notes => <<" NOTES");
1317 Returns an object/hash of transaction, circ, title where transaction = an open
1318 user transaction that has a balance (mbts objects), circ is the attached
1319 circluation, and title is the title the circ points to
1320 Params are login_session, user_id
1321 Optional third parameter is the transaction type. defaults to all
1324 __PACKAGE__->register_method(
1325 method => "user_transactions",
1326 api_name => "open-ils.actor.user.transactions.count",
1327 notes => <<" NOTES");
1328 Returns an object/hash of transaction, circ, title where transaction = an open
1329 user transactions (mbts objects), circ is the attached circluation, and title
1330 is the title the circ points to
1331 Params are login_session, user_id
1332 Optional third parameter is the transactions type. defaults to all
1335 __PACKAGE__->register_method(
1336 method => "user_transactions",
1337 api_name => "open-ils.actor.user.transactions.have_charge.count",
1338 notes => <<" NOTES");
1339 Returns an object/hash of transaction, circ, title where transaction = an open
1340 user transactions that has an initial charge (mbts objects), circ is the
1341 attached circluation, and title is the title the circ points to
1342 Params are login_session, user_id
1343 Optional third parameter is the transactions type. defaults to all
1346 __PACKAGE__->register_method(
1347 method => "user_transactions",
1348 api_name => "open-ils.actor.user.transactions.have_balance.count",
1349 notes => <<" NOTES");
1350 Returns an object/hash of transaction, circ, title where transaction = an open
1351 user transaction that has a balance (mbts objects), circ is the attached
1352 circluation, and title is the title the circ points to
1353 Params are login_session, user_id
1354 Optional third parameter is the transaction type. defaults to all
1357 __PACKAGE__->register_method(
1358 method => "user_transactions",
1359 api_name => "open-ils.actor.user.transactions.have_balance.total",
1360 notes => <<" NOTES");
1361 Returns an object/hash of transaction, circ, title where transaction = an open
1362 user transaction that has a balance (mbts objects), circ is the attached
1363 circluation, and title is the title the circ points to
1364 Params are login_session, user_id
1365 Optional third parameter is the transaction type. defaults to all
1370 sub user_transactions {
1371 my( $self, $client, $login_session, $user_id, $type ) = @_;
1373 my( $user_obj, $target, $evt ) = $apputils->checkses_requestor(
1374 $login_session, $user_id, 'VIEW_USER_TRANSACTIONS' );
1375 return $evt if $evt;
1377 my $api = $self->api_name();
1381 if(defined($type)) { @xact = (xact_type => $type);
1383 } else { @xact = (); }
1385 if($api =~ /have_charge/o) {
1387 $trans = $apputils->simple_scalar_request(
1389 "open-ils.storage.direct.money.open_billable_transaction_summary.search_where.atomic",
1390 { usr => $user_id, total_owed => { ">" => 0 }, @xact });
1392 } elsif($api =~ /have_balance/o) {
1394 $trans = $apputils->simple_scalar_request(
1396 "open-ils.storage.direct.money.open_billable_transaction_summary.search_where.atomic",
1397 { usr => $user_id, balance_owed => { ">" => 0 }, @xact });
1401 $trans = $apputils->simple_scalar_request(
1403 "open-ils.storage.direct.money.open_billable_transaction_summary.search_where.atomic",
1404 { usr => $user_id, @xact });
1407 if($api =~ /total/o) {
1409 for my $t (@$trans) {
1410 $total += $t->balance_owed;
1413 $logger->debug("Total balance owed by user $user_id: $total");
1417 if($api =~ /count/o) { return scalar @$trans; }
1418 if($api !~ /fleshed/o) { return $trans; }
1420 #warn "API: $api\n";
1423 for my $t (@$trans) {
1425 #warn $t->id . "\n";
1428 if( $t->xact_type ne 'circulation' ) {
1429 push @resp, {transaction => $t};
1433 my $circ = $apputils->simple_scalar_request(
1435 "open-ils.storage.direct.action.circulation.retrieve",
1440 my $title = $apputils->simple_scalar_request(
1442 "open-ils.storage.fleshed.biblio.record_entry.retrieve_by_copy",
1443 $circ->target_copy );
1447 my $u = OpenILS::Utils::ModsParser->new();
1448 $u->start_mods_batch($title->marc());
1449 my $mods = $u->finish_mods_batch();
1451 push @resp, {transaction => $t, circ => $circ, record => $mods };
1459 __PACKAGE__->register_method(
1460 method => "user_transaction_retrieve",
1461 api_name => "open-ils.actor.user.transaction.fleshed.retrieve",
1463 notes => <<" NOTES");
1464 Returns a fleshedtransaction record
1466 __PACKAGE__->register_method(
1467 method => "user_transaction_retrieve",
1468 api_name => "open-ils.actor.user.transaction.retrieve",
1470 notes => <<" NOTES");
1471 Returns a transaction record
1473 sub user_transaction_retrieve {
1474 my( $self, $client, $login_session, $bill_id ) = @_;
1476 my $trans = $apputils->simple_scalar_request(
1478 "open-ils.storage.direct.money.billable_transaction_summary.retrieve",
1482 my( $user_obj, $target, $evt ) = $apputils->checkses_requestor(
1483 $login_session, $trans->usr, 'VIEW_USER_TRANSACTIONS' );
1484 return $evt if $evt;
1486 my $api = $self->api_name();
1487 if($api !~ /fleshed/o) { return $trans; }
1489 if( $trans->xact_type ne 'circulation' ) {
1490 $logger->debug("Returning non-circ transaction");
1491 return {transaction => $trans};
1494 my $circ = $apputils->simple_scalar_request(
1496 "open-ils.storage.direct.action.circulation.retrieve",
1499 return {transaction => $trans} unless $circ;
1500 $logger->debug("Found the circ transaction");
1502 my $title = $apputils->simple_scalar_request(
1504 "open-ils.storage.fleshed.biblio.record_entry.retrieve_by_copy",
1505 $circ->target_copy );
1507 return {transaction => $trans, circ => $circ } unless $title;
1508 $logger->debug("Found the circ title");
1512 my $u = OpenILS::Utils::ModsParser->new();
1513 $u->start_mods_batch($title->marc());
1514 $mods = $u->finish_mods_batch();
1516 if ($title->id == -1) {
1517 my $copy = $apputils->simple_scalar_request(
1519 "open-ils.storage.direct.asset.copy.retrieve",
1520 $circ->target_copy );
1522 $mods = new Fieldmapper::metabib::virtual_record;
1524 $mods->title($copy->dummy_title);
1525 $mods->author($copy->dummy_author);
1529 $logger->debug("MODSized the circ title");
1531 return {transaction => $trans, circ => $circ, record => $mods };
1535 __PACKAGE__->register_method(
1536 method => "hold_request_count",
1537 api_name => "open-ils.actor.user.hold_requests.count",
1539 notes => <<" NOTES");
1540 Returns hold ready/total counts
1542 sub hold_request_count {
1543 my( $self, $client, $login_session, $userid ) = @_;
1545 my( $user_obj, $target, $evt ) = $apputils->checkses_requestor(
1546 $login_session, $userid, 'VIEW_HOLD' );
1547 return $evt if $evt;
1550 my $holds = $apputils->simple_scalar_request(
1552 "open-ils.storage.direct.action.hold_request.search_where.atomic",
1554 fulfillment_time => {"=" => undef } }
1558 for my $h (@$holds) {
1559 next unless $h->capture_time;
1561 my $copy = $apputils->simple_scalar_request(
1563 "open-ils.storage.direct.asset.copy.retrieve",
1567 if ($copy->status == 8) {
1572 return { total => scalar(@$holds), ready => scalar(@ready) };
1576 __PACKAGE__->register_method(
1577 method => "checkedout_count",
1578 api_name => "open-ils.actor.user.checked_out.count",
1580 notes => <<" NOTES");
1581 Returns a transaction record
1583 sub checkedout_count {
1584 my( $self, $client, $login_session, $userid ) = @_;
1586 my( $user_obj, $target, $evt ) = $apputils->checkses_requestor(
1587 $login_session, $userid, 'VIEW_CIRCULATIONS' );
1588 return $evt if $evt;
1591 my $circs = $apputils->simple_scalar_request(
1593 "open-ils.storage.direct.action.circulation.search_where.atomic",
1595 checkin_time => {"=" => undef } }
1598 my $parser = DateTime::Format::ISO8601->new;
1601 for my $c (@$circs) {
1602 my $due_dt = $parser->parse_datetime( clense_ISO8601( $c->due_date ) );
1603 my $due = $due_dt->epoch;
1605 if ($due < DateTime->today->epoch) {
1610 return { total => scalar(@$circs), overdue => scalar(@overdue) };
1613 __PACKAGE__->register_method(
1614 method => "user_transaction_history",
1615 api_name => "open-ils.actor.user.transactions.history",
1617 notes => <<" NOTES");
1618 Returns a list of billable transaction ids for a user, optionally by type
1620 sub user_transaction_history {
1621 my( $self, $client, $login_session, $user_id, $type ) = @_;
1623 my( $user_obj, $target, $evt ) = $apputils->checkses_requestor(
1624 $login_session, $user_id, 'VIEW_USER_TRANSACTIONS' );
1625 return $evt if $evt;
1627 my $api = $self->api_name();
1630 @xact = (xact_type => $type) if(defined($type));
1632 my $trans = $apputils->simple_scalar_request(
1634 "open-ils.storage.direct.money.billable_transaction_summary.search_where.atomic",
1635 { usr => $user_id, @xact }, { order_by => 'xact_start DESC' });
1637 return [ map { $_->id } @$trans ];
1641 __PACKAGE__->register_method(
1642 method => "user_perms",
1643 api_name => "open-ils.actor.permissions.user_perms.retrieve",
1645 notes => <<" NOTES");
1646 Returns a list of permissions
1649 my( $self, $client, $authtoken, $user ) = @_;
1651 my( $staff, $evt ) = $apputils->checkses($authtoken);
1652 return $evt if $evt;
1654 $user ||= $staff->id;
1656 if( $user != $staff->id and $evt = $apputils->check_perms( $staff->id, $staff->home_ou, 'VIEW_PERMISSION') ) {
1660 return $apputils->simple_scalar_request(
1662 "open-ils.storage.permission.user_perms.atomic",
1666 __PACKAGE__->register_method(
1667 method => "retrieve_perms",
1668 api_name => "open-ils.actor.permissions.retrieve",
1669 notes => <<" NOTES");
1670 Returns a list of permissions
1672 sub retrieve_perms {
1673 my( $self, $client ) = @_;
1674 return $apputils->simple_scalar_request(
1676 "open-ils.storage.direct.permission.perm_list.retrieve.all.atomic");
1679 __PACKAGE__->register_method(
1680 method => "retrieve_groups",
1681 api_name => "open-ils.actor.groups.retrieve",
1682 notes => <<" NOTES");
1683 Returns a list of user groupss
1685 sub retrieve_groups {
1686 my( $self, $client ) = @_;
1687 return $apputils->simple_scalar_request(
1689 "open-ils.storage.direct.permission.grp_tree.retrieve.all.atomic");
1692 __PACKAGE__->register_method(
1693 method => "retrieve_groups_tree",
1694 api_name => "open-ils.actor.groups.tree.retrieve",
1695 notes => <<" NOTES");
1696 Returns a list of user groups
1698 sub retrieve_groups_tree {
1699 my( $self, $client ) = @_;
1700 my $groups = $apputils->simple_scalar_request(
1702 "open-ils.storage.direct.permission.grp_tree.retrieve.all.atomic");
1703 return $self->build_group_tree($groups);
1707 # turns an org list into an org tree
1708 sub build_group_tree {
1710 my( $self, $grplist) = @_;
1712 return $grplist unless (
1713 ref($grplist) and @$grplist > 1 );
1715 my @list = sort { $a->name cmp $b->name } @$grplist;
1718 for my $grp (@list) {
1720 if ($grp and !defined($grp->parent)) {
1724 my ($parent) = grep { $_->id == $grp->parent} @list;
1726 $parent->children([]) unless defined($parent->children);
1727 push( @{$parent->children}, $grp );
1735 __PACKAGE__->register_method(
1736 method => "add_user_to_groups",
1737 api_name => "open-ils.actor.user.set_groups",
1738 notes => <<" NOTES");
1739 Adds a user to one or more permission groups
1742 sub add_user_to_groups {
1743 my( $self, $client, $authtoken, $userid, $groups ) = @_;
1745 my( $requestor, $target, $evt ) = $apputils->checkses_requestor(
1746 $authtoken, $userid, 'CREATE_USER_GROUP_LINK' );
1747 return $evt if $evt;
1749 ( $requestor, $target, $evt ) = $apputils->checkses_requestor(
1750 $authtoken, $userid, 'REMOVE_USER_GROUP_LINK' );
1751 return $evt if $evt;
1753 $apputils->simplereq(
1755 'open-ils.storage.direct.permission.usr_grp_map.mass_delete', { usr => $userid } );
1757 for my $group (@$groups) {
1758 my $link = Fieldmapper::permission::usr_grp_map->new;
1760 $link->usr($userid);
1762 my $id = $apputils->simplereq(
1764 'open-ils.storage.direct.permission.usr_grp_map.create', $link );
1770 __PACKAGE__->register_method(
1771 method => "get_user_perm_groups",
1772 api_name => "open-ils.actor.user.get_groups",
1773 notes => <<" NOTES");
1774 Retrieve a user's permission groups.
1778 sub get_user_perm_groups {
1779 my( $self, $client, $authtoken, $userid ) = @_;
1781 my( $requestor, $target, $evt ) = $apputils->checkses_requestor(
1782 $authtoken, $userid, 'VIEW_PERM_GROUPS' );
1783 return $evt if $evt;
1785 return $apputils->simplereq(
1787 'open-ils.storage.direct.permission.usr_grp_map.search.usr.atomic', $userid );
1792 __PACKAGE__->register_method (
1793 method => 'register_workstation',
1794 api_name => 'open-ils.actor.workstation.register',
1796 Registers a new workstion in the system
1797 @param authtoken The login session key
1798 @param name The name of the workstation id
1799 @param owner The org unit that owns this workstation
1800 @return The workstation id on success, WORKSTATION_NAME_EXISTS
1801 if the name is already in use.
1804 sub register_workstation {
1805 my( $self, $connection, $authtoken, $name, $owner ) = @_;
1806 my( $requestor, $evt ) = $U->checkses($authtoken);
1807 return $evt if $evt;
1808 $evt = $U->check_perms($requestor->id, $owner, 'REGISTER_WORKSTATION');
1809 return $evt if $evt;
1811 my $ws = $U->storagereq(
1812 'open-ils.storage.direct.actor.workstation.search.name', $name );
1813 return OpenILS::Event->new('WORKSTATION_NAME_EXISTS') if $ws;
1815 $ws = Fieldmapper::actor::workstation->new;
1816 $ws->owning_lib($owner);
1819 my $id = $U->storagereq(
1820 'open-ils.storage.direct.actor.workstation.create', $ws );
1821 return $U->DB_UPDATE_FAILED($ws) unless $id;
1828 __PACKAGE__->register_method (
1829 method => 'fetch_patron_note',
1830 api_name => 'open-ils.actor.note.retrieve.all',
1832 Returns a list of notes for a given user
1833 Requestor must have VIEW_USER permission if pub==false and
1834 @param authtoken The login session key
1835 @param args Hash of params including
1836 patronid : the patron's id
1837 pub : true if retrieving only public notes
1841 sub fetch_patron_note {
1842 my( $self, $conn, $authtoken, $args ) = @_;
1843 my $patronid = $$args{patronid};
1845 my($reqr, $evt) = $U->checkses($authtoken);
1848 ($patron, $evt) = $U->fetch_user($patronid);
1849 return $evt if $evt;
1852 if( $patronid ne $reqr->id ) {
1853 $evt = $U->check_perms($reqr->id, $patron->home_ou, 'VIEW_USER');
1854 return $evt if $evt;
1856 return $U->storagereq(
1857 'open-ils.storage.direct.actor.usr_note.search_where.atomic',
1858 { usr => $patronid, pub => 't' } );
1861 $evt = $U->check_perms($reqr->id, $patron->home_ou, 'VIEW_USER');
1862 return $evt if $evt;
1864 return $U->storagereq(
1865 'open-ils.storage.direct.actor.usr_note.search.usr.atomic', $patronid );
1868 __PACKAGE__->register_method (
1869 method => 'create_user_note',
1870 api_name => 'open-ils.actor.note.create',
1872 Creates a new note for the given user
1873 @param authtoken The login session key
1874 @param note The note object
1877 sub create_user_note {
1878 my( $self, $conn, $authtoken, $note ) = @_;
1879 my( $reqr, $patron, $evt ) =
1880 $U->checkses_requestor($authtoken, $note->usr, 'UPDATE_USER');
1881 return $evt if $evt;
1882 $logger->activity("user ".$reqr->id." creating note for user ".$note->usr);
1884 $note->creator($reqr->id);
1885 my $id = $U->storagereq(
1886 'open-ils.storage.direct.actor.usr_note.create', $note );
1887 return $U->DB_UPDATE_FAILED($note) unless $id;
1892 __PACKAGE__->register_method (
1893 method => 'delete_user_note',
1894 api_name => 'open-ils.actor.note.delete',
1896 Deletes a note for the given user
1897 @param authtoken The login session key
1898 @param noteid The note id
1901 sub delete_user_note {
1902 my( $self, $conn, $authtoken, $noteid ) = @_;
1904 my $note = $U->storagereq(
1905 'open-ils.storage.direct.actor.usr_note.retrieve', $noteid);
1906 return OpenILS::Event->new('USER_NOTE_NOT_FOUND') unless $note;
1908 my( $reqr, $patron, $evt ) =
1909 $U->checkses_requestor($authtoken, $note->usr, 'UPDATE_USER');
1910 return $evt if $evt;
1911 $logger->activity("user ".$reqr->id." deleting note [$noteid] for user ".$note->usr);
1913 my $stat = $U->storagereq(
1914 'open-ils.storage.direct.actor.usr_note.delete', $noteid );
1915 return $U->DB_UPDATE_FAILED($note) unless defined $stat;