b324ac29b1b39b98bb6279b6f4ba65aebebdddce
[working/Evergreen.git] / Open-ILS / src / perlmods / lib / OpenILS / Utils / Configure.pm
1 package OpenILS::Utils::Configure;
2
3 use strict;
4 use warnings;
5 use File::Spec;
6 use OpenILS::Utils::Cronscript;
7
8 sub fieldmapper {
9     my $web = shift;
10
11     my $core = OpenILS::Utils::Cronscript->new({nolockfile => 1});
12     $core->bootstrap;
13
14     my $output;
15     my $map = $Fieldmapper::fieldmap;
16
17     # if a true value is provided, we generate the web (light) version of the fieldmapper
18     if(!$web) { $web = ""; }
19
20     my @web_core = qw/ 
21         aou au perm_ex ex aout 
22         mvr ccs ahr aua ac actscecm cbreb acpl 
23         cbrebi acpn acp acnn acn bren asc asce 
24         clfm cifm citm cam ahtc
25         asv asva asvr asvq 
26         circ ccs ahn bre mrd
27         crcd crmf crrf mbts aoc aus 
28         mous mobts mb ancc cnct cnal
29         /;
30
31     my @reports = qw/ perm_ex ex ao aou aout /;
32
33
34     $output = "var _c = {};\n";
35
36     for my $object (keys %$map) {
37
38         my $hint = $map->{$object}->{hint};
39
40         if($web eq "web_core") {
41             next unless (grep { $_ eq $hint } @web_core );
42         }
43
44         if($web eq "reports") {
45             next unless (grep { $_ eq $hint } @web_core );
46         }
47
48
49         my $short_name = $map->{$object}->{hint};
50
51         my @fields;
52         for my $field (keys %{$map->{$object}->{fields}}) {
53             my $position = $map->{$object}->{fields}->{$field}->{position};
54             $fields[$position] = $field;
55         }
56
57         $output .= "_c[\"$short_name\"] = [";
58         for my $f (@fields) { 
59             next unless $f;
60             if( $f ne "isnew" and $f ne "ischanged" and $f ne "isdeleted" ) {
61                 $output .= "\"$f\","; 
62             }
63         }
64         $output .= "];\n";
65
66
67     }
68
69     $output .= "var fmclasses = _c;\n";
70     return $output;
71 }
72
73 sub org_tree_js {
74     # ------------------------------------------------------------
75     # turns the orgTree and orgTypes into js files
76     # ------------------------------------------------------------
77     use OpenSRF::Utils::Cache;
78
79     my $path = shift;
80     my $filename = shift;
81
82     my $core = OpenILS::Utils::Cronscript->new({nolockfile => 1});
83     $core->bootstrap;
84
85     # must be loaded after the IDL is parsed
86     require OpenILS::Utils::CStoreEditor;
87
88     # Get our list of locales
89     my $locales = get_locales();
90
91     foreach my $locale (@$locales) {
92         warn "removing OrgTree from the cache for locale " . $locale->code . "...\n";
93         my $cache = OpenSRF::Utils::Cache->new;
94         $cache->delete_cache("orgtree.$locale->code");
95
96         # fetch the org_unit's and org_unit_type's
97         my $e = OpenILS::Utils::CStoreEditor->new;
98         $e->init();
99         $e->session->session_locale($locale->code) if ($locale->code);
100
101         my $types = $e->retrieve_all_actor_org_unit_type;
102         my $tree = $e->request(
103             'open-ils.cstore.direct.actor.org_unit.search.atomic',
104             {id => {"!=" => undef}},
105             {order_by => {aou => 'name'}, no_i18n => $locale->code ? 0 : 1 }
106         );
107         my $dir = File::Spec->catdir($path, $locale->code);
108         if (!-d $dir) {
109             mkdir($dir);
110         }
111         build_tree_js($types, $tree, File::Spec->catfile($dir, $filename));
112     }
113 }
114
115 sub val {
116     my $v = shift;
117     return 'null' unless defined $v;
118
119     # required for JS code this is checking truthness 
120     # without using isTrue() (1/0 vs. t/f)
121     return 1 if $v eq 't';
122     return 0 if $v eq 'f';
123
124     $v =~ s/([\x{0080}-\x{fffd}])/sprintf('\u%04x',ord($1))/sgoe;
125
126     return "\"$v\"";
127 }
128
129 sub build_tree_js {
130     my $types = shift;
131     my $tree = shift;
132     my $outfile = shift;
133
134     my $pile = "var _l = [";
135
136     my @array;
137     for my $o (@$tree) {
138         my ($i,$t,$p,$n,$v,$s) = ($o->id,$o->ou_type,$o->parent_ou,val($o->name),val($o->opac_visible),val($o->shortname));
139         $p ||= 'null';
140         push @array, "[$i,$t,$p,$n,$v,$s]";
141     }
142
143     $pile .= join ',', @array;
144     $pile .= "]; /* Org Units */ \n";
145
146     $pile .= 'var globalOrgTypes = [';
147     for my $t (@$types) {
148         my ($u,$v,$d,$i,$n,$o,$p) = (val($t->can_have_users),val($t->can_have_vols),$t->depth,$t->id,val($t->name),val($t->opac_label),$t->parent);
149         $p ||= 'null';
150         $pile .= "new aout([null,$u,$v,$d,$i,$n,$o,$p]), ";
151     }
152     $pile =~ s/, $//; # remove trailing comma
153     $pile .= ']; /* OU Types */';
154
155     open(OUTFH, '>', $outfile) or die "Could not open $outfile : $!";
156     print OUTFH "$pile\n";
157     close(OUTFH);
158 }
159
160 sub org_tree_html_options {
161     # for each supported locale, turn the orgTree and orgTypes into a static HTML option list
162
163     use Unicode::Normalize;
164     use Data::Dumper;
165
166     my $path = shift;
167     my $filename = shift; 
168
169     my @types;
170
171     my $core = OpenILS::Utils::Cronscript->new({nolockfile => 1});
172     $core->bootstrap;
173
174     my $locales = get_locales();
175
176     foreach my $locale (@$locales) {
177         my $ses = OpenSRF::AppSession->create("open-ils.actor");
178         $ses->session_locale($locale->code);
179         my $tree = $ses->request("open-ils.actor.org_tree.retrieve")->gather(1);
180
181         my $aout = $ses->request("open-ils.actor.org_types.retrieve")->gather(1);
182         foreach my $type (@$aout) {
183             $types[int($type->id)] = $type;
184         }
185         my $dir = File::Spec->catdir($path, $locale->code);
186         if (!-d $dir) {
187             mkdir($dir) or die "Could not create output directory: $dir $!\n";
188         }
189
190         my @org_tree_html;
191         print_org_tree_html($tree, \@org_tree_html, \@types);
192         $ses->disconnect();
193
194         open(OUTFH, '>', File::Spec->catfile($dir, $filename)) or die $!;
195         print OUTFH @org_tree_html;
196         close OUTFH;
197     }
198
199 }
200
201 sub print_org_tree_html {
202         my $node = shift;
203         my $org_tree_html = shift;
204     my $types = shift;
205
206         return unless ($node->opac_visible =~ /^[y1t]+/i);
207
208         my $depth = $types->[$node->ou_type]->depth;
209         my $sname = OpenILS::Application::AppUtils->entityize($node->shortname);
210         my $name = OpenILS::Application::AppUtils->entityize($node->name);
211         my $kids = $node->children;
212
213         push @$org_tree_html, "<option value='$sname'>" . '&#160;&#160;&#160;'x$depth . "$name</option>\n";
214         print_org_tree_html($_, $org_tree_html, $types) for (@$kids);
215 }
216
217 sub org_lasso {
218     # Renders a JavaScript version of the org unit search groups
219     
220     my $core = OpenILS::Utils::Cronscript->new({nolockfile => 1});
221     $core->bootstrap;
222
223     # must be loaded after the IDL is parsed
224     require OpenILS::Utils::CStoreEditor;
225
226     my $output;
227
228     # fetch the org_unit's and org_unit_type's
229     my $e = OpenILS::Utils::CStoreEditor->new;
230     $e->init();
231     my $lassos = $e->request(
232         'open-ils.cstore.direct.actor.org_lasso.search.atomic',
233         {id => {"!=" => undef}},
234         {order_by => {lasso => 'name'}}
235     );
236
237     # We need at least one defined search group; otherwise, just generate an empty array
238     if (scalar(@$lassos) > 0) {
239        $output =  
240             "var _lasso = [\n  new lasso(" .
241             join( "),\n  new lasso(", map { OpenSRF::Utils::JSON->perl2JSON( bless($_, 'ARRAY') ) } @$lassos ) .
242             ")\n]; /* Org Search Groups (Lassos) */ \n";
243     } else {
244         $output = <<HERE;
245 var _lasso = [
246 ]; /* Org Search Groups (Lassos) */
247 HERE
248     }
249
250     return $output;
251 }
252
253 sub locale_html_options {
254     # Turns supported locales into a static HTML option list
255     my $locales = get_locales();
256
257         my $output = "<select name='locale'>\n";
258         foreach my $locale (@$locales) {
259                 my $code = OpenILS::Application::AppUtils->entityize($locale->code);
260                 my $name = OpenILS::Application::AppUtils->entityize($locale->name);
261                 $output .= "  <option value='$code'>$name</option>\n";
262         }
263         $output .= "</select>\n";
264
265     return $output;
266 }
267
268 sub facet_types {
269     # ------------------------------------------------------------
270     # turns the facet fields defined on config.metabib_field into JS
271     # ------------------------------------------------------------
272
273     my $path = shift;
274     my $filename = shift;
275     # Get our list of locales
276     my $locales = get_locales();
277
278     foreach my $locale (@$locales) {
279         warn "removing facet list from the cache for locale " . $locale->code . "...\n";
280         my $cache = OpenSRF::Utils::Cache->new;
281         $cache->delete_cache("facet_definition.".$locale->code);
282
283         # fetch the org_unit's and org_unit_type's
284         my $e = OpenILS::Utils::CStoreEditor->new;
285         $e->init();
286         $e->session->session_locale($locale->code) if ($locale->code);
287
288         my $types = $e->retrieve_all_actor_org_unit_type;
289         my $tree = $e->request(
290             'open-ils.cstore.direct.config.metabib_field.search.atomic',
291             {   facet_field     => 't' },
292             {   no_i18n         => $locale->code ? 0 : 1,
293                 flesh           => 1,
294                 flesh_fields    => { cmf => [ 'field_class' ] }
295             }
296         );
297         my $dir = File::Spec->catdir($path, $locale->code);
298         if (!-d $dir) {
299             mkdir($dir);
300         }
301         build_facet_type_js($tree, File::Spec->catfile($dir, $filename));
302     }
303 }
304
305 sub build_facet_type_js {
306     my $tree = shift;
307     my $outfile = shift;
308
309     my $pile = "var globalFacets = {";
310     my @array;
311     for my $o (@$tree) {
312         my %hash = (
313             id          => $o->id,
314             name        => val($o->name),
315             label       => val($o->label),
316             classname   => val($o->field_class->name),
317             classlabel  => val($o->field_class->label)
318         );
319
320         $pile .= $hash{id}.':{'.join(',', map { "$_:$hash{$_}" } keys %hash).'},';
321     }
322
323     $pile =~ s/,$//; # remove trailing comma
324     $pile .= "}; /* Facets */";
325
326     open(OUTFH, '>', $outfile) or die "Could not open $outfile : $!";
327     print OUTFH "$pile\n";
328     close(OUTFH);
329 }
330
331 sub org_tree_proximity {
332     # calculate the proximity of organizations in the organization tree
333
334     my $session = OpenILS::Utils::Cronscript->new({nolockfile => 1})->session('open-ils.storage');
335     my $result = $session->request("open-ils.storage.actor.org_unit.refresh_proximity");
336
337     if ($result) {
338         print "Successfully updated the organization proximity\n";
339     } else {
340         print "Failed to update the organization proximity\n";
341     }
342     $session->disconnect();
343 }
344
345 sub get_locales {
346     # Get our list of locales
347     my $session = OpenILS::Utils::Cronscript->new({nolockfile => 1})->session("open-ils.cstore");
348     my $locales = $session->request(
349         "open-ils.cstore.direct.config.i18n_locale.search.atomic",
350         {"code" => {"!=" => undef}},
351         {"order_by" => {"i18n_l" => "name"}}
352     )->gather();
353     $session->disconnect();
354
355     return $locales;
356 }
357
358 1;