FIX for Date calculation
[koha.git] / reports / acquisitions_stats.pl
1 #!/usr/bin/perl
2
3 # $Id$
4
5 # Copyright 2000-2002 Katipo Communications
6 #
7 # This file is part of Koha.
8 #
9 # Koha is free software; you can redistribute it and/or modify it under the
10 # terms of the GNU General Public License as published by the Free Software
11 # Foundation; either version 2 of the License, or (at your option) any later
12 # version.
13 #
14 # Koha is distributed in the hope that it will be useful, but WITHOUT ANY
15 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
16 # A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
17 #
18 # You should have received a copy of the GNU General Public License along with
19 # Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
20 # Suite 330, Boston, MA  02111-1307 USA
21
22 # test comment
23
24 use strict;
25 use C4::Auth;
26 use CGI;
27 use C4::Context;
28
29 use C4::Output;
30 use C4::Koha;
31 use C4::Circulation;
32 use C4::Date;
33
34 =head1 NAME
35
36 plugin that shows a stats on borrowers
37
38 =head1 DESCRIPTION
39
40 =over 2
41
42 =cut
43
44 my $input          = new CGI;
45 my $do_it          = $input->param('do_it');
46 my $fullreportname = "reports/acquisitions_stats.tmpl";
47 my $line           = $input->param("Line");
48 my $column         = $input->param("Column");
49 my @filters        = $input->param("Filter");
50 $filters[0]=format_date_in_iso($filters[0]);
51 $filters[1]=format_date_in_iso($filters[1]);
52 $filters[2]=format_date_in_iso($filters[2]);
53 $filters[3]=format_date_in_iso($filters[3]);
54 my $podsp          = $input->param("PlacedOnDisplay");
55 my $rodsp          = $input->param("ReceivedOnDisplay");
56 my $aodsp          = $input->param("AcquiredOnDisplay");    ##added by mason.
57 my $calc           = $input->param("Cellvalue");
58 my $output         = $input->param("output");
59 my $basename       = $input->param("basename");
60 my $mime           = $input->param("MIME");
61 my $del            = $input->param("sep");
62
63 #warn "calcul : ".$calc;
64 my ($template, $borrowernumber, $cookie)
65         = get_template_and_user({template_name => $fullreportname,
66                                 query => $input,
67                                 type => "intranet",
68                                 authnotrequired => 0,
69                                 flagsrequired => {reports => 1},
70                                 debug => 1,
71                                 });
72 $template->param(do_it => $do_it,
73         DHTMLcalendar_dateformat => get_date_format_string_for_DHTMLcalendar(),
74                 );
75 if ($do_it) {
76
77     #warn
78 "line=$line, col=$column, pod=$podsp, rod=$rodsp, aod=$aodsp, calc=$calc, filters=@filters\n";
79
80     my $results =
81       calculate( $line, $column, $podsp, $rodsp, $aodsp, $calc, \@filters );
82     if ( $output eq "screen" ) {
83         $template->param( mainloop => $results );
84         output_html_with_http_headers $input, $cookie, $template->output;
85         exit(1);
86     }
87     else {
88         print $input->header(
89             -type       => 'application/vnd.sun.xml.calc',
90             -encoding    => 'utf-8',
91             -attachment => "$basename.csv",
92             -name       => "$basename.csv"
93         );
94         my $cols  = @$results[0]->{loopcol};
95         my $lines = @$results[0]->{looprow};
96         my $sep;
97         $sep = C4::Context->preference("delimiter");
98         print @$results[0]->{line} . "/" . @$results[0]->{column} . $sep;
99         foreach my $col (@$cols) {
100             print $col->{coltitle} . $sep;
101         }
102         print "Total\n";
103         foreach my $line (@$lines) {
104             my $x = $line->{loopcell};
105             print $line->{rowtitle} . $sep;
106             foreach my $cell (@$x) {
107                 print $cell->{value} . $sep;
108             }
109             print $line->{totalrow};
110             print "\n";
111         }
112         print "TOTAL";
113         $cols = @$results[0]->{loopfooter};
114         foreach my $col (@$cols) {
115             print $sep. $col->{totalcol};
116         }
117         print $sep. @$results[0]->{total};
118         exit(1);
119     }
120 }
121 else {
122     my $dbh = C4::Context->dbh;
123     my @values;
124     my %labels;
125     my %select;
126     my $req;
127     $req =
128       $dbh->prepare(
129         "SELECT distinctrow id,name FROM aqbooksellers ORDER BY name");
130     $req->execute;
131     my @select;
132     push @select, "";
133
134     #       $select{""}="";
135     while ( my ( $value, $desc ) = $req->fetchrow ) {
136         push @select, $desc;
137
138         #               $select{$value}=$desc;
139     }
140     my $CGIBookSellers = CGI::scrolling_list(
141         -name   => 'Filter',
142         -id     => 'supplier',
143         -values => \@select,
144
145         #                               -labels   => \%select,
146         -size     => 1,
147         -multiple => 0
148     );
149
150     $req =
151       $dbh->prepare(
152 "SELECT DISTINCTROW itemtype,description FROM itemtypes ORDER BY description"
153       );
154     $req->execute;
155     undef @select;
156     undef %select;
157     push @select, "";
158     $select{""} = "";
159     while ( my ( $value, $desc ) = $req->fetchrow ) {
160         push @select, $value;
161         $select{$value} = $desc;
162     }
163     my $CGIItemTypes = CGI::scrolling_list(
164         -name     => 'Filter',
165         -id       => 'itemtypes',
166         -values   => \@select,
167         -labels   => \%select,
168         -size     => 1,
169         -multiple => 0
170     );
171
172     $req =
173       $dbh->prepare(
174 "SELECT DISTINCTROW bookfundid,bookfundname FROM aqbookfund ORDER BY bookfundname"
175       );
176     $req->execute;
177     undef @select;
178     undef %select;
179     push @select, "";
180     $select{""} = "";
181
182     while ( my ( $value, $desc ) = $req->fetchrow ) {
183         push @select, $value;
184         $select{$value} = $desc;
185     }
186     my $CGIBudget = CGI::scrolling_list(
187         -name     => 'Filter',
188         -id       => 'budget',
189         -values   => \@select,
190         -labels   => \%select,
191         -size     => 1,
192         -multiple => 0
193     );
194
195     $req =
196       $dbh->prepare(
197 "SELECT DISTINCTROW sort1 FROM aqorders WHERE sort1 IS NOT NULL ORDER BY sort1"
198       );
199     $req->execute;
200     undef @select;
201     push @select, "";
202     my $hassort1;
203     while ( my ($value) = $req->fetchrow ) {
204         $hassort1 = 1 if ($value);
205         push @select, $value;
206     }
207     my $CGISort1 = CGI::scrolling_list(
208         -name     => 'Filter',
209         -id       => 'sort1',
210         -values   => \@select,
211         -size     => 1,
212         -multiple => 0
213     );
214
215     $req =
216       $dbh->prepare(
217 "SELECT DISTINCTROW sort2 FROM aqorders WHERE sort2 IS NOT NULL ORDER BY sort2"
218       );
219     $req->execute;
220     undef @select;
221     push @select, "";
222     my $hassort2;
223     my $hglghtsort2;
224
225     while ( my ($value) = $req->fetchrow ) {
226         $hassort2 = 1 if ($value);
227         $hglghtsort2 = !($hassort1);
228         push @select, $value;
229     }
230     my $CGISort2 = CGI::scrolling_list(
231         -name     => 'Filter',
232         -id       => 'sort2',
233         -values   => \@select,
234         -size     => 1,
235         -multiple => 0
236     );
237
238     my @mime = ( C4::Context->preference("MIME") );
239     foreach my $mime (@mime) {
240
241         #               warn "".$mime;
242     }
243
244     my $CGIextChoice = CGI::scrolling_list(
245         -name     => 'MIME',
246         -id       => 'MIME',
247         -values   => \@mime,
248         -size     => 1,
249         -multiple => 0
250     );
251
252     my @dels         = ( C4::Context->preference("delimiter") );
253     my $CGIsepChoice = CGI::scrolling_list(
254         -name     => 'sep',
255         -id       => 'sep',
256         -values   => \@dels,
257         -size     => 1,
258         -multiple => 0
259     );
260
261     $template->param(
262         CGIBookSeller => $CGIBookSellers,
263         CGIItemType   => $CGIItemTypes,
264         CGIBudget     => $CGIBudget,
265         hassort1      => $hassort1,
266         hassort2      => $hassort2,
267         HlghtSort2    => $hglghtsort2,
268         CGISort1      => $CGISort1,
269         CGISort2      => $CGISort2,
270         CGIextChoice  => $CGIextChoice,
271         CGIsepChoice  => $CGIsepChoice
272     );
273
274 }
275 output_html_with_http_headers $input, $cookie, $template->output;
276
277 sub calculate {
278     my ( $line, $column, $podsp, $rodsp, $aodsp, $process, $filters ) = @_;
279     my @mainloop;
280     my @loopfooter;
281     my @loopcol;
282     my @loopline;
283     my @looprow;
284     my %globalline;
285     my $grantotal = 0;
286
287     # extract parameters
288     my $dbh = C4::Context->dbh;
289
290     # Filters
291     # Checking filters
292     #
293     my @loopfilter;
294     for ( my $i = 0 ; $i <= 8 ; $i++ ) {
295         my %cell;
296         if ( @$filters[$i] ) {
297             if ( ( ( $i == 1 ) or ( $i == 3 ) ) and ( @$filters[ $i - 1 ] ) ) {
298                 $cell{err} = 1 if ( @$filters[$i] < @$filters[ $i - 1 ] );
299             }
300             # format the dates filters, otherwise just fill as is
301             if ($i>=4) {
302                 $cell{filter} .= @$filters[$i];
303             } else {
304                 $cell{filter} .= format_date(@$filters[$i]);
305             }
306             $cell{crit}   .= "Placed On From" if ( $i == 0 );
307             $cell{crit}   .= "Placed On To" if ( $i == 1 );
308             $cell{crit}   .= "Received On From" if ( $i == 2 );
309             $cell{crit}   .= "Received On To" if ( $i == 3 );
310
311             $cell{crit} .= "Acquired On From" if ( $i == 4 );
312             $cell{crit} .= "Acquired On To"   if ( $i == 5 );
313
314             $cell{crit} .= "BookSeller" if ( $i == 6 );
315             $cell{crit} .= "Doc Type"   if ( $i == 7 );
316             $cell{crit} .= "Budget"     if ( $i == 8 );
317             $cell{crit} .= "Sort1"      if ( $i == 9 );
318             $cell{crit} .= "Sort2"      if ( $i == 10 );
319             push @loopfilter, \%cell;
320         }
321     }
322
323     my @linefilter;
324
325     #       warn "filtres ".@filters[0];
326     #       warn "filtres ".@filters[1];
327     #       warn "filtres ".@filters[2];
328     #       warn "filtres ".@filters[3];
329
330     $linefilter[0] = @$filters[0] if ( $line =~ /closedate/ );
331     $linefilter[1] = @$filters[1] if ( $line =~ /closedate/ );
332     $linefilter[0] = @$filters[2] if ( $line =~ /received/ );
333     $linefilter[1] = @$filters[3] if ( $line =~ /received/ );
334
335     $linefilter[0] = @$filters[4] if ( $line =~ /acquired/ );
336     $linefilter[1] = @$filters[5] if ( $line =~ /acquired/ );
337
338     $linefilter[0] = @$filters[6]  if ( $line =~ /bookseller/ );
339     $linefilter[0] = @$filters[7]  if ( $line =~ /itemtype/ );
340     $linefilter[0] = @$filters[8]  if ( $line =~ /bookfund/ );
341     $linefilter[0] = @$filters[9]  if ( $line =~ /sort1/ );
342     $linefilter[0] = @$filters[10] if ( $line =~ /sort2/ );
343
344     #warn "filtre lignes".$linefilter[0]." ".$linefilter[1];
345     #
346     my @colfilter;
347     $colfilter[0] = @$filters[0] if ( $column =~ /closedate/ );
348     $colfilter[1] = @$filters[1] if ( $column =~ /closedate/ );
349     $colfilter[0] = @$filters[2] if ( $column =~ /received/ );
350     $colfilter[1] = @$filters[3] if ( $column =~ /received/ );
351
352     $colfilter[0] = @$filters[4] if ( $column =~ /acquired/ );
353     $colfilter[1] = @$filters[5] if ( $column =~ /acquired/ );
354
355     $colfilter[0] = @$filters[6]  if ( $column =~ /bookseller/ );
356     $colfilter[0] = @$filters[7]  if ( $column =~ /itemtype/ );
357     $colfilter[0] = @$filters[8]  if ( $column =~ /bookfund/ );
358     $colfilter[0] = @$filters[9]  if ( $column =~ /sort1/ );
359     $colfilter[0] = @$filters[10] if ( $column =~ /sort2/ );
360
361     #warn "filtre col ".$colfilter[0]." ".$colfilter[1];
362
363     #warn "line=$line, podsp=$podsp, rodsp=$rodsp, aodsp=$aodsp\n";
364
365     # 1st, loop rows.
366     my $linefield;
367     if ( ( $line =~ /closedate/ ) and ( $podsp == 1 ) ) {
368
369         #Display by day
370         $linefield .= "dayname($line)";
371     }
372     elsif ( ( $line =~ /closedate/ ) and ( $podsp == 2 ) ) {
373
374         #Display by Month
375         $linefield .= "monthname($line)";
376     }
377     elsif ( ( $line =~ /closedate/ ) and ( $podsp == 3 ) ) {
378
379         #Display by Year
380         $linefield .= "Year($line)";
381
382     }
383     elsif ( ( $line =~ /received/ ) and ( $rodsp == 1 ) ) {
384
385         #Display by day
386         $linefield .= "dayname($line)";
387     }
388     elsif ( ( $line =~ /received/ ) and ( $rodsp == 2 ) ) {
389
390         #Display by Month
391         $linefield .= "monthname($line)";
392     }
393     elsif ( ( $line =~ /received/ ) and ( $rodsp == 3 ) ) {
394
395         #Display by Year
396         $linefield .= "Year($line)";
397
398     }
399     elsif ( ( $line =~ /acquired/ ) and ( $aodsp == 1 ) ) {
400
401         #Display by day
402         $linefield .= "dayname($line)";
403     }
404     elsif ( ( $line =~ /acquired/ ) and ( $aodsp == 2 ) ) {
405
406         #Display by Month
407         $linefield .= "monthname($line)";
408     }
409     elsif ( ( $line =~ /acquired/ ) and ( $aodsp == 3 ) ) {
410
411         #Display by Year
412         $linefield .= "Year($line)";
413
414     }
415     else {
416         $linefield .= $line;
417     }
418
419     my $strsth;
420     $strsth .=
421       "SELECT DISTINCTROW $linefield FROM (aqorders, aqbasket,aqorderbreakdown)
422                 LEFT JOIN items ON (aqorders.biblioitemnumber= items.biblioitemnumber)
423                 LEFT JOIN biblioitems ON (aqorders.biblioitemnumber= biblioitems.biblioitemnumber)
424                 LEFT JOIN aqorderdelivery ON (aqorders.ordernumber =aqorderdelivery.ordernumber )
425                 LEFT JOIN aqbooksellers ON (aqbasket.booksellerid=aqbooksellers.id) WHERE (aqorders.basketno=aqbasket.basketno)
426                 AND (aqorderbreakdown.ordernumber=aqorders.ordernumber) AND $line IS NOT NULL ";
427
428     if (@linefilter) {
429         if ( $linefilter[1] ) {
430             if ( $linefilter[0] ) {
431                 $strsth .= " AND $line BETWEEN ? AND ? ";
432             }
433             else {
434                 $strsth .= " AND $line < ? ";
435             }
436         }
437         elsif (
438             ( $linefilter[0] )
439             and (  ( $line =~ /closedate/ )
440                 or ( $line =~ /received/ )
441                 or ( $line =~ /acquired/ ) )
442           )
443         {
444             $strsth .= " AND $line > ? ";
445         }
446         elsif ( $linefilter[0] ) {
447             $linefilter[0] =~ s/\*/%/g;
448             $strsth .= " AND $line LIKE ? ";
449         }
450     }
451     $strsth .= " GROUP BY $linefield";
452     $strsth .= " ORDER BY $linefield";
453
454     #warn "377:strsth= $strsth";
455
456     my $sth = $dbh->prepare($strsth);
457     if ( (@linefilter) and ( $linefilter[1] ) ) {
458         $sth->execute( "'" . $linefilter[0] . "'", "'" . $linefilter[1] . "'" );
459     }
460     elsif ( $linefilter[0] ) {
461         $sth->execute( $linefilter[0] );
462     }
463     else {
464         $sth->execute;
465     }
466
467     while ( my ($celvalue) = $sth->fetchrow ) {
468         my %cell;
469         if ($celvalue) {
470             $cell{rowtitle} = $celvalue;
471
472             #               } else {
473             #                       $cell{rowtitle} = "";
474         }
475         $cell{totalrow} = 0;
476         push @loopline, \%cell;
477     }
478
479     #warn "column=$column, podsp=$podsp, rodsp=$rodsp, aodsp=$aodsp\n";
480
481     # 2nd, loop cols.
482     my $colfield;
483     if ( ( $column =~ /closedate/ ) and ( $podsp == 1 ) ) {
484
485         #Display by day
486         $colfield .= "dayname($column)";
487     }
488     elsif ( ( $column =~ /closedate/ ) and ( $podsp == 2 ) ) {
489
490         #Display by Month
491         $colfield .= "monthname($column)";
492     }
493     elsif ( ( $column =~ /closedate/ ) and ( $podsp == 3 ) ) {
494
495         #Display by Year
496         $colfield .= "Year($column)";
497
498     }
499     elsif ( ( $column =~ /deliverydate/ ) and ( $rodsp == 1 ) ) {
500
501         #Display by day
502         $colfield .= "dayname($column)";
503     }
504     elsif ( ( $column =~ /deliverydate/ ) and ( $rodsp == 2 ) ) {
505
506         #Display by Month
507         $colfield .= "monthname($column)";
508     }
509     elsif ( ( $column =~ /deliverydate/ ) and ( $rodsp == 3 ) ) {
510
511         #Display by Year
512         $colfield .= "Year($column)";
513
514     }
515     elsif ( ( $column =~ /dateaccessioned/ ) and ( $aodsp == 1 ) ) {
516
517         #Display by day
518         $colfield .= "dayname($column)";
519     }
520     elsif ( ( $column =~ /dateaccessioned/ ) and ( $aodsp == 2 ) ) {
521
522         #Display by Month
523         $colfield .= "monthname($column)";
524     }
525     elsif ( ( $column =~ /dateaccessioned/ ) and ( $aodsp == 3 ) ) {
526
527         #Display by Year
528         $colfield .= "Year($column)";
529
530     }
531     else {
532         $colfield .= $column;
533     }
534
535     my $strsth2;
536     $strsth2 .=
537       "SELECT distinctrow $colfield FROM (aqorders, aqbasket,aqorderbreakdown)
538                  LEFT JOIN items ON (aqorders.biblioitemnumber= items.biblioitemnumber)
539                  LEFT JOIN biblioitems ON (aqorders.biblioitemnumber= biblioitems.biblioitemnumber)
540                  LEFT JOIN aqorderdelivery ON (aqorders.ordernumber =aqorderdelivery.ordernumber )
541                  LEFT JOIN aqbooksellers ON (aqbasket.booksellerid=aqbooksellers.id)
542                  WHERE (aqorders.basketno=aqbasket.basketno) AND (aqorderbreakdown.ordernumber=aqorders.ordernumber)
543                  AND $column IS NOT NULL";
544
545     if (@colfilter) {
546         if ( $colfilter[1] ) {
547             if ( $colfilter[0] ) {
548                 $strsth2 .= " AND $column BETWEEN  ? AND ? ";
549             }
550             else {
551                 $strsth2 .= " AND $column < ? ";
552             }
553         }
554         elsif (
555             ( $colfilter[0] )
556             and (  ( $column =~ /closedate/ )
557                 or ( $line =~ /received/ )
558                 or ( $line =~ /acquired/ ) )
559           )
560         {
561             $strsth2 .= " AND $column > ? ";
562         }
563         elsif ( $colfilter[0] ) {
564             $colfilter[0] =~ s/\*/%/g;
565             $strsth2 .= " AND $column LIKE ? ";
566         }
567     }
568     $strsth2 .= " GROUP BY $colfield";
569     $strsth2 .= " ORDER BY $colfield";
570
571     #        warn "MASON:. $strsth2";
572
573     my $sth2 = $dbh->prepare($strsth2);
574     if ( (@colfilter) and ( $colfilter[1] ) ) {
575
576         #                warn "from : ".$colfilter[0]." To  :".$colfilter[1];
577         $sth2->execute( "'" . $colfilter[0] . "'", "'" . $colfilter[1] . "'" );
578     }
579     elsif ( $colfilter[0] ) {
580         $sth2->execute( $colfilter[0] );
581     }
582     else {
583         $sth2->execute;
584     }
585
586     while ( my ($celvalue) = $sth2->fetchrow ) {
587         my %cell;
588         if ($celvalue) {
589
590             #               warn "coltitle :".$celvalue;
591             $cell{coltitle} = $celvalue;
592         }
593         push @loopcol, \%cell;
594     }
595
596     #       warn "fin des titres colonnes";
597
598     my $i = 0;
599     my @totalcol;
600     my $hilighted = -1;
601
602     #Initialization of cell values.....
603     my %table;
604
605     #       warn "init table";
606     foreach my $row (@loopline) {
607         foreach my $col (@loopcol) {
608
609 #                       warn " init table : $row->{rowtitle} / $col->{coltitle} ";
610             $table{ $row->{rowtitle} }->{ $col->{coltitle} } = 0;
611         }
612         $table{ $row->{rowtitle} }->{totalrow} = 0;
613     }
614
615     # preparing calculation
616     my $strcalc;
617     $strcalc .= "SELECT $linefield, $colfield, ";
618     $strcalc .= "SUM( aqorders.quantity ) " if ( $process == 1 );
619     $strcalc .= "SUM( aqorders.quantity * aqorders.listprice ) "
620       if ( $process == 2 );
621     $strcalc .= "FROM (aqorders, aqbasket,aqorderbreakdown)
622                  LEFT JOIN items ON (aqorders.biblioitemnumber= items.biblioitemnumber)
623                  LEFT JOIN biblioitems ON (aqorders.biblioitemnumber= biblioitems.biblioitemnumber)
624                  LEFT JOIN aqorderdelivery ON (aqorders.ordernumber =aqorderdelivery.ordernumber )
625                  LEFT JOIN aqbooksellers ON (aqbasket.booksellerid=aqbooksellers.id) WHERE (aqorders.basketno=aqbasket.basketno)
626                       AND (aqorderbreakdown.ordernumber=aqorders.ordernumber) ";
627
628     @$filters[0] =~ s/\*/%/g if ( @$filters[0] );
629     $strcalc .= " AND aqbasket.closedate > '" . @$filters[0] . "'"
630       if ( @$filters[0] );
631     @$filters[1] =~ s/\*/%/g if ( @$filters[1] );
632     $strcalc .= " AND aqbasket.closedate < '" . @$filters[1] . "'"
633       if ( @$filters[1] );
634     @$filters[2] =~ s/\*/%/g if ( @$filters[2] );
635     $strcalc .= " AND aqorderdelivery.deliverydate > '" . @$filters[2] . "'"
636       if ( @$filters[2] );
637     @$filters[3] =~ s/\*/%/g if ( @$filters[3] );
638     $strcalc .= " AND aqorderdelivery.deliverydate < '" . @$filters[3] . "'"
639       if ( @$filters[3] );
640     @$filters[4] =~ s/\*/%/g if ( @$filters[4] );
641     $strcalc .= " AND aqbasket.closedate > '" . @$filters[4] . "'"
642       if ( @$filters[4] );
643     @$filters[5] =~ s/\*/%/g if ( @$filters[5] );
644     $strcalc .= " AND aqbasket.closedate < '" . @$filters[5] . "'"
645       if ( @$filters[5] );
646     @$filters[6] =~ s/\*/%/g if ( @$filters[6] );
647     $strcalc .= " AND aqbooksellers.name LIKE '" . @$filters[6] . "'"
648       if ( @$filters[6] );
649     @$filters[7] =~ s/\*/%/g if ( @$filters[7] );
650     $strcalc .= " AND biblioitems.itemtype LIKE '" . @$filters[7] . "'"
651       if ( @$filters[7] );
652     @$filters[8] =~ s/\*/%/g if ( @$filters[8] );
653     $strcalc .= " AND aqbookfund.bookfundid LIKE '" . @$filters[8] . "'"
654       if ( @$filters[8] );
655     @$filters[9] =~ s/\*/%/g if ( @$filters[9] );
656     $strcalc .= " AND aqorders.sort1 LIKE '" . @$filters[9] . "'"
657       if ( @$filters[9] );
658     @$filters[10] =~ s/\*/%/g if ( @$filters[10] );
659     $strcalc .= " AND aqorders.sort2 LIKE '" . @$filters[10] . "'"
660       if ( @$filters[10] );
661     $strcalc .= " GROUP BY $linefield, $colfield ORDER BY $linefield,$colfield";
662
663     #        warn "/n/n". $strcalc;
664     my $dbcalc = $dbh->prepare($strcalc);
665     $dbcalc->execute;
666
667     #       warn "filling table";
668     my $emptycol;
669     while ( my ( $row, $col, $value ) = $dbcalc->fetchrow ) {
670
671         #              warn "filling table $row / $col / $value ";
672         $emptycol = 1         if ( $col eq undef );
673         $col      = "zzEMPTY" if ( $col eq undef );
674         $row      = "zzEMPTY" if ( $row eq undef );
675
676         $table{$row}->{$col}     += $value;
677         $table{$row}->{totalrow} += $value;
678         $grantotal               += $value;
679     }
680
681     push @loopcol, { coltitle => "NULL" } if ($emptycol);
682
683     foreach my $row ( sort keys %table ) {
684         my @loopcell;
685
686         #@loopcol ensures the order for columns is common with column titles
687         # and the number matches the number of columns
688         foreach my $col (@loopcol) {
689             my $value = $table{$row}->{
690                 ( $col->{coltitle} eq "NULL" )
691                 ? "zzEMPTY"
692                 : $col->{coltitle}
693               };
694             push @loopcell, { value => $value };
695         }
696         push @looprow,
697           {
698             'rowtitle' => ( $row eq "zzEMPTY" ) ? "NULL" : $row,
699             'loopcell'  => \@loopcell,
700             'hilighted' => ( $hilighted > 0 ),
701             'totalrow'  => $table{$row}->{totalrow}
702           };
703         $hilighted = -$hilighted;
704     }
705
706     #       warn "footer processing";
707     foreach my $col (@loopcol) {
708         my $total = 0;
709         foreach my $row (@looprow) {
710             $total += $table{
711                 ( $row->{rowtitle} eq "NULL" ) ? "zzEMPTY"
712                 : $row->{rowtitle}
713               }->{
714                 ( $col->{coltitle} eq "NULL" ) ? "zzEMPTY"
715                 : $col->{coltitle}
716               };
717
718 #                       warn "value added ".$table{$row->{rowtitle}}->{$col->{coltitle}}. "for line ".$row->{rowtitle};
719         }
720
721         #               warn "summ for column ".$col->{coltitle}."  = ".$total;
722         push @loopfooter, { 'totalcol' => $total };
723     }
724
725     # the header of the table
726     #        $globalline{loopfilter}=\@loopfilter;
727     # the core of the table
728     $globalline{looprow} = \@looprow;
729     $globalline{loopcol} = \@loopcol;
730
731     #       # the foot (totals by borrower type)
732     $globalline{loopfooter} = \@loopfooter;
733     $globalline{total}      = $grantotal;
734     $globalline{line}       = $line;
735     $globalline{column}     = $column;
736     push @mainloop, \%globalline;
737     return \@mainloop;
738 }
739
740 1;
741