Bug 19804: Add a 'Fine charging interval' for suspension days
authorJonathan Druart <jonathan.druart@bugs.koha-community.org>
Wed, 13 Dec 2017 19:57:40 +0000 (16:57 -0300)
committerJonathan Druart <jonathan.druart@bugs.koha-community.org>
Mon, 9 Apr 2018 19:15:19 +0000 (16:15 -0300)
We already have a chargeperiod (Fine charging interval) value which is
taken into account for fine ($) for not for the suspension period.

This patch adds a new column suspension_chargeperiod (Fine day charging
interval) to add the same behaviour when a suspension is calculated.

Test plan:
Add overdue item and play with the circulation rules (and the calendar).
The suspension period must be correctly calculated.
Please provide the different tests you made.

Signed-off-by: Hugo Agud <hagud@orex.es>
Signed-off-by: Katrin Fischer <katrin.fischer.83@web.de>
Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
C4/Circulation.pm
t/db_dependent/Circulation.t

index b9bd533..67ee4e5 100644 (file)
@@ -22,6 +22,7 @@ package C4::Circulation;
 use strict;
 #use warnings; FIXME - Bug 2505
 use DateTime;
+use POSIX qw( floor );
 use Koha::DateUtils;
 use C4::Context;
 use C4::Stats;
@@ -2238,6 +2239,13 @@ sub _debar_user_on_return {
                 }
             }
 
+            if ( $issuing_rule->suspension_chargeperiod > 1 ) {
+                # No need to / 1 and do not consider / 0
+                $suspension_days = DateTime::Duration->new(
+                    days => floor( $suspension_days->in_units('days') / $issuing_rule->suspension_chargeperiod )
+                );
+            }
+
             my $new_debar_dt =
               $return_date->clone()->add_duration( $suspension_days );
 
index d9c614b..497df64 100755 (executable)
 
 use Modern::Perl;
 
-use Test::More tests => 113;
+use Test::More tests => 114;
 
 use DateTime;
-
+use POSIX qw( floor );
 use t::lib::Mocks;
 use t::lib::TestBuilder;
 
@@ -1750,6 +1750,115 @@ subtest 'AddReturn + CumulativeRestrictionPeriods' => sub {
     is( $debarments->[0]->{expiration}, $expected_expiration );
 };
 
+subtest 'AddReturn + suspension_chargeperiod' => sub {
+    plan tests => 6;
+
+    my $library = $builder->build( { source => 'Branch' } );
+    my $patron  = $builder->build( { source => 'Borrower', value => { categorycode => $patron_category->{categorycode} } } );
+
+    # Add 2 items
+    my $biblioitem_1 = $builder->build( { source => 'Biblioitem' } );
+    my $item_1 = $builder->build(
+        {
+            source => 'Item',
+            value  => {
+                homebranch    => $library->{branchcode},
+                holdingbranch => $library->{branchcode},
+                notforloan    => 0,
+                itemlost      => 0,
+                withdrawn     => 0,
+                biblionumber  => $biblioitem_1->{biblionumber}
+            }
+        }
+    );
+
+    # And the issuing rule
+    Koha::IssuingRules->search->delete;
+    my $rule = Koha::IssuingRule->new(
+        {
+            categorycode => '*',
+            itemtype     => '*',
+            branchcode   => '*',
+            maxissueqty  => 99,
+            issuelength  => 1,
+            firstremind  => 0,        # 0 day of grace
+            finedays     => 2,        # 2 days of fine per day of overdue
+            suspension_chargeperiod => 1,
+            lengthunit   => 'days',
+        }
+    );
+    $rule->store();
+
+    my $five_days_ago = dt_from_string->subtract( days => 5 );
+    AddIssue( $patron, $item_1->{barcode}, $five_days_ago );    # Add an overdue
+
+    # We want to charge 2 days every day, without grace
+    # With 5 days of overdue: 5 * Z
+    AddReturn( $item_1->{barcode}, $library->{branchcode},
+        undef, undef, dt_from_string );
+    my $debarments = Koha::Patron::Debarments::GetDebarments(
+        { borrowernumber => $patron->{borrowernumber}, type => 'SUSPENSION' } );
+    is( scalar(@$debarments), 1 );
+
+    my $expected_expiration = output_pref(
+        {
+            dt         => dt_from_string->add( days => ( 5 * 2 ) / 1 ),
+            dateformat => 'sql',
+            dateonly   => 1
+        }
+    );
+    is( $debarments->[0]->{expiration}, $expected_expiration );
+    Koha::Patron::Debarments::DelUniqueDebarment(
+        { borrowernumber => $patron->{borrowernumber}, type => 'SUSPENSION' } );
+
+    # We want to charge 2 days every 2 days, without grace
+    # With 5 days of overdue: (5 * 2) / 2
+    $rule->suspension_chargeperiod(2)->store;
+    AddIssue( $patron, $item_1->{barcode}, $five_days_ago );    # Add an overdue
+
+    AddReturn( $item_1->{barcode}, $library->{branchcode},
+        undef, undef, dt_from_string );
+    $debarments = Koha::Patron::Debarments::GetDebarments(
+        { borrowernumber => $patron->{borrowernumber}, type => 'SUSPENSION' } );
+    is( scalar(@$debarments), 1 );
+
+    $expected_expiration = output_pref(
+        {
+            dt         => dt_from_string->add( days => floor( 5 * 2 ) / 2 ),
+            dateformat => 'sql',
+            dateonly   => 1
+        }
+    );
+    is( $debarments->[0]->{expiration}, $expected_expiration );
+    Koha::Patron::Debarments::DelUniqueDebarment(
+        { borrowernumber => $patron->{borrowernumber}, type => 'SUSPENSION' } );
+
+    # We want to charge 2 days every 3 days, with 1 day of grace
+    # With 5 days of overdue: ((5-1) / 3 ) * 2
+    $rule->suspension_chargeperiod(3)->store;
+    $rule->firstremind(1)->store;
+    AddIssue( $patron, $item_1->{barcode}, $five_days_ago );    # Add an overdue
+
+    AddReturn( $item_1->{barcode}, $library->{branchcode},
+        undef, undef, dt_from_string );
+    $debarments = Koha::Patron::Debarments::GetDebarments(
+        { borrowernumber => $patron->{borrowernumber}, type => 'SUSPENSION' } );
+    is( scalar(@$debarments), 1 );
+
+    $expected_expiration = output_pref(
+        {
+            dt         => dt_from_string->add( days => floor( ( ( 5 - 1 ) / 3 ) * 2 ) ),
+            dateformat => 'sql',
+            dateonly   => 1
+        }
+    );
+    is( $debarments->[0]->{expiration}, $expected_expiration );
+    Koha::Patron::Debarments::DelUniqueDebarment(
+        { borrowernumber => $patron->{borrowernumber}, type => 'SUSPENSION' } );
+
+};
+
+
 subtest 'AddReturn | is_overdue' => sub {
     plan tests => 5;