]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/perlmods/OpenILS/Application/Circ/ScriptBuilder.pm
added some logging, unfleshing ou_type for now
[Evergreen.git] / Open-ILS / src / perlmods / OpenILS / Application / Circ / ScriptBuilder.pm
1 package OpenILS::Application::Circ::ScriptBuilder;
2 use strict; use warnings;
3 use OpenILS::Utils::ScriptRunner;
4 use OpenILS::Utils::CStoreEditor qw/:funcs/;
5 use OpenILS::Application::AppUtils;
6 use OpenILS::Application::Actor;
7 use OpenSRF::Utils::Logger qw/$logger/;
8 my $U = "OpenILS::Application::AppUtils";
9 use Data::Dumper;
10
11 my $evt = "environment";
12 my @COPY_STATUSES;
13 my @COPY_LOCATIONS;
14 my %GROUP_SET;
15 my $GROUP_TREE;
16 my $ORG_TREE;
17 my @ORG_LIST;
18
19
20 # -----------------------------------------------------------------------
21 # Possible Args:
22 #  copy
23 #  copy_id
24 #  copy_barcode
25 #
26 #  patron
27 #  patron_id
28 #  patron_barcode
29 #
30 #  fetch_patron_circ_info - load info on items out, overdues, and fines.
31 #
32 #  _direct - this is a hash of key/value pairs to shove directly into the 
33 #  script runner.  Use this to cover data not covered by this module
34 # -----------------------------------------------------------------------
35 sub build {
36         my( $class, $args ) = @_;
37
38         my $evt;
39         my @evts;
40
41         my $editor = $$args{editor} || new_editor();
42
43         $args->{_direct} = {} unless $args->{_direct};
44         
45         $evt = fetch_bib_data($editor, $args);
46         push(@evts, $evt) if $evt;
47         $evt = fetch_user_data($editor, $args);
48         push(@evts, $evt) if $evt;
49
50         if(@evts) {
51                 my @e;
52                 push( @e, $_->{textcode} ) for @evts;
53                 $logger->info("script_builder: some events occurred: @e");
54                 $logger->debug("script_builder: some events occurred: " . Dumper(\@evts));
55                 $args->{_events} = \@evts;
56         }
57
58         return build_runner($editor, $args);
59 }
60
61
62 sub build_runner {
63         my $editor      = shift;
64         my $ctx         = shift;
65
66         my $runner = OpenILS::Utils::ScriptRunner->new;
67
68         $runner->insert( "$evt.groupTree",      $GROUP_TREE, 1);
69
70
71         $runner->insert( "$evt.patron",         $ctx->{patron}, 1);
72         $runner->insert( "$evt.copy",                   $ctx->{copy}, 1);
73         $runner->insert( "$evt.volume",         $ctx->{volume}, 1);
74         $runner->insert( "$evt.title",          $ctx->{title}, 1);
75         $runner->insert( "$evt.requestor",      $ctx->{requestor}, 1);
76         $runner->insert( "$evt.titleDescriptor", $ctx->{titleDescriptor}, 1);
77
78         $runner->insert( "$evt.patronItemsOut", $ctx->{patronItemsOut}, 1 );
79         $runner->insert( "$evt.patronOverdueCount", $ctx->{patronOverdue}, 1 );
80         $runner->insert( "$evt.patronFines", $ctx->{patronFines}, 1 );
81
82         $runner->insert("$evt.$_", $ctx->{_direct}->{$_}) for keys %{$ctx->{_direct}};
83
84         $ctx->{runner} = $runner;
85
86         insert_org_methods( $editor, $ctx );
87
88         return $runner;
89 }
90
91 sub fetch_bib_data {
92         my $e = shift;
93         my $ctx = shift;
94
95         if(!$ctx->{copy}) {
96
97                 if($ctx->{copy_id}) {
98                         $ctx->{copy} = $e->retrieve_asset_copy($ctx->{copy_id})
99                                 or return $e->event;
100
101                 } elsif( $ctx->{copy_barcode} ) {
102
103                         my $cps = $e->search_asset_copy({barcode => $ctx->{copy_barcode}});
104                         return $e->event unless @$cps;
105                         $ctx->{copy} = $$cps[0];
106                 }
107         }
108
109         return undef unless my $copy = $ctx->{copy};
110
111         # --------------------------------------------------------------------
112         # Fetch/Cache the copy status and location objects
113         # --------------------------------------------------------------------
114         if(!@COPY_STATUSES) {
115                 my $s = $e->retrieve_all_config_copy_status();
116                 @COPY_STATUSES = @$s;
117                 $s = $e->retrieve_all_asset_copy_location();
118                 @COPY_LOCATIONS = @$s;
119         }
120
121         # Flesh the status and location
122         $copy->status( 
123                 grep { $_->id == $copy->status } @COPY_STATUSES ) 
124                 unless ref $copy->status;
125
126         $copy->location( 
127                 grep { $_->id == $copy->location } @COPY_LOCATIONS ) 
128                 unless ref $copy->location;
129
130         $copy->circ_lib( 
131                 $e->retrieve_actor_org_unit($copy->circ_lib)) 
132                 unless ref $copy->circ_lib;
133
134         $ctx->{volume} = $e->retrieve_asset_call_number(
135                 $ctx->{copy}->call_number) or return $e->event;
136
137         $ctx->{title} = $e->retrieve_biblio_record_entry(
138                 $ctx->{volume}->record) or return $e->event;
139
140         if(!$ctx->{titleDescriptor}) {
141                 $ctx->{titleDescriptor} = $e->search_metabib_record_descriptor( 
142                         { record => $ctx->{title}->id }) or return $e->event;
143
144                 $ctx->{titleDescriptor} = $ctx->{titleDescriptor}->[0];
145         }
146
147         #insert_copy_method();  
148
149         return undef;
150 }
151
152
153
154 sub fetch_user_data {
155         my( $e, $ctx ) = @_;
156         
157         if(!$ctx->{patron}) {
158
159                 if( $ctx->{patron_id} ) {
160                         $ctx->{patron} = $e->retrieve_actor_user($ctx->{patron_id});
161
162                 } elsif( $ctx->{patron_barcode} ) {
163
164                         my $card = $e->search_actor_card( 
165                                 { barcode => $ctx->{patron_barcode} } ) or return $e->event;
166
167                         $ctx->{patron} = $e->search_actor_user( 
168                                 { card => $card->[0]->id }) or return $e->event;
169                         $ctx->{patron} = $ctx->{patron}->[0];
170                 }
171         }
172
173         return undef unless my $patron = $ctx->{patron};
174
175         $patron->home_ou( 
176                 $e->retrieve_actor_org_unit($patron->home_ou) ) 
177                 unless ref $patron->home_ou;
178
179         $patron->home_ou->ou_type(
180                 $patron->home_ou->ou_type->id) 
181                 if ref $patron->home_ou->ou_type;
182
183         if(!%GROUP_SET) {
184                 $GROUP_TREE = $e->search_permission_grp_tree(
185                         [
186                                 { parent => undef }, 
187                                 { 
188                                         flesh => 100,
189                                         flesh_fields => { pgt => ['children'] }
190                                 } 
191                         ]
192                 )->[0];
193
194                 flatten_groups($GROUP_TREE);
195         }
196
197         $patron->profile( $GROUP_SET{$patron->profile} )
198                 unless ref $patron->profile;
199
200         $patron->card($e->retrieve_actor_card($patron->card));
201
202         $ctx->{requestor} = $ctx->{requestor} || $e->requestor;
203
204         # this could alter the requestor object within the editor..
205         #if( my $req = $ctx->{requestor} ) {
206         #       $req->home_ou( $e->retrieve_actor_org_unit($requestor->home_ou) );      
207         #       $req->ws_ou( $e->retrieve_actor_org_unit($requestor->ws_ou) );  
208         #}
209
210         if( $ctx->{fetch_patron_circ_info} ) {
211
212                 my $circ_counts = 
213                         OpenILS::Application::Actor::_checked_out(1, $e, $patron->id);
214
215                 $ctx->{patronOverdue} = $circ_counts->{overdue} || 0;
216                 $ctx->{patronItemsOut} = $ctx->{patronOverdue} + $circ_counts->{out};
217
218                 # Grab the fines
219                 my $fxacts = $e->search_money_open_billable_transaction_summary(
220                         { usr => $patron->id, balance_owed => { ">" => 0 } });
221
222                 my $fines = 0;
223                 $fines += $_->balance_owed for @$fxacts;
224                 $ctx->{patronFines} = $fines;
225
226                 $logger->debug("script_builder: patron fines determined to be $fines");
227                 $logger->debug("script_builder: patron overdue count is " . $ctx->{patronOverdue});
228         }
229
230         return undef;
231 }
232
233
234 sub flatten_groups {
235         my $tree = shift;
236         return undef unless $tree;
237         $GROUP_SET{$tree->id} = $tree;
238         if( $tree->children ) {
239                 flatten_groups($_) for @{$tree->children};
240         }
241 }
242
243 sub flatten_org_tree {
244         my $tree = shift;
245         return undef unless $tree;
246         push( @ORG_LIST, $tree );
247         if( $tree->children ) {
248                 flatten_org_tree($_) for @{$tree->children};
249         }
250 }
251
252
253
254 sub insert_org_methods {
255         my ( $editor, $ctx ) = @_;
256         my $runner = $ctx->{runner};
257
258         if(!$ORG_TREE) {
259                 $ORG_TREE = $editor->search_actor_org_unit(
260                         [
261                                 {"parent_ou" => undef },
262                                 {
263                                         flesh                           => 2,
264                                         flesh_fields    => { aou =>  ['children'] },
265                                         order_by                        => { aou => 'name'}
266                                 }
267                         ]
268                 )->[0];
269                 flatten_org_tree($ORG_TREE);
270         }
271
272         $runner->insert(__OILS_FUNC_isOrgDescendent  => 
273                 sub {
274                         my( $write_key, $sname, $id ) = @_;
275                         my ($parent)    = grep { $_->shortname eq $sname } @ORG_LIST;
276                         my ($child)             = grep { $_->id == $id } @ORG_LIST;
277                         my $val = is_org_descendent( $parent, $child );
278                         $runner->insert($write_key, $val);
279                         return $val;
280                 }
281         );
282 }
283
284
285 sub is_org_descendent {
286         my( $parent, $child ) = @_;
287         return 0 unless $parent and $child;
288         do {
289                 return 1 if $parent->id == $child->id;
290         } while( ($child) = grep { $_->id == $child->parent_ou } @ORG_LIST );
291         return 0;
292 }
293
294
295
296 #       if( $ctx->{copy} ) {
297 #               
298 #               # allows a script to fetch a hold that is currently targeting the
299 #               # copy in question
300 #               $runner->insert_method( 'environment.copy', '__OILS_FUNC_fetch_hold', sub {
301 #                               my $key = shift;
302 #                               my $hold = $holdcode->fetch_related_holds($ctx->{copy}->id);
303 #                               $hold = undef unless $hold;
304 #                               $runner->insert( $key, $hold, 1 );
305 #                       }
306 #               );
307 #       }
308
309
310
311 1;