From 71b4be928da03712f09e55e30a735a24c6db5bd1 Mon Sep 17 00:00:00 2001 From: Jonathan Druart Date: Wed, 13 Dec 2017 16:57:40 -0300 Subject: [PATCH] Bug 19804: Add a 'Fine charging interval' for suspension days 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 --- C4/Circulation.pm | 8 +++ t/db_dependent/Circulation.t | 113 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 119 insertions(+), 2 deletions(-) diff --git a/C4/Circulation.pm b/C4/Circulation.pm index 3e711cdb01..66af0e1cf6 100644 --- a/C4/Circulation.pm +++ b/C4/Circulation.pm @@ -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; @@ -2237,6 +2238,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 ); diff --git a/t/db_dependent/Circulation.t b/t/db_dependent/Circulation.t index 0e82019e6e..1ea0394048 100755 --- a/t/db_dependent/Circulation.t +++ b/t/db_dependent/Circulation.t @@ -17,10 +17,10 @@ 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; -- 2.11.0