|
Lines 20-32
Link Here
|
| 20 |
use Modern::Perl; |
20 |
use Modern::Perl; |
| 21 |
use utf8; |
21 |
use utf8; |
| 22 |
|
22 |
|
| 23 |
use Test::More tests => 7; |
23 |
use Test::More tests => 8; |
| 24 |
use Test::NoWarnings; |
24 |
use Test::NoWarnings; |
| 25 |
|
25 |
|
| 26 |
use Test::Warn; |
26 |
use Test::Warn; |
| 27 |
|
27 |
|
| 28 |
use Test::Exception; |
28 |
use Test::Exception; |
| 29 |
|
29 |
|
|
|
30 |
use Koha::CirculationRules; |
| 30 |
use Koha::DateUtils qw( dt_from_string ); |
31 |
use Koha::DateUtils qw( dt_from_string ); |
| 31 |
use Koha::Notice::Template; |
32 |
use Koha::Notice::Template; |
| 32 |
use Koha::Notice::Templates; |
33 |
use Koha::Notice::Templates; |
|
Lines 1227-1229
subtest 'store() skips clash detection on terminal status transition' => sub {
Link Here
|
| 1227 |
|
1228 |
|
| 1228 |
$schema->storage->txn_rollback; |
1229 |
$schema->storage->txn_rollback; |
| 1229 |
}; |
1230 |
}; |
| 1230 |
- |
1231 |
|
|
|
1232 |
subtest 'lead/trail period enforcement tests' => sub { |
| 1233 |
plan tests => 8; |
| 1234 |
$schema->storage->txn_begin; |
| 1235 |
|
| 1236 |
my $patron = $builder->build_object( { class => "Koha::Patrons" } ); |
| 1237 |
t::lib::Mocks::mock_userenv( { patron => $patron } ); |
| 1238 |
|
| 1239 |
my $item = $builder->build_sample_item( { bookable => 1 } ); |
| 1240 |
my $branchcode = $item->homebranch; |
| 1241 |
my $itype = $item->effective_itemtype; |
| 1242 |
|
| 1243 |
# Set lead=3 days, trail=2 days |
| 1244 |
Koha::CirculationRules->set_rule( |
| 1245 |
{ |
| 1246 |
branchcode => $branchcode, |
| 1247 |
itemtype => $itype, |
| 1248 |
rule_name => 'bookings_lead_period', |
| 1249 |
rule_value => 3, |
| 1250 |
} |
| 1251 |
); |
| 1252 |
Koha::CirculationRules->set_rule( |
| 1253 |
{ |
| 1254 |
branchcode => $branchcode, |
| 1255 |
itemtype => $itype, |
| 1256 |
rule_name => 'bookings_trail_period', |
| 1257 |
rule_value => 2, |
| 1258 |
} |
| 1259 |
); |
| 1260 |
|
| 1261 |
# Existing booking B1: today+10 to today+20 |
| 1262 |
# B1 effective period (with lead=3, trail=2): today+7 to today+22 |
| 1263 |
my $b1_start = dt_from_string->add( days => 10 )->truncate( to => 'day' ); |
| 1264 |
my $b1_end = dt_from_string->add( days => 20 )->truncate( to => 'day' ); |
| 1265 |
my $booking1 = Koha::Booking->new( |
| 1266 |
{ |
| 1267 |
patron_id => $patron->borrowernumber, |
| 1268 |
biblio_id => $item->biblio->biblionumber, |
| 1269 |
item_id => $item->itemnumber, |
| 1270 |
pickup_library_id => $branchcode, |
| 1271 |
start_date => $b1_start, |
| 1272 |
end_date => $b1_end, |
| 1273 |
} |
| 1274 |
)->store; |
| 1275 |
ok( $booking1->in_storage, 'First booking stored OK' ); |
| 1276 |
|
| 1277 |
# FAIL: B2 ends inside B1's lead period (B2: today+5 to today+8, B1 lead starts today+7) |
| 1278 |
throws_ok { |
| 1279 |
Koha::Booking->new( |
| 1280 |
{ |
| 1281 |
patron_id => $patron->borrowernumber, |
| 1282 |
biblio_id => $item->biblio->biblionumber, |
| 1283 |
item_id => $item->itemnumber, |
| 1284 |
pickup_library_id => $branchcode, |
| 1285 |
start_date => dt_from_string->add( days => 5 )->truncate( to => 'day' ), |
| 1286 |
end_date => dt_from_string->add( days => 8 )->truncate( to => 'day' ), |
| 1287 |
} |
| 1288 |
)->store; |
| 1289 |
} |
| 1290 |
'Koha::Exceptions::Booking::Clash', |
| 1291 |
'Throws when new booking ends inside an existing booking lead period'; |
| 1292 |
|
| 1293 |
# SUCCESS: B2 ends before B1's effective period (B2: today+3 to today+4) |
| 1294 |
# B2 effective end = today+4+trail=today+6 < B1 effective start today+7 |
| 1295 |
my $booking2 = Koha::Booking->new( |
| 1296 |
{ |
| 1297 |
patron_id => $patron->borrowernumber, |
| 1298 |
biblio_id => $item->biblio->biblionumber, |
| 1299 |
item_id => $item->itemnumber, |
| 1300 |
pickup_library_id => $branchcode, |
| 1301 |
start_date => dt_from_string->add( days => 3 )->truncate( to => 'day' ), |
| 1302 |
end_date => dt_from_string->add( days => 4 )->truncate( to => 'day' ), |
| 1303 |
} |
| 1304 |
)->store; |
| 1305 |
ok( $booking2->in_storage, 'Booking OK when it ends before existing booking effective period' ); |
| 1306 |
|
| 1307 |
# FAIL: B3 starts inside B1's trail period (B3: today+22 to today+25, B1 trail ends today+22) |
| 1308 |
throws_ok { |
| 1309 |
Koha::Booking->new( |
| 1310 |
{ |
| 1311 |
patron_id => $patron->borrowernumber, |
| 1312 |
biblio_id => $item->biblio->biblionumber, |
| 1313 |
item_id => $item->itemnumber, |
| 1314 |
pickup_library_id => $branchcode, |
| 1315 |
start_date => dt_from_string->add( days => 22 )->truncate( to => 'day' ), |
| 1316 |
end_date => dt_from_string->add( days => 25 )->truncate( to => 'day' ), |
| 1317 |
} |
| 1318 |
)->store; |
| 1319 |
} |
| 1320 |
'Koha::Exceptions::Booking::Clash', |
| 1321 |
'Throws when new booking starts inside an existing booking trail period'; |
| 1322 |
|
| 1323 |
# FAIL: B3 lead period overlaps B1's trail period |
| 1324 |
# B3: today+23 to today+25, lead=3 → B3 eff start=today+20, which overlaps B1 end at today+20 |
| 1325 |
throws_ok { |
| 1326 |
Koha::Booking->new( |
| 1327 |
{ |
| 1328 |
patron_id => $patron->borrowernumber, |
| 1329 |
biblio_id => $item->biblio->biblionumber, |
| 1330 |
item_id => $item->itemnumber, |
| 1331 |
pickup_library_id => $branchcode, |
| 1332 |
start_date => dt_from_string->add( days => 23 )->truncate( to => 'day' ), |
| 1333 |
end_date => dt_from_string->add( days => 25 )->truncate( to => 'day' ), |
| 1334 |
} |
| 1335 |
)->store; |
| 1336 |
} |
| 1337 |
'Koha::Exceptions::Booking::Clash', |
| 1338 |
"Throws when new booking's lead period overlaps an existing booking's trail period"; |
| 1339 |
|
| 1340 |
# SUCCESS: B3 starts after B1's full effective period ends |
| 1341 |
# B3: today+26 to today+30, B3 eff start = today+26-3=today+23 > B1 eff end today+22 |
| 1342 |
my $booking3 = Koha::Booking->new( |
| 1343 |
{ |
| 1344 |
patron_id => $patron->borrowernumber, |
| 1345 |
biblio_id => $item->biblio->biblionumber, |
| 1346 |
item_id => $item->itemnumber, |
| 1347 |
pickup_library_id => $branchcode, |
| 1348 |
start_date => dt_from_string->add( days => 26 )->truncate( to => 'day' ), |
| 1349 |
end_date => dt_from_string->add( days => 30 )->truncate( to => 'day' ), |
| 1350 |
} |
| 1351 |
)->store; |
| 1352 |
ok( |
| 1353 |
$booking3->in_storage, |
| 1354 |
'Booking OK when new effective period starts after existing effective period ends' |
| 1355 |
); |
| 1356 |
|
| 1357 |
# Checkout tests: item must be returned at least lead_days before booking start. |
| 1358 |
# Use dates outside all existing bookings' effective periods (B3 effective end = today+32, |
| 1359 |
# so B4 effective start must be > today+32 → B4 start >= today+36). |
| 1360 |
# FAIL: checkout due today+34, booking start today+36 (lead=3 → must return by today+33) |
| 1361 |
# today+34 >= today+33 → FAIL |
| 1362 |
$builder->build_object( |
| 1363 |
{ |
| 1364 |
class => 'Koha::Checkouts', |
| 1365 |
value => { |
| 1366 |
itemnumber => $item->itemnumber, |
| 1367 |
date_due => dt_from_string->add( days => 34 )->truncate( to => 'day' )->datetime(q{ }), |
| 1368 |
} |
| 1369 |
} |
| 1370 |
); |
| 1371 |
throws_ok { |
| 1372 |
Koha::Booking->new( |
| 1373 |
{ |
| 1374 |
patron_id => $patron->borrowernumber, |
| 1375 |
biblio_id => $item->biblio->biblionumber, |
| 1376 |
item_id => $item->itemnumber, |
| 1377 |
pickup_library_id => $branchcode, |
| 1378 |
start_date => dt_from_string->add( days => 36 )->truncate( to => 'day' ), |
| 1379 |
end_date => dt_from_string->add( days => 40 )->truncate( to => 'day' ), |
| 1380 |
} |
| 1381 |
)->store; |
| 1382 |
} |
| 1383 |
'Koha::Exceptions::Booking::Clash', |
| 1384 |
'Throws when checked-out item is due within the booking lead period'; |
| 1385 |
|
| 1386 |
# SUCCESS: checkout due today+32, booking start today+36 (lead=3 → must return by today+33) |
| 1387 |
# today+32 < today+33 → OK |
| 1388 |
# Update the checkout to an earlier due date |
| 1389 |
Koha::Checkouts->search( { itemnumber => $item->itemnumber } ) |
| 1390 |
->update( { date_due => dt_from_string->add( days => 32 )->truncate( to => 'day' )->datetime(q{ }) } ); |
| 1391 |
my $booking4 = Koha::Booking->new( |
| 1392 |
{ |
| 1393 |
patron_id => $patron->borrowernumber, |
| 1394 |
biblio_id => $item->biblio->biblionumber, |
| 1395 |
item_id => $item->itemnumber, |
| 1396 |
pickup_library_id => $branchcode, |
| 1397 |
start_date => dt_from_string->add( days => 36 )->truncate( to => 'day' ), |
| 1398 |
end_date => dt_from_string->add( days => 40 )->truncate( to => 'day' ), |
| 1399 |
} |
| 1400 |
)->store; |
| 1401 |
ok( $booking4->in_storage, 'Booking OK when checkout is due before the lead period starts' ); |
| 1402 |
|
| 1403 |
$schema->storage->txn_rollback; |
| 1404 |
}; |