]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/perlmods/OpenILS/Application/Actor.pm
added some transactions and fines summary methods
[Evergreen.git] / Open-ILS / src / perlmods / OpenILS / Application / Actor.pm
1 package OpenILS::Application::Actor;
2 use base qw/OpenSRF::Application/;
3 use strict; use warnings;
4 use Data::Dumper;
5
6 use Digest::MD5 qw(md5_hex);
7
8 use OpenSRF::EX qw(:try);
9 use OpenILS::EX;
10
11 use OpenILS::Application::AppUtils;
12 use OpenILS::Utils::Fieldmapper;
13 use OpenILS::Application::Search::Actor;
14 use OpenILS::Utils::ModsParser;
15
16 my $apputils = "OpenILS::Application::AppUtils";
17 sub _d { warn "Patron:\n" . Dumper(shift()); }
18 my $cache_client = OpenSRF::Utils::Cache->new("global", 0);
19
20
21 __PACKAGE__->register_method(
22         method  => "update_patron",
23         api_name        => "open-ils.actor.patron.update",);
24
25 sub update_patron {
26         my( $self, $client, $user_session, $patron ) = @_;
27
28         my $session = $apputils->start_db_session();
29         my $err = undef;
30
31         warn $user_session . " " . $patron . "\n";
32         _d($patron);
33
34         my $user_obj = 
35                 OpenILS::Application::AppUtils->check_user_session( 
36                                 $user_session ); #throws EX on error
37
38         # XXX does this user have permission to add/create users.  Granularity?
39
40         # $new_patron is the patron in progress.  $patron is the original patron
41         # passed in with the method.  new_patron will change as the components
42         # of patron are added/updated.
43
44         my $new_patron;
45
46         #try {
47                 # create/update the patron first so we can use his id
48                 if($patron->isnew()) {
49                         $new_patron = _add_patron(
50                                         $session, _clone_patron($patron));
51                         if(UNIVERSAL::isa($new_patron, "OpenILS::EX")) {
52                                 $client->respond_complete($new_patron->ex);
53                                 return undef;
54                         }
55
56                 } else { 
57                         $new_patron = $patron; 
58                 }
59
60                 $new_patron = _add_update_addresses($session, $patron, $new_patron);
61                 $new_patron = _add_update_cards($session, $patron, $new_patron);
62
63                 if(UNIVERSAL::isa($new_patron,"OpenILS::EX")) {
64                         $client->respond_complete($new_patron->ex);
65                         return undef;
66                 }
67
68                 $new_patron = _add_survey_responses($session, $patron, $new_patron);
69                 $new_patron     = _create_stat_maps($session, $user_session, $patron, $new_patron);
70
71                 # re-update the patron if anything has happened to him during this process
72                 if($new_patron->ischanged()) {
73                         $new_patron = _update_patron($session, $new_patron);
74                 }
75                 $apputils->commit_db_session($session);
76
77 =head
78         } catch Error with { 
79                 my $e = shift;
80                 $err =  "-*- Failure adding user: $e";
81                 $apputils->rollback_db_session($session);
82                 warn $err;
83         };
84
85         if($err) { throw OpenSRF::EX::ERROR ($err); }
86 =cut
87
88         warn "Patron Update/Create complete\n";
89         return flesh_user($new_patron->id());
90 }
91
92
93
94
95 __PACKAGE__->register_method(
96         method  => "user_retrieve_fleshed_by_id",
97         api_name        => "open-ils.actor.user.fleshed.retrieve",);
98
99 sub user_retrieve_fleshed_by_id {
100         my( $self, $client, $user_session, $user_id ) = @_;
101         my $user_obj = $apputils->check_user_session( $user_session ); 
102         return flesh_user($user_id);
103 }
104
105
106 sub flesh_user {
107         my $id = shift;
108         my $session = shift;
109
110         my $kill = 0;
111
112         if(!$session) {
113                 $session = OpenSRF::AppSession->create("open-ils.storage");
114                 $kill = 1;
115         }
116
117         # grab the user with the given id 
118         my $ureq = $session->request(
119                         "open-ils.storage.direct.actor.user.retrieve", $id);
120         my $user = $ureq->gather(1);
121
122         if(!$user) { return undef; }
123
124         # grab the cards
125         my $cards_req = $session->request(
126                         "open-ils.storage.direct.actor.card.search.usr.atomic",
127                         $user->id() );
128         $user->cards( $cards_req->gather(1) );
129
130         for my $c(@{$user->cards}) {
131                 if($c->id == $user->card || $c->id eq $user->card ) {
132                         warn "Setting my card to " . $c->id . "\n";
133                         $user->card($c);
134                 }
135         }
136
137         my $add_req = $session->request(
138                         "open-ils.storage.direct.actor.user_address.search.usr.atomic",
139                         $user->id() );
140         $user->addresses( $add_req->gather(1) );
141
142         for my $c(@{$user->addresses}) {
143                 if($c->id == $user->billing_address || $c->id eq $user->billing_address ) {
144                         warn "Setting my address to " . $c->id . "\n";
145                         $user->billing_address($c);
146                 }
147         }
148
149         for my $c(@{$user->addresses}) {
150                 if($c->id == $user->mailing_address || $c->id eq $user->mailing_address ) {
151                         warn "Setting my address to " . $c->id . "\n";
152                         $user->mailing_address($c);
153                 }
154         }
155
156         my $stat_req = $session->request(
157                 "open-ils.storage.direct.actor.stat_cat_entry_user_map.search.target_usr.atomic",
158                 $user->id() );
159         $user->stat_cat_entries($stat_req->gather(1));
160
161         if($kill) { $session->disconnect(); }
162         $user->clear_passwd();
163         warn Dumper $user;
164
165         return $user;
166
167 }
168
169
170 # clone and clear stuff that would break the database
171 sub _clone_patron {
172         my $patron = shift;
173
174         my $new_patron = Fieldmapper::actor::user->new();
175
176         my $fmap = $Fieldmapper::fieldmap;
177         no strict; # shallow clone, may be useful in the fieldmapper
178         for my $field 
179                 (keys %{$fmap->{"Fieldmapper::actor::user"}->{'fields'}}) {
180                         $new_patron->$field( $patron->$field() );
181         }
182         use strict;
183
184         # clear these
185         $new_patron->clear_billing_address();
186         $new_patron->clear_mailing_address();
187         $new_patron->clear_addresses();
188         $new_patron->clear_card();
189         $new_patron->clear_cards();
190         $new_patron->clear_id();
191         $new_patron->clear_isnew();
192         $new_patron->clear_changed();
193         $new_patron->clear_deleted();
194         $new_patron->clear_stat_cat_entries();
195
196         return $new_patron;
197 }
198
199
200 sub _add_patron {
201         my $session             = shift;
202         my $patron              = shift;
203
204         warn "Creating new patron\n";
205         _d($patron);
206
207         my $req = $session->request(
208                 "open-ils.storage.direct.actor.user.create",$patron);
209         my $id = $req->gather(1);
210         if(!$id) { 
211                 return OpenILS::EX->new("DUPLICATE_USER_USERNAME");
212         }
213
214         # retrieve the patron from the db to collect defaults
215         my $ureq = $session->request(
216                         "open-ils.storage.direct.actor.user.retrieve",
217                         $id);
218
219         warn "Created new patron with id $id\n";
220
221         return $ureq->gather(1);
222 }
223
224
225 sub _update_patron {
226         my( $session, $patron) = @_;
227
228         warn "updating patron " . Dumper($patron) . "\n";
229
230         my $req = $session->request(
231                 "open-ils.storage.direct.actor.user.update",$patron );
232         my $status = $req->gather(1);
233         if(!defined($status)) { 
234                 throw OpenSRF::EX::ERROR 
235                         ("Unknown error updating patron"); 
236         }
237         return $patron;
238 }
239
240
241 sub _add_update_addresses {
242         my $session = shift;
243         my $patron = shift;
244         my $new_patron = shift;
245
246         my $current_id; # id of the address before creation
247
248         for my $address (@{$patron->addresses()}) {
249
250                 $address->usr($new_patron->id());
251
252                 if(ref($address) and $address->isnew()) {
253                         warn "Adding new address at street " . $address->street1() . "\n";
254
255                         $current_id = $address->id();
256                         $address = _add_address($session,$address);
257
258                         if( $patron->billing_address() and 
259                                         $patron->billing_address() == $current_id ) {
260                                 $new_patron->billing_address($address->id());
261                                 $new_patron->ischanged(1);
262                         }
263
264                         if( $patron->mailing_address() and
265                                         $patron->mailing_address() == $current_id ) {
266                                 $new_patron->mailing_address($address->id());
267                                 $new_patron->ischanged(1);
268                         }
269
270                 } elsif( ref($address) and $address->ischanged() ) {
271                         warn "Updating address at street " . $address->street1();
272                         $address->usr($new_patron->id());
273                         _update_address($session,$address);
274
275                 } elsif( ref($address) and $address->isdeleted() ) {
276                         warn "Deleting address at street " . $address->street1();
277
278                         if( $address->id() == $new_patron->mailing_address() ) {
279                                 $new_patron->clear_mailing_address();
280                                 _update_patron($session, $new_patron);
281                         }
282
283                         if( $address->id() == $new_patron->billing_address() ) {
284                                 $new_patron->clear_billing_address();
285                                 _update_patron($session, $new_patron);
286                         }
287
288                         _delete_address($session,$address);
289                 }
290         }
291
292         return $new_patron;
293 }
294
295
296 # adds an address to the db and returns the address with new id
297 sub _add_address {
298         my($session, $address) = @_;
299         $address->clear_id();
300
301         # put the address into the database
302         my $req = $session->request(
303                 "open-ils.storage.direct.actor.user_address.create",
304                 $address );
305
306         #update the id
307         my $id = $req->gather(1);
308         if(!$id) { 
309                 throw OpenSRF::EX::ERROR 
310                         ("Unable to create new user address"); 
311         }
312
313         warn "Created address with id $id\n";
314
315         # update all the necessary id's
316         $address->id( $id );
317         return $address;
318 }
319
320
321 sub _update_address {
322         my( $session, $address ) = @_;
323         my $req = $session->request(
324                 "open-ils.storage.direct.actor.user_address.update",
325                 $address );
326         my $status = $req->gather(1);
327         if(!defined($status)) { 
328                 throw OpenSRF::EX::ERROR 
329                         ("Unknown error updating address"); 
330         }
331         return $address;
332 }
333
334
335
336 sub _add_update_cards {
337
338         my $session = shift;
339         my $patron = shift;
340         my $new_patron = shift;
341
342         my $virtual_id; #id of the card before creation
343         for my $card (@{$patron->cards()}) {
344
345                 $card->usr($new_patron->id());
346
347                 if(ref($card) and $card->isnew()) {
348
349                         $virtual_id = $card->id();
350                         $card = _add_card($session,$card);
351                         if(UNIVERSAL::isa($card,"OpenILS::EX")) {
352                                 return $card;
353                         }
354
355                         if($patron->card() == $virtual_id) {
356                                 $new_patron->card($card->id());
357                                 $new_patron->ischanged(1);
358                         }
359
360                 } elsif( ref($card) and $card->ischanged() ) {
361                         $card->usr($new_patron->id());
362                         _update_card($session, $card);
363                 }
364         }
365         return $new_patron;
366 }
367
368
369 # adds an card to the db and returns the card with new id
370 sub _add_card {
371         my( $session, $card ) = @_;
372         $card->clear_id();
373
374         warn "Adding card with barcode " . $card->barcode() . "\n";
375         my $req = $session->request(
376                 "open-ils.storage.direct.actor.card.create",
377                 $card );
378
379         my $id = $req->gather(1);
380         if(!$id) { 
381                 return OpenILS::EX->new("DUPLICATE_INVALID_USER_BARCODE");
382         }
383
384         $card->id($id);
385         warn "Created patron card with id $id\n";
386         return $card;
387 }
388
389
390 sub _update_card {
391         my( $session, $card ) = @_;
392         warn Dumper $card;
393
394         my $req = $session->request(
395                 "open-ils.storage.direct.actor.card.update",
396                 $card );
397         my $status = $req->gather(1);
398         if(!defined($status)) { 
399                 throw OpenSRF::EX::ERROR 
400                         ("Unknown error updating card"); 
401         }
402         return $card;
403 }
404
405
406
407
408 sub _delete_address {
409         my( $session, $address ) = @_;
410
411         warn "Deleting address " . $address->street1() . "\n";
412
413         my $req = $session->request(
414                 "open-ils.storage.direct.actor.user_address.delete",
415                 $address );
416         my $status = $req->gather(1);
417         if(!defined($status)) { 
418                 throw OpenSRF::EX::ERROR 
419                         ("Unknown error updating address"); 
420         }
421         warn "Delete address status is $status\n";
422 }
423
424
425
426 sub _add_survey_responses {
427         my ($session, $patron, $new_patron) = @_;
428
429         warn "updating responses for user " . $new_patron->id . "\n";
430
431         my $responses = $patron->survey_responses;
432         for my $resp( @$responses ) {
433                 $resp->usr($new_patron->id);
434         }
435
436         my $status = $apputils->simple_scalar_request(
437                 "open-ils.circ", 
438                 "open-ils.circ.survey.submit.user_id",
439                 $responses );
440
441         return $new_patron;
442 }
443
444
445 sub _create_stat_maps {
446
447         my($session, $user_session, $patron, $new_patron) = @_;
448
449         my $maps = $patron->stat_cat_entries();
450
451         for my $map (@$maps) {
452
453                 next unless($map->isnew() || $map->ischanged());
454
455                 my $method = "open-ils.storage.direct.actor.stat_cat_entry_user_map.update";
456                 if($map->isnew()) {
457                         $method = "open-ils.storage.direct.actor.stat_cat_entry_user_map.create";
458                 }
459
460                 $map->target_usr($new_patron->id);
461
462                 warn "Updating stat entry with method $method and session $user_session and map $map\n";
463
464                 my $req = $session->request($method, $map);
465                 my $status = $req->gather(1);
466
467                 warn "Updated\n";
468
469                 if(!$status) {
470                         throw OpenSRF::EX::ERROR 
471                                 ("Error updating stat map with method $method");        
472                 }
473         }
474
475         return $new_patron;
476 }
477
478
479
480 __PACKAGE__->register_method(
481         method  => "search_username",
482         api_name        => "open-ils.actor.user.search.username",
483 );
484
485 sub search_username {
486         my($self, $client, $username) = @_;
487         my $users = OpenILS::Application::AppUtils->simple_scalar_request(
488                         "open-ils.storage", 
489                         "open-ils.storage.direct.actor.user.search.usrname.atomic",
490                         $username );
491         return $users;
492 }
493
494
495
496
497 __PACKAGE__->register_method(
498         method  => "user_retrieve_by_barcode",
499         api_name        => "open-ils.actor.user.fleshed.retrieve_by_barcode",);
500
501 sub user_retrieve_by_barcode {
502         my($self, $client, $user_session, $barcode) = @_;
503         warn "Searching for user with barcode $barcode\n";
504         my $user_obj = $apputils->check_user_session( $user_session ); 
505
506         my $session = OpenSRF::AppSession->create("open-ils.storage");
507
508         # find the card with the given barcode
509         my $creq        = $session->request(
510                         "open-ils.storage.direct.actor.card.search.barcode.atomic",
511                         $barcode );
512         my $card = $creq->gather(1);
513
514         if(!$card || !$card->[0]) {
515                 $session->disconnect();
516                 return undef;
517         }
518
519         $card = $card->[0];
520         my $user = flesh_user($card->usr(), $session);
521         $session->disconnect();
522         return $user;
523
524 }
525
526
527
528 __PACKAGE__->register_method(
529         method  => "get_user_by_id",
530         api_name        => "open-ils.actor.user.retrieve",);
531
532 sub get_user_by_id {
533         my ($self, $client, $user_session, $id) = @_;
534
535         my $user_obj = $apputils->check_user_session( $user_session ); 
536
537         return $apputils->simple_scalar_request(
538                 "open-ils.storage",
539                 "open-ils.storage.direct.actor.user.retrieve",
540                 $id );
541 }
542
543
544
545 __PACKAGE__->register_method(
546         method  => "get_org_types",
547         api_name        => "open-ils.actor.org_types.retrieve",);
548
549 my $org_types;
550 sub get_org_types {
551         my($self, $client) = @_;
552
553         return $org_types if $org_types;
554          return $org_types = 
555                  $apputils->simple_scalar_request(
556                         "open-ils.storage",
557                         "open-ils.storage.direct.actor.org_unit_type.retrieve.all.atomic" );
558 }
559
560
561
562 __PACKAGE__->register_method(
563         method  => "get_user_profiles",
564         api_name        => "open-ils.actor.user.profiles.retrieve",
565 );
566
567 my $user_profiles;
568 sub get_user_profiles {
569         return $user_profiles if $user_profiles;
570
571         return $user_profiles = 
572                 $apputils->simple_scalar_request(
573                         "open-ils.storage",
574                         "open-ils.storage.direct.actor.profile.retrieve.all.atomic");
575 }
576
577
578
579 __PACKAGE__->register_method(
580         method  => "get_user_ident_types",
581         api_name        => "open-ils.actor.user.ident_types.retrieve",
582 );
583 my $ident_types;
584 sub get_user_ident_types {
585         return $ident_types if $ident_types;
586         return $ident_types = 
587                 $apputils->simple_scalar_request(
588                 "open-ils.storage",
589                 "open-ils.storage.direct.config.identification_type.retrieve.all.atomic" );
590 }
591
592
593
594
595 __PACKAGE__->register_method(
596         method  => "get_org_unit",
597         api_name        => "open-ils.actor.org_unit.retrieve",
598 );
599
600 sub get_org_unit {
601
602         my( $self, $client, $user_session, $org_id ) = @_;
603
604         if(defined($user_session) && !defined($org_id)) {
605                 my $user_obj = 
606                         OpenILS::Application::AppUtils->check_user_session( $user_session ); #throws EX on error
607                 if(!defined($org_id)) {
608                         $org_id = $user_obj->home_ou;
609                 }
610         }
611
612
613         my $home_ou = OpenILS::Application::AppUtils->simple_scalar_request(
614                 "open-ils.storage",
615                 "open-ils.storage.direct.actor.org_unit.retrieve", 
616                 $org_id );
617
618         return $home_ou;
619 }
620
621
622 # build the org tree
623
624 __PACKAGE__->register_method(
625         method  => "get_org_tree",
626         api_name        => "open-ils.actor.org_tree.retrieve",
627         argc            => 1, 
628         note            => "Returns the entire org tree structure",
629 );
630
631 sub get_org_tree {
632         my( $self, $client) = @_;
633
634         # see if it's in the cache
635         warn "Getting ORG Tree\n";
636         my $tree = $cache_client->get_cache('orgtree');
637         if($tree) { 
638                 warn "Found orgtree in cache. returning...\n";
639                 return $tree; 
640         }
641
642         my $orglist = $apputils->simple_scalar_request( 
643                 "open-ils.storage", 
644                 "open-ils.storage.direct.actor.org_unit.retrieve.all.atomic" );
645
646         if($orglist) {
647                 warn "found org list\n";
648         }
649
650         $tree = $self->build_org_tree($orglist);
651         $cache_client->put_cache('orgtree', $tree);
652
653         return $tree;
654
655 }
656
657 # turns an org list into an org tree
658 sub build_org_tree {
659
660         my( $self, $orglist) = @_;
661
662         return $orglist unless ( 
663                         ref($orglist) and @$orglist > 1 );
664
665         my @list = sort { 
666                 $a->ou_type <=> $b->ou_type ||
667                 $a->name cmp $b->name } @$orglist;
668
669         for my $org (@list) {
670
671                 next unless ($org and defined($org->parent_ou));
672                 my ($parent) = grep { $_->id == $org->parent_ou } @list;
673                 next unless $parent;
674
675                 $parent->children([]) unless defined($parent->children); 
676                 push( @{$parent->children}, $org );
677         }
678
679         return $list[0];
680
681 }
682
683
684 __PACKAGE__->register_method(
685         method  => "get_org_descendants",
686         api_name        => "open-ils.actor.org_tree.descendants.retrieve"
687 );
688
689 # depth is optional.  org_unit is the id
690 sub get_org_descendants {
691         my( $self, $client, $org_unit, $depth ) = @_;
692         my $orglist = $apputils->simple_scalar_request(
693                         "open-ils.storage", 
694                         "open-ils.storage.actor.org_unit.descendants.atomic",
695                         $org_unit, $depth );
696         return $self->build_org_tree($orglist);
697 }
698
699
700 __PACKAGE__->register_method(
701         method  => "get_org_ancestors",
702         api_name        => "open-ils.actor.org_tree.ancestors.retrieve"
703 );
704
705 # depth is optional.  org_unit is the id
706 sub get_org_ancestors {
707         my( $self, $client, $org_unit, $depth ) = @_;
708         my $orglist = $apputils->simple_scalar_request(
709                         "open-ils.storage", 
710                         "open-ils.storage.actor.org_unit.ancestors.atomic",
711                         $org_unit, $depth );
712         return $self->build_org_tree($orglist);
713 }
714
715
716 __PACKAGE__->register_method(
717         method  => "get_standings",
718         api_name        => "open-ils.actor.standings.retrieve"
719 );
720
721 my $user_standings;
722 sub get_standings {
723         return $user_standings if $user_standings;
724         return $user_standings = 
725                 $apputils->simple_scalar_request(
726                         "open-ils.storage",
727                         "open-ils.storage.direct.config.standing.retrieve.all.atomic" );
728 }
729
730
731
732 __PACKAGE__->register_method(
733         method  => "get_my_org_path",
734         api_name        => "open-ils.actor.org_unit.full_path.retrieve"
735 );
736
737 sub get_my_org_path {
738         my( $self, $client, $user_session, $org_id ) = @_;
739         my $user_obj = $apputils->check_user_session($user_session); 
740         if(!defined($org_id)) { $org_id = $user_obj->home_ou; }
741
742         return $apputils->simple_scalar_request(
743                 "open-ils.storage",
744                 "open-ils.storage.actor.org_unit.full_path.atomic",
745                 $org_id );
746 }
747
748
749 __PACKAGE__->register_method(
750         method  => "patron_adv_search",
751         api_name        => "open-ils.actor.patron.search.advanced" );
752
753 sub patron_adv_search {
754         my( $self, $client, $staff_login, $search_hash ) = @_;
755
756         use Data::Dumper;
757         warn "patron adv with $staff_login and search " . 
758                 Dumper($search_hash) . "\n";
759
760         my $session = OpenSRF::AppSession->create("open-ils.storage");
761         my $req = $session->request(
762                 "open-ils.storage.actor.user.crazy_search", $search_hash);
763
764         my $ans = $req->gather(1);
765
766         my %hash = map { ($_ =>1) } @$ans;
767         $ans = [ keys %hash ];
768
769         warn "Returning @$ans\n";
770
771         $session->disconnect();
772         return $ans;
773
774 }
775
776
777
778 sub _verify_password {
779         my($user_session, $password) = @_;
780         my $user_obj = $apputils->check_user_session($user_session); 
781
782         #grab the user with password
783         $user_obj = $apputils->simple_scalar_request(
784                 "open-ils.storage", 
785                 "open-ils.storage.direct.actor.user.retrieve",
786                 $user_obj->id );
787
788         if($user_obj->passwd eq $password) {
789                 return 1;
790         }
791
792         return 0;
793 }
794
795
796 __PACKAGE__->register_method(
797         method  => "update_password",
798         api_name        => "open-ils.actor.user.password.update");
799
800 __PACKAGE__->register_method(
801         method  => "update_password",
802         api_name        => "open-ils.actor.user.username.update");
803
804 __PACKAGE__->register_method(
805         method  => "update_password",
806         api_name        => "open-ils.actor.user.email.update");
807
808 sub update_password {
809         my( $self, $client, $user_session, $new_value, $current_password ) = @_;
810
811         warn "Updating user with method " .$self->api_name . "\n";
812         my $user_obj = $apputils->check_user_session($user_session); 
813
814         if($self->api_name =~ /password/) {
815
816                 #make sure they know the current password
817                 if(!_verify_password($user_session, md5_hex($current_password))) {
818                         return OpenILS::EX->new("USER_WRONG_PASSWORD")->ex;
819                 }
820
821                 $user_obj->passwd($new_value);
822         } 
823         elsif($self->api_name =~ /username/) {
824                 $user_obj->usrname($new_value);
825         }
826
827         elsif($self->api_name =~ /email/) {
828                 warn "Updating email to $new_value\n";
829                 $user_obj->email($new_value);
830         }
831
832         my $session = $apputils->start_db_session();
833         $user_obj = _update_patron($session, $user_obj);
834         $apputils->commit_db_session($session);
835
836         if($user_obj) { return 1; }
837         return undef;
838 }
839
840
841 # returns undef on success, the first perm_type that failed
842 # on permission error
843
844 __PACKAGE__->register_method(
845         method  => "check_user_perms",
846         api_name        => "open-ils.actor.user.perm.check",
847         notes           => <<"  NOTES"
848         Takes a user id, an org id, and an array of perm type strings.  For each
849         perm type, if the user does *not* have the given permission it is added
850         to a list which is returned from the method.  If all permissions
851         are allowed, an empty list is returned
852         NOTES
853         );
854
855 sub check_user_perms {
856         my( $self, $client, $user_id, $org_id, $perm_types ) = @_;
857
858         my @not_allowed;
859         for my $perm (@$perm_types) {
860                 if($apputils->check_user_perms($user_id, $org_id, $perm)) {
861                         push @not_allowed, $perm;
862                 }
863         }
864
865         return \@not_allowed
866 }
867
868
869
870 __PACKAGE__->register_method(
871         method  => "user_fines_summary",
872         api_name        => "open-ils.actor.user.fines.summary",
873         notes           => <<"  NOTES"
874         Returns a short summary of the users total open fines, excluding voided fines
875         Params are login_session, user_id
876         Returns a 'mus' object.
877         NOTES
878         );
879
880 sub user_fines_summary {
881         my( $self, $client, $login_session, $user_id ) = @_;
882
883         my $user_obj = $apputils->check_user_session($login_session); 
884         if($user_obj->id ne $user_id) {
885                 if($apputils->check_user_perms($user_obj->id, $user_obj->home_ou, "VIEW_USER_FINES_SUMMARY")) {
886                         return OpenILS::Perm->new("VIEW_USER_FINES_SUMMARY"); 
887                 }
888         }
889
890         return $apputils->simple_scalar_request( 
891                 "open-ils.storage",
892                 "open-ils.storage.direct.money.user_summary.search.usr",
893                 $user_id );
894
895 }
896
897
898
899
900 __PACKAGE__->register_method(
901         method  => "user_transactions",
902         api_name        => "open-ils.actor.user.transactions",
903         notes           => <<"  NOTES");
904         Returns a list of open user transactions (mbts objects);
905         Params are login_session, user_id
906         Optional third parameter is the transactions type.  defaults to all
907         NOTES
908
909 __PACKAGE__->register_method(
910         method  => "user_transactions",
911         api_name        => "open-ils.actor.user.transactions.have_charge",
912         notes           => <<"  NOTES");
913         Returns a list of all open user transactions (mbts objects) that have an initial charge
914         Params are login_session, user_id
915         Optional third parameter is the transactions type.  defaults to all
916         NOTES
917
918 __PACKAGE__->register_method(
919         method  => "user_transactions",
920         api_name        => "open-ils.actor.user.transactions.have_balance",
921         notes           => <<"  NOTES");
922         Returns a list of all open user transactions (mbts objects) that have a balance
923         Params are login_session, user_id
924         Optional third parameter is the transactions type.  defaults to all
925         NOTES
926
927 __PACKAGE__->register_method(
928         method  => "user_transactions",
929         api_name        => "open-ils.actor.user.transactions.fleshed",
930         notes           => <<"  NOTES");
931         Returns an object/hash of transaction, circ, title where transaction = an open 
932         user transactions (mbts objects), circ is the attached circluation, and title
933         is the title the circ points to
934         Params are login_session, user_id
935         Optional third parameter is the transactions type.  defaults to all
936         NOTES
937
938 __PACKAGE__->register_method(
939         method  => "user_transactions",
940         api_name        => "open-ils.actor.user.transactions.have_charge.fleshed",
941         notes           => <<"  NOTES");
942         Returns an object/hash of transaction, circ, title where transaction = an open 
943         user transactions that has an initial charge (mbts objects), circ is the 
944         attached circluation, and title is the title the circ points to
945         Params are login_session, user_id
946         Optional third parameter is the transactions type.  defaults to all
947         NOTES
948
949 __PACKAGE__->register_method(
950         method  => "user_transactions",
951         api_name        => "open-ils.actor.user.transactions.have_balance.fleshed",
952         notes           => <<"  NOTES");
953         Returns an object/hash of transaction, circ, title where transaction = an open 
954         user transaction that has a balance (mbts objects), circ is the attached 
955         circluation, and title is the title the circ points to
956         Params are login_session, user_id
957         Optional third parameter is the transaction type.  defaults to all
958         NOTES
959
960
961
962 sub user_transactions {
963         my( $self, $client, $login_session, $user_id, $type ) = @_;
964
965         my $user_obj = $apputils->check_user_session($login_session); 
966         if($user_obj->id ne $user_id) {
967                 if($apputils->check_user_perms($user_obj->id, $user_obj->home_ou, "VIEW_USER_TRANSACTIONS")) {
968                         return OpenILS::Perm->new("VIEW_USER_TRANSACTIONS"); 
969                 }
970         }
971
972         my $api = $self->api_name();
973         my $trans;
974         my @xact;
975         if(defined($type)) { @xact = (xact_type =>  $type); 
976         } else { @xact = (); }
977
978         if($api =~ /have_charge/) {
979
980                 $trans = $apputils->simple_scalar_request( 
981                         "open-ils.storage",
982                         "open-ils.storage.direct.money.billable_transaction_summary.search_where.atomic",
983                         { usr => $user_id, total_owed => { ">" => 0 }, @xact });
984
985         } elsif($api =~ /have_balance/) {
986
987                 $trans =  $apputils->simple_scalar_request( 
988                         "open-ils.storage",
989                         "open-ils.storage.direct.money.billable_transaction_summary.search_where.atomic",
990                         { usr => $user_id, balance_owed => { ">" => 0 }, @xact });
991
992         } else {
993
994                 $trans =  $apputils->simple_scalar_request( 
995                         "open-ils.storage",
996                         "open-ils.storage.direct.money.billable_transaction_summary.search_where.atomic",
997                         { usr => $user_id, @xact });
998         }
999
1000         if($api !~ /fleshed/) { return $trans; }
1001
1002         warn "API: $api\n";
1003
1004         my @resp;
1005         for my $t (@$trans) {
1006                         
1007                 warn $t->id . "\n";
1008
1009                 my $circ = $apputils->simple_scalar_request(
1010                                 "open-ils.storage",
1011                                 "open-ils.storage.direct.action.circulation.retrieve",
1012                                 $t->id );
1013
1014                 my $title = $apputils->simple_scalar_request(
1015                         "open-ils.storage", 
1016                         "open-ils.storage.fleshed.biblio.record_entry.retrieve_by_copy",
1017                         $circ->target_copy );
1018
1019                 my $u = OpenILS::Utils::ModsParser->new();
1020                 $u->start_mods_batch($title->marc());
1021                 my $mods = $u->finish_mods_batch();
1022
1023                 push @resp, {transaction => $t, circ => $circ, record => $mods };
1024
1025         }
1026
1027         return \@resp; 
1028
1029
1030 1;
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067 __END__
1068
1069
1070 some old methods that may be good to keep around for now
1071
1072 sub _delete_card {
1073         my( $session, $card ) = @_;
1074
1075         warn "Deleting card with barcode " . $card->barcode() . "\n";
1076         my $req = $session->request(
1077                 "open-ils.storage.direct.actor.card.delete",
1078                 $card );
1079         my $status = $req->gather(1);
1080         if(!defined($status)) { 
1081                 throw OpenSRF::EX::ERROR 
1082                         ("Unknown error updating card"); 
1083         }
1084 }
1085
1086
1087
1088 # deletes the patron and any attached addresses and cards
1089 __PACKAGE__->register_method(
1090         method  => "delete_patron",
1091         api_name        => "open-ils.actor.patron.delete",
1092 );
1093
1094 sub delete_patron {
1095
1096         my( $self, $client, $patron ) = @_;
1097         my $session = $apputils->start_db_session();
1098         my $err = undef;
1099
1100         try {
1101
1102                 $patron->clear_mailing_address();
1103                 $patron->clear_billing_address();
1104                 $patron->ischanged(1);
1105
1106                 _update_patron($session, $patron);
1107                 _delete_address($session,$_) for (@{$patron->addresses()});
1108                 _delete_card($session,$_) for (@{$patron->cards()});
1109                 _delete_patron($session,$patron);
1110                 $apputils->commit_db_session($session);
1111
1112         } catch Error with {
1113                 my $e = shift;
1114                 $err =  "-*- Failure deleting user: $e";
1115                 $apputils->rollback_db_session($session);
1116                 warn $err;
1117         };
1118
1119         if($err) { throw OpenSRF::EX::ERROR ($err); }
1120         warn "Patron Delete complete\n";
1121         return 1;
1122 }
1123
1124 sub _delete_patron {
1125         my( $session, $patron ) = @_;
1126
1127         warn "Deleting patron " . $patron->usrname() . "\n";
1128
1129         my $req = $session->request(
1130                 "open-ils.storage.direct.actor.user.delete",
1131                 $patron );
1132         my $status = $req->gather(1);
1133         if(!defined($status)) { 
1134                 throw OpenSRF::EX::ERROR 
1135                         ("Unknown error updating patron"); 
1136         }
1137 }
1138
1139