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