]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/src/perlmods/OpenILS/Application/Actor.pm
onward and upward
[working/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 use OpenSRF::EX qw(:try);
6 use OpenILS::Application::AppUtils;
7 use OpenILS::Utils::Fieldmapper;
8 use OpenILS::Application::Search::Actor;
9
10 my $apputils = "OpenILS::Application::AppUtils";
11 sub _d { warn "Patron:\n" . Dumper(shift()); }
12 my $cache_client = OpenSRF::Utils::Cache->new( "global", 0 );
13
14
15 __PACKAGE__->register_method(
16         method  => "update_patron",
17         api_name        => "open-ils.actor.patron.update",
18 );
19
20
21 sub update_patron {
22         my( $self, $client, $user_session, $patron ) = @_;
23
24         my $session = $apputils->start_db_session();
25         my $err = undef;
26
27         warn $user_session . " " . $patron . "\n";
28         _d($patron);
29
30         my $user_obj = 
31                 OpenILS::Application::AppUtils->check_user_session( 
32                                 $user_session ); #throws EX on error
33
34         # XXX does this user have permission to add/create users.  Granularity?
35
36         # $new_patron is the patron in progress.  $patron is the original patron
37         # passed in with the method.  new_patron will change as the components
38         # of patron are added/updated.
39
40         my $new_patron;
41
42         try {
43                 # create/update the patron first so we can use his id
44                 if($patron->isnew()) {
45                         $new_patron = _add_patron(
46                                         $session, _clone_patron($patron));
47                 } else { 
48                         $new_patron = $patron; 
49                 }
50
51                 $new_patron = _add_update_addresses($session, $patron, $new_patron);
52                 $new_patron = _add_update_cards($session, $patron, $new_patron);
53                 $new_patron = _add_survey_responses($session, $patron, $new_patron);
54                 $new_patron     = _create_stat_maps($user_session, $patron, $new_patron);
55
56                 # re-update the patron if anything has happened to him during this process
57                 if($new_patron->ischanged()) {
58                         $new_patron = _update_patron($session, $new_patron);
59                 }
60                 $apputils->commit_db_session($session);
61
62         } catch Error with { 
63                 my $e = shift;
64                 $err =  "-*- Failure adding user: $e";
65                 $apputils->rollback_db_session($session);
66                 warn $err;
67         };
68
69         if($err) { throw OpenSRF::EX::ERROR ($err); }
70         warn "Patron Update/Create complete\n";
71         return flesh_user($new_patron->id());
72 }
73
74
75 sub flesh_user {
76         my $id = shift;
77         my $session = shift;
78         my $kill = 0;
79
80         if(!$session) {
81                 $session = OpenSRF::AppSession->create("open-ils.storage");
82                 $kill = 1;
83         }
84
85         # grab the user with the given card
86         my $ureq = $session->request(
87                         "open-ils.storage.direct.actor.user.retrieve",
88                         $id);
89         my $user = $ureq->gather(1);
90
91         # grab the cards
92         my $cards_req = $session->request(
93                         "open-ils.storage.direct.actor.card.search.usr",
94                         $user->id() );
95         $user->cards( $cards_req->gather(1) );
96
97         my $add_req = $session->request(
98                         "open-ils.storage.direct.actor.user_address.search.usr",
99                         $user->id() );
100         $user->addresses( $add_req->gather(1) );
101
102         my $stat_req = $session->request(
103                 "open-ils.storage.direct.actor.stat_cat_entry_user_map.search.target_usr",
104                 $user->id() );
105         $user->stat_cat_entries($stat_req->gather(1));
106
107         if($kill) { $session->disconnect(); }
108         $user->clear_passwd();
109         warn Dumper $user;
110
111         return $user;
112
113 }
114
115
116 # clone and clear stuff that would break the database
117 sub _clone_patron {
118         my $patron = shift;
119
120         my $new_patron = Fieldmapper::actor::user->new();
121
122         my $fmap = $Fieldmapper::fieldmap;
123         no strict; # shallow clone, may be useful in the fieldmapper
124         for my $field 
125                 (keys %{$fmap->{"Fieldmapper::actor::user"}->{'fields'}}) {
126                         $new_patron->$field( $patron->$field() );
127         }
128         use strict;
129
130         # clear these
131         $new_patron->clear_billing_address();
132         $new_patron->clear_mailing_address();
133         $new_patron->clear_addresses();
134         $new_patron->clear_card();
135         $new_patron->clear_cards();
136         $new_patron->clear_id();
137         $new_patron->clear_isnew();
138         $new_patron->clear_changed();
139         $new_patron->clear_deleted();
140         $new_patron->clear_stat_cat_entries();
141
142         return $new_patron;
143 }
144
145
146 sub _add_patron {
147         my $session             = shift;
148         my $patron              = shift;
149
150         warn "Creating new patron\n";
151         _d($patron);
152
153         my $req = $session->request(
154                 "open-ils.storage.direct.actor.user.create",$patron);
155         my $id = $req->gather(1);
156         if(!$id) { throw OpenSRF::EX::ERROR ("Unable to create new user"); }
157         warn "Created new patron with id $id\n";
158
159         # retrieve the patron from the db to collect defaults
160         my $ureq = $session->request(
161                         "open-ils.storage.direct.actor.user.retrieve",
162                         $id);
163         return $ureq->gather(1);
164 }
165
166
167 sub _update_patron {
168         my( $session, $patron) = @_;
169
170         warn "updating patron " . Dumper($patron) . "\n";
171
172         my $req = $session->request(
173                 "open-ils.storage.direct.actor.user.update",$patron );
174         my $status = $req->gather(1);
175         if(!defined($status)) { 
176                 throw OpenSRF::EX::ERROR 
177                         ("Unknown error updating patron"); 
178         }
179         return $patron;
180 }
181
182
183 sub _add_update_addresses {
184         my $session = shift;
185         my $patron = shift;
186         my $new_patron = shift;
187
188         my $current_id; # id of the address before creation
189
190         for my $address (@{$patron->addresses()}) {
191
192                 $address->usr($new_patron->id());
193
194                 if(ref($address) and $address->isnew()) {
195                         warn "Adding new address at street " . $address->street1() . "\n";
196
197                         $current_id = $address->id();
198                         $address = _add_address($session,$address);
199
200                         if( $patron->billing_address() and 
201                                         $patron->billing_address() == $current_id ) {
202                                 $new_patron->billing_address($address->id());
203                                 $new_patron->ischanged(1);
204                         }
205
206                         if( $patron->mailing_address() and
207                                         $patron->mailing_address() == $current_id ) {
208                                 $new_patron->mailing_address($address->id());
209                                 $new_patron->ischanged(1);
210                         }
211
212                 } elsif( ref($address) and $address->ischanged() ) {
213                         warn "Updating address at street " . $address->street1();
214                         $address->usr($new_patron->id());
215                         _update_address($session,$address);
216
217                 } elsif( ref($address) and $address->isdeleted() ) {
218                         warn "Deleting address at street " . $address->street1();
219
220                         if( $address->id() == $new_patron->mailing_address() ) {
221                                 $new_patron->clear_mailing_address();
222                                 _update_patron($session, $new_patron);
223                         }
224
225                         if( $address->id() == $new_patron->billing_address() ) {
226                                 $new_patron->clear_billing_address();
227                                 _update_patron($session, $new_patron);
228                         }
229
230                         _delete_address($session,$address);
231                 }
232         }
233
234         return $new_patron;
235 }
236
237
238 # adds an address to the db and returns the address with new id
239 sub _add_address {
240         my($session, $address) = @_;
241         $address->clear_id();
242
243         # put the address into the database
244         my $req = $session->request(
245                 "open-ils.storage.direct.actor.user_address.create",
246                 $address );
247
248         #update the id
249         my $id = $req->gather(1);
250         if(!$id) { 
251                 throw OpenSRF::EX::ERROR 
252                         ("Unable to create new user address"); 
253         }
254
255         warn "Created address with id $id\n";
256
257         # update all the necessary id's
258         $address->id( $id );
259         return $address;
260 }
261
262
263 sub _update_address {
264         my( $session, $address ) = @_;
265         my $req = $session->request(
266                 "open-ils.storage.direct.actor.user_address.update",
267                 $address );
268         my $status = $req->gather(1);
269         if(!defined($status)) { 
270                 throw OpenSRF::EX::ERROR 
271                         ("Unknown error updating address"); 
272         }
273         return $address;
274 }
275
276
277
278 sub _add_update_cards {
279
280         my $session = shift;
281         my $patron = shift;
282         my $new_patron = shift;
283
284         my $virtual_id; #id of the card before creation
285         for my $card (@{$patron->cards()}) {
286
287                 $card->usr($new_patron->id());
288
289                 if(ref($card) and $card->isnew()) {
290
291                         $virtual_id = $card->id();
292                         $card = _add_card($session,$card);
293
294                         if($patron->card() == $virtual_id) {
295                                 $new_patron->card($card->id());
296                                 $new_patron->ischanged(1);
297                         }
298
299                 } elsif( ref($card) and $card->ischanged() ) {
300                         $card->usr($new_patron->id());
301                         _update_card($session, $card);
302                 }
303         }
304         return $new_patron;
305 }
306
307
308 # adds an card to the db and returns the card with new id
309 sub _add_card {
310         my( $session, $card ) = @_;
311         $card->clear_id();
312
313         warn "Adding card with barcode " . $card->barcode() . "\n";
314         my $req = $session->request(
315                 "open-ils.storage.direct.actor.card.create",
316                 $card );
317
318         my $id = $req->gather(1);
319         if(!$id) { 
320                 throw OpenSRF::EX::ERROR 
321                         ("Unknown error creating card"); 
322         }
323
324         $card->id($id);
325         warn "Created patron card with id $id\n";
326         return $card;
327 }
328
329
330 sub _update_card {
331         my( $session, $card ) = @_;
332         warn Dumper $card;
333
334         my $req = $session->request(
335                 "open-ils.storage.direct.actor.card.update",
336                 $card );
337         my $status = $req->gather(1);
338         if(!defined($status)) { 
339                 throw OpenSRF::EX::ERROR 
340                         ("Unknown error updating card"); 
341         }
342         return $card;
343 }
344
345
346
347
348 sub _delete_address {
349         my( $session, $address ) = @_;
350
351         warn "Deleting address " . $address->street1() . "\n";
352
353         my $req = $session->request(
354                 "open-ils.storage.direct.actor.user_address.delete",
355                 $address );
356         my $status = $req->gather(1);
357         if(!defined($status)) { 
358                 throw OpenSRF::EX::ERROR 
359                         ("Unknown error updating address"); 
360         }
361         warn "Delete address status is $status\n";
362 }
363
364
365
366 sub _add_survey_responses {
367         my ($session, $patron, $new_patron) = @_;
368
369         warn "updating responses for user " . $new_patron->id . "\n";
370
371         my $responses = $patron->survey_responses;
372         for my $resp( @$responses ) {
373                 $resp->usr($new_patron->id);
374         }
375
376         my $status = $apputils->simple_scalar_request(
377                 "open-ils.circ", 
378                 "open-ils.circ.survey.submit.user_id",
379                 $responses );
380
381         return $new_patron;
382 }
383
384
385 sub _create_stat_maps {
386
387         my($user_session, $patron, $new_patron) = @_;
388         my $maps = $patron->stat_cat_entries();
389
390         my $session = OpenSRF::AppSession->create("open-ils.circ");
391
392         for my $map (@$maps) {
393
394                 next unless($map->isnew() || $map->ischanged());
395
396                 my $method = "open-ils.circ.stat_cat.actor.user_map.update";
397                 if($map->isnew()) {
398                         $method = "open-ils.circ.stat_cat.actor.user_map.create";
399                 }
400
401                 warn "Updating stat entry with method $method and 
402                         session $user_session and map $map\n";
403
404                 my $req = $session->request($method, $user_session, $map);
405                 my $status = $req->gather(1);
406
407                 warn "Updated\n";
408
409                 if(!$status) {
410                         throw OpenSRF::EX::ERROR 
411                                 ("Error updating stat map with method $method");        
412                 }
413         }
414
415         $session->disconnect();
416         return $new_patron;
417 }
418
419
420
421 __PACKAGE__->register_method(
422         method  => "search_username",
423         api_name        => "open-ils.actor.user.search.username",
424 );
425
426 sub search_username {
427         my($self, $client, $username) = @_;
428         my $users = OpenILS::Application::AppUtils->simple_scalar_request(
429                         "open-ils.storage", 
430                         "open-ils.storage.direct.actor.user.search.usrname",
431                         $username );
432         return $users;
433 }
434
435
436
437
438 __PACKAGE__->register_method(
439         method  => "user_retrieve_by_barcode",
440         api_name        => "open-ils.actor.user.fleshed.retrieve_by_barcode",
441 );
442
443 sub user_retrieve_by_barcode {
444         my($self, $client, $barcode) = @_;
445         warn "Searching for user with barcode $barcode\n";
446
447         my $session = OpenSRF::AppSession->create("open-ils.storage");
448
449         # find the card with the given barcode
450         my $creq        = $session->request(
451                         "open-ils.storage.direct.actor.card.search.barcode",
452                         $barcode );
453         my $card = $creq->gather(1);
454         $card = $card->[0];
455         my $user = flesh_user($card->usr(), $session);
456         $session->disconnect();
457         return $user;
458
459 }
460
461
462
463 __PACKAGE__->register_method(
464         method  => "get_user_by_id",
465         api_name        => "open-ils.actor.user.retrieve",);
466
467 sub get_user_by_id {
468         my ($self, $client, $user_session, $id) = @_;
469
470         my $user_obj = $apputils->check_user_session( $user_session ); 
471
472         return $apputils->simple_scalar_request(
473                 "open-ils.storage",
474                 "open-ils.storage.direct.actor.user.retrieve",
475                 $id );
476 }
477
478
479
480 __PACKAGE__->register_method(
481         method  => "get_org_types",
482         api_name        => "open-ils.actor.org_types.retrieve",);
483
484 my $org_types;
485 sub get_org_types {
486         my($self, $client) = @_;
487
488         return $org_types if $org_types;
489          return $org_types = 
490                  $apputils->simple_scalar_request(
491                         "open-ils.storage",
492                         "open-ils.storage.direct.actor.org_unit_type.retrieve.all.atomic" );
493 }
494
495
496
497 __PACKAGE__->register_method(
498         method  => "get_user_profiles",
499         api_name        => "open-ils.actor.user.profiles.retrieve",
500 );
501
502 my $user_profiles;
503 sub get_user_profiles {
504         return $user_profiles if $user_profiles;
505
506         return $user_profiles = 
507                 $apputils->simple_scalar_request(
508                         "open-ils.storage",
509                         "open-ils.storage.direct.actor.profile.retrieve.all.atomic");
510 }
511
512
513
514 __PACKAGE__->register_method(
515         method  => "get_user_ident_types",
516         api_name        => "open-ils.actor.user.ident_types.retrieve",
517 );
518 my $ident_types;
519 sub get_user_ident_types {
520         return $ident_types if $ident_types;
521         return $ident_types = 
522                 $apputils->simple_scalar_request(
523                 "open-ils.storage",
524                 "open-ils.storage.direct.config.identification_type.retrieve.all.atomic" );
525 }
526
527
528
529
530 __PACKAGE__->register_method(
531         method  => "get_org_unit",
532         api_name        => "open-ils.actor.org_unit.retrieve",
533 );
534
535 sub get_org_unit {
536
537         my( $self, $client, $user_session ) = @_;
538
539         my $user_obj = 
540                 OpenILS::Application::AppUtils->check_user_session( $user_session ); #throws EX on error
541
542         my $home_ou = OpenILS::Application::AppUtils->simple_scalar_request(
543                 "open-ils.storage",
544                 "open-ils.storage.direct.actor.org_unit.retrieve", 
545                 $user_obj->home_ou );
546
547         return $home_ou;
548 }
549
550
551 # build the org tree
552
553 __PACKAGE__->register_method(
554         method  => "get_org_tree",
555         api_name        => "open-ils.actor.org_tree.retrieve",
556         argc            => 1, 
557         note            => "Returns the entire org tree structure",
558 );
559
560 sub get_org_tree {
561         my( $self, $client) = @_;
562
563         # see if it's in the cache
564         warn "Getting ORG Tree\n";
565         my $tree = $cache_client->get_cache('orgtree');
566         if($tree) { 
567                 warn "Found orgtree in cache. returning...\n";
568                 return $tree; 
569         }
570
571         my $orglist = $apputils->simple_scalar_request( 
572                 "open-ils.storage", 
573                 "open-ils.storage.direct.actor.org_unit.retrieve.all.atomic" );
574
575         $tree = $self->build_org_tree($orglist);
576         $cache_client->put_cache('orgtree', $tree);
577
578         return $tree;
579
580 }
581
582 # turns an org list into an org tree
583 sub build_org_tree {
584
585         my( $self, $orglist) = @_;
586
587         return $orglist unless ( 
588                         ref($orglist) and @$orglist > 1 );
589
590         my @list = sort { 
591                 $a->ou_type <=> $b->ou_type ||
592                 $a->name cmp $b->name } @$orglist;
593
594         for my $org (@list) {
595
596                 next unless ($org and defined($org->parent_ou));
597                 my ($parent) = grep { $_->id == $org->parent_ou } @list;
598                 next unless $parent;
599
600                 $parent->children([]) unless defined($parent->children); 
601                 push( @{$parent->children}, $org );
602         }
603
604         return $list[0];
605
606 }
607
608
609 __PACKAGE__->register_method(
610         method  => "get_org_descendants",
611         api_name        => "open-ils.actor.org_tree.descendants.retrieve"
612 );
613
614 # depth is optional.  org_unit is the id
615 sub get_org_descendants {
616         my( $self, $client, $org_unit, $depth ) = @_;
617         my $orglist = $apputils->simple_scalar_request(
618                         "open-ils.storage", 
619                         "open-ils.storage.actor.org_unit.descendants.atomic",
620                         $org_unit, $depth );
621         return $self->build_org_tree($orglist);
622 }
623
624
625 __PACKAGE__->register_method(
626         method  => "get_org_ancestors",
627         api_name        => "open-ils.actor.org_tree.ancestors.retrieve"
628 );
629
630 # depth is optional.  org_unit is the id
631 sub get_org_ancestors {
632         my( $self, $client, $org_unit, $depth ) = @_;
633         my $orglist = $apputils->simple_scalar_request(
634                         "open-ils.storage", 
635                         "open-ils.storage.actor.org_unit.ancestors.atomic",
636                         $org_unit, $depth );
637         return $self->build_org_tree($orglist);
638 }
639
640
641 __PACKAGE__->register_method(
642         method  => "get_standings",
643         api_name        => "open-ils.actor.standings.retrieve"
644 );
645
646 my $user_standings;
647 sub get_standings {
648         return $user_standings if $user_standings;
649         return $user_standings = 
650                 $apputils->simple_scalar_request(
651                         "open-ils.storage",
652                         "open-ils.storage.direct.config.standing.retrieve.all.atomic" );
653 }
654
655
656
657 __PACKAGE__->register_method(
658         method  => "get_my_org_path",
659         api_name        => "open-ils.actor.org_unit.full_path.retrieve"
660 );
661
662 sub get_my_org_path {
663         my( $self, $client, $user_session, $org_id ) = @_;
664         my $user_obj = $apputils->check_user_session($user_session); 
665         if(!defined($org_id)) { $org_id = $user_obj->home_ou; }
666
667         return $apputils->simple_scalar_request(
668                 "open-ils.storage",
669                 "open-ils.storage.actor.org_unit.full_path.atomic",
670                 $org_id );
671 }
672
673
674 __PACKAGE__->register_method(
675         method  => "patron_adv_search",
676         api_name        => "open-ils.actor.patron.search.advanced" );
677
678 sub patron_adv_search {
679         my( $self, $client, $staff_login, $search_hash ) = @_;
680
681         use Data::Dumper;
682         warn "patron adv with $staff_login and search " . 
683                 Dumper($search_hash) . "\n";
684
685         my $session = OpenSRF::AppSession->create("open-ils.storage");
686         my $req = $session->request(
687                 "open-ils.storage.actor.user.crazy_search", $search_hash);
688
689         my $ans = $req->gather(1);
690         $session->disconnect();
691         return $ans;
692
693 }
694
695
696
697
698
699
700
701
702 1;
703
704
705
706
707 __END__
708
709
710 some old methods that may be good to keep around for now
711
712 sub _delete_card {
713         my( $session, $card ) = @_;
714
715         warn "Deleting card with barcode " . $card->barcode() . "\n";
716         my $req = $session->request(
717                 "open-ils.storage.direct.actor.card.delete",
718                 $card );
719         my $status = $req->gather(1);
720         if(!defined($status)) { 
721                 throw OpenSRF::EX::ERROR 
722                         ("Unknown error updating card"); 
723         }
724 }
725
726
727
728 # deletes the patron and any attached addresses and cards
729 __PACKAGE__->register_method(
730         method  => "delete_patron",
731         api_name        => "open-ils.actor.patron.delete",
732 );
733
734 sub delete_patron {
735
736         my( $self, $client, $patron ) = @_;
737         my $session = $apputils->start_db_session();
738         my $err = undef;
739
740         try {
741
742                 $patron->clear_mailing_address();
743                 $patron->clear_billing_address();
744                 $patron->ischanged(1);
745
746                 _update_patron($session, $patron);
747                 _delete_address($session,$_) for (@{$patron->addresses()});
748                 _delete_card($session,$_) for (@{$patron->cards()});
749                 _delete_patron($session,$patron);
750                 $apputils->commit_db_session($session);
751
752         } catch Error with {
753                 my $e = shift;
754                 $err =  "-*- Failure deleting user: $e";
755                 $apputils->rollback_db_session($session);
756                 warn $err;
757         };
758
759         if($err) { throw OpenSRF::EX::ERROR ($err); }
760         warn "Patron Delete complete\n";
761         return 1;
762 }
763
764 sub _delete_patron {
765         my( $session, $patron ) = @_;
766
767         warn "Deleting patron " . $patron->usrname() . "\n";
768
769         my $req = $session->request(
770                 "open-ils.storage.direct.actor.user.delete",
771                 $patron );
772         my $status = $req->gather(1);
773         if(!defined($status)) { 
774                 throw OpenSRF::EX::ERROR 
775                         ("Unknown error updating patron"); 
776         }
777 }
778