X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=circ%2Foverdue.pl;h=eea9e05dcafcecaf1f761b7c1dd05ce5bf287368;hb=4a4b3aa9486e97cd247042d0e13e418570719be0;hp=e59961a3027d85a0938a072cfedaa7e8be4b5473;hpb=2202ee78c3abf41aa46d131036b1a4162c8faf35;p=koha.git diff --git a/circ/overdue.pl b/circ/overdue.pl index e59961a302..eea9e05dca 100755 --- a/circ/overdue.pl +++ b/circ/overdue.pl @@ -6,52 +6,59 @@ # # 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 CGI qw(-oldstyle_urls -utf8); use C4::Auth; -use C4::Branch; use C4::Debug; -use C4::Dates qw/format_date format_date_in_iso/; -use Date::Calc qw/Today/; use Text::CSV_XS; +use Koha::DateUtils; +use DateTime; +use DateTime::Format::MySQL; my $input = new CGI; -my $order = $input->param('order') || ''; 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 $op = $input->param('op') || ''; -my $dateduefrom = format_date_in_iso($input->param( 'dateduefrom' )) || ''; -my $datedueto = format_date_in_iso($input->param( 'datedueto' )) || ''; + +my ($dateduefrom, $datedueto); +if ( $dateduefrom = $input->param('dateduefrom') ) { + $dateduefrom = dt_from_string( $dateduefrom ); +} +if ( $datedueto = $input->param('datedueto') ) { + $datedueto = dt_from_string( $datedueto )->set_hour(23)->set_minute(59); +} + 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" }, + flagsrequired => { circulate => "overdues_report" }, debug => 1, } ); @@ -80,12 +87,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 @@ -93,8 +94,8 @@ $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; @@ -103,20 +104,6 @@ for my $attrcode (grep { /^patron_attr_filter_/ } $input->param) { 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 @@ -137,19 +124,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 @@ -204,17 +179,16 @@ 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, + homebranchfilter => $homebranchfilter, + holdingbranchfilter => $homebranchfilter, 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' ) || '', + dateduefrom => $dateduefrom, + datedueto => $datedueto, ); if ($noreport) { @@ -229,7 +203,9 @@ if ($noreport) { # FIX 2: ensure there are indexes for columns participating in the WHERE clauses, where feasible/reasonable - my $todaysdate = sprintf("%-04.4d-%-02.2d-%02.2d", Today()); + my $today_dt = DateTime->now(time_zone => C4::Context->tz); + $today_dt->truncate(to => 'minute'); + my $todaysdate = $today_dt->strftime('%Y-%m-%d %H:%M'); $bornamefilter =~s/\*/\%/g; $bornamefilter =~s/\?/\_/g; @@ -247,16 +223,20 @@ if ($noreport) { borrowers.country, borrowers.phone, borrowers.email, + borrowers.cardnumber, 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.replacementprice, + items.enumchron FROM issues LEFT JOIN borrowers ON (issues.borrowernumber=borrowers.borrowernumber ) LEFT JOIN items ON (issues.itemnumber=items.itemnumber) @@ -274,26 +254,31 @@ if ($noreport) { $strsth.=" AND biblioitems.itemtype = '" . $itemtypefilter . "' "; } } - $strsth.=" AND borrowers.flags = '" . $borflagsfilter . "' " if $borflagsfilter; + if ( $borflagsfilter eq 'gonenoaddress' ) { + $strsth .= " AND borrowers.gonenoaddress <> 0"; + } + elsif ( $borflagsfilter eq 'debarred' ) { + $strsth .= " AND borrowers.debarred >= CURDATE()" ; + } + elsif ( $borflagsfilter eq 'lost') { + $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) { @@ -311,11 +296,12 @@ if ($noreport) { } push @overduedata, { - duedate => format_date($data->{date_due}), + duedate => $data->{date_due}, borrowernumber => $data->{borrowernumber}, barcode => $data->{barcode}, + cardnumber => $data->{cardnumber}, itemnum => $data->{itemnumber}, - issuedate => format_date($data->{issuedate}), + issuedate => output_pref({ dt => dt_from_string( $data->{issuedate} ), dateonly => 1 }), borrowertitle => $data->{borrowertitle}, surname => $data->{surname}, firstname => $data->{firstname}, @@ -332,35 +318,15 @@ if ($noreport) { title => $data->{title}, author => $data->{author}, branchcode => $data->{branchcode}, + homebranchcode => $data->{homebranchcode}, + holdingbranchcode => $data->{holdingbranchcode}, itemcallnumber => $data->{itemcallnumber}, replacementprice => $data->{replacementprice}, + enumchron => $data->{enumchron}, 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); @@ -379,7 +345,7 @@ if ($noreport) { $template->param( csv_param_string => $csv_param_string, - todaysdate => format_date($todaysdate), + todaysdate => output_pref($today_dt), overdueloop => \@overduedata, nnoverdue => scalar(@overduedata), noverdue_is_plural => scalar(@overduedata) != 1, @@ -403,7 +369,7 @@ sub build_csv { my @lines = (); # build header ... - my @keys = qw /duedate title author borrowertitle name phone barcode email address address2 zipcode city country + 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 $csv = Text::CSV_XS->new(); $csv->combine(@keys);