|
Lines 285-291
sub CanBookBeReserved{
Link Here
|
| 285 |
my $canReserve = { status => '' }; |
285 |
my $canReserve = { status => '' }; |
| 286 |
foreach my $itemnumber (@itemnumbers) { |
286 |
foreach my $itemnumber (@itemnumbers) { |
| 287 |
$canReserve = CanItemBeReserved( $borrowernumber, $itemnumber, $pickup_branchcode ); |
287 |
$canReserve = CanItemBeReserved( $borrowernumber, $itemnumber, $pickup_branchcode ); |
| 288 |
return { status => 'OK' } if $canReserve->{status} eq 'OK'; |
288 |
return $canReserve if $canReserve->{status} eq 'OK'; |
| 289 |
} |
289 |
} |
| 290 |
return $canReserve; |
290 |
return $canReserve; |
| 291 |
} |
291 |
} |
|
Lines 323-353
sub CanItemBeReserved {
Link Here
|
| 323 |
my $patron = Koha::Patrons->find( $borrowernumber ); |
323 |
my $patron = Koha::Patrons->find( $borrowernumber ); |
| 324 |
my $borrower = $patron->unblessed; |
324 |
my $borrower = $patron->unblessed; |
| 325 |
|
325 |
|
| 326 |
# If an item is damaged and we don't allow holds on damaged items, we can stop right here |
|
|
| 327 |
return { status =>'damaged' } |
| 328 |
if ( $item->damaged |
| 329 |
&& !C4::Context->preference('AllowHoldsOnDamagedItems') ); |
| 330 |
|
| 331 |
# Check for the age restriction |
| 332 |
my ( $ageRestriction, $daysToAgeRestriction ) = |
| 333 |
C4::Circulation::GetAgeRestriction( $biblio->biblioitem->agerestriction, $borrower ); |
| 334 |
return { status => 'ageRestricted' } if $daysToAgeRestriction && $daysToAgeRestriction > 0; |
| 335 |
|
| 336 |
# Check that the patron doesn't have an item level hold on this item already |
| 337 |
return { status =>'itemAlreadyOnHold' } |
| 338 |
if Koha::Holds->search( { borrowernumber => $borrowernumber, itemnumber => $itemnumber } )->count(); |
| 339 |
|
| 340 |
my $controlbranch = C4::Context->preference('ReservesControlBranch'); |
326 |
my $controlbranch = C4::Context->preference('ReservesControlBranch'); |
| 341 |
|
327 |
|
| 342 |
my $querycount = q{ |
|
|
| 343 |
SELECT count(*) AS count |
| 344 |
FROM reserves |
| 345 |
LEFT JOIN items USING (itemnumber) |
| 346 |
LEFT JOIN biblioitems ON (reserves.biblionumber=biblioitems.biblionumber) |
| 347 |
LEFT JOIN borrowers USING (borrowernumber) |
| 348 |
WHERE borrowernumber = ? |
| 349 |
}; |
| 350 |
|
| 351 |
my $branchcode = ""; |
328 |
my $branchcode = ""; |
| 352 |
my $branchfield = "reserves.branchcode"; |
329 |
my $branchfield = "reserves.branchcode"; |
| 353 |
|
330 |
|
|
Lines 361-376
sub CanItemBeReserved {
Link Here
|
| 361 |
} |
338 |
} |
| 362 |
|
339 |
|
| 363 |
# we retrieve rights |
340 |
# we retrieve rights |
| 364 |
if ( my $rights = GetHoldRule( $borrower->{'categorycode'}, $item->effective_itemtype, $branchcode ) ) { |
341 |
my $issuingrule; |
| 365 |
$ruleitemtype = $rights->{itemtype}; |
342 |
if ( $issuingrule = GetHoldRule( $borrower->{'categorycode'}, $item->effective_itemtype, $branchcode ) ) { |
| 366 |
$allowedreserves = $rights->{reservesallowed}; |
343 |
$ruleitemtype = $issuingrule->{itemtype}; |
| 367 |
$holds_per_record = $rights->{holds_per_record}; |
344 |
$allowedreserves = $issuingrule->{reservesallowed}; |
| 368 |
$holds_per_day = $rights->{holds_per_day}; |
345 |
$holds_per_record = $issuingrule->{holds_per_record}; |
|
|
346 |
$holds_per_day = $issuingrule->{holds_per_day}; |
| 369 |
} |
347 |
} |
| 370 |
else { |
348 |
else { |
| 371 |
$ruleitemtype = '*'; |
349 |
$ruleitemtype = '*'; |
| 372 |
} |
350 |
} |
| 373 |
|
351 |
|
|
|
352 |
my $circulation_rule = Koha::CirculationRules->get_effective_rule( |
| 353 |
{ |
| 354 |
categorycode => $borrower->{categorycode}, |
| 355 |
branchcode => $branchcode, |
| 356 |
rule_name => 'max_holds', |
| 357 |
} |
| 358 |
); |
| 359 |
|
| 360 |
# If an item is damaged and we don't allow holds on damaged items, we can stop right here |
| 361 |
return { status =>'damaged', issuingrule => $issuingrule, circulation_rule => $circulation_rule } |
| 362 |
if ( $item->damaged |
| 363 |
&& !C4::Context->preference('AllowHoldsOnDamagedItems') ); |
| 364 |
|
| 365 |
# Check for the age restriction |
| 366 |
my ( $ageRestriction, $daysToAgeRestriction ) = |
| 367 |
C4::Circulation::GetAgeRestriction( $biblio->biblioitem->agerestriction, $borrower ); |
| 368 |
return { status => 'ageRestricted', issuingrule => $issuingrule, circulation_rule => $circulation_rule } if $daysToAgeRestriction && $daysToAgeRestriction > 0; |
| 369 |
|
| 370 |
# Check that the patron doesn't have an item level hold on this item already |
| 371 |
return { status =>'itemAlreadyOnHold', issuingrule => $issuingrule, circulation_rule => $circulation_rule } |
| 372 |
if Koha::Holds->search( { borrowernumber => $borrowernumber, itemnumber => $itemnumber } )->count(); |
| 373 |
|
| 374 |
my $querycount = q{ |
| 375 |
SELECT count(*) AS count |
| 376 |
FROM reserves |
| 377 |
LEFT JOIN items USING (itemnumber) |
| 378 |
LEFT JOIN biblioitems ON (reserves.biblionumber=biblioitems.biblionumber) |
| 379 |
LEFT JOIN borrowers USING (borrowernumber) |
| 380 |
WHERE borrowernumber = ? |
| 381 |
}; |
| 382 |
|
| 383 |
$item = Koha::Items->find( $itemnumber ); |
| 374 |
my $holds = Koha::Holds->search( |
384 |
my $holds = Koha::Holds->search( |
| 375 |
{ |
385 |
{ |
| 376 |
borrowernumber => $borrowernumber, |
386 |
borrowernumber => $borrowernumber, |
|
Lines 379-385
sub CanItemBeReserved {
Link Here
|
| 379 |
} |
389 |
} |
| 380 |
); |
390 |
); |
| 381 |
if ( $holds->count() >= $holds_per_record ) { |
391 |
if ( $holds->count() >= $holds_per_record ) { |
| 382 |
return { status => "tooManyHoldsForThisRecord", limit => $holds_per_record }; |
392 |
$issuingrule->{exceeded} = 'holds_per_record'; |
|
|
393 |
return { status => "tooManyHoldsForThisRecord", |
| 394 |
limit => $holds_per_record, |
| 395 |
issuingrule => $issuingrule, |
| 396 |
circulation_rule => $circulation_rule }; |
| 383 |
} |
397 |
} |
| 384 |
|
398 |
|
| 385 |
my $today_holds = Koha::Holds->search({ |
399 |
my $today_holds = Koha::Holds->search({ |
|
Lines 391-397
sub CanItemBeReserved {
Link Here
|
| 391 |
( ( $holds_per_day > 0 && $today_holds->count() >= $holds_per_day ) |
405 |
( ( $holds_per_day > 0 && $today_holds->count() >= $holds_per_day ) |
| 392 |
or ( $holds_per_day == 0 ) ) |
406 |
or ( $holds_per_day == 0 ) ) |
| 393 |
) { |
407 |
) { |
| 394 |
return { status => 'tooManyReservesToday', limit => $holds_per_day }; |
408 |
$issuingrule->{exceeded} = 'holds_per_day'; |
|
|
409 |
return { status => 'tooManyReservesToday', |
| 410 |
limit => $holds_per_day, |
| 411 |
issuingrule => $issuingrule, |
| 412 |
circulation_rule => $circulation_rule }; |
| 395 |
} |
413 |
} |
| 396 |
|
414 |
|
| 397 |
# we retrieve count |
415 |
# we retrieve count |
|
Lines 422-446
sub CanItemBeReserved {
Link Here
|
| 422 |
|
440 |
|
| 423 |
# we check if it's ok or not |
441 |
# we check if it's ok or not |
| 424 |
if ( $reservecount >= $allowedreserves ) { |
442 |
if ( $reservecount >= $allowedreserves ) { |
| 425 |
return { status => 'tooManyReserves', limit => $allowedreserves }; |
443 |
$issuingrule->{exceeded} = 'allowedreserves'; |
|
|
444 |
return { status => 'tooManyReserves', |
| 445 |
limit => $allowedreserves, |
| 446 |
issuingrule => $issuingrule, |
| 447 |
circulation_rule => $circulation_rule }; |
| 426 |
} |
448 |
} |
| 427 |
|
449 |
|
| 428 |
# Now we need to check hold limits by patron category |
450 |
# Now we need to check hold limits by patron category |
| 429 |
my $rule = Koha::CirculationRules->get_effective_rule( |
451 |
if ( $circulation_rule && defined( $circulation_rule->rule_value ) && $circulation_rule->rule_value ne '' ) { |
| 430 |
{ |
|
|
| 431 |
categorycode => $borrower->{categorycode}, |
| 432 |
branchcode => $branchcode, |
| 433 |
rule_name => 'max_holds', |
| 434 |
} |
| 435 |
); |
| 436 |
if ( $rule && defined( $rule->rule_value ) && $rule->rule_value ne '' ) { |
| 437 |
my $total_holds_count = Koha::Holds->search( |
452 |
my $total_holds_count = Koha::Holds->search( |
| 438 |
{ |
453 |
{ |
| 439 |
borrowernumber => $borrower->{borrowernumber} |
454 |
borrowernumber => $borrower->{borrowernumber} |
| 440 |
} |
455 |
} |
| 441 |
)->count(); |
456 |
)->count(); |
| 442 |
|
457 |
|
| 443 |
return { status => 'tooManyReserves', limit => $rule->rule_value} if $total_holds_count >= $rule->rule_value; |
458 |
return { |
|
|
459 |
status => 'tooManyReserves', |
| 460 |
limit => $circulation_rule->rule_value, |
| 461 |
issuingrule => $issuingrule, |
| 462 |
circulation_rule => $circulation_rule, |
| 463 |
circulation_rule_exceeded => 1 |
| 464 |
} if $total_holds_count >= $circulation_rule->rule_value; |
| 444 |
} |
465 |
} |
| 445 |
|
466 |
|
| 446 |
my $reserves_control_branch = |
467 |
my $reserves_control_branch = |
|
Lines 449-461
sub CanItemBeReserved {
Link Here
|
| 449 |
C4::Circulation::GetBranchItemRule( $reserves_control_branch, $item->itype ); # FIXME Should not be item->effective_itemtype? |
470 |
C4::Circulation::GetBranchItemRule( $reserves_control_branch, $item->itype ); # FIXME Should not be item->effective_itemtype? |
| 450 |
|
471 |
|
| 451 |
if ( $branchitemrule->{holdallowed} == 0 ) { |
472 |
if ( $branchitemrule->{holdallowed} == 0 ) { |
| 452 |
return { status => 'notReservable' }; |
473 |
return { status => 'notReservable', issuingrule => $issuingrule, circulation_rule => $circulation_rule }; |
| 453 |
} |
474 |
} |
| 454 |
|
475 |
|
| 455 |
if ( $branchitemrule->{holdallowed} == 1 |
476 |
if ( $branchitemrule->{holdallowed} == 1 |
| 456 |
&& $borrower->{branchcode} ne $item->homebranch ) |
477 |
&& $borrower->{branchcode} ne $item->homebranch ) |
| 457 |
{ |
478 |
{ |
| 458 |
return { status => 'cannotReserveFromOtherBranches' }; |
479 |
return { status => 'cannotReserveFromOtherBranches', issuingrule => $issuingrule, circulation_rule => $circulation_rule }; |
| 459 |
} |
480 |
} |
| 460 |
|
481 |
|
| 461 |
# If reservecount is ok, we check item branch if IndependentBranches is ON |
482 |
# If reservecount is ok, we check item branch if IndependentBranches is ON |
|
Lines 464-470
sub CanItemBeReserved {
Link Here
|
| 464 |
and !C4::Context->preference('canreservefromotherbranches') ) |
485 |
and !C4::Context->preference('canreservefromotherbranches') ) |
| 465 |
{ |
486 |
{ |
| 466 |
if ( $item->homebranch ne $borrower->{branchcode} ) { |
487 |
if ( $item->homebranch ne $borrower->{branchcode} ) { |
| 467 |
return { status => 'cannotReserveFromOtherBranches' }; |
488 |
return { status => 'cannotReserveFromOtherBranches', issuingrule => $issuingrule, circulation_rule => $circulation_rule }; |
| 468 |
} |
489 |
} |
| 469 |
} |
490 |
} |
| 470 |
|
491 |
|
|
Lines 474-490
sub CanItemBeReserved {
Link Here
|
| 474 |
}); |
495 |
}); |
| 475 |
|
496 |
|
| 476 |
unless ($destination) { |
497 |
unless ($destination) { |
| 477 |
return { status => 'libraryNotFound' }; |
498 |
return { status => 'libraryNotFound', issuingrule => $issuingrule, circulation_rule => $circulation_rule }; |
| 478 |
} |
499 |
} |
| 479 |
unless ($destination->pickup_location) { |
500 |
unless ($destination->pickup_location) { |
| 480 |
return { status => 'libraryNotPickupLocation' }; |
501 |
return { status => 'libraryNotPickupLocation', issuingrule => $issuingrule, circulation_rule => $circulation_rule }; |
| 481 |
} |
502 |
} |
| 482 |
unless ($item->can_be_transferred({ to => $destination })) { |
503 |
unless ($item->can_be_transferred({ to => $destination })) { |
| 483 |
return { status => 'cannotBeTransferred' }; |
504 |
return { status => 'cannotBeTransferred' }; |
| 484 |
} |
505 |
} |
| 485 |
} |
506 |
} |
| 486 |
|
507 |
|
| 487 |
return { status => 'OK' }; |
508 |
return { status => 'OK', issuingrule => $issuingrule, circulation_rule => $circulation_rule }; |
| 488 |
} |
509 |
} |
| 489 |
|
510 |
|
| 490 |
=head2 CanReserveBeCanceledFromOpac |
511 |
=head2 CanReserveBeCanceledFromOpac |