]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/perlmods/OpenILS/Application/Actor.pm
added full_path retrieval for org
[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 sub get_org_types {
399         my($self, $client) = @_;
400
401          my $org_typelist = OpenILS::Application::AppUtils->simple_scalar_request(
402                 "open-ils.storage",
403                 "open-ils.storage.direct.actor.org_unit_type.retrieve.all.atomic" );
404
405          return $org_typelist;
406 }
407
408
409 __PACKAGE__->register_method(
410         method  => "get_user_profiles",
411         api_name        => "open-ils.actor.user.profiles.retrieve",
412 );
413 sub get_user_profiles {
414         return OpenILS::Application::AppUtils->simple_scalar_request(
415                         "open-ils.storage",
416                         "open-ils.storage.direct.actor.profile.retrieve.all.atomic",
417                         ( "1", "2", "3" ) );
418 }
419
420
421
422 __PACKAGE__->register_method(
423         method  => "get_user_ident_types",
424         api_name        => "open-ils.actor.user.ident_types.retrieve",
425 );
426 sub get_user_ident_types {
427         return OpenILS::Application::AppUtils->simple_scalar_request(
428                         "open-ils.storage",
429                         "open-ils.storage.direct.config.identification_type.retrieve.all.atomic" );
430 }
431
432
433
434
435 __PACKAGE__->register_method(
436         method  => "get_org_unit",
437         api_name        => "open-ils.actor.org_unit.retrieve",
438 );
439
440 sub get_org_unit {
441
442         my( $self, $client, $user_session ) = @_;
443
444         my $user_obj = 
445                 OpenILS::Application::AppUtils->check_user_session( $user_session ); #throws EX on error
446
447         my $home_ou = OpenILS::Application::AppUtils->simple_scalar_request(
448                 "open-ils.storage",
449                 "open-ils.storage.direct.actor.org_unit.retrieve", 
450                 $user_obj->home_ou );
451
452         return $home_ou;
453 }
454
455
456 # build the org tree
457
458 __PACKAGE__->register_method(
459         method  => "get_org_tree",
460         api_name        => "open-ils.actor.org_tree.retrieve",
461         argc            => 1, 
462         note            => "Returns the entire org tree structure",
463 );
464
465 sub get_org_tree {
466         my( $self, $client) = @_;
467
468         # see if it's in the cache
469         warn "Getting ORG Tree\n";
470         my $tree = $cache_client->get_cache('orgtree');
471         if($tree) { 
472                 warn "Found orgtree in cache. returning...\n";
473                 return $tree; 
474         }
475
476         my $orglist = $apputils->simple_scalar_request( 
477                 "open-ils.storage", 
478                 "open-ils.storage.direct.actor.org_unit.retrieve.all.atomic" );
479
480         $tree = $self->build_org_tree($orglist);
481         $cache_client->put_cache('orgtree', $tree);
482
483         return $tree;
484
485 }
486
487 # turns an org list into an org tree
488 sub build_org_tree {
489
490         my( $self, $orglist) = @_;
491
492         return $orglist unless ( 
493                         ref($orglist) and @$orglist > 1 );
494
495         my @list = sort { 
496                 $a->ou_type <=> $b->ou_type ||
497                 $a->name cmp $b->name } @$orglist;
498
499         for my $org (@list) {
500
501                 next unless ($org and defined($org->parent_ou));
502                 my ($parent) = grep { $_->id == $org->parent_ou } @list;
503                 next unless $parent;
504
505                 $parent->children([]) unless defined($parent->children); 
506                 push( @{$parent->children}, $org );
507         }
508
509         return $list[0];
510
511 }
512
513
514 __PACKAGE__->register_method(
515         method  => "get_org_descendants",
516         api_name        => "open-ils.actor.org_tree.descendants.retrieve"
517 );
518
519 # depth is optional.  org_unit is the id
520 sub get_org_descendants {
521         my( $self, $client, $org_unit, $depth ) = @_;
522         my $orglist = $apputils->simple_scalar_request(
523                         "open-ils.storage", 
524                         "open-ils.storage.actor.org_unit.descendants.atomic",
525                         $org_unit, $depth );
526         return $self->build_org_tree($orglist);
527 }
528
529
530 __PACKAGE__->register_method(
531         method  => "get_org_ancestors",
532         api_name        => "open-ils.actor.org_tree.ancestors.retrieve"
533 );
534
535 # depth is optional.  org_unit is the id
536 sub get_org_ancestors {
537         my( $self, $client, $org_unit, $depth ) = @_;
538         my $orglist = $apputils->simple_scalar_request(
539                         "open-ils.storage", 
540                         "open-ils.storage.actor.org_unit.ancestors.atomic",
541                         $org_unit, $depth );
542         return $self->build_org_tree($orglist);
543 }
544
545
546 __PACKAGE__->register_method(
547         method  => "get_standings",
548         api_name        => "open-ils.actor.standings.retrieve"
549 );
550
551 sub get_standings {
552         return $apputils->simple_scalar_request(
553                         "open-ils.storage",
554                         "open-ils.storage.direct.config.standing.retrieve.all.atomic" );
555 }
556
557
558
559 __PACKAGE__->register_method(
560         method  => "get_my_org_path",
561         api_name        => "open-ils.actor.org_unit.full_path.retrieve"
562 );
563
564 sub get_my_org_path {
565         my( $self, $client, $user_session, $org_id ) = @_;
566         my $user_obj = $apputils->check_user_session($user_session); 
567         if(!defined($org_id)) { $org_id = $user_obj->home_ou; }
568
569         return $apputils->simple_scalar_request(
570                 "open-ils.storage",
571                 "open-ils.storage.actor.org_unit.full_path.atomic",
572                 $org_id );
573 }
574
575
576
577 1;
578
579
580
581
582 __END__
583
584
585 some old methods that may be good to keep around for now
586
587 sub _delete_card {
588         my( $session, $card ) = @_;
589
590         warn "Deleting card with barcode " . $card->barcode() . "\n";
591         my $req = $session->request(
592                 "open-ils.storage.direct.actor.card.delete",
593                 $card );
594         my $status = $req->gather(1);
595         if(!defined($status)) { 
596                 throw OpenSRF::EX::ERROR 
597                         ("Unknown error updating card"); 
598         }
599 }
600
601
602
603 # deletes the patron and any attached addresses and cards
604 __PACKAGE__->register_method(
605         method  => "delete_patron",
606         api_name        => "open-ils.actor.patron.delete",
607 );
608
609 sub delete_patron {
610
611         my( $self, $client, $patron ) = @_;
612         my $session = $apputils->start_db_session();
613         my $err = undef;
614
615         try {
616
617                 $patron->clear_mailing_address();
618                 $patron->clear_billing_address();
619                 $patron->ischanged(1);
620
621                 _update_patron($session, $patron);
622                 _delete_address($session,$_) for (@{$patron->addresses()});
623                 _delete_card($session,$_) for (@{$patron->cards()});
624                 _delete_patron($session,$patron);
625                 $apputils->commit_db_session($session);
626
627         } catch Error with {
628                 my $e = shift;
629                 $err =  "-*- Failure deleting user: $e";
630                 $apputils->rollback_db_session($session);
631                 warn $err;
632         };
633
634         if($err) { throw OpenSRF::EX::ERROR ($err); }
635         warn "Patron Delete complete\n";
636         return 1;
637 }
638
639 sub _delete_patron {
640         my( $session, $patron ) = @_;
641
642         warn "Deleting patron " . $patron->usrname() . "\n";
643
644         my $req = $session->request(
645                 "open-ils.storage.direct.actor.user.delete",
646                 $patron );
647         my $status = $req->gather(1);
648         if(!defined($status)) { 
649                 throw OpenSRF::EX::ERROR 
650                         ("Unknown error updating patron"); 
651         }
652 }
653