Dictionary now working
[koha.git] / reports / guided_reports.pl
1 #!/usr/bin/perl
2
3 # Copyright 2007 Liblime ltd
4 #
5 # This file is part of Koha.
6 #
7 # Koha is free software; you can redistribute it and/or modify it under the
8 # terms of the GNU General Public License as published by the Free Software
9 # Foundation; either version 2 of the License, or (at your option) any later
10 # version.
11 #
12 # Koha is distributed in the hope that it will be useful, but WITHOUT ANY
13 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
14 # A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License along with
17 # Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
18 # Suite 330, Boston, MA  02111-1307 USA
19 use CGI::Carp qw(fatalsToBrowser);
20 use strict;
21 use C4::Auth;
22 use CGI;
23 use C4::Output;
24 use C4::Reports;
25
26 =head1 NAME
27
28 Script to control the guided report creation
29
30 =head1 DESCRIPTION
31
32
33 =over2
34
35 =cut
36
37 my $input = new CGI;
38 my ( $template, $borrowernumber, $cookie ) = get_template_and_user(
39     {
40         template_name   => "reports/guided_reports_start.tmpl",
41         query           => $input,
42         type            => "intranet",
43         authnotrequired => 0,
44         flagsrequired   => { editcatalogue => 1 },
45         debug           => 1,
46     }
47 );
48
49 my $phase = $input->param('phase');
50 my $no_html = 0; # this will be set if we dont want to print out an html::template
51
52 if ( !$phase ) {
53     $template->param( 'start' => 1 );
54
55     # show welcome page
56 }
57
58 elsif ( $phase eq 'Build new' ) {
59
60     # build a new report
61     $template->param( 'build1' => 1 );
62
63     # get report areas
64     my $areas = C4::Reports::get_report_areas();
65     $template->param( 'areas' => $areas );
66
67 }
68
69 elsif ( $phase eq 'Used saved' ) {
70
71     # use a saved report
72     # get list of reports and display them
73     $template->param( 'saved1' => 1 );
74     my $reports = get_saved_reports();
75     $template->param( 'savedreports' => $reports );
76 }
77
78 elsif ( $phase eq 'Report on this Area' ) {
79
80     # they have choosen a new report and the area to report on
81     # get area
82     my $area = $input->param('areas');
83     $template->param(
84         'build2' => 1,
85         'area'   => $area
86     );
87
88     # get report types
89     my $types = C4::Reports::get_report_types();
90     $template->param( 'types' => $types );
91 }
92
93 elsif ( $phase eq 'Choose this type' ) {
94
95     # they have chosen type and area
96     # get area and type and pass them to the template
97     my $area = $input->param('area');
98     my $type = $input->param('types');
99     $template->param(
100         'build3' => 1,
101         'area'   => $area,
102         'type'   => $type,
103     );
104
105     # get columns
106     my $columns = get_columns($area);
107     $template->param( 'columns' => $columns );
108 }
109
110 elsif ( $phase eq 'Choose these columns' ) {
111
112     # we now know type, area, and columns
113     # next step is the constraints
114     my $area    = $input->param('area');
115     my $type    = $input->param('type');
116     my @columns = $input->param('columns');
117     my $column  = join( ',', @columns );
118     $template->param(
119         'build4' => 1,
120         'area'   => $area,
121         'type'   => $type,
122         'column' => $column,
123     );
124     my $criteria = get_criteria($area);
125     $template->param( 'criteria' => $criteria );
126 }
127
128 elsif ( $phase eq 'Choose these criteria' ) {
129     my $area     = $input->param('area');
130     my $type     = $input->param('type');
131     my $column   = $input->param('column');
132     my @criteria = $input->param('criteria_column');
133         my $query_criteria;
134     foreach my $crit (@criteria) {
135         my $value = $input->param( $crit . "_value" );
136         if ($value) {
137             $query_criteria .= " AND $crit='$value'";
138         }
139     }
140
141     $template->param(
142         'build5'         => 1,
143         'area'           => $area,
144         'type'           => $type,
145         'column'         => $column,
146         'criteriastring' => $query_criteria,
147     );
148
149     # get columns
150     my @columns = split( ',', $column );
151     my @total_by;
152
153     # build structue for use by tmpl_loop to choose columns to order by
154     # need to do something about the order of the order :)
155         # we also want to use the %columns hash to get the plain english names
156     foreach my $col (@columns) {
157         my %total;
158         $total{'name'} = $col;
159         my @selects;
160         my %select1;
161         $select1{'value'} = 'sum';
162         push @selects, \%select1;
163         my %select2;
164         $select2{'value'} = 'min';
165         push @selects, \%select2;
166         my %select3;
167         $select3{'value'} = 'max';
168         push @selects, \%select3;
169         my %select4;
170         $select4{'value'} = 'avg';
171         push @selects, \%select4;
172         my %select5;
173         $select5{'value'} = 'count';
174         push @selects, \%select5;
175
176         $total{'select'} = \@selects;
177         push @total_by, \%total;
178     }
179
180     $template->param( 'total_by' => \@total_by );
181 }
182
183 elsif ( $phase eq 'Choose Totals' ) {
184     my $area     = $input->param('area');
185     my $type     = $input->param('type');
186     my $column   = $input->param('column');
187     my $criteria = $input->param('criteria');
188     my @total_by = $input->param('total_by');
189     my $totals;
190     foreach my $total (@total_by) {
191         my $value = $input->param( $total . "_tvalue" );
192         $totals .= "$value($total),";
193     }
194
195     $template->param(
196         'build6'         => 1,
197         'area'           => $area,
198         'type'           => $type,
199         'column'         => $column,
200         'criteriastring' => $criteria,
201         'totals'         => $totals,
202     );
203
204     # get columns
205     my @columns = split( ',', $column );
206     my @order_by;
207
208     # build structue for use by tmpl_loop to choose columns to order by
209     # need to do something about the order of the order :)
210     foreach my $col (@columns) {
211         my %order;
212         $order{'name'} = $col;
213         my @selects;
214         my %select1;
215         $select1{'value'} = 'asc';
216         push @selects, \%select1;
217         my %select2;
218         $select2{'value'} = 'desc';
219         push @selects, \%select2;
220         $order{'select'} = \@selects;
221         push @order_by, \%order;
222     }
223
224     $template->param( 'order_by' => \@order_by );
225 }
226
227 elsif ( $phase eq 'Build Report' ) {
228
229     # now we have all the info we need and can build the sql
230     my $area     = $input->param('area');
231     my $type     = $input->param('type');
232     my $column   = $input->param('column');
233     my $crit     = $input->param('criteria');
234     my $totals   = $input->param('totals');
235 #    my @criteria = split( ',', $crit );
236     my $query_criteria=$crit;
237     # split the columns up by ,
238     my @columns = split( ',', $column );
239     my @order_by = $input->param('order_by');
240
241     my $query_orderby;
242     foreach my $order (@order_by) {
243         my $value = $input->param( $order . "_ovalue" );
244         if ($query_orderby) {
245             $query_orderby .= ",$order $value";
246         }
247         else {
248             $query_orderby = " ORDER BY $order $value";
249         }
250     }
251
252     # get the sql
253     my $sql =
254       build_query( \@columns, $query_criteria, $query_orderby, $area, $totals );
255     $template->param(
256         'showreport' => 1,
257         'sql'        => $sql,
258         'type'       => $type
259     );
260 }
261
262 elsif ( $phase eq 'Save' ) {
263         # Save the report that has just been built
264     my $sql  = $input->param('sql');
265     my $type = $input->param('type');
266     $template->param(
267         'save' => 1,
268         'sql'  => $sql,
269         'type' => $type
270     );
271 }
272
273 elsif ( $phase eq 'Save Report' ) {
274     # save the sql pasted in by a user 
275     my $sql  = $input->param('sql');
276     my $name = $input->param('reportname');
277     my $type = $input->param('type');
278         my $notes = $input->param('notes');
279     save_report( $sql, $name, $type, $notes );
280 }
281
282 elsif ( $phase eq 'Execute' ) {
283         # run the sql, and output results in a template 
284     my $sql     = $input->param('sql');
285     my $type    = $input->param('type');
286     my $results = execute_query($sql,$type);
287     $template->param(
288         'results' => $results,
289                 'sql' => $sql,
290         'execute' => 1
291     );
292 }
293
294 elsif ($phase eq 'Run this report'){
295     # execute a saved report
296         my $report = $input->param('reports');
297         my ($sql,$type) = get_saved_report($report);
298         my $results = execute_query($sql,$type);
299     $template->param(
300         'results' => $results,
301                 'sql' => $sql,
302         'execute' => 1
303     );
304 }       
305
306 elsif ($phase eq 'Export'){
307         # export results to tab separated text
308         my $sql     = $input->param('sql');
309         $no_html=1;
310         print $input->header(   -type => 'application/octet-stream',
311                   -attachment=>'reportresults.csv');
312         my $format=$input->param('format');
313         my $results = execute_query($sql,1,$format);
314         print $results;
315         
316 }
317
318 elsif ($phase eq 'Create report from SQL'){
319         # alllow the user to paste in sql 
320         $template->param('create' => 1);
321          my $types = C4::Reports::get_report_types();
322         $template->param( 'types' => $types ); 
323 }
324
325 elsif ($phase eq 'Create Compound Report'){
326         my $reports = get_saved_reports();  
327         $template->param( 'savedreports' => $reports,
328                 'compound' => 1,
329         );
330 }
331
332 elsif ($phase eq 'Save Compound'){
333     my $master = $input->param('master');
334         my $subreport = $input->param('subreport');
335 #       my $compound_report = create_compound($master,$subreport);
336 #       my $results = run_compound($compound_report);
337         my ($mastertables,$subtables) = create_compound($master,$subreport);
338         $template->param( 'save_compound' => 1,
339                 master=>$mastertables,
340                 subsql=>$subtables
341         );
342 }
343
344 elsif ($phase eq 'View Dictionary'){
345         # view the dictionary we use to set up abstract variables such as all borrowers over fifty who live in a certain town
346         ( $template, $borrowernumber, $cookie ) = get_template_and_user(
347     {
348         template_name   => "reports/dictionary.tmpl",
349         query           => $input,
350         type            => "intranet",
351         authnotrequired => 0,
352         flagsrequired   => { editcatalogue => 1 },
353         debug           => 1,
354     }
355         );
356         my $areas = C4::Reports::get_report_areas();
357         my $definitions = get_from_dictionary();
358         $template->param( 'areas' => $areas ,
359                 'start_dictionary' => 1,
360                 'definitions' => $definitions,
361         );
362 }
363 elsif ($phase eq 'Add New Definition'){
364         # display form allowing them to add a new definition
365         ( $template, $borrowernumber, $cookie ) = get_template_and_user(
366     {
367         template_name   => "reports/dictionary.tmpl",
368         query           => $input,
369         type            => "intranet",
370         authnotrequired => 0,
371         flagsrequired   => { editcatalogue => 1 },
372         debug           => 1,
373     }
374         );
375
376         $template->param( 'new_dictionary' => 1,
377                 );
378 }
379
380 elsif ($phase eq 'New Term step 2'){
381         # Choosing the area
382         ( $template, $borrowernumber, $cookie ) = get_template_and_user(
383     {
384         template_name   => "reports/dictionary.tmpl",
385         query           => $input,
386         type            => "intranet",
387         authnotrequired => 0,
388         flagsrequired   => { editcatalogue => 1 },
389         debug           => 1,
390     }
391         );
392         my $areas = C4::Reports::get_report_areas();
393         my $definition_name=$input->param('definition_name');
394         my $definition_description=$input->param('definition_description');             
395         $template->param( 'step_2' => 1,
396                 'areas' => $areas,
397                 'definition_name' => $definition_name,
398                 'definition_description' => $definition_description,
399         );
400 }
401
402 elsif ($phase eq 'New Term step 3'){
403         # Choosing the columns
404         ( $template, $borrowernumber, $cookie ) = get_template_and_user(
405     {
406         template_name   => "reports/dictionary.tmpl",
407         query           => $input,
408         type            => "intranet",
409         authnotrequired => 0,
410         flagsrequired   => { editcatalogue => 1 },
411         debug           => 1,
412     }
413         );
414         my $area = $input->param('areas');
415         my $columns = get_columns($area);
416         my $definition_name=$input->param('definition_name');
417         my $definition_description=$input->param('definition_description');             
418         $template->param( 'step_3' => 1,
419                 'area' => $area,
420                 'columns' => $columns,
421                 'definition_name' => $definition_name,
422                 'definition_description' => $definition_description,
423         );
424 }
425
426 elsif ($phase eq 'New Term step 4'){
427         # Choosing the values
428         ( $template, $borrowernumber, $cookie ) = get_template_and_user(
429     {
430         template_name   => "reports/dictionary.tmpl",
431         query           => $input,
432         type            => "intranet",
433         authnotrequired => 0,
434         flagsrequired   => { editcatalogue => 1 },
435         debug           => 1,
436     }
437         );
438         my $area=$input->param('area');
439         my $definition_name=$input->param('definition_name');
440         my $definition_description=$input->param('definition_description');             
441     my @columns = $input->param('columns');
442         my $columnstring = join (',',@columns);
443         my @column_loop;
444         foreach my $column (@columns){
445                 my %tmp_hash;
446                 $tmp_hash{'name'}=$column;
447                 my $type =get_column_type($column);
448                 if ($type eq 'distinct'){
449                         my $values = get_distinct_values($column);
450                         $tmp_hash{'values'} = $values;
451                         $tmp_hash{'distinct'} = 1;
452                           
453                 }
454                 if ($type eq 'DATE'){
455                         $tmp_hash{'date'}=1;
456                 }
457 #               else {
458 #                       die $type;#
459 #                       }
460                 push @column_loop,\%tmp_hash;
461                 }
462
463         $template->param( 'step_4' => 1,
464                 'area' => $area,
465                 'definition_name' => $definition_name,
466                 'definition_description' => $definition_description,
467                 'columns' => \@column_loop,
468                 'columnstring' => $columnstring,
469
470         );
471 }
472
473 elsif ($phase eq 'New Term step 5'){
474         # Confirmation screen
475         ( $template, $borrowernumber, $cookie ) = get_template_and_user(
476     {
477         template_name   => "reports/dictionary.tmpl",
478         query           => $input,
479         type            => "intranet",
480         authnotrequired => 0,
481         flagsrequired   => { editcatalogue => 1 },
482         debug           => 1,
483     }
484         );
485         my $area = $input->param('area');
486         my $columnstring = $input->param('columnstring');
487         my $definition_name=$input->param('definition_name');
488         my $definition_description=$input->param('definition_description');     
489         my @criteria = $input->param('criteria_column'); 
490         my $query_criteria;
491         my @criteria_loop;
492         foreach my $crit (@criteria) {
493                 my $value = $input->param( $crit . "_value" );
494                 if ($value) {
495                         $query_criteria .= " AND $crit='$value'";
496                         my %tmp_hash;
497                         $tmp_hash{'name'}=$crit;
498                         $tmp_hash{'value'} = $value;
499                         push @criteria_loop,\%tmp_hash;
500                 }
501                 
502                 $value = $input->param( $crit . "_start_value" );
503                 if ($value) {
504                         $query_criteria .= " AND $crit > '$value'";
505                         my %tmp_hash;
506                         $tmp_hash{'name'}="$crit Start";
507                         $tmp_hash{'value'} = $value;
508                         push @criteria_loop,\%tmp_hash;
509                 }
510                 $value = $input->param( $crit . "_end_value" );
511                 if ($value) {
512                         $query_criteria .= " AND $crit <= '$value'";
513                         my %tmp_hash;
514                         $tmp_hash{'name'}="$crit End";
515                         $tmp_hash{'value'} = $value;
516                         push @criteria_loop,\%tmp_hash;
517                 }                 
518         }
519         $template->param( 'step_5' => 1,
520                 'area' => $area,
521                 'definition_name' => $definition_name,
522                 'definition_description' => $definition_description,
523                 'query' => $query_criteria,
524                 'columnstring' => $columnstring,
525                 'criteria_loop' => \@criteria_loop,
526         );
527 }
528
529 elsif ($phase eq 'New Term step 6'){
530         # Choosing the columns
531         ( $template, $borrowernumber, $cookie ) = get_template_and_user(
532     {
533         template_name   => "reports/dictionary.tmpl",
534         query           => $input,
535         type            => "intranet",
536         authnotrequired => 0,
537         flagsrequired   => { editcatalogue => 1 },
538         debug           => 1,
539     }
540         );
541         my $area = $input->param('area');
542         my $definition_name=$input->param('definition_name');
543         my $definition_description=$input->param('definition_description');             
544         my $sql=$input->param('sql');
545         save_dictionary($definition_name,$definition_description,$sql,$area);
546         $template->param( 'step_6' => 1,
547                 'area' => $area,
548                 'definition_name' => $definition_name,
549                 'definition_description' => $definition_description,
550         );
551 }
552 elsif ($phase eq 'Delete Definition'){
553         $no_html=1;
554         my $id = $input->param('id');
555         delete_definition($id);
556         print $input->redirect("/cgi-bin/koha/reports/guided_reports.pl?phase=View%20Dictionary");
557         }
558
559 if (!$no_html){
560         output_html_with_http_headers $input, $cookie, $template->output;
561 }