|
Lines 1318-1323
sub move_to_deleted {
Link Here
|
| 1318 |
return Koha::Database->new->schema->resultset('Deletedborrower')->create($patron_infos); |
1318 |
return Koha::Database->new->schema->resultset('Deletedborrower')->create($patron_infos); |
| 1319 |
} |
1319 |
} |
| 1320 |
|
1320 |
|
|
|
1321 |
=head3 can_place_holds |
| 1322 |
|
| 1323 |
my $result = $patron->can_place_holds(); |
| 1324 |
my $result = $patron->can_place_holds( |
| 1325 |
{ |
| 1326 |
overrides => { debt_limit => 1, card_lost => 1 }, |
| 1327 |
no_short_circuit => 1 |
| 1328 |
} |
| 1329 |
); |
| 1330 |
|
| 1331 |
if ( $patron->can_place_holds() ) { |
| 1332 |
# patron can place holds |
| 1333 |
} else { |
| 1334 |
my @messages = $result->messages; |
| 1335 |
# handle error messages |
| 1336 |
} |
| 1337 |
|
| 1338 |
Checks if a patron is allowed to place holds based on various patron conditions. |
| 1339 |
|
| 1340 |
=head4 Parameters |
| 1341 |
|
| 1342 |
=over 4 |
| 1343 |
|
| 1344 |
=item * C<$options> (optional) - Hashref with the following keys: |
| 1345 |
|
| 1346 |
=over 8 |
| 1347 |
|
| 1348 |
=item * C<overrides> - Hashref of checks to skip. Keys should match error message codes. |
| 1349 |
|
| 1350 |
=item * C<no_short_circuit> - Boolean. If true, performs all checks and collects all error messages instead of stopping at first failure. Default: false. |
| 1351 |
|
| 1352 |
=back |
| 1353 |
|
| 1354 |
=back |
| 1355 |
|
| 1356 |
=head4 Returns |
| 1357 |
|
| 1358 |
Koha::Result::Boolean object - true if patron can place holds, false otherwise. |
| 1359 |
When false, the result object contains error messages with details about why |
| 1360 |
holds are blocked. |
| 1361 |
|
| 1362 |
=head4 Error Messages |
| 1363 |
|
| 1364 |
The following error message codes may be returned: |
| 1365 |
|
| 1366 |
=over 4 |
| 1367 |
|
| 1368 |
=item * C<expired> - Patron account has expired and expired patrons are blocked from placing holds |
| 1369 |
|
| 1370 |
=item * C<debt_limit> - Patron owes more than the maximum allowed outstanding amount |
| 1371 |
|
| 1372 |
=item * C<bad_address> - Patron's address is marked as incorrect |
| 1373 |
|
| 1374 |
=item * C<card_lost> - Patron's library card is marked as lost |
| 1375 |
|
| 1376 |
=item * C<restricted> - Patron account is restricted/debarred |
| 1377 |
|
| 1378 |
=item * C<hold_limit> - Patron has reached the maximum number of allowed holds |
| 1379 |
|
| 1380 |
=back |
| 1381 |
|
| 1382 |
Error messages may include additional payload data with relevant details |
| 1383 |
(amounts, limits, counts, etc.). |
| 1384 |
|
| 1385 |
=cut |
| 1386 |
|
| 1387 |
sub can_place_holds { |
| 1388 |
my ( $self, $options ) = @_; |
| 1389 |
$options //= {}; |
| 1390 |
|
| 1391 |
my $overrides = $options->{overrides} // {}; |
| 1392 |
my $no_short_circuit = $options->{no_short_circuit} // 0; |
| 1393 |
|
| 1394 |
my $result = Koha::Result::Boolean->new(1); |
| 1395 |
|
| 1396 |
# expired patron check |
| 1397 |
unless ( $overrides->{expired} ) { |
| 1398 |
if ( $self->is_expired && $self->category->effective_BlockExpiredPatronOpacActions_contains('hold') ) { |
| 1399 |
$result->set_value(0); |
| 1400 |
$result->add_message( { message => 'expired', type => 'error' } ); |
| 1401 |
|
| 1402 |
return $result unless $no_short_circuit; |
| 1403 |
} |
| 1404 |
} |
| 1405 |
|
| 1406 |
# debt check |
| 1407 |
unless ( $overrides->{debt_limit} ) { |
| 1408 |
my $max_outstanding = C4::Context->preference("maxoutstanding"); |
| 1409 |
my $outstanding = $self->account->balance; |
| 1410 |
|
| 1411 |
if ( $max_outstanding && $outstanding && ( $outstanding > $max_outstanding ) ) { |
| 1412 |
$result->set_value(0); |
| 1413 |
$result->add_message( |
| 1414 |
{ |
| 1415 |
message => 'debt_limit', type => 'error', |
| 1416 |
payload => { total_outstanding => $outstanding, max_outstanding => $max_outstanding } |
| 1417 |
} |
| 1418 |
); |
| 1419 |
|
| 1420 |
return $result unless $no_short_circuit; |
| 1421 |
} |
| 1422 |
} |
| 1423 |
|
| 1424 |
# check address marked as incorrect |
| 1425 |
unless ( $overrides->{bad_address} ) { |
| 1426 |
if ( $self->gonenoaddress ) { |
| 1427 |
$result->set_value(0); |
| 1428 |
$result->add_message( { message => 'bad_address', type => 'error' } ); |
| 1429 |
|
| 1430 |
return $result unless $no_short_circuit; |
| 1431 |
} |
| 1432 |
} |
| 1433 |
|
| 1434 |
# check lost card |
| 1435 |
unless ( $overrides->{card_lost} ) { |
| 1436 |
if ( $self->lost ) { |
| 1437 |
$result->set_value(0); |
| 1438 |
$result->add_message( { message => 'card_lost', type => 'error' } ); |
| 1439 |
return $result unless $no_short_circuit; |
| 1440 |
} |
| 1441 |
} |
| 1442 |
|
| 1443 |
# check restrictions |
| 1444 |
unless ( $overrides->{restricted} ) { |
| 1445 |
if ( $self->is_debarred ) { |
| 1446 |
$result->set_value(0); |
| 1447 |
$result->add_message( { message => 'restricted', type => 'error' } ); |
| 1448 |
|
| 1449 |
return $result unless $no_short_circuit; |
| 1450 |
} |
| 1451 |
} |
| 1452 |
|
| 1453 |
# check max reserves |
| 1454 |
unless ( $overrides->{hold_limit} ) { |
| 1455 |
my $max_holds = C4::Context->preference("maxreserves"); |
| 1456 |
my $holds_count = $self->holds->count; |
| 1457 |
if ( $max_holds && ( $holds_count >= $max_holds ) ) { |
| 1458 |
$result->set_value(0); |
| 1459 |
$result->add_message( |
| 1460 |
{ |
| 1461 |
message => 'hold_limit', type => 'error', |
| 1462 |
payload => { total_holds => $holds_count, max_holds => $max_holds } |
| 1463 |
} |
| 1464 |
); |
| 1465 |
|
| 1466 |
return $result unless $no_short_circuit; |
| 1467 |
} |
| 1468 |
} |
| 1469 |
|
| 1470 |
return $result; |
| 1471 |
} |
| 1472 |
|
| 1321 |
=head3 can_request_article |
1473 |
=head3 can_request_article |
| 1322 |
|
1474 |
|
| 1323 |
if ( $patron->can_request_article( $library->id ) ) { ... } |
1475 |
if ( $patron->can_request_article( $library->id ) ) { ... } |
| 1324 |
- |
|
|