<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"/>
# 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
}
}
+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 {
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
);
--- /dev/null
+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;
--- /dev/null
+== 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.
+
+