]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/src/perlmods/OpenILS/Application/Actor.pm
moving as much 'actor' code to here as i can for maintainability
[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.create",
18 );
19
20 __PACKAGE__->register_method(
21         method  => "update_patron",
22         api_name        => "open-ils.actor.patron.update",
23 );
24
25
26 sub update_patron {
27         my( $self, $client, $patron ) = @_;
28
29         my $session = $apputils->start_db_session();
30         my $err = undef;
31
32
33         # $new_patron is the patron in progress.  $patron is the original patron
34         # passed in with the method.  new_patron will change as the components
35         # of patron are added/updated.
36
37         my $new_patron;
38
39         try {
40                 # create/update the patron first so we can use his id
41                 if( $self->api_name =~ /create/ ) {
42                         $new_patron = _add_patron(
43                                         $session, _clone_patron($patron));
44                 } else { 
45                         $new_patron = $patron; 
46                 }
47
48                 $new_patron = _add_update_addresses($session, $patron, $new_patron);
49                 $new_patron = _add_update_cards($session, $patron, $new_patron);
50
51                 # re-update the patron if anything has happened to him during this process
52                 if($new_patron->ischanged()) {
53                         $new_patron = _update_patron($session, $new_patron);
54                 }
55                 $apputils->commit_db_session($session);
56
57         } catch Error with { 
58                 my $e = shift;
59                 $err =  "-*- Failure adding user: $e";
60                 $apputils->rollback_db_session($session);
61                 warn $err;
62         };
63
64         if($err) { throw OpenSRF::EX::ERROR ($err); }
65         warn "Patron Update/Create complete\n";
66         return flesh_user($new_patron->id());
67 }
68
69
70 sub flesh_user {
71         my $id = shift;
72         my $session = shift;
73         my $kill = 0;
74
75         if(!$session) {
76                 $session = OpenSRF::AppSession->create("open-ils.storage");
77                 $kill = 1;
78         }
79
80         # grab the user with the given card
81         my $ureq = $session->request(
82                         "open-ils.storage.direct.actor.user.retrieve",
83                         $id);
84         my $user = $ureq->gather(1);
85
86         # grab the cards
87         my $cards_req = $session->request(
88                         "open-ils.storage.direct.actor.card.search.usr",
89                         $user->id() );
90         $user->cards( $cards_req->gather(1) );
91
92         my $add_req = $session->request(
93                         "open-ils.storage.direct.actor.user_address.search.usr",
94                         $user->id() );
95         $user->addresses( $add_req->gather(1) );
96
97         if($kill) { $session->disconnect(); }
98
99         return $user;
100
101 }
102
103
104 # clone and clear stuff that would break the database
105 sub _clone_patron {
106         my $patron = shift;
107
108         my $new_patron = Fieldmapper::actor::user->new();
109
110         my $fmap = $Fieldmapper::fieldmap;
111         no strict; # shallow clone, may be useful in the fieldmapper
112         for my $field 
113                 (keys %{$fmap->{"Fieldmapper::actor::user"}->{'fields'}}) {
114                         $new_patron->$field( $patron->$field() );
115         }
116         use strict;
117
118         # clear these
119         $new_patron->clear_billing_address();
120         $new_patron->clear_mailing_address();
121         $new_patron->clear_addresses();
122         $new_patron->clear_card();
123         $new_patron->clear_cards();
124         $new_patron->clear_id();
125         $new_patron->clear_isnew();
126         $new_patron->clear_changed();
127         $new_patron->clear_deleted();
128
129         return $new_patron;
130 }
131
132
133 sub _add_patron {
134         my $session             = shift;
135         my $patron              = shift;
136
137         my $req = $session->request(
138                 "open-ils.storage.direct.actor.user.create",$patron);
139         my $id = $req->gather(1);
140         if(!$id) { throw OpenSRF::EX::ERROR ("Unable to create new user"); }
141         warn "Created new patron with id $id\n";
142         $patron->id($id);
143
144         return $patron;
145 }
146
147
148 sub _update_patron {
149         my( $session, $patron) = @_;
150
151         warn "updating patron " . $patron->usrname() . "\n";
152         my $req = $session->request(
153                 "open-ils.storage.direct.actor.user.update",$patron );
154         my $status = $req->gather(1);
155         if(!defined($status)) { 
156                 throw OpenSRF::EX::ERROR 
157                         ("Unknown error updating patron"); 
158         }
159         return $patron;
160 }
161
162
163 sub _add_update_addresses {
164         my $session = shift;
165         my $patron = shift;
166         my $new_patron = shift;
167
168         my $current_id; # id of the address before creation
169
170         for my $address (@{$patron->addresses()}) {
171
172                 $address->usr($new_patron->id());
173
174                 if(ref($address) and $address->isnew()) {
175                         warn "Adding new address at street " . $address->street1() . "\n";
176
177                         $current_id = $address->id();
178                         $address = _add_address($session,$address);
179
180                         if( $patron->billing_address() == $current_id ) {
181                                 $new_patron->billing_address($address->id());
182                                 $new_patron->ischanged(1);
183                         }
184
185                         if( $patron->mailing_address() == $current_id ) {
186                                 $new_patron->mailing_address($address->id());
187                                 $new_patron->ischanged(1);
188                         }
189
190                 } elsif( ref($address) and $address->ischanged() ) {
191                         warn "Updating address at street " . $address->street1();
192                         _update_address($session,$address);
193
194                 } elsif( ref($address) and $address->isdeleted() ) {
195                         warn "Deleting address at street " . $address->street1();
196                         _delete_address($session,$address);
197                 }
198         }
199
200         return $new_patron;
201 }
202
203
204 # adds an address to the db and returns the address with new id
205 sub _add_address {
206         my($session, $address) = @_;
207         $address->clear_id();
208
209         # put the address into the database
210         my $req = $session->request(
211                 "open-ils.storage.direct.actor.user_address.create",
212                 $address );
213
214         #update the id
215         my $id = $req->gather(1);
216         if(!$id) { 
217                 throw OpenSRF::EX::ERROR 
218                         ("Unable to create new user address"); 
219         }
220
221         warn "Created address with id $id\n";
222
223         # update all the necessary id's
224         $address->id( $id );
225         return $address;
226 }
227
228
229 sub _update_address {
230         my( $session, $address ) = @_;
231         my $req = $session->request(
232                 "open-ils.storage.direct.actor.user_address.update",
233                 $address );
234         my $status = $req->gather(1);
235         if(!defined($status)) { 
236                 throw OpenSRF::EX::ERROR 
237                         ("Unknown error updating address"); 
238         }
239         return $address;
240 }
241
242
243
244 sub _add_update_cards {
245
246         my $session = shift;
247         my $patron = shift;
248         my $new_patron = shift;
249
250         my $virtual_id; #id of the card before creation
251         for my $card (@{$patron->cards()}) {
252
253                 $card->usr($new_patron->id());
254
255                 if(ref($card) and $card->isnew()) {
256
257                         $virtual_id = $card->id();
258                         $card = _add_card($session,$card);
259
260                         if($patron->card() == $virtual_id) {
261                                 $new_patron->card($card->id());
262                                 $new_patron->ischanged(1);
263                         }
264
265                 } elsif( ref($card) and $card->ischanged() ) {
266                         _update_card($session, $card);
267                 }
268         }
269         return $new_patron;
270 }
271
272
273 # adds an card to the db and returns the card with new id
274 sub _add_card {
275         my( $session, $card ) = @_;
276         $card->clear_id();
277
278         warn "Adding card with barcode " . $card->barcode() . "\n";
279         my $req = $session->request(
280                 "open-ils.storage.direct.actor.card.create",
281                 $card );
282
283         my $id = $req->gather(1);
284         if(!$id) { 
285                 throw OpenSRF::EX::ERROR 
286                         ("Unknown error creating card"); 
287         }
288
289         $card->id($id);
290         warn "Created patron card with id $id\n";
291         return $card;
292 }
293
294
295 sub _update_card {
296         my( $session, $card ) = @_;
297         warn Dumper $card;
298
299         my $req = $session->request(
300                 "open-ils.storage.direct.actor.card.update",
301                 $card );
302         my $status = $req->gather(1);
303         if(!defined($status)) { 
304                 throw OpenSRF::EX::ERROR 
305                         ("Unknown error updating card"); 
306         }
307         return $card;
308 }
309
310
311
312
313 sub _delete_address {
314         my( $session, $address ) = @_;
315
316         warn "Deleting address " . $address->street1() . "\n";
317
318         my $req = $session->request(
319                 "open-ils.storage.direct.actor.user_address.delete",
320                 $address );
321         my $status = $req->gather(1);
322         if(!defined($status)) { 
323                 throw OpenSRF::EX::ERROR 
324                         ("Unknown error updating address"); 
325         }
326 }
327
328
329
330
331 __PACKAGE__->register_method(
332         method  => "search_username",
333         api_name        => "open-ils.actor.user.search.username",
334 );
335
336 sub search_username {
337         my($self, $client, $username) = @_;
338         my $users = OpenILS::Application::AppUtils->simple_scalar_request(
339                         "open-ils.storage", 
340                         "open-ils.storage.direct.actor.user.search.usrname",
341                         $username );
342         return $users;
343 }
344
345
346 __PACKAGE__->register_method(
347         method  => "user_retrieve_by_barcode",
348         api_name        => "open-ils.actor.user.fleshed.retrieve_by_barcode",
349 );
350
351 sub user_retrieve_by_barcode {
352         my($self, $client, $barcode) = @_;
353         warn "Searching for user with barcode $barcode\n";
354
355         my $session = OpenSRF::AppSession->create("open-ils.storage");
356
357         # find the card with the given barcode
358         my $creq        = $session->request(
359                         "open-ils.storage.direct.actor.card.search.barcode",
360                         $barcode );
361         my $card = $creq->gather(1);
362         $card = $card->[0];
363         my $user = flesh_user($card->usr(), $session);
364         $session->disconnect();
365         return $user;
366
367 }
368
369
370
371
372 __PACKAGE__->register_method(
373         method  => "get_org_types",
374         api_name        => "open-ils.actor.org_types.retrieve",
375 );
376 sub get_org_types {
377         my($self, $client) = @_;
378
379          my $org_typelist = OpenILS::Application::AppUtils->simple_scalar_request(
380                 "open-ils.storage",
381                 "open-ils.storage.direct.actor.org_unit_type.retrieve.all.atomic" );
382
383          return $org_typelist;
384 }
385
386
387 __PACKAGE__->register_method(
388         method  => "get_user_profiles",
389         api_name        => "open-ils.actor.user.profiles.retrieve",
390 );
391 sub get_user_profiles {
392         return OpenILS::Application::AppUtils->simple_scalar_request(
393                         "open-ils.storage",
394                         "open-ils.storage.direct.actor.profile.retrieve.all.atomic",
395                         ( "1", "2", "3" ) );
396 }
397
398
399
400 __PACKAGE__->register_method(
401         method  => "get_user_ident_types",
402         api_name        => "open-ils.actor.user.ident_types.retrieve",
403 );
404 sub get_user_ident_types {
405         return OpenILS::Application::AppUtils->simple_scalar_request(
406                         "open-ils.storage",
407                         "open-ils.storage.direct.config.identification_type.retrieve.all.atomic" );
408 }
409
410
411
412
413 __PACKAGE__->register_method(
414         method  => "get_org_unit",
415         api_name        => "open-ils.actor.org_unit.retrieve",
416         argc            => 1, 
417         note            => "Returns the entire org tree structure",
418 );
419
420 sub get_org_unit {
421
422         my( $self, $client, $user_session ) = @_;
423
424         my $user_obj = 
425                 OpenILS::Application::AppUtils->check_user_session( $user_session ); #throws EX on error
426
427         my $home_ou = OpenILS::Application::AppUtils->simple_scalar_request(
428                 "open-ils.storage",
429                 "open-ils.storage.direct.actor.org_unit.retrieve", 
430                 $user_obj->home_ou );
431
432         return $home_ou;
433 }
434
435
436 # build the org tree
437
438 __PACKAGE__->register_method(
439         method  => "get_org_tree",
440         api_name        => "open-ils.actor.org_tree.retrieve",
441         argc            => 1, 
442         note            => "Returns the entire org tree structure",
443 );
444
445 sub get_org_tree {
446         my( $self, $client) = @_;
447
448         # see if it's in the cache
449         warn "Getting ORG Tree\n";
450         my $tree = $cache_client->get_cache('orgtree');
451         if($tree) { 
452                 warn "Found orgtree in cache. returning...\n";
453                 return $tree; 
454         }
455
456         my $orglist = $apputils->simple_scalar_request( 
457                 "open-ils.storage", 
458                 "open-ils.storage.direct.actor.org_unit.retrieve.all.atomic" );
459
460         $tree = $self->build_org_tree($orglist);
461         $cache_client->put_cache('orgtree', $tree);
462
463         return $tree;
464
465 }
466
467 sub build_org_tree {
468
469         my( $self, $orglist) = @_;
470
471         return $orglist unless ( 
472                         ref($orglist) and @$orglist > 1 );
473
474         my @list = sort { 
475                 $a->ou_type <=> $b->ou_type ||
476                 $a->name cmp $b->name } @$orglist;
477
478         for my $org (@list) {
479
480                 next unless ($org and defined($org->parent_ou));
481                 my ($parent) = grep { $_->id == $org->parent_ou } @list;
482                 next unless $parent;
483
484                 $parent->children([]) unless defined($parent->children); 
485                 push( @{$parent->children}, $org );
486         }
487
488         return $list[0];
489
490 }
491
492
493
494
495
496 1;
497
498
499
500
501
502
503 __END__
504
505
506 sub _delete_card {
507         my( $session, $card ) = @_;
508
509         warn "Deleting card with barcode " . $card->barcode() . "\n";
510         my $req = $session->request(
511                 "open-ils.storage.direct.actor.card.delete",
512                 $card );
513         my $status = $req->gather(1);
514         if(!defined($status)) { 
515                 throw OpenSRF::EX::ERROR 
516                         ("Unknown error updating card"); 
517         }
518 }
519
520
521
522 # deletes the patron and any attached addresses and cards
523 __PACKAGE__->register_method(
524         method  => "delete_patron",
525         api_name        => "open-ils.actor.patron.delete",
526 );
527
528 sub delete_patron {
529
530         my( $self, $client, $patron ) = @_;
531         my $session = $apputils->start_db_session();
532         my $err = undef;
533
534         try {
535
536                 $patron->clear_mailing_address();
537                 $patron->clear_billing_address();
538                 $patron->ischanged(1);
539
540                 _update_patron($session, $patron);
541                 _delete_address($session,$_) for (@{$patron->addresses()});
542                 _delete_card($session,$_) for (@{$patron->cards()});
543                 _delete_patron($session,$patron);
544                 $apputils->commit_db_session($session);
545
546         } catch Error with {
547                 my $e = shift;
548                 $err =  "-*- Failure deleting user: $e";
549                 $apputils->rollback_db_session($session);
550                 warn $err;
551         };
552
553         if($err) { throw OpenSRF::EX::ERROR ($err); }
554         warn "Patron Delete complete\n";
555         return 1;
556 }
557
558
559
560 sub _delete_patron {
561         my( $session, $patron ) = @_;
562
563         warn "Deleting patron " . $patron->usrname() . "\n";
564
565         my $req = $session->request(
566                 "open-ils.storage.direct.actor.user.delete",
567                 $patron );
568         my $status = $req->gather(1);
569         if(!defined($status)) { 
570                 throw OpenSRF::EX::ERROR 
571                         ("Unknown error updating patron"); 
572         }
573 }
574