Bug 24159: Move useDaysMode pref to circulation rules
authorJonathan Druart <jonathan.druart@bugs.koha-community.org>
Fri, 28 Feb 2020 12:29:09 +0000 (13:29 +0100)
committerJonathan Druart <jonathan.druart@bugs.koha-community.org>
Thu, 25 Jun 2020 08:51:59 +0000 (10:51 +0200)
Moving the useDaysMode system preference to a circulation rule will add
much more flexibility in the calculation of the due date.

The initial request was to make hourly loan returned on closed when
(when checked out on the same close day).
To do so we do not want to take into account the calendar.
However the calendar need to be taken into account for other loan item types.

Other scenarios are possible, for instance depending on the branch.

This patchset will add a new "Days mode" column (next to "Loan period")
to the circulation rules page, with the different values of the
"useDaysMode" system preference + a "default" value, to default to the
system preference value.

Test plan:
- Define a long loan item type (like 10 days) that will use the calendar
(or default to the pref value, if the pref is not set to "ignore the
calendar")
- and a hourly loan (like 2 hours) that will ignore the calendar
- Create items with those item types
- Mark today as a closed day
- Check the items out
=> The hourly loan is due the same day
=> The other loan is due on an open day

QA note:
There is the need to force the "days_mode" option when Koha::Calendar is
initiated for the due date calculation. To make sure devs will not
forget it, the methods that need have it defined will throw an
exception.

Sponsored-by: Institute of Technology Carlow
Signed-off-by: Simon Perry <simon.perry@itcarlow.ie>
Signed-off-by: Martin Renvoize <martin.renvoize@ptfs-europe.com>

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>

C4/Circulation.pm
C4/UsageStats.pm
Koha/CirculationRules.pm
t/db_dependent/UsageStats.t

index 7a3b21b..40caeba 100644 (file)
@@ -3576,7 +3576,7 @@ sub updateWrongTransfer {
 $newdatedue = CalcDateDue($startdate,$itemtype,$branchcode,$borrower);
 
 this function calculates the due date given the start date and configured circulation rules,
-checking against the holidays calendar as per the 'useDaysMode' syspref.
+checking against the holidays calendar as per the useDaysMode circulation rule.
 C<$startdate>   = DateTime object representing start date of loan period (assumed to be today)
 C<$itemtype>  = itemtype code of item in question
 C<$branch>  = location whose calendar to use
@@ -3610,8 +3610,16 @@ sub CalcDateDue {
     }
 
 
+    my $useDaysMode_value = Koha::CirculationRules->get_useDaysMode_effective_value(
+        {
+            categorycode => $borrower->{categorycode},
+            itemtype     => $itemtype,
+            branchcode   => $branch,
+        }
+    );
+
     # calculate the datedue as normal
-    if ( C4::Context->preference('useDaysMode') eq 'Days' )
+    if ( $useDaysMode_value eq 'Days' )
     {    # ignoring calendar
         if ( $loanlength->{lengthunit} eq 'hours' ) {
             $datedue->add( hours => $loanlength->{$length_key} );
@@ -3628,7 +3636,7 @@ sub CalcDateDue {
         else { # days
             $dur = DateTime::Duration->new( days => $loanlength->{$length_key});
         }
-        my $calendar = Koha::Calendar->new( branchcode => $branch );
+        my $calendar = Koha::Calendar->new( branchcode => $branch, days_mode => $useDaysMode_value );
         $datedue = $calendar->addDate( $datedue, $dur, $loanlength->{lengthunit} );
         if ($loanlength->{lengthunit} eq 'days') {
             $datedue->set_hour(23);
@@ -3666,8 +3674,8 @@ sub CalcDateDue {
                 $datedue = $expiry_dt->clone->set_time_zone( C4::Context->tz );
             }
         }
-        if ( C4::Context->preference('useDaysMode') ne 'Days' ) {
-          my $calendar = Koha::Calendar->new( branchcode => $branch );
+        if ( $useDaysMode_value ne 'Days' ) {
+          my $calendar = Koha::Calendar->new( branchcode => $branch, days_mode => $useDaysMode_value );
           if ( $calendar->is_holiday($datedue) ) {
               # Don't return on a closed day
               $datedue = $calendar->prev_open_days( $datedue, 1 );
index 52fb4ce..7aecc00 100644 (file)
@@ -155,7 +155,6 @@ sub BuildReport {
         ReturnBeforeExpiry
         TransfersMaxDaysWarning
         UseBranchTransferLimits
-        useDaysMode
         UseTransportCostMatrix
         UseCourseReserves
         finesCalendar
index 5042e6f..df68310 100644 (file)
@@ -487,6 +487,36 @@ sub guess_article_requestable_itemtypes {
     return $res;
 }
 
+=head3 get_useDaysMode_effective_value
+
+Return the value for useDaysMode defined in the circulation rules.
+If not defined (or empty string), the value of the system preference useDaysMode is returned
+
+=cut
+
+sub get_useDaysMode_effective_value {
+    my ( $class, $params ) = @_;
+
+    my $categorycode     = $params->{categorycode};
+    my $itemtype         = $params->{itemtype};
+    my $branchcode       = $params->{branchcode};
+
+    my $useDaysMode_rule = $class->get_effective_rule(
+        {
+            categorycode => $categorycode,
+            itemtype     => $itemtype,
+            branchcode   => $branchcode,
+            rule_name    => 'useDaysMode',
+        }
+    );
+
+    return ( defined($useDaysMode_rule)
+          and $useDaysMode_rule->rule_value ne '' )
+      ? $useDaysMode_rule->rule_value
+      : C4::Context->preference('useDaysMode');
+
+}
+
 
 =head3 type
 
index f4e9949..d31b517 100644 (file)
@@ -416,7 +416,6 @@ sub mocking_systempreferences_to_a_set_value {
         ReturnBeforeExpiry
         TransfersMaxDaysWarning
         UseBranchTransferLimits
-        useDaysMode
         UseTransportCostMatrix
         UseCourseReserves
         finesCalendar