X-Git-Url: http://koha-dev.rot13.org:8081/gitweb/?a=blobdiff_plain;f=circ%2Foverdue.pl;h=b8ed200b527787ac19d2bfd99307733c98f102b2;hb=9d6d641d1f8b77271800f43bc027b651f9aea52b;hp=56e0941081af3be160549fc0356d6283783a0502;hpb=1ee7f449be2ba45c2458d2ac571172ecf58752b2;p=srvgit diff --git a/circ/overdue.pl b/circ/overdue.pl index 56e0941081..b8ed200b52 100755 --- a/circ/overdue.pl +++ b/circ/overdue.pl @@ -6,65 +6,76 @@ # # This file is part of Koha. # -# Koha is free software; you can redistribute it and/or modify it under the -# terms of the GNU General Public License as published by the Free Software -# Foundation; either version 2 of the License, or (at your option) any later -# version. +# Koha is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. # -# Koha is distributed in the hope that it will be useful, but WITHOUT ANY -# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR -# A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# Koha is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. # -# You should have received a copy of the GNU General Public License along -# with Koha; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# You should have received a copy of the GNU General Public License +# along with Koha; if not, see . -use strict; -use warnings; +use Modern::Perl; use C4::Context; -use C4::Output; -use CGI qw(-oldstyle_urls); -use C4::Auth; -use C4::Branch; -use C4::Debug; -use C4::Dates qw/format_date format_date_in_iso/; +use C4::Output qw( output_html_with_http_headers ); +use CGI qw(-oldstyle_urls -utf8); +use C4::Auth qw( get_template_and_user ); use Text::CSV_XS; -use Koha::DateUtils; +use Koha::DateUtils qw( dt_from_string output_pref ); use DateTime; +use DateTime::Format::MySQL; -my $input = new CGI; -my $order = $input->param('order') || ''; +my $input = CGI->new; my $showall = $input->param('showall'); my $bornamefilter = $input->param('borname') || ''; my $borcatfilter = $input->param('borcat') || ''; my $itemtypefilter = $input->param('itemtype') || ''; my $borflagsfilter = $input->param('borflag') || ''; my $branchfilter = $input->param('branch') || ''; +my $homebranchfilter = $input->param('homebranch') || ''; +my $holdingbranchfilter = $input->param('holdingbranch') || ''; +my $dateduefrom = $input->param('dateduefrom'); +my $datedueto = $input->param('datedueto'); my $op = $input->param('op') || ''; -my $dateduefrom = format_date_in_iso($input->param( 'dateduefrom' )) || ''; -my $datedueto = format_date_in_iso($input->param( 'datedueto' )) || ''; -# FIXME This is a kludge to include times -if ($datedueto) { - $datedueto .= ' 23:59'; + +if ( $dateduefrom ) { + $dateduefrom = dt_from_string( $dateduefrom ); } -if ($dateduefrom) { - $dateduefrom .= ' 00:00'; +if ( $datedueto ) { + $datedueto = dt_from_string( $datedueto )->set_hour(23)->set_minute(59); } -# kludge end + +my $filters = { + itemtype => $itemtypefilter, + borname => $bornamefilter, + borcat => $borcatfilter, + itemtype => $itemtypefilter, + borflag => $borflagsfilter, + branch => $branchfilter, + homebranch => $homebranchfilter, + holdingbranch => $holdingbranchfilter, + dateduefrom => $dateduefrom, + datedueto => $datedueto, +}; + my $isfiltered = $op =~ /apply/i && $op =~ /filter/i; my $noreport = C4::Context->preference('FilterBeforeOverdueReport') && ! $isfiltered && $op ne "csv"; my ( $template, $loggedinuser, $cookie ) = get_template_and_user( { - template_name => "circ/overdue.tmpl", + template_name => "circ/overdue.tt", query => $input, type => "intranet", - authnotrequired => 0, - flagsrequired => { reports => 1, circulate => "circulate_remaining_permissions" }, - debug => 1, + flagsrequired => { circulate => "overdues_report" }, } ); +our $logged_in_user = Koha::Patrons->find( $loggedinuser ); + my $dbh = C4::Context->dbh; my $req; @@ -89,12 +100,6 @@ while (my ($itemtype, $description) =$req->fetchrow) { itemtypename => $description, }; } -my $onlymine=C4::Context->preference('IndependantBranches') && - C4::Context->userenv && - C4::Context->userenv->{flags} % 2 !=1 && - C4::Context->userenv->{branch}; - -$branchfilter = C4::Context->userenv->{'branch'} if ($onlymine && !$branchfilter); # Filtering by Patron Attributes # @patron_attr_filter_loop is non empty if there are any patron attribute filters @@ -102,30 +107,15 @@ $branchfilter = C4::Context->userenv->{'branch'} if ($onlymine && !$branchfilter # %borrowernumber_to_attributes is populated by those borrowernumbers matching the patron attribute filters my %cgi_attrcode_to_attrvalues; # ( patron_attribute_code => [ zero or more attribute filter values from the CGI ] ) -for my $attrcode (grep { /^patron_attr_filter_/ } $input->param) { - if (my @attrvalues = grep { length($_) > 0 } $input->param($attrcode)) { +for my $attrcode (grep { /^patron_attr_filter_/ } $input->multi_param) { + if (my @attrvalues = grep { length($_) > 0 } $input->multi_param($attrcode)) { $attrcode =~ s/^patron_attr_filter_//; $cgi_attrcode_to_attrvalues{$attrcode} = \@attrvalues; - print STDERR ">>>param($attrcode)[@{[scalar @attrvalues]}] = '@attrvalues'\n" if $debug; } } my $have_pattr_filter_data = keys(%cgi_attrcode_to_attrvalues) > 0; my @patron_attr_filter_loop; # array of [ domid cgivalue ismany isclone ordinal code description repeatable authorised_value_category ] -my @patron_attr_order_loop; # array of { label => $patron_attr_label, value => $patron_attr_order } - -my @sort_roots = qw(borrower title barcode date_due); -push @sort_roots, map {$_ . " desc"} @sort_roots; -my @order_loop = ({selected => $order ? 0 : 1}); # initial blank row -foreach (@sort_roots) { - my $tmpl_name = $_; - $tmpl_name =~ s/\s/_/g; - push @order_loop, { - selected => $order eq $_ ? 1 : 0, - ordervalue => $_, - 'order_' . $tmpl_name => 1, - }; -} my $sth = $dbh->prepare('SELECT code,description,repeatable,authorised_value_category FROM borrower_attribute_types @@ -146,19 +136,7 @@ while (my $row = $sth->fetchrow_hashref) { $row->{isclone} = $isclone; push @patron_attr_filter_loop, { %$row }; # careful: must store a *deep copy* of the modified row } continue { $isclone = 1, ++$serial } - foreach my $sortorder ('asc', 'desc') { - my $ordervalue = "patron_attr_${sortorder}_${code}"; - push @order_loop, { - selected => $order eq $ordervalue ? 1 : 0, - ordervalue => $ordervalue, - label => $row->{description}, - $sortorder => 1, - }; - } } continue { ++$ordinal } -for (@patron_attr_order_loop) { $_->{selected} = 1 if $order eq $_->{value} } - -$template->param(ORDER_LOOP => \@order_loop); my %borrowernumber_to_attributes; # hash of { borrowernumber => { attrcode => [ [val,display], [val,display], ... ] } } # i.e. val differs from display when attr is an authorised value @@ -200,12 +178,6 @@ if (@patron_attr_filter_loop) { last; } } - if ($debug) { - my $showkeep = $keep ? 'keep' : 'do NOT keep'; - print STDERR ">>> patron $bn: $showkeep attributes: "; - for (sort keys %$pattrs) { my @a=map { "$_->[0]/$_->[1] " } @{$pattrs->{$_}}; print STDERR "attrcode $_ = [@a] " } - print STDERR "\n"; - } delete $borrowernumber_to_attributes{$bn} if !$keep; } } @@ -213,17 +185,11 @@ if (@patron_attr_filter_loop) { $template->param( patron_attr_header_loop => [ map { { header => $_->{description} } } grep { ! $_->{isclone} } @patron_attr_filter_loop ], - branchloop => GetBranchesLoop($branchfilter, $onlymine), - branchfilter => $branchfilter, + filters => $filters, borcatloop=> \@borcatloop, itemtypeloop => \@itemtypeloop, patron_attr_filter_loop => \@patron_attr_filter_loop, - borname => $bornamefilter, - order => $order, showall => $showall, - DHTMLcalendar_dateformat => C4::Dates->DHTMLcalendar(), - dateduefrom => $input->param( 'dateduefrom' ) || '', - datedueto => $input->param( 'datedueto' ) || '', ); if ($noreport) { @@ -238,8 +204,8 @@ if ($noreport) { # FIX 2: ensure there are indexes for columns participating in the WHERE clauses, where feasible/reasonable - my $today_dt = DateTime->now(time_zone => C4::Context->tz); - $today_dt->truncate(to => 'minutes'); + my $today_dt = dt_from_string(); + $today_dt->truncate(to => 'minute'); my $todaysdate = $today_dt->strftime('%Y-%m-%d %H:%M'); $bornamefilter =~s/\*/\%/g; @@ -250,7 +216,7 @@ if ($noreport) { borrowers.surname, borrowers.firstname, borrowers.streetnumber, - borrowers.streettype, + borrowers.streettype, borrowers.address, borrowers.address2, borrowers.city, @@ -258,17 +224,22 @@ if ($noreport) { borrowers.country, borrowers.phone, borrowers.email, + borrowers.cardnumber, + borrowers.borrowernumber, + borrowers.branchcode, issues.itemnumber, issues.issuedate, items.barcode, + items.homebranch, + items.holdingbranch, biblio.title, biblio.author, - borrowers.borrowernumber, biblio.biblionumber, - borrowers.branchcode, items.itemcallnumber, items.replacementprice, - items.enumchron + items.enumchron, + items.itemnotes_nonpublic, + items.itype FROM issues LEFT JOIN borrowers ON (issues.borrowernumber=borrowers.borrowernumber ) LEFT JOIN items ON (issues.itemnumber=items.itemnumber) @@ -296,24 +267,21 @@ if ($noreport) { $strsth .= " AND borrowers.lost <> 0"; } $strsth.=" AND borrowers.branchcode = '" . $branchfilter . "' " if $branchfilter; - $strsth.=" AND date_due < '" . $datedueto . "' " if $datedueto; - $strsth.=" AND date_due > '" . $dateduefrom . "' " if $dateduefrom; + $strsth.=" AND items.homebranch = '" . $homebranchfilter . "' " if $homebranchfilter; + $strsth.=" AND items.holdingbranch = '" . $holdingbranchfilter . "' " if $holdingbranchfilter; + $strsth.=" AND date_due >= ?" if $dateduefrom; + $strsth.=" AND date_due <= ?" if $datedueto; # restrict patrons (borrowers) to those matching the patron attribute filter(s), if any my $bnlist = $have_pattr_filter_data ? join(',',keys %borrowernumber_to_attributes) : ''; $strsth =~ s/WHERE 1=1/WHERE 1=1 AND borrowers.borrowernumber IN ($bnlist)/ if $bnlist; $strsth =~ s/WHERE 1=1/WHERE 0=1/ if $have_pattr_filter_data && !$bnlist; # no match if no borrowers matched patron attrs - $strsth.=" ORDER BY " . ( - ($order eq "borrower") ? "surname, firstname, date_due" : - ($order eq "borrower desc") ? "surname desc, firstname desc, date_due" : - ($order eq "title" or $order eq "title desc") ? "$order, date_due, surname, firstname" : - ($order eq "barcode" or $order eq "barcode desc") ? "items.$order, date_due, surname, firstname" : - ($order eq "date_due desc") ? "date_due DESC, surname, firstname" : - "date_due, surname, firstname" # default sort order - ); + $strsth.=" ORDER BY date_due, surname, firstname"; $template->param(sql=>$strsth); my $sth=$dbh->prepare($strsth); - #warn "overdue.pl : query string ".$strsth; - $sth->execute(); + $sth->execute( + ($dateduefrom ? DateTime::Format::MySQL->format_datetime($dateduefrom) : ()), + ($datedueto ? DateTime::Format::MySQL->format_datetime($datedueto) : ()), + ); my @overduedata; while (my $data = $sth->fetchrow_hashref) { @@ -329,60 +297,42 @@ if ($noreport) { my @displayvalues = map { $_->[1] } @{ $pattrs->{$pattr_filter->{code}} }; # grab second value from each subarray push @patron_attr_value_loop, { value => join(', ', sort { lc $a cmp lc $b } @displayvalues) }; } - my $dt = dt_from_string($data->{date_due}, 'sql'); push @overduedata, { - duedate => output_pref($dt), + patron => Koha::Patrons->find( $data->{borrowernumber} ), + duedate => $data->{date_due}, borrowernumber => $data->{borrowernumber}, - barcode => $data->{barcode}, - itemnum => $data->{itemnumber}, - issuedate => format_date($data->{issuedate}), + cardnumber => $data->{cardnumber}, borrowertitle => $data->{borrowertitle}, surname => $data->{surname}, firstname => $data->{firstname}, - streetnumber => $data->{streetnumber}, - streettype => $data->{streettype}, - address => $data->{address}, - address2 => $data->{address2}, - city => $data->{city}, - zipcode => $data->{zipcode}, + streetnumber => $data->{streetnumber}, + streettype => $data->{streettype}, + address => $data->{address}, + address2 => $data->{address2}, + city => $data->{city}, + zipcode => $data->{zipcode}, country => $data->{country}, phone => $data->{phone}, email => $data->{email}, + branchcode => $data->{branchcode}, + barcode => $data->{barcode}, + itemnum => $data->{itemnumber}, + issuedate => output_pref({ dt => dt_from_string( $data->{issuedate} ), dateonly => 1 }), biblionumber => $data->{biblionumber}, title => $data->{title}, author => $data->{author}, - branchcode => $data->{branchcode}, + homebranchcode => $data->{homebranch}, + holdingbranchcode => $data->{holdingbranch}, itemcallnumber => $data->{itemcallnumber}, replacementprice => $data->{replacementprice}, + itemnotes_nonpublic => $data->{itemnotes_nonpublic}, enumchron => $data->{enumchron}, + itemtype => $data->{itype}, patron_attr_value_loop => \@patron_attr_value_loop, }; } - my ($attrorder) = $order =~ /patron_attr_(.*)$/; - my $patrorder = ''; - my $sortorder = 'asc'; - if (defined $attrorder) { - ($sortorder, $patrorder) = split /_/, $attrorder, 2; - } - print STDERR ">>> order is $order, patrorder is $patrorder, sortorder is $sortorder\n" if $debug; - - if (my @attrtype = grep { $_->{'code'} eq $patrorder } @patron_attr_filter_loop) { # sort by patron attrs perhaps? - my $ordinal = $attrtype[0]{ordinal}; - print STDERR ">>> sort ordinal is $ordinal\n" if $debug; - - sub patronattr_sorter_asc { - lc $a->{patron_attr_value_loop}[$ordinal]{value} - cmp - lc $b->{patron_attr_value_loop}[$ordinal]{value} } - - sub patronattr_sorter_des { -patronattr_sorter_asc() } - - my $sorter = $sortorder eq 'desc' ? \&patronattr_sorter_des : \&patronattr_sorter_asc; - @overduedata = sort $sorter @overduedata; - } - if ($op eq 'csv') { binmode(STDOUT, ":encoding(UTF-8)"); my $csv = build_csv(\@overduedata); @@ -397,10 +347,8 @@ if ($noreport) { # generate parameter list for CSV download link my $new_cgi = CGI->new($input); $new_cgi->delete('op'); - my $csv_param_string = $new_cgi->query_string(); $template->param( - csv_param_string => $csv_param_string, todaysdate => output_pref($today_dt), overdueloop => \@overduedata, nnoverdue => scalar(@overduedata), @@ -425,14 +373,19 @@ sub build_csv { my @lines = (); # build header ... - my @keys = qw /duedate title author borrowertitle firstname surname phone barcode email address address2 zipcode city country - branchcode itemcallnumber biblionumber borrowernumber itemnum issuedate replacementprice streetnumber streettype/; + my @keys = + qw ( duedate title author borrowertitle firstname surname phone barcode email address address2 zipcode city country + branchcode itemcallnumber biblionumber borrowernumber itemnum issuedate replacementprice itemnotes_nonpublic streetnumber streettype); my $csv = Text::CSV_XS->new(); $csv->combine(@keys); push @lines, $csv->string(); + my @private_keys = qw( borrowertitle firstname surname phone email address address2 zipcode city country streetnumber streettype ); # ... and rest of report foreach my $overdue ( @{ $overdues } ) { + unless ( $logged_in_user->can_see_patron_infos( $overdue->{patron} ) ) { + $overdue->{$_} = undef for @private_keys; + } push @lines, $csv->string() if $csv->combine(map { $overdue->{$_} } @keys); }