Bug 7955: Followup : Check the syspref value (avoid sql injection)
[koha.git] / members / statistics.pl
1 #!/usr/bin/perl
2
3 # Copyright 2012 BibLibre
4 # This file is part of Koha.
5 #
6 # Koha is free software; you can redistribute it and/or modify it under the
7 # terms of the GNU General Public License as published by the Free Software
8 # Foundation; either version 2 of the License, or (at your option) any later
9 # version.
10 #
11 # Koha is distributed in the hope that it will be useful, but WITHOUT ANY
12 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
13 # A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License along with
16 # Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
17 # Suite 330, Boston, MA  02111-1307 USA
18
19
20 =head1 members/statistics.pl
21   Generate statistic issues for a member
22 =cut
23
24 use Modern::Perl;
25
26 use CGI;
27 use C4::Auth;
28 use C4::Branch;
29 use C4::Context;
30 use C4::Members;
31 use C4::Members::Statistics;
32 use C4::Output;
33
34 my $input = new CGI;
35
36 my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
37     {   template_name   => "members/statistics.tmpl",
38         query           => $input,
39         type            => "intranet",
40         authnotrequired => 0,
41         flagsrequired   => { borrowers => 1 },
42         debug           => 1,
43     }
44 );
45
46 my $borrowernumber = $input->param('borrowernumber');
47
48 # Set informations for the patron
49 my $borrower = GetMemberDetails( $borrowernumber, 0 );
50 if ( not defined $borrower ) {
51     $template->param (unknowuser => 1);
52     output_html_with_http_headers $input, $cookie, $template->output;
53     exit;
54 }
55
56 foreach my $key ( keys %$borrower ) {
57     $template->param( $key => $borrower->{$key} );
58 }
59
60 # Construct column names
61 my $fields = C4::Members::Statistics::get_fields();
62 our @statistic_column_names = split '\|', $fields;
63 our @value_column_names = ( 'count_precedent_state', 'count_total_issues_today', 'count_total_issues_returned_today' );
64 our @column_names = ( @statistic_column_names, @value_column_names );
65
66 # Get statistics
67 my $precedent_state = GetPrecedentStateByBorrower( $borrowernumber );
68 my $total_issues_today = GetTotalIssuesTodayByBorrower( $borrowernumber );
69 my $total_issues_returned_today = GetTotalIssuesReturnedTodayByBorrower( $borrowernumber );
70 my $r = merge (
71     @$precedent_state, @$total_issues_today, @$total_issues_returned_today
72 );
73
74 add_actual_state( $r );
75 my ( $total, $datas ) = build_array( $r );
76
77 # Gettings sums
78 my $count_total_precedent_state = $total->{count_precedent_state} || 0;
79 my $count_total_issues = $total->{count_total_issues_today} || 0;
80 my $count_total_issues_returned = $total->{count_total_issues_returned_today} || 0;
81 my $count_total_actual_state = ($count_total_precedent_state - $count_total_issues_returned + $count_total_issues);
82
83 $template->param(
84     statisticsview => 1,
85     datas          => $datas,
86     column_names   => \@statistic_column_names,
87     length_keys    => scalar( @statistic_column_names),
88     count_total_issues => $count_total_issues,
89     count_total_issues_returned => $count_total_issues_returned,
90     count_total_precedent_state => $count_total_precedent_state,
91     count_total_actual_state => $count_total_actual_state,
92 );
93
94 output_html_with_http_headers $input, $cookie, $template->output;
95
96
97 =head1 FUNCTIONS
98
99 =head2 add_actual_state
100   Add a 'count_actual_state' key in all hashes
101   count_actual_state = count_precedent_state - count_total_issues_returned_today + count_total_issues_today
102 =cut
103 sub add_actual_state {
104     my ( $array ) = @_;
105     for my $hash ( @$array ) {
106         $hash->{count_actual_state} = ( $hash->{count_precedent_state} // 0 ) - ( $hash->{count_total_issues_returned_today} // 0 ) + ( $hash->{count_total_issues_today} // 0 );
107     }
108 }
109
110 =head2 build_array
111   Build a new array containing values of hashes.
112   It used by template whitch display silly values.
113   ex:
114     $array = [
115       {
116         'count_total_issues_returned_today' => 1,
117         'ccode' => 'ccode',
118         'count_actual_state' => 1,
119         'count_precedent_state' => 1,
120         'homebranch' => 'homebranch',
121         'count_total_issues_today' => 1,
122         'itype' => 'itype'
123       }
124     ];
125   and returns:
126     [
127       [
128         'homebranch',
129         'itype',
130         'ccode',
131         1,
132         1,
133         1,
134         1
135       ]
136     ];
137
138 =cut
139 sub build_array {
140     my ( $array ) = @_;
141     my ( @r, $total );
142     for my $hash ( @$array) {
143         my @line;
144         for my $cn ( ( @column_names, 'count_actual_state') ) {
145             if ( grep /$cn/, ( @value_column_names, 'count_actual_state') ) {
146                 $hash->{$cn} //= 0;
147                 if ( exists $total->{$cn} ) {
148                     $total->{$cn} += $hash->{$cn} if $hash->{$cn};
149                 } else {
150                     $total->{$cn} = $hash->{$cn};
151                 }
152             }
153             push @line, $hash->{$cn};
154         }
155         push @r, \@line;
156     }
157     return ( $total, \@r );
158 }
159
160 =head2 merge
161   Merge hashes with the same statistic column names into one
162   param: array, a arrayref of arrayrefs
163   ex:
164   @array = (
165      {
166        'ccode' => 'ccode',
167        'count_precedent_state' => '1',
168        'homebranch' => 'homebranch',
169        'itype' => 'itype'
170      },
171      {
172        'count_total_issues_returned_today' => '1',
173        'ccode' => 'ccode',
174        'homebranch' => 'homebranch',
175        'itype' => 'itype'
176      }
177    );
178    and returns:
179    [
180      {
181        'count_total_issues_returned_today' => '1',
182        'ccode' => 'ccode',
183        'count_precedent_state' => '1',
184        'homebranch' => 'homebranch',
185        'itype' => 'itype'
186      }
187    ];
188
189 =cut
190 sub merge {
191     my @array = @_;
192     my @r;
193     for my $h ( @array ) {
194         my $exists = 0;
195         for my $ch ( @r ) {
196             $exists = 1;
197             for my $cn ( @statistic_column_names ) {
198                 if ( $ch->{$cn} and not $ch->{$cn} eq $h->{$cn} ) {
199                     $exists = 0;
200                     last;
201                 }
202             }
203             if ($exists){
204                 for my $cn ( @value_column_names ) {
205                     next if not exists $h->{$cn};
206                     $ch->{$cn} = $h->{$cn} ? $h->{$cn} : 0;
207                 }
208                 last;
209             }
210         }
211
212         if ( not $exists ) {push @r, $h;}
213     }
214     return \@r;
215 }