From 11ef1d756469b17971f0866511c5b9f92c900058 Mon Sep 17 00:00:00 2001 From: Hammat Wele Date: Mon, 14 Apr 2025 19:42:27 +0000 Subject: [PATCH] Bug 39631: longoverdue.pl does not consider OverdueNoticeCalendar when calculating overdue days MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When the system preference OverdueNoticeCalendar is activated, the script longoverdue.pl continues to calculate overdue duration using calendar days instead of working days. This creates a discrepancy with overdue_notices.pl, which correctly uses working days for triggering overdue notices when OverdueNoticeCalendar is enabled. As a result, items may be marked as lost by longoverdue.pl before the final configured overdue notice (e.g., ODUE3) has a chance to be sent. To test 1. Set the system preference OverdueNoticeCalendar to « ignore calendar » 2. Set the following preferences: DefaultLongOverdueLostValue = Long Overdue DefaultLongOverdueDays = 15 3. Define days when the library is closed 3.1. Go to Tools > Calendar 3.2. Click on a Saturday (e.g., 2025-04-12) Fill Description = Saturdays, Click on "Holiday repeated every same day of the week." and Click on Copy to all libraries and submit 3.3. Repeat step 3.2. by clicking on Sundays (e.g., 2025-04-13) similarly. 4. Checkout an item to a patron of category type Board, and set due date to 2025-03-29 (15 days before today). 4.1. Click on "Show checkouts", click the barcode, and note the itemnumber. 5. Run: ./misc/cronjobs/longoverdue.pl --> The item should be flagged as overdue (e.g., item 378 appears in the output). 6. Now Enable the system preference OverdueNoticeCalendar. 7. Run longoverdue.pl again: --> The item is still detected as overdue, even though it should not be (due to holidays). 8. Apply the patch 9. Repeat step 7: --> Now, the item is not detected as overdue — correct behavior. 10. Change DefaultLongOverdueDays to 10. 11. Repeat step 7: -->Now, the item is detected as overdue, correctly considering holidays. --- misc/cronjobs/longoverdue.pl | 44 +++++++++++++++++++++++++++++++++--- 1 file changed, 41 insertions(+), 3 deletions(-) diff --git a/misc/cronjobs/longoverdue.pl b/misc/cronjobs/longoverdue.pl index d23df572be..de2f6994a7 100755 --- a/misc/cronjobs/longoverdue.pl +++ b/misc/cronjobs/longoverdue.pl @@ -38,6 +38,7 @@ use Koha::ItemTypes; use Koha::Patron::Categories; use Koha::Patrons; use Koha::Script -cron; +use Koha::DateUtils qw( dt_from_string ); my $lost; # key=lost value, value=num days. my ( $charge, $verbose, $confirm, $quiet ); @@ -350,8 +351,18 @@ sub longoverdue_sth { SELECT items.itemnumber, borrowernumber, date_due, itemlost FROM issues, items WHERE items.itemnumber = issues.itemnumber - AND DATE_SUB(CURDATE(), INTERVAL ? DAY) > date_due - AND DATE_SUB(CURDATE(), INTERVAL ? DAY) <= date_due + "; + if ( !C4::Context->preference('OverdueNoticeCalendar') ) { + $query .= " + AND DATE_SUB(CURDATE(), INTERVAL ? DAY) > date_due + AND DATE_SUB(CURDATE(), INTERVAL ? DAY) <= date_due + "; + } else { + $query .= " + AND TO_DAYS(NOW())-TO_DAYS(issues.date_due) >= 0 + "; + } + $query .= " AND itemlost <> ? $skip_lost_values_sql ORDER BY date_due @@ -471,7 +482,11 @@ foreach my $startrange ( sort keys %$lost ) { $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 ); + if ( C4::Context->preference('OverdueNoticeCalendar') ) { + $sth_items->execute($lostvalue); + } else { + $sth_items->execute( $startrange, $endrange, $lostvalue ); + } $count = 0; ITEM: while ( my $row = $sth_items->fetchrow_hashref ) { my $patron; @@ -498,6 +513,29 @@ foreach my $startrange ( sort keys %$lost ) { } next ITEM unless ( $branches_to_process{$lib} ); } + if ( C4::Context->preference('OverdueNoticeCalendar') ) { + my $lib; + if ( $circ_control_pref eq 'PatronLibrary' ) { + $patron ||= Koha::Patrons->find( $row->{borrowernumber} ); + $lib = $patron->branchcode(); + } elsif ( $circ_control_pref eq 'PickupLibrary' ) { + $lib = C4::Context->userenv->{'branch'}; + } else { # ( $_ eq 'ItemHomeLibrary' ) + if ( $circ_control_pref eq 'homebranch' ) { + $lib = Koha::Items->find( $row->{itemnumber} )->homebranch(); + } else { # ( $circ_control_pref eq 'holdingbranch' ) + $lib = Koha::Items->find( $row->{itemnumber} )->holdingbranch(); + } + } + my $calendar = Koha::Calendar->new( branchcode => $lib ); + my $date_to_run = dt_from_string(); + my $days_between = $calendar->days_between( dt_from_string( $row->{date_due} ), $date_to_run ); + $days_between = $days_between->in_units('days'); + my $longoverdue_days = C4::Context->preference('DefaultLongOverdueDays'); + if ( $days_between < $longoverdue_days ) { + next; + } + } if ($filter_itemtypes) { my $it = uc Koha::Items->find( $row->{itemnumber} )->effective_itemtype(); next ITEM unless ( $itemtype_to_process{$it} ); -- 2.34.1