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