Bug 12230: Set a maximum suspension days as a new issuing rule
This patch adds a new issuing rule: maxsuspensiondays. A new column "Max. suspension duration (day)" appears in the main table of the issuing rules. If this value is filled, on returning an item, a patron won't be suspended longer than this cap. Test plan: 1/ Set "suspension in days" to 2. 2/ Check an item out to a patron and specify a due date to today - 10 days. 3/ Check the item in and verify the patron is suspended until today + 10 * 2 days. 4/ Remove the suspension. 5/ Set "Max. suspension duration" to 10. 6/ Check an item out to a patron and specify a due date to today - 10 days. 7/ Check the item in and verify the patron is suspended until today + 10 days. Signed-off-by: Paola Rossi <paola.rossi@cineca.it> Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com> Signed-off-by: Galen Charlton <gmc@esilibrary.com>
This commit is contained in:
parent
2ff88b27b8
commit
aa6117da36
4 changed files with 107 additions and 5 deletions
|
@ -2085,10 +2085,21 @@ sub _debar_user_on_return {
|
|||
# grace period is measured in the same units as the loan
|
||||
my $grace =
|
||||
DateTime::Duration->new( $unit => $issuingrule->{firstremind} );
|
||||
|
||||
if ( $deltadays->subtract($grace)->is_positive() ) {
|
||||
my $suspension_days = $deltadays * $finedays;
|
||||
|
||||
# If the max suspension days is < than the suspension days
|
||||
# the suspension days is limited to this maximum period.
|
||||
my $max_sd = $issuingrule->{maxsuspensiondays};
|
||||
if ( defined $max_sd ) {
|
||||
$max_sd = DateTime::Duration->new( days => $max_sd );
|
||||
$suspension_days = $max_sd
|
||||
if DateTime::Duration->compare( $max_sd, $suspension_days ) < 0;
|
||||
}
|
||||
|
||||
my $new_debar_dt =
|
||||
$dt_today->clone()->add_duration( $deltadays * $finedays );
|
||||
$dt_today->clone()->add_duration( $suspension_days );
|
||||
|
||||
Koha::Borrower::Debarments::AddUniqueDebarment({
|
||||
borrowernumber => $borrower->{borrowernumber},
|
||||
|
|
|
@ -101,14 +101,15 @@ elsif ($op eq 'delete-branch-item') {
|
|||
# save the values entered
|
||||
elsif ($op eq 'add') {
|
||||
my $sth_search = $dbh->prepare('SELECT COUNT(*) AS total FROM issuingrules WHERE branchcode=? AND categorycode=? AND itemtype=?');
|
||||
my $sth_insert = $dbh->prepare('INSERT INTO issuingrules (branchcode, categorycode, itemtype, maxissueqty, renewalsallowed, renewalperiod, norenewalbefore, reservesallowed, issuelength, lengthunit, hardduedate, hardduedatecompare, fine, finedays, firstremind, chargeperiod,rentaldiscount, overduefinescap) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)');
|
||||
my $sth_update=$dbh->prepare("UPDATE issuingrules SET fine=?, finedays=?, firstremind=?, chargeperiod=?, maxissueqty=?, renewalsallowed=?, renewalperiod=?, norenewalbefore=?, reservesallowed=?, issuelength=?, lengthunit = ?, hardduedate=?, hardduedatecompare=?, rentaldiscount=?, overduefinescap=? WHERE branchcode=? AND categorycode=? AND itemtype=?");
|
||||
my $sth_insert = $dbh->prepare('INSERT INTO issuingrules (branchcode, categorycode, itemtype, maxissueqty, renewalsallowed, renewalperiod, norenewalbefore, reservesallowed, issuelength, lengthunit, hardduedate, hardduedatecompare, fine, finedays, maxsuspensiondays, firstremind, chargeperiod,rentaldiscount, overduefinescap) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)');
|
||||
my $sth_update=$dbh->prepare("UPDATE issuingrules SET fine=?, finedays=?, maxsuspensiondays=?, firstremind=?, chargeperiod=?, maxissueqty=?, renewalsallowed=?, renewalperiod=?, norenewalbefore=?, reservesallowed=?, issuelength=?, lengthunit = ?, hardduedate=?, hardduedatecompare=?, rentaldiscount=?, overduefinescap=? WHERE branchcode=? AND categorycode=? AND itemtype=?");
|
||||
|
||||
my $br = $branch; # branch
|
||||
my $bor = $input->param('categorycode'); # borrower category
|
||||
my $cat = $input->param('itemtype'); # item type
|
||||
my $fine = $input->param('fine');
|
||||
my $finedays = $input->param('finedays');
|
||||
my $maxsuspensiondays = $input->param('maxsuspensiondays');
|
||||
my $firstremind = $input->param('firstremind');
|
||||
my $chargeperiod = $input->param('chargeperiod');
|
||||
my $maxissueqty = $input->param('maxissueqty');
|
||||
|
@ -131,9 +132,9 @@ elsif ($op eq 'add') {
|
|||
$sth_search->execute($br,$bor,$cat);
|
||||
my $res = $sth_search->fetchrow_hashref();
|
||||
if ($res->{total}) {
|
||||
$sth_update->execute($fine, $finedays,$firstremind, $chargeperiod, $maxissueqty, $renewalsallowed, $renewalperiod, $norenewalbefore, $reservesallowed, $issuelength,$lengthunit, $hardduedate,$hardduedatecompare,$rentaldiscount,$overduefinescap, $br,$bor,$cat);
|
||||
$sth_update->execute($fine, $finedays, $maxsuspensiondays, $firstremind, $chargeperiod, $maxissueqty, $renewalsallowed, $renewalperiod, $norenewalbefore, $reservesallowed, $issuelength,$lengthunit, $hardduedate,$hardduedatecompare,$rentaldiscount,$overduefinescap, $br,$bor,$cat);
|
||||
} else {
|
||||
$sth_insert->execute($br,$bor,$cat,$maxissueqty,$renewalsallowed, $renewalperiod, $norenewalbefore, $reservesallowed,$issuelength,$lengthunit,$hardduedate,$hardduedatecompare,$fine,$finedays,$firstremind,$chargeperiod,$rentaldiscount,$overduefinescap);
|
||||
$sth_insert->execute($br,$bor,$cat,$maxissueqty,$renewalsallowed, $renewalperiod, $norenewalbefore, $reservesallowed,$issuelength,$lengthunit,$hardduedate,$hardduedatecompare,$fine,$finedays, $maxsuspensiondays, $firstremind,$chargeperiod,$rentaldiscount,$overduefinescap);
|
||||
}
|
||||
}
|
||||
elsif ($op eq "set-branch-defaults") {
|
||||
|
|
|
@ -148,6 +148,7 @@ for="tobranch"><strong>Clone these rules to:</strong></label> <input type="hidde
|
|||
<th>Fine grace period (day)</th>
|
||||
<th>Overdue fines cap (amount)</th>
|
||||
<th>Suspension in days (day)</th>
|
||||
<th>Max. suspension duration (day)</th>
|
||||
<th>Renewals allowed (count)</th>
|
||||
<th>Renewal period</th>
|
||||
<th>No renewal before</th>
|
||||
|
@ -206,6 +207,7 @@ for="tobranch"><strong>Clone these rules to:</strong></label> <input type="hidde
|
|||
<td>[% rule.firstremind %]</td>
|
||||
<td>[% rule.overduefinescap FILTER format("%.2f") %]</td>
|
||||
<td>[% rule.finedays %]</td>
|
||||
<td>[% rule.maxsuspensiondays %]</td>
|
||||
<td>[% rule.renewalsallowed %]</td>
|
||||
<td>[% rule.renewalperiod %]</td>
|
||||
<td>[% rule.norenewalbefore %]</td>
|
||||
|
@ -256,6 +258,7 @@ for="tobranch"><strong>Clone these rules to:</strong></label> <input type="hidde
|
|||
<td><input type="text" name="firstremind" id="firstremind" size="2" /> </td>
|
||||
<td><input type="text" name="overduefinescap" id="overduefinescap" size="6" /> </td>
|
||||
<td><input type="text" name="finedays" id="fined" size="3" /> </td>
|
||||
<td><input type="text" name="maxsuspensiondays" id="maxsuspensiondays" size="3" /> </td>
|
||||
<td><input type="text" name="renewalsallowed" id="renewalsallowed" size="2" /></td>
|
||||
<td><input type="text" name="renewalperiod" id="renewalperiod" size="3" /></td>
|
||||
<td><input type="text" name="norenewalbefore" id="norenewalbefore" size="3" /></td>
|
||||
|
|
87
t/db_dependent/Circulation/IssuingRules/maxsuspensiondays.t
Normal file
87
t/db_dependent/Circulation/IssuingRules/maxsuspensiondays.t
Normal file
|
@ -0,0 +1,87 @@
|
|||
use Modern::Perl;
|
||||
use Test::More tests => 2;
|
||||
|
||||
use MARC::Record;
|
||||
use MARC::Field;
|
||||
use Test::MockModule;
|
||||
use C4::Context;
|
||||
|
||||
use C4::Biblio qw( AddBiblio );
|
||||
use C4::Circulation qw( AddIssue AddReturn );
|
||||
use C4::Items qw( AddItem );
|
||||
use C4::Members qw( AddMember GetMember );
|
||||
use Koha::DateUtils;
|
||||
use Koha::Borrower::Debarments qw( GetDebarments DelDebarment );
|
||||
my $dbh = C4::Context->dbh;
|
||||
$dbh->{RaiseError} = 1;
|
||||
$dbh->{AutoCommit} = 0;
|
||||
|
||||
my $branchcode = 'CPL';
|
||||
local $SIG{__WARN__} = sub { warn $_[0] unless $_[0] =~ /redefined/ };
|
||||
my $userenv->{branch} = $branchcode;
|
||||
*C4::Context::userenv = \&Mock_userenv;
|
||||
|
||||
my $circulation_module = Test::MockModule->new('C4::Circulation');
|
||||
|
||||
# Test without maxsuspensiondays set
|
||||
$circulation_module->mock('GetIssuingRule', sub {
|
||||
return {
|
||||
firstremind => 0,
|
||||
finedays => 2,
|
||||
lengthunit => 'days',
|
||||
}
|
||||
});
|
||||
|
||||
my $borrowernumber = AddMember(
|
||||
firstname => 'my firstname',
|
||||
surname => 'my surname',
|
||||
categorycode => 'S',
|
||||
branchcode => $branchcode,
|
||||
);
|
||||
my $borrower = GetMember( borrowernumber => $borrowernumber );
|
||||
|
||||
my $record = MARC::Record->new();
|
||||
$record->append_fields(
|
||||
MARC::Field->new('100', ' ', ' ', a => 'My author'),
|
||||
MARC::Field->new('245', ' ', ' ', a => 'My title'),
|
||||
);
|
||||
|
||||
my $barcode = 'bc_maxsuspensiondays';
|
||||
my ($biblionumber, $biblioitemnumber) = AddBiblio($record, '');
|
||||
my (undef, undef, $itemnumber) = AddItem({
|
||||
homebranch => $branchcode,
|
||||
holdingbranch => $branchcode,
|
||||
barcode => $barcode,
|
||||
} , $biblionumber);
|
||||
|
||||
|
||||
my $daysago20 = dt_from_string->add_duration(DateTime::Duration->new(days => -20));
|
||||
my $daysafter40 = dt_from_string->add_duration(DateTime::Duration->new(days => 40));
|
||||
|
||||
AddIssue( $borrower, $barcode, $daysago20 );
|
||||
AddReturn( $barcode, $branchcode );
|
||||
my $debarments = GetDebarments({borrowernumber => $borrower->{borrowernumber}});
|
||||
is( $debarments->[0]->{expiration}, output_pref({ dt => $daysafter40, dateformat => 'iso', dateonly => 1 }));
|
||||
DelDebarment( $debarments->[0]->{borrower_debarment_id} );
|
||||
|
||||
# Test with maxsuspensiondays = 10 days
|
||||
$circulation_module->mock('GetIssuingRule', sub {
|
||||
return {
|
||||
firstremind => 0,
|
||||
finedays => 2,
|
||||
maxsuspensiondays => 10,
|
||||
lengthunit => 'days',
|
||||
}
|
||||
});
|
||||
my $daysafter10 = dt_from_string->add_duration(DateTime::Duration->new(days => 10));
|
||||
AddIssue( $borrower, $barcode, $daysago20 );
|
||||
AddReturn( $barcode, $branchcode );
|
||||
$debarments = GetDebarments({borrowernumber => $borrower->{borrowernumber}});
|
||||
is( $debarments->[0]->{expiration}, output_pref({ dt => $daysafter10, dateformat => 'iso', dateonly => 1 }));
|
||||
DelDebarment( $debarments->[0]->{borrower_debarment_id} );
|
||||
|
||||
|
||||
# C4::Context->userenv
|
||||
sub Mock_userenv {
|
||||
return $userenv;
|
||||
}
|
Loading…
Reference in a new issue