Bugzilla – Attachment 183198 Details for
Bug 40101
Add `Koha::Patron->can_place_holds`
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 40101: Add `Koha::Patron->can_place_holds()`
Bug-40101-Add-KohaPatron-canplaceholds.patch (text/plain), 6.44 KB, created by
Andrew Fuerste-Henry
on 2025-06-12 12:37:17 UTC
(
hide
)
Description:
Bug 40101: Add `Koha::Patron->can_place_holds()`
Filename:
MIME Type:
Creator:
Andrew Fuerste-Henry
Created:
2025-06-12 12:37:17 UTC
Size:
6.44 KB
patch
obsolete
>From 776ad5f3c0f7dfdbfecd6d0917a9d0ada416b0be Mon Sep 17 00:00:00 2001 >From: Tomas Cohen Arazi <tomascohen@theke.io> >Date: Mon, 9 Jun 2025 13:46:12 -0300 >Subject: [PATCH] Bug 40101: Add `Koha::Patron->can_place_holds()` > >This patch adds a new method to the `Koha::Patron` class. > >As described in the POD, this method makes checks on the patron's >current situation and returns a boolean telling if it should be allowed >to place holds. This doesn't check specific item/biblio holdability. It >only covers patron specific conditions that could prevent holds to be >placed. > >Both in `opac-reserve.pl` and `reserve/request.pl` this checks are all >run, and all blocking situations are presented to the UI user. Feedback >in community (so far) expressed this is a desirable situation, so that >behavior can be retained with the use of the `no_short_circuit` >parameter. > >If `no_short_circuit` is not passed, then the routine will return on the >first blocking condition it finds. > >An `overrides` parameter is added, allowing to be passed a list of >strings that match the possible error messages. > >This way, this method can be asked not to check for patron expiration, >for example, and things like that. This is of course designed with the >API overrides use case in mind. > >To test: >1. Apply this patches >2. Run: > $ ktd --shell > k$ prove t/db_dependent/Koha/Patron.t >=> SUCCESS: Tests pass! >3. Sign off :-D > >Signed-off-by: Tomas Cohen Arazi <tomascohen@theke.io> > >Signed-off-by: Kristi Krueger <kkrueger@cuyahogalibrary.org> >--- > Koha/Patron.pm | 152 +++++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 152 insertions(+) > >diff --git a/Koha/Patron.pm b/Koha/Patron.pm >index dcfff7aeb08..14d5838e6be 100644 >--- a/Koha/Patron.pm >+++ b/Koha/Patron.pm >@@ -1318,6 +1318,158 @@ sub move_to_deleted { > return Koha::Database->new->schema->resultset('Deletedborrower')->create($patron_infos); > } > >+=head3 can_place_holds >+ >+ my $result = $patron->can_place_holds(); >+ my $result = $patron->can_place_holds( >+ { >+ overrides => { debt_limit => 1, card_lost => 1 }, >+ no_short_circuit => 1 >+ } >+ ); >+ >+ if ( $patron->can_place_holds() ) { >+ # patron can place holds >+ } else { >+ my @messages = $result->messages; >+ # handle error messages >+ } >+ >+Checks if a patron is allowed to place holds based on various patron conditions. >+ >+=head4 Parameters >+ >+=over 4 >+ >+=item * C<$options> (optional) - Hashref with the following keys: >+ >+=over 8 >+ >+=item * C<overrides> - Hashref of checks to skip. Keys should match error message codes. >+ >+=item * C<no_short_circuit> - Boolean. If true, performs all checks and collects all error messages instead of stopping at first failure. Default: false. >+ >+=back >+ >+=back >+ >+=head4 Returns >+ >+Koha::Result::Boolean object - true if patron can place holds, false otherwise. >+When false, the result object contains error messages with details about why >+holds are blocked. >+ >+=head4 Error Messages >+ >+The following error message codes may be returned: >+ >+=over 4 >+ >+=item * C<expired> - Patron account has expired and expired patrons are blocked from placing holds >+ >+=item * C<debt_limit> - Patron owes more than the maximum allowed outstanding amount >+ >+=item * C<bad_address> - Patron's address is marked as incorrect >+ >+=item * C<card_lost> - Patron's library card is marked as lost >+ >+=item * C<restricted> - Patron account is restricted/debarred >+ >+=item * C<hold_limit> - Patron has reached the maximum number of allowed holds >+ >+=back >+ >+Error messages may include additional payload data with relevant details >+(amounts, limits, counts, etc.). >+ >+=cut >+ >+sub can_place_holds { >+ my ( $self, $options ) = @_; >+ $options //= {}; >+ >+ my $overrides = $options->{overrides} // {}; >+ my $no_short_circuit = $options->{no_short_circuit} // 0; >+ >+ my $result = Koha::Result::Boolean->new(1); >+ >+ # expired patron check >+ unless ( $overrides->{expired} ) { >+ if ( $self->is_expired && $self->category->effective_BlockExpiredPatronOpacActions_contains('hold') ) { >+ $result->set_value(0); >+ $result->add_message( { message => 'expired', type => 'error' } ); >+ >+ return $result unless $no_short_circuit; >+ } >+ } >+ >+ # debt check >+ unless ( $overrides->{debt_limit} ) { >+ my $max_outstanding = C4::Context->preference("maxoutstanding"); >+ my $outstanding = $self->account->balance; >+ >+ if ( $max_outstanding && $outstanding && ( $outstanding > $max_outstanding ) ) { >+ $result->set_value(0); >+ $result->add_message( >+ { >+ message => 'debt_limit', type => 'error', >+ payload => { total_outstanding => $outstanding, max_outstanding => $max_outstanding } >+ } >+ ); >+ >+ return $result unless $no_short_circuit; >+ } >+ } >+ >+ # check address marked as incorrect >+ unless ( $overrides->{bad_address} ) { >+ if ( $self->gonenoaddress ) { >+ $result->set_value(0); >+ $result->add_message( { message => 'bad_address', type => 'error' } ); >+ >+ return $result unless $no_short_circuit; >+ } >+ } >+ >+ # check lost card >+ unless ( $overrides->{card_lost} ) { >+ if ( $self->lost ) { >+ $result->set_value(0); >+ $result->add_message( { message => 'card_lost', type => 'error' } ); >+ return $result unless $no_short_circuit; >+ } >+ } >+ >+ # check restrictions >+ unless ( $overrides->{restricted} ) { >+ if ( $self->is_debarred ) { >+ $result->set_value(0); >+ $result->add_message( { message => 'restricted', type => 'error' } ); >+ >+ return $result unless $no_short_circuit; >+ } >+ } >+ >+ # check max reserves >+ unless ( $overrides->{hold_limit} ) { >+ my $max_holds = C4::Context->preference("maxreserves"); >+ my $holds_count = $self->holds->count; >+ if ( $max_holds && ( $holds_count >= $max_holds ) ) { >+ $result->set_value(0); >+ $result->add_message( >+ { >+ message => 'hold_limit', type => 'error', >+ payload => { total_holds => $holds_count, max_holds => $max_holds } >+ } >+ ); >+ >+ return $result unless $no_short_circuit; >+ } >+ } >+ >+ return $result; >+} >+ > =head3 can_request_article > > if ( $patron->can_request_article( $library->id ) ) { ... } >-- >2.39.5
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 40101
:
183104
|
183105
|
183106
|
183197
|
183198
|
183199
|
183204
|
183242
|
183243
|
183244
|
183488
|
183489
|
183490