MT 2360 : Adds address, city and zipcode to overdues csv export
[koha.git] / circ / overdue.pl
1 #!/usr/bin/perl
2
3
4 # Copyright 2000-2002 Katipo Communications
5 #
6 # This file is part of Koha.
7 #
8 # Koha is free software; you can redistribute it and/or modify it under the
9 # terms of the GNU General Public License as published by the Free Software
10 # Foundation; either version 2 of the License, or (at your option) any later
11 # version.
12 #
13 # Koha is distributed in the hope that it will be useful, but WITHOUT ANY
14 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
15 # A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
16 #
17 # You should have received a copy of the GNU General Public License along with
18 # Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
19 # Suite 330, Boston, MA  02111-1307 USA
20
21 use strict;
22 # use warnings; # FIXME
23 use C4::Context;
24 use C4::Output;
25 use CGI;
26 use C4::Auth;
27 use C4::Branch;
28 use C4::Dates qw/format_date/;
29 use Date::Calc qw/Today/;
30 use Text::CSV_XS;
31
32 my $input = new CGI;
33 my $order   = $input->param( 'order' ) || '';
34 my $showall = $input->param('showall');
35
36 my  $bornamefilter = $input->param( 'borname');
37 my   $borcatfilter = $input->param( 'borcat' );
38 my $itemtypefilter = $input->param('itemtype');
39 my $borflagsfilter = $input->param('borflags') || "";
40 my   $branchfilter = $input->param( 'branch' );
41 my $op             = $input->param(   'op'   ) || '';
42
43 my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
44     {
45         template_name   => "circ/overdue.tmpl",
46         query           => $input,
47         type            => "intranet",
48         authnotrequired => 0,
49         flagsrequired   => { reports => 1, circulate => "circulate_remaining_permissions" },
50         debug           => 1,
51     }
52 );
53
54 my $dbh = C4::Context->dbh;
55
56 my $req;
57 $req = $dbh->prepare( "select categorycode, description from categories order by description");
58 $req->execute;
59 my @borcatloop;
60 while (my ($catcode, $description) =$req->fetchrow) {
61     push @borcatloop, {
62         value    => $catcode,
63         selected => $catcode eq $borcatfilter ? 1 : 0,
64         catname  => $description,
65     };
66 }
67
68 $req = $dbh->prepare( "select itemtype, description from itemtypes order by description");
69 $req->execute;
70 my @itemtypeloop;
71 while (my ($itemtype, $description) =$req->fetchrow) {
72     push @itemtypeloop, {
73         value        => $itemtype,
74         selected     => $itemtype eq $itemtypefilter ? 1 : 0,
75         itemtypename => $description,
76     };
77 }
78 my $onlymine=C4::Context->preference('IndependantBranches') && 
79              C4::Context->userenv && 
80              C4::Context->userenv->{flags}!=1 && 
81              C4::Context->userenv->{branch};
82
83 $branchfilter = C4::Context->userenv->{'branch'} if ($onlymine && !$branchfilter);
84
85 $template->param(
86     branchloop   => GetBranchesLoop($branchfilter, $onlymine),
87     branchfilter => $branchfilter,
88     borcatloop   => \@borcatloop,
89     itemtypeloop => \@itemtypeloop,
90     borname      => $bornamefilter,
91     order        => $order,
92     showall      => $showall,
93     csv_param_string => $input->query_string(),
94 );
95
96 my @sort_roots = qw(borrower title barcode date_due);
97 push @sort_roots, map {$_ . " desc"} @sort_roots;
98 my @order_loop = ({selected => $order ? 0 : 1});   # initial blank row
99 foreach (@sort_roots) {
100     my $tmpl_name = $_;
101     $tmpl_name =~ s/\s/_/g;
102     push @order_loop, {
103         selected => $order eq $_ ? 1 : 0,
104         ordervalue => $_,
105         foo => $tmpl_name,
106         'order_' . $tmpl_name => 1,
107     };
108 }
109 $template->param(ORDER_LOOP => \@order_loop);
110
111 my $todaysdate = sprintf("%-04.4d-%-02.2d-%02.2d", Today());
112
113 $bornamefilter =~s/\*/\%/g;
114 $bornamefilter =~s/\?/\_/g;
115
116 my $strsth="SELECT date_due,
117   concat(surname,' ', firstname) as borrower, 
118   borrowers.address,
119   borrowers.city,
120   borrowers.zipcode,
121   borrowers.phone,
122   borrowers.email,
123   issues.itemnumber,
124   items.barcode,
125   biblio.title,
126   biblio.author,
127   borrowers.borrowernumber,
128   biblio.biblionumber,
129   borrowers.branchcode 
130   FROM issues
131 LEFT JOIN borrowers   ON (issues.borrowernumber=borrowers.borrowernumber )
132 LEFT JOIN items       ON (issues.itemnumber=items.itemnumber)
133 LEFT JOIN biblioitems ON (biblioitems.biblioitemnumber=items.biblioitemnumber)
134 LEFT JOIN biblio      ON (biblio.biblionumber=items.biblionumber )
135 WHERE 1=1 "; # placeholder, since it is possible that none of the additional
136              # conditions will be selected by user
137 $strsth.=" AND date_due               < NOW() " unless ($showall);
138 $strsth.=" AND (borrowers.firstname like '".$bornamefilter."%' or borrowers.surname like '".$bornamefilter."%' or borrowers.cardnumber like '".$bornamefilter."%')" if($bornamefilter) ;
139 $strsth.=" AND borrowers.categorycode = '" . $borcatfilter   . "' " if $borcatfilter;
140 $strsth.=" AND biblioitems.itemtype   = '" . $itemtypefilter . "' " if $itemtypefilter;
141 $strsth.=" AND borrowers.flags        = '" . $borflagsfilter . "' " if $borflagsfilter;
142 $strsth.=" AND borrowers.branchcode   = '" . $branchfilter   . "' " if $branchfilter;
143 $strsth.=" ORDER BY " . (
144     ($order eq "borrower" or $order eq "borrower desc") ? "$order, date_due"                 : 
145     ($order eq "title"    or $order eq    "title desc") ? "$order, date_due, borrower"       :
146     ($order eq "barcode"  or $order eq  "barcode desc") ? "items.$order, date_due, borrower" :
147                             ($order eq "date_due desc") ? "date_due DESC, borrower"          :
148                                                           "date_due, borrower"  # default sort order
149 );
150 $template->param(sql=>$strsth);
151 my $sth=$dbh->prepare($strsth);
152 #warn "overdue.pl : query string ".$strsth;
153 $sth->execute();
154
155 my @overduedata;
156 while (my $data=$sth->fetchrow_hashref) {
157     push @overduedata, {
158         duedate        => format_date($data->{date_due}),
159         borrowernumber => $data->{borrowernumber},
160         barcode        => $data->{barcode},
161         itemnum        => $data->{itemnumber},
162         name           => $data->{borrower},
163         address        => $data->{address},
164         city           => $data->{city},
165         zipcode        => $data->{zipcode},
166         phone          => $data->{phone},
167         email          => $data->{email},
168         biblionumber   => $data->{biblionumber},
169         title          => $data->{title},
170         author         => $data->{author},
171         branchcode     => $data->{branchcode},
172     };
173 }
174
175 $template->param(
176     todaysdate  => format_date($todaysdate),
177     overdueloop => \@overduedata
178 );
179
180 # download the complete CSV
181 if ($op eq 'csv') {
182         binmode(STDOUT, ":utf8");
183         my $csv = build_csv(\@overduedata);
184         print $input->header(-type => 'application/vnd.sun.xml.calc',
185                              -encoding    => 'utf-8',
186                              -attachment=>"overdues.csv",
187                              -filename=>"overdues.csv" );
188         print $csv;
189         exit;
190 }
191
192 output_html_with_http_headers $input, $cookie, $template->output;
193
194
195 sub build_csv {
196     my $overdues = shift;
197
198     return "" if scalar(@$overdues) == 0;
199
200     my @lines = ();
201
202     # build header ...
203     my @keys = sort keys %{ $overdues->[0] };
204     my $csv = Text::CSV_XS->new({
205         sep_char => C4::Context->preference("delimiter") ? 
206                     C4::Context->preference("delimiter") : ';' ,
207     });
208     $csv->combine(@keys);
209     push @lines, $csv->string();
210
211     # ... and rest of report
212     foreach my $overdue ( @{ $overdues } ) {
213         push @lines, $csv->string() if $csv->combine(map { $overdue->{$_} } @keys);
214     }
215
216     return join("\n", @lines) . "\n";
217 }