From 1d30ee826fff0a677f6709df5746fd2d84b53ae3 Mon Sep 17 00:00:00 2001 From: Thibaud Guillot Date: Wed, 2 Feb 2022 17:02:15 +0100 Subject: [PATCH] Bug 18064 : Add syspref to launch longOverdue script with calendar support The problem here is that the longOverdue script does not support calendars and when libraries set their holidays, long overdues do not take this into account. For example, during the covid pandemic, some libraries were closed for days, maybe months, but longOverdue didn't care and set "lost" or other values on the items. This fix / enhancement based on taking calendars into account to test it, regardless of your rules related to longOverdue, I propose this test plan: Test plan : 1) For clearer vision on what the patch does, have at least "2" libraries 2) Go to Tools/Calendar and place holidays, on each of the libraries for example, of any kind (special, repeated, as you want) 3) Manually run the misc/cronjobs/longoverdue.pl script with the -v (verbose) argument to get as much information as possible 4) You will see a common "block", with today's date + 366 days (by default if you don't pass any arguments to the script), holidays are not taken into account in this date range 5) Apply my patch 6) Launch the updatedatabase 7) Set the new system preference "LongOverdueNoticeCalendar" to "use calendar" 8) Repeat step 3 9) You will see in output one line per library and according to the number of days off in the interval of dates, the start date of the analysis will have been postponed by as many days in order to take these holidays into account. If something is not completely clear, we can of course discuss it --- ...4-add_LongOverdueNoticeCalendar_syspref.pl | 12 ++++ installer/data/mysql/mandatory/sysprefs.sql | 1 + .../admin/preferences/circulation.pref | 6 ++ misc/cronjobs/longoverdue.pl | 64 +++++++++++++++++-- 4 files changed, 79 insertions(+), 4 deletions(-) create mode 100644 installer/data/mysql/atomicupdate/bug_18064-add_LongOverdueNoticeCalendar_syspref.pl diff --git a/installer/data/mysql/atomicupdate/bug_18064-add_LongOverdueNoticeCalendar_syspref.pl b/installer/data/mysql/atomicupdate/bug_18064-add_LongOverdueNoticeCalendar_syspref.pl new file mode 100644 index 0000000000..070be9be2e --- /dev/null +++ b/installer/data/mysql/atomicupdate/bug_18064-add_LongOverdueNoticeCalendar_syspref.pl @@ -0,0 +1,12 @@ +use Modern::Perl; + +return { + bug_number => "BUG_18064", + description => "Add new system preference LongOverdueNoticeCalendar", + up => sub { + my ($args) = @_; + my ($dbh, $out) = @$args{qw(dbh out)}; + + $dbh->do(q{INSERT IGNORE INTO systempreferences (variable,value,options,explanation,type) VALUES ('LongOverdueNoticeCalendar', '0', NULL, 'Take the calendar into consideration when generating long overdue notices', 'Yes/No') }); + }, +}; \ No newline at end of file diff --git a/installer/data/mysql/mandatory/sysprefs.sql b/installer/data/mysql/mandatory/sysprefs.sql index dd83a00fd8..95c7d6f667 100644 --- a/installer/data/mysql/mandatory/sysprefs.sql +++ b/installer/data/mysql/mandatory/sysprefs.sql @@ -506,6 +506,7 @@ INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` ('OverDrivePasswordRequired','0',NULL,'Does the library require passwords for OverDrive SIP authentication','YesNo'), ('OverDriveUsername','cardnumber','cardnumber|userid','Which patron information should be passed as OverDrive username','Choice'), ('OverdueNoticeCalendar',0,NULL,'Take the calendar into consideration when generating overdue notices','YesNo'), +('LongOverdueNoticeCalendar',0,NULL,'Take the calendar into consideration when generating long overdue notices','YesNo'), ('OverduesBlockCirc','noblock','noblock|confirmation|block','When checking out an item should overdues block checkout, generate a confirmation dialogue, or allow checkout','Choice'), ('OverduesBlockRenewing','allow','allow|blockitem|block','If any of patron checked out documents is late, should renewal be allowed, blocked only on overdue items or blocked on whatever checked out document','Choice'), ('PassItemMarcToXSLT','0',NULL,'If enabled, item fields in the MARC record will be made avaiable to XSLT sheets. Otherwise they will be removed.','YesNo'), 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 43ccf3fd33..ea1b8ce8c0 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 @@ -394,6 +394,12 @@ Circulation: - "Send all notices as a BCC to this email address:" - pref: NoticeBcc class: email + - + - pref: LongOverdueNoticeCalendar + choices: + 1: Use calendar + 0: Ignore calendar + - "when working out the period for long overdue notices." - - pref: OverdueNoticeCalendar choices: diff --git a/misc/cronjobs/longoverdue.pl b/misc/cronjobs/longoverdue.pl index 457ddf4465..b4cd403a16 100755 --- a/misc/cronjobs/longoverdue.pl +++ b/misc/cronjobs/longoverdue.pl @@ -30,6 +30,8 @@ use warnings; use Getopt::Long qw( GetOptions ); use Pod::Usage qw( pod2usage ); +use DateTime; +use DateTime::Duration; use C4::Circulation qw( LostItem MarkIssueReturned ); use C4::Context; @@ -38,6 +40,9 @@ use Koha::ItemTypes; use Koha::Patron::Categories; use Koha::Patrons; use Koha::Script -cron; +use Koha::Calendar; +use Koha::DateUtils qw( dt_from_string ); + my $lost; # key=lost value, value=num days. my ($charge, $verbose, $confirm, $quiet); @@ -312,6 +317,36 @@ sub longoverdue_sth { return C4::Context->dbh->prepare($query); } +my @holidays_by_branch; + +sub get_number_of_holidays { + my ( $start_date, $end_date ) = @_; + + $start_date = dt_from_string($start_date); + $end_date = dt_from_string($end_date); + + my @branches = Koha::Libraries->search( {}, { order_by => ['branchcode'] } ); + my $calendar; + + foreach my $branch ( @branches ) { + my $date_to_run = $start_date->clone(); + my $branchcode = $branch->branchcode; + my $i = 0; + + $calendar = Koha::Calendar->new( branchcode => $branchcode ); + + while ( $date_to_run ne $end_date ) { + # printf "\n Treatment of the day : %s \n", $date_to_run; + if ( $calendar->is_holiday( $date_to_run ) ) { + $i++; + } + $date_to_run->add( days => 1 ); + } + push @holidays_by_branch, { 'branchcode' => $branchcode, 'nb_holidays' => $i }; + } + return @holidays_by_branch; +} + my $dbh = C4::Context->dbh; my @available_categories = Koha::Patron::Categories->search()->get_column('categorycode'); @@ -384,11 +419,30 @@ foreach my $startrange (sort keys %$lost) { if( my $lostvalue = $lost->{$startrange} ) { my ($date1) = bounds($startrange); my ($date2) = bounds( $endrange); + + if ( C4::Context->preference( 'LongOverdueNoticeCalendar' ) ) { + get_number_of_holidays( $date2, $date1 ); + + foreach my $branch ( @holidays_by_branch ) { + + my $date2_with_holidays = dt_from_string($date2) + ->subtract( days => $branch->{'nb_holidays'} )->ymd; + my $endrange_with_holidays = + $endrange + $branch->{'nb_holidays'}; + + $verbose and + printf "\nBranchcode %s\nDue %3s - %3s days ago (%s to %s) - with %s holiday(s), lost => %s\n", $branch->{'branchcode'}, + $startrange, $endrange_with_holidays, $date2_with_holidays, $date1, $branch->{'nb_holidays'}, $lostvalue; + $sth_items->execute($startrange, $endrange_with_holidays, $lostvalue); + } + } else { + # 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, $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 ) { @@ -438,8 +492,10 @@ sub summarize { } } -if (!$quiet){ - print "\n### LONGOVERDUE SUMMARY ###"; - summarize (\@report, 1); - print "\nTOTAL: $total items\n"; +if (!( C4::Context->preference( 'LongOverdueNoticeCalendar' ) )) { + if (!$quiet){ + print "\n### LONGOVERDUE SUMMARY ###"; + summarize (\@report, 1); + print "\nTOTAL: $total items\n"; + } } -- 2.25.1