LP1891369 Renewal due date extensions
authorBill Erickson <berickxx@gmail.com>
Fri, 25 Jun 2021 15:20:15 +0000 (11:20 -0400)
committerGalen Charlton <gmc@equinoxOLI.org>
Fri, 28 Oct 2022 01:04:23 +0000 (21:04 -0400)
When an item is renewed before it's due date, libraries now have the option
to extend the renewal's due date to include any time lost from the early
renewal.

For example, a 14 day checkout renewed after 12 days will result in a due date
on the renewal of 14 days plus 2 days to cover the lost time.

Two new fields are available under Admin => Local Administration =>
Circulation Policies.

*Early Renewal Extends Due Date*

Enables this new feature for a circulation policy.

*Early Renewal Minimum Duration Percent*

Specifies how early in a checkout a renewal will result in an extended
due date.  E.g. A value of 50 (percent) means no due date extension
would occur if an attempt to renew occurred after 5 days of a 14 day
circulation duration.  In this case, the renewal would still be allowed,
it just wouldn't get the extended due date.

Signed-off-by: Bill Erickson <berickxx@gmail.com>
Signed-off-by: Michele Morgan <mmorgan@noblenet.org>
Signed-off-by: Galen Charlton <gmc@equinoxOLI.org>

Open-ILS/examples/fm_IDL.xml
Open-ILS/src/perlmods/lib/OpenILS/Application/Circ/Circulate.pm
Open-ILS/src/sql/Pg/100.circ_matrix.sql
Open-ILS/src/sql/Pg/upgrade/XXXX.data.renewals-use-full-time.sql [new file with mode: 0644]
docs/RELEASE_NOTES_NEXT/Circulation/renewals-extend-due-date.adoc [new file with mode: 0644]

index 7fe2821..e22a2eb 100644 (file)
@@ -2195,6 +2195,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
                        <field name="total_copy_hold_ratio" reporter:datatype="float" reporter:label="Minimum Total Copy/Hold Ratio"/>
                        <field name="available_copy_hold_ratio" reporter:datatype="float" reporter:label="Minimum Available Copy/Hold Ratio"/>
                        <field name="description" reporter:datatype="text" reporter:label="Description"/>
+                       <field name="renew_extends_due_date" reporter:datatype="bool" reporter:label="Early Renewal Extends Due Date"/>
+                       <field name="renew_extend_percent" reporter:datatype="float" reporter:label="Early Renewal Minimum Duration Percent"/>
                </fields>
                <links>
                        <link field="org_unit" reltype="has_a" key="id" map="" class="aou"/>
index 0546e52..68273a2 100644 (file)
@@ -2345,6 +2345,8 @@ sub apply_modified_due_date {
       # if the due_date lands on a day when the location is closed
       return unless $copy and $circ->due_date;
 
+        $self->extend_renewal_due_date if $self->is_renewal;
+
         #my $org = (ref $copy->circ_lib) ? $copy->circ_lib->id : $copy->circ_lib;
 
         # due-date overlap should be determined by the location the item
@@ -2373,6 +2375,45 @@ sub apply_modified_due_date {
    }
 }
 
+sub extend_renewal_due_date {
+    my $self = shift;
+    my $circ = $self->circ;
+    my $matchpoint = $self->circ_matrix_matchpoint;
+
+    return unless $U->is_true($matchpoint->renew_extends_due_date);
+
+    my $prev_circ = $self->editor->retrieve_action_circulation($self->parent_circ);
+
+    my $start_time = DateTime::Format::ISO8601->new
+        ->parse_datetime(clean_ISO8601($prev_circ->xact_start))->epoch;
+
+    my $end_time = DateTime::Format::ISO8601->new
+        ->parse_datetime(clean_ISO8601($prev_circ->due_date))->epoch;
+
+    my $now_time = DateTime->now->epoch;
+
+    if (my $percent = $matchpoint->renew_extend_percent) {
+        # If the percent is zero, all renewals are extended.
+
+        my $total_duration = $end_time - $start_time;
+        my $checkout_duration = $now_time - $start_time;
+        my $duration_percent = ($checkout_duration / $total_duration) * 100;
+
+        return if $duration_percent < $percent;
+    }
+
+    my $remaining_duration = $end_time - $now_time;
+
+    # $circ->due_date is already in the correct timezone.
+    my $due_date = DateTime::Format::ISO8601->new
+        ->parse_datetime(clean_ISO8601($circ->due_date));
+
+    $due_date->add(seconds => $remaining_duration);
+
+    $logger->info("circulator: extended renewal due date to $due_date");
+
+    $circ->due_date($due_date->strftime('%FT%T%z'));
+}
 
 
 sub create_due_date {
index 61ab73b..1eff550 100644 (file)
@@ -83,6 +83,8 @@ CREATE TABLE config.circ_matrix_matchpoint (
     script_test          TEXT,                           -- javascript source 
     total_copy_hold_ratio     FLOAT,
     available_copy_hold_ratio FLOAT,
+    renew_extends_due_date    BOOLEAN NOT NULL DEFAULT FALSE,
+    renew_extend_percent      FLOAT NOT NULL DEFAULT 0,
     description          TEXT
 );
 
diff --git a/Open-ILS/src/sql/Pg/upgrade/XXXX.data.renewals-use-full-time.sql b/Open-ILS/src/sql/Pg/upgrade/XXXX.data.renewals-use-full-time.sql
new file mode 100644 (file)
index 0000000..3e2a0d8
--- /dev/null
@@ -0,0 +1,9 @@
+BEGIN;
+
+-- SELECT evergreen.upgrade_deps_block_check('TODO', :eg_version);
+
+ALTER TABLE config.circ_matrix_matchpoint
+    ADD COLUMN renew_extends_due_date BOOLEAN NOT NULL DEFAULT FALSE,
+    ADD COLUMN renew_extend_percent FLOAT NOT NULL DEFAULT 0;
+
+COMMIT;
diff --git a/docs/RELEASE_NOTES_NEXT/Circulation/renewals-extend-due-date.adoc b/docs/RELEASE_NOTES_NEXT/Circulation/renewals-extend-due-date.adoc
new file mode 100644 (file)
index 0000000..b7b1b90
--- /dev/null
@@ -0,0 +1,27 @@
+== Renewal Due Date Extended to Cover Lost Time ==
+
+When an item is renewed before it's due date, libraries now have the option
+to extend the renewal's due date to include any time lost from the early 
+renewal.
+
+For example, a 14 day checkout renewed after 12 days will result in a due date
+on the renewal of 14 days plus 2 days to cover the lost time.
+
+=== Settings ===
+
+Two new fields are available under Admin => Local Administration => 
+Circulation Policies.
+
+*Early Renewal Extends Due Date*
+
+Enables this new feature for a circulation policy.
+
+*Early Renewal Minimum Duration Percent*
+
+Specifies how early in a checkout a renewal will result in an extended
+due date.  E.g. A value of 50 (percent) means no due date extension
+would occur if an attempt to renew occurred after 5 days of a 14 day
+circulation duration.  In this case, the renewal would still be allowed,
+it just wouldn't get the extended due date.
+
+