From 858ac03fea6466f47ab666b64a6bfb32775dfa3b Mon Sep 17 00:00:00 2001 From: Bill Erickson Date: Thu, 17 Mar 2022 10:50:06 -0400 Subject: [PATCH] LP1891369 Renewal extension never shortens previous due date Ensure the calculated due date of a renewal never occurs before the due date of the previous circulation. Signed-off-by: Bill Erickson Signed-off-by: Michele Morgan Signed-off-by: Galen Charlton --- .../lib/OpenILS/Application/Circ/Circulate.pm | 41 ++++++++++++++++------ 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Circ/Circulate.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Circ/Circulate.pm index ca293dcfa2..aec6471953 100644 --- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Circ/Circulate.pm +++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Circ/Circulate.pm @@ -2387,32 +2387,53 @@ sub extend_renewal_due_date { my $start_time = DateTime::Format::ISO8601->new ->parse_datetime(clean_ISO8601($prev_circ->xact_start))->epoch; - my $due_time = DateTime::Format::ISO8601->new - ->parse_datetime(clean_ISO8601($prev_circ->due_date))->epoch; + my $prev_due_date = DateTime::Format::ISO8601->new + ->parse_datetime(clean_ISO8601($prev_circ->due_date)); + + my $due_date = DateTime::Format::ISO8601->new + ->parse_datetime(clean_ISO8601($circ->due_date)); + + my $prev_due_time = $prev_due_date->epoch; my $now_time = DateTime->now->epoch; - return if $due_time < $now_time; # Renewed circ was overdue. + return if $prev_due_time < $now_time; # Renewed circ was overdue. if (my $interval = $matchpoint->renew_extend_min_interval) { my $min_duration = OpenILS::Utils::DateTime->interval_to_seconds($interval); my $checkout_duration = $now_time - $start_time; - return if $checkout_duration < $min_duration; + if ($checkout_duration < $min_duration) { + # Renewal occurred too early in the cycle to result in an + # extension of the due date on the renewal. + + # If the new due date falls before the due date of + # the previous circulation, use the due date of the prev. + # circ so the patron does not lose time. + my $due = $due_date < $prev_due_date ? $prev_due_date : $due_date; + $circ->due_date($due->strftime('%FT%T%z')); + + return; + } } - my $remaining_duration = $due_time - $now_time; + # Item was checked out long enough during the previous circulation + # to consider extending the due date of the renewal to cover the gap. - my $due_date = DateTime::Format::ISO8601->new - ->parse_datetime(clean_ISO8601($circ->due_date)); + # Amount of the previous duration that was left unused. + my $remaining_duration = $prev_due_time - $now_time; $due_date->add(seconds => $remaining_duration); - $logger->info("circulator: extended renewal due date to $due_date"); + # If the calculated due date falls before the due date of the previous + # circulation, use the due date of the prev. circ so the patron does + # not lose time. + my $due = $due_date < $prev_due_date ? $prev_due_date : $due_date; + + $logger->info("circulator: renewal due date extension landed on due date: $due"); - # $circ->due_date is already in the needed timezone. - $circ->due_date($due_date->strftime('%FT%T%z')); + $circ->due_date($due->strftime('%FT%T%z')); } -- 2.11.0