From f586c9a1529e306a00e6213128bdbe480a483195 Mon Sep 17 00:00:00 2001 From: Matthias Le Gac Date: Thu, 22 Feb 2024 10:45:19 -0500 Subject: [PATCH] Bug 35169: Make long overdue borrower category options configurable in interface --- .../admin/preferences/circulation.pref | 18 ++ misc/cronjobs/longoverdue.pl | 203 ++++++++++-------- 2 files changed, 130 insertions(+), 91 deletions(-) diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref index 080e8fa494..c55345f13c 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref @@ -445,6 +445,24 @@ Circulation: - "." -
Leave this field empty if you don't want to skip any LOST statuses. -
Set to a list of comma separated values, e.g. 5,6,7. + + - + - pref: DefaultLongOverdueBorrowerCategories + choices: patron-categories + class: multiple + - the borrower categories that will be listed. Exclude all others. + -
WARNING — This preference will be active only if DefaultLongOverdueSkipBorrowerCategories is empty. + - "
NOTE: This system preference requires the misc/cronjobs/longoverdue.pl cronjob. Ask your system administrator to schedule it." + + + - + - pref: DefaultLongOverdueSkipBorrowerCategories + choices: patron-categories + class: multiple + - the borrower categories that will not be listed. Include all others. + -
WARNING - This preference overrides the DefaultLongOverdueBorrowerCategories preference, so the DefaultLongOverdueBorrowerCategories filter will not take effect. + - "
NOTE: This system preference requires the misc/cronjobs/longoverdue.pl cronjob. Ask your system administrator to schedule it." + - - "When issuing an item that has been marked as lost, " - pref: IssueLostItem diff --git a/misc/cronjobs/longoverdue.pl b/misc/cronjobs/longoverdue.pl index 2d313b77b2..a53fafe434 100755 --- a/misc/cronjobs/longoverdue.pl +++ b/misc/cronjobs/longoverdue.pl @@ -39,21 +39,21 @@ use Koha::Patron::Categories; use Koha::Patrons; use Koha::Script -cron; -my $lost; # key=lost value, value=num days. -my ($charge, $verbose, $confirm, $quiet); +my $lost; # key=lost value, value=num days. +my ( $charge, $verbose, $confirm, $quiet ); my $endrange = 366; my $mark_returned; -my $borrower_category = []; +my $borrower_category = []; my $skip_borrower_category = []; -my $itemtype = []; -my $skip_itemtype = []; -my $help=0; -my $man=0; -my $list_categories = 0; -my $list_itemtypes = 0; +my $itemtype = []; +my $skip_itemtype = []; +my $help = 0; +my $man = 0; +my $list_categories = 0; +my $list_itemtypes = 0; my @skip_lost_values; -my $command_line_options = join(" ",@ARGV); +my $command_line_options = join( " ", @ARGV ); GetOptions( 'l|lost=s%' => \$lost, @@ -74,42 +74,41 @@ GetOptions( 'skip-lost-value=s' => \@skip_lost_values, ); -if ( $man ) { - pod2usage( -verbose => 2 - -exitval => 0 - ); +if ($man) { + pod2usage( -verbose => 2 -exitval => 0 ); } -if ( $help ) { - pod2usage( -verbose => 1, - -exitval => 0 - ); +if ($help) { + pod2usage( + -verbose => 1, + -exitval => 0 + ); } -if ( scalar @$borrower_category && scalar @$skip_borrower_category) { - pod2usage( -verbose => 1, - -message => "The options --category and --skip-category are mutually exclusive.\n" - . "Use one or the other.", - -exitval => 1 - ); +if ( scalar @$borrower_category && scalar @$skip_borrower_category ) { + pod2usage( + -verbose => 1, + -message => "The options --category and --skip-category are mutually exclusive.\n" . "Use one or the other.", + -exitval => 1 + ); } -if ( scalar @$itemtype && scalar @$skip_itemtype) { - pod2usage( -verbose => 1, - -message => "The options --itemtype and --skip-itemtype are mutually exclusive.\n" - . "Use one or the other.", - -exitval => 1 - ); +if ( scalar @$itemtype && scalar @$skip_itemtype ) { + pod2usage( + -verbose => 1, + -message => "The options --itemtype and --skip-itemtype are mutually exclusive.\n" . "Use one or the other.", + -exitval => 1 + ); } -if ( $list_categories ) { +if ($list_categories) { my @categories = Koha::Patron::Categories->search()->get_column('categorycode'); print "\nBorrower Categories: " . join( " ", @categories ) . "\n\n"; exit 0; } -if ( $list_itemtypes ) { +if ($list_itemtypes) { my @itemtypes = Koha::ItemTypes->search()->get_column('itemtype'); print "\nItemtypes: " . join( " ", @itemtypes ) . "\n\n"; exit 0; @@ -252,35 +251,54 @@ near-term release, so this script is not intended to have a long lifetime. # unless ( scalar @skip_lost_values ) { - my $preference = C4::Context->preference( 'DefaultLongOverdueSkipLostStatuses' ); + my $preference = C4::Context->preference('DefaultLongOverdueSkipLostStatuses'); @skip_lost_values = split( ',', $preference ); } -if ( ! defined($lost) ) { +if ( !defined($lost) ) { my $longoverdue_value = C4::Context->preference('DefaultLongOverdueLostValue'); - my $longoverdue_days = C4::Context->preference('DefaultLongOverdueDays'); - if(defined($longoverdue_value) and defined($longoverdue_days) and $longoverdue_value ne '' and $longoverdue_days ne '' and $longoverdue_days >= 0) { + my $longoverdue_days = C4::Context->preference('DefaultLongOverdueDays'); + if ( defined($longoverdue_value) + and defined($longoverdue_days) + and $longoverdue_value ne '' + and $longoverdue_days ne '' + and $longoverdue_days >= 0 ) + { $lost->{$longoverdue_days} = $longoverdue_value; - } - else { - pod2usage( { + } else { + pod2usage( + { -exitval => 1, - -msg => q|ERROR: No --lost (-l) option or system preferences DefaultLongOverdueLostValue/DefaultLongOverdueDays defined|, - } ); + -msg => + q|ERROR: No --lost (-l) option or system preferences DefaultLongOverdueLostValue/DefaultLongOverdueDays defined|, + } + ); } } -if ( ! defined($charge) ) { + +if ( !defined($charge) ) { my $charge_value = C4::Context->preference('DefaultLongOverdueChargeValue'); - if(defined($charge_value) and $charge_value ne '') { + if ( defined($charge_value) and $charge_value ne '' ) { $charge = $charge_value; } } + +if ( C4::Context->preference('DefaultLongOverdueBorrowerCategories') ) { + my $categories = C4::Context->preference('DefaultLongOverdueBorrowerCategories'); + $borrower_category = [ split( ',', $categories ) ]; +} + +if ( C4::Context->preference('DefaultLongOverdueSkipBorrowerCategories') ) { + my $categories = C4::Context->preference('DefaultLongOverdueSkipBorrowerCategories'); + $skip_borrower_category = [ split( ',', $categories ) ]; +} + unless ($confirm) { - $verbose = 1; # If you're not running it for real, then the whole point is the print output. + $verbose = 1; # If you're not running it for real, then the whole point is the print output. print "### TEST MODE -- NO ACTIONS TAKEN ###\n"; } -cronlogaction({ info => $command_line_options }); +cronlogaction( { info => $command_line_options } ); # In my opinion, this line is safe SQL to have outside the API. --atz our $bounds_sth = C4::Context->dbh->prepare("SELECT DATE_SUB(CURDATE(), INTERVAL ? DAY)"); @@ -292,13 +310,13 @@ sub bounds { # FIXME - This sql should be inside the API. sub longoverdue_sth { - my ( $params ) = @_; + my ($params) = @_; my $skip_lost_values = $params->{skip_lost_values}; my $skip_lost_values_sql = q{}; - if ( @$skip_lost_values ) { + if (@$skip_lost_values) { my $values = join( ',', map { qq{'$_'} } @$skip_lost_values ); - $skip_lost_values_sql = "AND itemlost NOT IN ( $values )" + $skip_lost_values_sql = "AND itemlost NOT IN ( $values )"; } my $query = " @@ -317,10 +335,10 @@ sub longoverdue_sth { my $dbh = C4::Context->dbh; my @available_categories = Koha::Patron::Categories->search()->get_column('categorycode'); -$borrower_category = [ map { uc $_ } @$borrower_category ]; -$skip_borrower_category = [ map { uc $_} @$skip_borrower_category ]; +$borrower_category = [ map { uc $_ } @$borrower_category ]; +$skip_borrower_category = [ map { uc $_ } @$skip_borrower_category ]; my %category_to_process; -for my $cat ( @$borrower_category ) { +for my $cat (@$borrower_category) { unless ( grep { $_ eq $cat } @available_categories ) { pod2usage( '-exitval' => 1, @@ -329,8 +347,8 @@ for my $cat ( @$borrower_category ) { } $category_to_process{$cat} = 1; } -if ( @$skip_borrower_category ) { - for my $cat ( @$skip_borrower_category ) { +if (@$skip_borrower_category) { + for my $cat (@$skip_borrower_category) { unless ( grep { $_ eq $cat } @available_categories ) { pod2usage( '-exitval' => 1, @@ -345,10 +363,10 @@ if ( @$skip_borrower_category ) { my $filter_borrower_categories = ( scalar @$borrower_category || scalar @$skip_borrower_category ); my @available_itemtypes = Koha::ItemTypes->search()->get_column('itemtype'); -$itemtype = [ map { uc $_ } @$itemtype ]; -$skip_itemtype = [ map { uc $_} @$skip_itemtype ]; +$itemtype = [ map { uc $_ } @$itemtype ]; +$skip_itemtype = [ map { uc $_ } @$skip_itemtype ]; my %itemtype_to_process; -for my $it ( @$itemtype ) { +for my $it (@$itemtype) { unless ( grep { $_ eq $it } @available_itemtypes ) { pod2usage( '-exitval' => 1, @@ -357,8 +375,8 @@ for my $it ( @$itemtype ) { } $itemtype_to_process{$it} = 1; } -if ( @$skip_itemtype ) { - for my $it ( @$skip_itemtype ) { +if (@$skip_itemtype) { + for my $it (@$skip_itemtype) { unless ( grep { $_ eq $it } @available_itemtypes ) { pod2usage( '-exitval' => 1, @@ -375,53 +393,56 @@ my $filter_itemtypes = ( scalar @$itemtype || scalar @$skip_itemtype ); my $count; my @report; my $total = 0; -my $i = 0; +my $i = 0; # FIXME - The item is only marked returned if you supply --charge . # We need a better way to handle this. # -my $sth_items = longoverdue_sth({ skip_lost_values => \@skip_lost_values }); +my $sth_items = longoverdue_sth( { skip_lost_values => \@skip_lost_values } ); -foreach my $startrange (sort keys %$lost) { - if( my $lostvalue = $lost->{$startrange} ) { +foreach my $startrange ( sort keys %$lost ) { + if ( my $lostvalue = $lost->{$startrange} ) { my ($date1) = bounds($startrange); - my ($date2) = bounds( $endrange); + my ($date2) = bounds($endrange); + # print "\nRange ", ++$i, "\nDue $startrange - $endrange days ago ($date2 to $date1), lost => $lostvalue\n" if($verbose); - $verbose and - printf "\nRange %s\nDue %3s - %3s days ago (%s to %s), lost => %s\n", ++$i, + $verbose + and printf "\nRange %s\nDue %3s - %3s days ago (%s to %s), lost => %s\n", ++$i, $startrange, $endrange, $date2, $date1, $lostvalue; - $sth_items->execute($startrange, $endrange, $lostvalue); - $count=0; - ITEM: while (my $row=$sth_items->fetchrow_hashref) { - if( $filter_borrower_categories ) { + $sth_items->execute( $startrange, $endrange, $lostvalue ); + $count = 0; + ITEM: while ( my $row = $sth_items->fetchrow_hashref ) { + if ($filter_borrower_categories) { my $category = uc Koha::Patrons->find( $row->{borrowernumber} )->categorycode(); - next ITEM unless ( $category_to_process{ $category } ); + next ITEM unless ( $category_to_process{$category} ); } if ($filter_itemtypes) { my $it = uc Koha::Items->find( $row->{itemnumber} )->effective_itemtype(); next ITEM unless ( $itemtype_to_process{$it} ); } - printf ("Due %s: item %5s from borrower %5s to lost: %s\n", $row->{date_due}, $row->{itemnumber}, $row->{borrowernumber}, $lostvalue) if($verbose); - if($confirm) { - Koha::Items->find( $row->{itemnumber} )->itemlost($lostvalue) - ->store; + printf( + "Due %s: item %5s from borrower %5s to lost: %s\n", $row->{date_due}, $row->{itemnumber}, + $row->{borrowernumber}, $lostvalue + ) if ($verbose); + if ($confirm) { + Koha::Items->find( $row->{itemnumber} )->itemlost($lostvalue)->store; if ( $charge && $charge eq $lostvalue ) { LostItem( $row->{'itemnumber'}, 'cronjob', $mark_returned ); - } elsif ( $mark_returned ) { + } elsif ($mark_returned) { my $patron = Koha::Patrons->find( $row->{borrowernumber} ); - MarkIssueReturned($row->{borrowernumber},$row->{itemnumber},undef,$patron->privacy) + MarkIssueReturned( $row->{borrowernumber}, $row->{itemnumber}, undef, $patron->privacy ); } } $count++; } push @report, { - startrange => $startrange, - endrange => $endrange, - range => "$startrange - $endrange", - date1 => $date1, - date2 => $date2, - lostvalue => $lostvalue, - count => $count, + startrange => $startrange, + endrange => $endrange, + range => "$startrange - $endrange", + date1 => $date1, + date2 => $date2, + lostvalue => $lostvalue, + count => $count, }; $total += $count; } @@ -429,21 +450,21 @@ foreach my $startrange (sort keys %$lost) { } sub summarize { - my $arg = shift; # ref to array - my $got_items = shift || 0; # print "count" line for items - my @report = @$arg or return; - my $i = 0; + my $arg = shift; # ref to array + my $got_items = shift || 0; # print "count" line for items + my @report = @$arg or return; + my $i = 0; for my $range (@report) { printf "\nRange %s\nDue %3s - %3s days ago (%s to %s), lost => %s\n", ++$i, - map {$range->{$_}} qw(startrange endrange date2 date1 lostvalue); + map { $range->{$_} } qw(startrange endrange date2 date1 lostvalue); $got_items and printf " %4s items\n", $range->{count}; } } -if (!$quiet){ +if ( !$quiet ) { print "\n### LONGOVERDUE SUMMARY ###"; - summarize (\@report, 1); + summarize( \@report, 1 ); print "\nTOTAL: $total items\n"; } -cronlogaction({ action => 'End', info => "COMPLETED" }); +cronlogaction( { action => 'End', info => "COMPLETED" } ); -- 2.34.1