Browse Source
This patch makes koha automatically set expiration date when reserves become waitting. Also it adds a new syspref "ExcludeHolidaysFromMaxPickUpDelay" that allows to take holidays into account while calculating expiration date. Test plan: - Install this patch and run updatedatabase.pl script, - allow ExpireReservesMaxPickUpDelay in system preferences, - set ReservesMaxPickUpDelay to 5. - Place an hold on a checked out item and check in this item: The hold's expiration date should be today + 5. - Allow ExcludeHolidaysFromMaxPickUpDelay in system preferences, - add holiday during this pickup delay period, - Create a new hold and make it comes waitting: The hold's expiration date should be today + 5 + number of closed day(s). Also: - Check that ExpireReservesOnHolidays syspref works again without ExcludeHolidaysFromMaxPickUpDelay. - Check that cancel fees apply again if wanted. Signed-off-by: sonia BOUIS <sonia.bouis@univ-lyon3.fr> Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl> Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>17.05.x
9 changed files with 384 additions and 93 deletions
@ -0,0 +1 @@ |
|||
INSERT IGNORE INTO systempreferences (variable,value,explanation,options,type) VALUES ('ExcludeHolidaysFromMaxPickUpDelay', '0', 'If ON, reserves max pickup delay takes into account the closed days.', NULL, 'Integer'); |
@ -0,0 +1,101 @@ |
|||
#!/usr/bin/perl |
|||
|
|||
use Modern::Perl; |
|||
|
|||
use C4::Reserves; |
|||
use Koha::DateUtils; |
|||
|
|||
use t::lib::Mocks; |
|||
use t::lib::TestBuilder; |
|||
|
|||
use Test::More tests => 5; |
|||
|
|||
use_ok('C4::Reserves'); |
|||
|
|||
my $schema = Koha::Database->new->schema; |
|||
$schema->storage->txn_begin; |
|||
|
|||
my $dbh = C4::Context->dbh; |
|||
$dbh->{AutoCommit} = 0; |
|||
$dbh->{RaiseError} = 1; |
|||
|
|||
my $builder = t::lib::TestBuilder->new(); |
|||
|
|||
t::lib::Mocks::mock_preference('ExpireReservesOnHolidays', 0); |
|||
|
|||
my $today = dt_from_string(); |
|||
my $reserve_reservedate = $today->clone; |
|||
$reserve_reservedate->subtract(days => 30); |
|||
|
|||
my $reserve1_expirationdate = $today->clone; |
|||
$reserve1_expirationdate->add(days => 1); |
|||
|
|||
# Reserve not expired |
|||
my $reserve1 = $builder->build({ |
|||
source => 'Reserve', |
|||
value => { |
|||
reservedate => $reserve_reservedate, |
|||
expirationdate => $reserve1_expirationdate, |
|||
cancellationdate => undef, |
|||
priority => 0, |
|||
found => 'W', |
|||
}, |
|||
}); |
|||
|
|||
CancelExpiredReserves(); |
|||
my $r1 = Koha::Holds->find($reserve1->{reserve_id}); |
|||
ok($r1, 'Reserve 1 should not be canceled.'); |
|||
|
|||
my $reserve2_expirationdate = $today->clone; |
|||
$reserve2_expirationdate->subtract(days => 1); |
|||
|
|||
# Reserve expired |
|||
my $reserve2 = $builder->build({ |
|||
source => 'Reserve', |
|||
value => { |
|||
reservedate => $reserve_reservedate, |
|||
expirationdate => $reserve2_expirationdate, |
|||
cancellationdate => undef, |
|||
priority => 0, |
|||
found => 'W', |
|||
}, |
|||
}); |
|||
|
|||
CancelExpiredReserves(); |
|||
my $r2 = Koha::Holds->find($reserve2->{reserve_id}); |
|||
is($r2, undef,'Reserve 2 should be canceled.'); |
|||
|
|||
# Reserve expired on holiday |
|||
my $reserve3 = $builder->build({ |
|||
source => 'Reserve', |
|||
value => { |
|||
reservedate => $reserve_reservedate, |
|||
expirationdate => $reserve2_expirationdate, |
|||
branchcode => 'LIB1', |
|||
cancellationdate => undef, |
|||
priority => 0, |
|||
found => 'W', |
|||
}, |
|||
}); |
|||
|
|||
Koha::Cache->get_instance()->flush_all(); |
|||
my $holiday = $builder->build({ |
|||
source => 'SpecialHoliday', |
|||
value => { |
|||
branchcode => 'LIB1', |
|||
day => $today->day, |
|||
month => $today->month, |
|||
year => $today->year, |
|||
title => 'My holiday', |
|||
isexception => 0 |
|||
}, |
|||
}); |
|||
|
|||
CancelExpiredReserves(); |
|||
my $r3 = Koha::Holds->find($reserve3->{reserve_id}); |
|||
ok($r3,'Reserve 3 should not be canceled.'); |
|||
|
|||
t::lib::Mocks::mock_preference('ExpireReservesOnHolidays', 1); |
|||
CancelExpiredReserves(); |
|||
$r3 = Koha::Holds->find($reserve3->{reserve_id}); |
|||
is($r3, undef,'Reserve 3 should be canceled.'); |
@ -0,0 +1,208 @@ |
|||
#!/usr/bin/perl |
|||
|
|||
use Modern::Perl; |
|||
|
|||
use C4::Reserves; |
|||
use Koha::DateUtils; |
|||
|
|||
use t::lib::Mocks; |
|||
use t::lib::TestBuilder; |
|||
|
|||
use Test::More tests => 10; |
|||
|
|||
use_ok('C4::Reserves'); |
|||
|
|||
my $schema = Koha::Database->new->schema; |
|||
$schema->storage->txn_begin; |
|||
|
|||
my $dbh = C4::Context->dbh; |
|||
$dbh->{AutoCommit} = 0; |
|||
$dbh->{RaiseError} = 1; |
|||
$dbh->do(q{DELETE FROM special_holidays}); |
|||
|
|||
my $builder = t::lib::TestBuilder->new(); |
|||
|
|||
# Category, branch and patrons |
|||
$builder->build({ |
|||
source => 'Category', |
|||
value => { |
|||
categorycode => 'XYZ1', |
|||
}, |
|||
}); |
|||
$builder->build({ |
|||
source => 'Branch', |
|||
value => { |
|||
branchcode => 'LIB1', |
|||
}, |
|||
}); |
|||
|
|||
$builder->build({ |
|||
source => 'Branch', |
|||
value => { |
|||
branchcode => 'LIB2', |
|||
}, |
|||
}); |
|||
|
|||
my $patron1 = $builder->build({ |
|||
source => 'Borrower', |
|||
value => { |
|||
categorycode => 'XYZ1', |
|||
branchcode => 'LIB1', |
|||
}, |
|||
}); |
|||
|
|||
my $patron2 = $builder->build({ |
|||
source => 'Borrower', |
|||
value => { |
|||
categorycode => 'XYZ1', |
|||
branchcode => 'LIB2', |
|||
}, |
|||
}); |
|||
|
|||
my $biblio = $builder->build({ |
|||
source => 'Biblio', |
|||
value => { |
|||
title => 'Title 1', }, |
|||
}); |
|||
|
|||
my $biblio2 = $builder->build({ |
|||
source => 'Biblio', |
|||
value => { |
|||
title => 'Title 2', }, |
|||
}); |
|||
|
|||
my $biblio3 = $builder->build({ |
|||
source => 'Biblio', |
|||
value => { |
|||
title => 'Title 3', }, |
|||
}); |
|||
|
|||
my $item1 = $builder->build({ |
|||
source => 'Item', |
|||
value => { |
|||
biblionumber => $biblio->{biblionumber}, |
|||
}, |
|||
}); |
|||
|
|||
my $item2 = $builder->build({ |
|||
source => 'Item', |
|||
value => { |
|||
biblionumber => $biblio2->{biblionumber}, |
|||
}, |
|||
}); |
|||
|
|||
my $item3 = $builder->build({ |
|||
source => 'Item', |
|||
value => { |
|||
biblionumber => $biblio3->{biblionumber}, |
|||
}, |
|||
}); |
|||
|
|||
my $today = dt_from_string(); |
|||
|
|||
my $reserve1_reservedate = $today->clone; |
|||
$reserve1_reservedate->subtract(days => 20); |
|||
|
|||
my $reserve1_expirationdate = $today->clone; |
|||
$reserve1_expirationdate->add(days => 6); |
|||
|
|||
my $reserve1 = $builder->build({ |
|||
source => 'Reserve', |
|||
value => { |
|||
borrowernumber => $patron1->{borrowernumber}, |
|||
reservedate => $reserve1_reservedate->ymd, |
|||
expirationdate => undef, |
|||
biblionumber => $biblio->{biblionumber}, |
|||
branchcode => 'LIB1', |
|||
priority => 1, |
|||
found => '', |
|||
}, |
|||
}); |
|||
|
|||
t::lib::Mocks::mock_preference('ExpireReservesMaxPickUpDelay', 1); |
|||
t::lib::Mocks::mock_preference('ReservesMaxPickUpDelay', 6); |
|||
|
|||
ModReserveAffect( $item1->{itemnumber}, $patron1->{borrowernumber}, 0); |
|||
my $r = Koha::Holds->find($reserve1->{reserve_id}); |
|||
|
|||
is($r->waitingdate, $today->ymd, 'Waiting date should be set to today' ); |
|||
is($r->expirationdate, $reserve1_expirationdate->ymd, 'Expiration date should be set to today + 6' ); |
|||
is($r->found, 'W', 'Reserve status is now "waiting"' ); |
|||
is($r->priority, 0, 'Priority should be 0' ); |
|||
is($r->itemnumber, $item1->{itemnumber}, 'Item number should be set correctly' ); |
|||
|
|||
my $reserve2 = $builder->build({ |
|||
source => 'Reserve', |
|||
value => { |
|||
borrowernumber => $patron2->{borrowernumber}, |
|||
reservedate => $reserve1_reservedate->ymd, |
|||
expirationdate => undef, |
|||
biblionumber => $biblio2->{biblionumber}, |
|||
branchcode => 'LIB1', |
|||
priority => 1, |
|||
found => '', |
|||
}, |
|||
}); |
|||
|
|||
ModReserveAffect( $item2->{itemnumber}, $patron2->{borrowernumber}, 1); |
|||
my $r2 = Koha::Holds->find($reserve2->{reserve_id}); |
|||
|
|||
is($r2->found, 'T', '2nd reserve - Reserve status is now "To transfer"' ); |
|||
is($r2->priority, 0, '2nd reserve - Priority should be 0' ); |
|||
is($r2->itemnumber, $item2->{itemnumber}, '2nd reserve - Item number should be set correctly' ); |
|||
|
|||
my $reserve3 = $builder->build({ |
|||
source => 'Reserve', |
|||
value => { |
|||
borrowernumber => $patron2->{borrowernumber}, |
|||
reservedate => $reserve1_reservedate->ymd, |
|||
expirationdate => undef, |
|||
biblionumber => $biblio3->{biblionumber}, |
|||
branchcode => 'LIB1', |
|||
priority => 1, |
|||
found => '', |
|||
}, |
|||
}); |
|||
|
|||
my $special_holiday1_dt = $today->clone; |
|||
$special_holiday1_dt->add(days => 2); |
|||
|
|||
Koha::Cache->get_instance()->flush_all(); |
|||
my $holiday = $builder->build({ |
|||
source => 'SpecialHoliday', |
|||
value => { |
|||
branchcode => 'LIB1', |
|||
day => $special_holiday1_dt->day, |
|||
month => $special_holiday1_dt->month, |
|||
year => $special_holiday1_dt->year, |
|||
title => 'My special holiday', |
|||
isexception => 0 |
|||
}, |
|||
}); |
|||
|
|||
my $special_holiday2_dt = $today->clone; |
|||
$special_holiday2_dt->add(days => 4); |
|||
|
|||
my $holiday2 = $builder->build({ |
|||
source => 'SpecialHoliday', |
|||
value => { |
|||
branchcode => 'LIB1', |
|||
day => $special_holiday2_dt->day, |
|||
month => $special_holiday2_dt->month, |
|||
year => $special_holiday2_dt->year, |
|||
title => 'My special holiday 2', |
|||
isexception => 0 |
|||
}, |
|||
}); |
|||
|
|||
t::lib::Mocks::mock_preference('ExcludeHolidaysFromMaxPickUpDelay', 1); |
|||
ModReserveAffect( $item3->{itemnumber}, $patron2->{borrowernumber}, 0); |
|||
|
|||
# Add 6 days of pickup delay + 1 day of holiday. |
|||
my $expected_expiration = $today->clone; |
|||
$expected_expiration->add(days => 8); |
|||
|
|||
my $r3 = Koha::Holds->find($reserve3->{reserve_id}); |
|||
is($r3->expirationdate, $expected_expiration->ymd, 'Expiration date should be set to today + 7' ); |
|||
|
|||
$dbh->rollback; |
Loading…
Reference in new issue