Can now view sql, and reports run page shows name
[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 warningsToBrowser);
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 $referer = $input->referer();
39 my ( $template, $borrowernumber, $cookie ) = get_template_and_user(
40     {
41         template_name   => "reports/guided_reports_start.tmpl",
42         query           => $input,
43         type            => "intranet",
44         authnotrequired => 0,
45         flagsrequired   => { editcatalogue => 1 },
46         debug           => 1,
47     }
48 );
49
50 my $phase = $input->param('phase');
51 my $no_html = 0; # this will be set if we dont want to print out an html::template
52
53 if ( !$phase ) {
54     $template->param( 'start' => 1 );
55
56     # show welcome page
57 }
58
59 elsif ( $phase eq 'Build new' ) {
60
61     # build a new report
62     $template->param( 'build1' => 1 );
63
64     # get report areas
65     my $areas = C4::Reports::get_report_areas();
66     $template->param( 'areas' => $areas );
67
68 }
69
70 elsif ( $phase eq 'Used saved' ) {
71
72     # use a saved report
73     # get list of reports and display them
74     $template->param( 'saved1' => 1 );
75     my $reports = get_saved_reports();
76     $template->param( 'savedreports' => $reports );
77 }
78
79 elsif ( $phase eq 'Delete Saved') {
80         
81         # delete a report from the saved reports list
82         $no_html = 1;
83         my $id = $input->param('reports');
84         delete_report($id);
85     print $input->redirect("/cgi-bin/koha/reports/guided_reports.pl?phase=Used%20saved");
86         
87 }               
88
89 elsif ( $phase eq 'Show SQL'){
90         
91         my $id = $input->param('reports');
92         my $sql = get_sql($id);
93         $template->param(
94                 'sql' => $sql,
95                 'showsql' => 1,
96                 );
97 }
98
99 elsif ($phase eq 'retrieve results') {
100         my $id = $input->param('id');
101         my $results = format_results($id);
102         # do something
103         $template->param(
104                 'retresults' => 1,
105                 'results' => $results,
106                 );
107         
108 }
109
110 elsif ( $phase eq 'Report on this Area' ) {
111
112     # they have choosen a new report and the area to report on
113     # get area
114     my $area = $input->param('areas');
115     $template->param(
116         'build2' => 1,
117         'area'   => $area
118     );
119
120     # get report types
121     my $types = C4::Reports::get_report_types();
122     $template->param( 'types' => $types );
123 }
124
125 elsif ( $phase eq 'Choose this type' ) {
126
127     # they have chosen type and area
128     # get area and type and pass them to the template
129     my $area = $input->param('area');
130     my $type = $input->param('types');
131     $template->param(
132         'build3' => 1,
133         'area'   => $area,
134         'type'   => $type,
135     );
136
137     # get columns
138     my $columns = get_columns($area);
139     $template->param( 'columns' => $columns );
140 }
141
142 elsif ( $phase eq 'Choose these columns' ) {
143
144     # we now know type, area, and columns
145     # next step is the constraints
146     my $area    = $input->param('area');
147     my $type    = $input->param('type');
148     my @columns = $input->param('columns');
149     my $column  = join( ',', @columns );
150         my $definitions = get_from_dictionary($area);
151     $template->param(
152         'build4' => 1,
153         'area'   => $area,
154         'type'   => $type,
155         'column' => $column,
156     );
157     my $criteria = get_criteria($area);
158     $template->param( 'criteria' => $criteria,
159         'definitions' => $definitions);
160 }
161
162 elsif ( $phase eq 'Choose these criteria' ) {
163     my $area     = $input->param('area');
164     my $type     = $input->param('type');
165     my $column   = $input->param('column');
166         my @definitions = $input->param('definition');
167         my $definition = join (',',@definitions);
168     my @criteria = $input->param('criteria_column');
169         my $query_criteria;
170     foreach my $crit (@criteria) {
171         my $value = $input->param( $crit . "_value" );
172         if ($value) {
173             $query_criteria .= " AND $crit='$value'";
174         }
175     }
176
177     $template->param(
178         'build5'         => 1,
179         'area'           => $area,
180         'type'           => $type,
181         'column'         => $column,
182                 'definition'     => $definition,
183         'criteriastring' => $query_criteria,
184     );
185
186     # get columns
187     my @columns = split( ',', $column );
188     my @total_by;
189
190     # build structue for use by tmpl_loop to choose columns to order by
191     # need to do something about the order of the order :)
192         # we also want to use the %columns hash to get the plain english names
193     foreach my $col (@columns) {
194         my %total;
195         $total{'name'} = $col;
196         my @selects;
197         my %select1;
198         $select1{'value'} = 'sum';
199         push @selects, \%select1;
200         my %select2;
201         $select2{'value'} = 'min';
202         push @selects, \%select2;
203         my %select3;
204         $select3{'value'} = 'max';
205         push @selects, \%select3;
206         my %select4;
207         $select4{'value'} = 'avg';
208         push @selects, \%select4;
209         my %select5;
210         $select5{'value'} = 'count';
211         push @selects, \%select5;
212
213         $total{'select'} = \@selects;
214         push @total_by, \%total;
215     }
216
217     $template->param( 'total_by' => \@total_by );
218 }
219
220 elsif ( $phase eq 'Choose These Operations' ) {
221     my $area     = $input->param('area');
222     my $type     = $input->param('type');
223     my $column   = $input->param('column');
224     my $criteria = $input->param('criteria');
225         my $definition = $input->param('definition');
226     my @total_by = $input->param('total_by');
227     my $totals;
228     foreach my $total (@total_by) {
229         my $value = $input->param( $total . "_tvalue" );
230         $totals .= "$value($total),";
231     }
232
233     $template->param(
234         'build6'         => 1,
235         'area'           => $area,
236         'type'           => $type,
237         'column'         => $column,
238         'criteriastring' => $criteria,
239         'totals'         => $totals,
240                 'definition'    => $definition,
241     );
242
243     # get columns
244     my @columns = split( ',', $column );
245     my @order_by;
246
247     # build structue for use by tmpl_loop to choose columns to order by
248     # need to do something about the order of the order :)
249     foreach my $col (@columns) {
250         my %order;
251         $order{'name'} = $col;
252         my @selects;
253         my %select1;
254         $select1{'value'} = 'asc';
255         push @selects, \%select1;
256         my %select2;
257         $select2{'value'} = 'desc';
258         push @selects, \%select2;
259         $order{'select'} = \@selects;
260         push @order_by, \%order;
261     }
262
263     $template->param( 'order_by' => \@order_by );
264 }
265
266 elsif ( $phase eq 'Build Report' ) {
267
268     # now we have all the info we need and can build the sql
269     my $area     = $input->param('area');
270     my $type     = $input->param('type');
271     my $column   = $input->param('column');
272     my $crit     = $input->param('criteria');
273     my $totals   = $input->param('totals');
274         my $definition = $input->param('definition');
275 #    my @criteria = split( ',', $crit );
276     my $query_criteria=$crit;
277     # split the columns up by ,
278     my @columns = split( ',', $column );
279     my @order_by = $input->param('order_by');
280
281     my $query_orderby;
282     foreach my $order (@order_by) {
283         my $value = $input->param( $order . "_ovalue" );
284         if ($query_orderby) {
285             $query_orderby .= ",$order $value";
286         }
287         else {
288             $query_orderby = " ORDER BY $order $value";
289         }
290     }
291
292     # get the sql
293     my $sql =
294       build_query( \@columns, $query_criteria, $query_orderby, $area, $totals, $definition );
295     $template->param(
296         'showreport' => 1,
297         'sql'        => $sql,
298         'type'       => $type
299     );
300 }
301
302 elsif ( $phase eq 'Save' ) {
303         # Save the report that has just been built
304     my $sql  = $input->param('sql');
305     my $type = $input->param('type');
306     $template->param(
307         'save' => 1,
308         'sql'  => $sql,
309         'type' => $type
310     );
311 }
312
313 elsif ( $phase eq 'Save Report' ) {
314     # save the sql pasted in by a user 
315     my $sql  = $input->param('sql');
316     my $name = $input->param('reportname');
317     my $type = $input->param('type');
318         my $notes = $input->param('notes');
319     save_report( $sql, $name, $type, $notes );
320 }
321
322 elsif ( $phase eq 'Execute' ) {
323         # run the sql, and output results in a template 
324     my $sql     = $input->param('sql');
325     my $type    = $input->param('type');
326     my $results = execute_query($sql,$type);
327     $template->param(
328         'results' => $results,
329                 'sql' => $sql,
330         'execute' => 1
331     );
332 }
333
334 elsif ($phase eq 'Run this report'){
335     # execute a saved report
336         my $report = $input->param('reports');
337         my ($sql,$type,$name,$notes) = get_saved_report($report);
338         my $results = execute_query($sql,$type);
339     $template->param(
340         'results' => $results,
341                 'sql' => $sql,
342         'execute' => 1,
343                 'name' => $name,
344                 'notes' => $notes,
345     );
346 }       
347
348 elsif ($phase eq 'Export'){
349         # export results to tab separated text
350         my $sql     = $input->param('sql');
351         $no_html=1;
352         print $input->header(   -type => 'application/octet-stream',
353                   -attachment=>'reportresults.csv');
354         my $format=$input->param('format');
355         my $results = execute_query($sql,1,$format);
356         print $results;
357         
358 }
359
360 elsif ($phase eq 'Create report from SQL'){
361         # alllow the user to paste in sql 
362         $template->param('create' => 1);
363          my $types = C4::Reports::get_report_types();
364         $template->param( 'types' => $types ); 
365 }
366
367 elsif ($phase eq 'Create Compound Report'){
368         my $reports = get_saved_reports();  
369         $template->param( 'savedreports' => $reports,
370                 'compound' => 1,
371         );
372 }
373
374 elsif ($phase eq 'Save Compound'){
375     my $master = $input->param('master');
376         my $subreport = $input->param('subreport');
377 #       my $compound_report = create_compound($master,$subreport);
378 #       my $results = run_compound($compound_report);
379         my ($mastertables,$subtables) = create_compound($master,$subreport);
380         $template->param( 'save_compound' => 1,
381                 master=>$mastertables,
382                 subsql=>$subtables
383         );
384 }
385
386
387 $template->param( 'referer' => $referer );
388
389
390 if (!$no_html){
391         output_html_with_http_headers $input, $cookie, $template->output;
392 }