Bugzilla – Attachment 192133 Details for
Bug 41728
Add `Koha::Item::Checkin::Availability` to centralize logic
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
[POC]Â Bug 41728: Add Koha::Item::Checkout::Availability class
7d32a15.patch (text/plain), 9.29 KB, created by
Tomás Cohen Arazi (tcohen)
on 2026-01-28 19:55:17 UTC
(
hide
)
Description:
[POC]Â Bug 41728: Add Koha::Item::Checkout::Availability class
Filename:
MIME Type:
Creator:
Tomás Cohen Arazi (tcohen)
Created:
2026-01-28 19:55:17 UTC
Size:
9.29 KB
patch
obsolete
>From 7d32a15947b1f55e4db462f18ad5a6b7207dba68 Mon Sep 17 00:00:00 2001 >From: =?UTF-8?q?Tom=C3=A1s=20Cohen=20Arazi?= <tomascohen@theke.io> >Date: Wed, 28 Jan 2026 16:29:06 -0300 >Subject: [PATCH] =?UTF-8?q?[POC]=C2=A0Bug=2041728:=20Add=20Koha::Item::Che?= > =?UTF-8?q?ckout::Availability=20class?= >MIME-Version: 1.0 >Content-Type: text/plain; charset=UTF-8 >Content-Transfer-Encoding: 8bit > >This is for illustration purposes only! Not intended to be tested or pushed. > >This patch introduces a checkout availability class that wraps >C4::Circulation::CanBookBeIssued in a Result object interface, >providing a consistent API for availability checks. > >The class: >- Wraps CanBookBeIssued and maps its return values to Result object >- Maps 'impossible' to blockers >- Maps 'confirmation' to confirmations >- Maps 'alerts' and 'messages' to warnings >- Provides $item->checkout_availability() convenience method > >This enables the REST API and other code to use a consistent >availability checking interface across different operations >(checkout, check-in, renewal, etc.). > >Test plan: >1. Apply patch >2. Run: > $ ktd --shell > k$ prove t/db_dependent/Koha/Item/Checkout/Availability.t >=> SUCCESS: Tests pass! >3. Verify checkout availability checks work: > - Available items return no blockers > - Debarred patrons get DEBARRED blocker > - Context includes patron and item objects >4. Sign off :-D >--- > Koha/Item.pm | 29 +++++ > Koha/Item/Checkout/Availability.pm | 122 ++++++++++++++++++ > .../Koha/Item/Checkout/Availability.t | 82 ++++++++++++ > 3 files changed, 233 insertions(+) > create mode 100644 Koha/Item/Checkout/Availability.pm > create mode 100644 t/db_dependent/Koha/Item/Checkout/Availability.t > >diff --git a/Koha/Item.pm b/Koha/Item.pm >index 8d239dc14c..a7cada5163 100644 >--- a/Koha/Item.pm >+++ b/Koha/Item.pm >@@ -807,6 +807,35 @@ sub checkin_availability { > return Koha::Item::Checkin::Availability->check( $self, $params ); > } > >+=head3 checkout_availability >+ >+ my $availability = $item->checkout_availability( >+ { >+ patron => $patron, >+ } >+ ); >+ >+Returns checkout availability information for this item. >+ >+This is a convenience method that calls Koha::Item::Checkout::Availability->check(). >+ >+Returns a Koha::Availability::Result object with methods: >+ available() # Boolean: true if checkout allowed >+ needs_confirmation()# Boolean: true if confirmation required >+ blockers() # Hashref of blocking conditions >+ confirmations() # Hashref of conditions requiring confirmation >+ warnings() # Hashref of warning messages >+ context() # Hashref with patron and item objects >+ >+=cut >+ >+sub checkout_availability { >+ my ( $self, $params ) = @_; >+ >+ require Koha::Item::Checkout::Availability; >+ return Koha::Item::Checkout::Availability->check( $self, $params ); >+} >+ > =head3 request_transfer > > my $transfer = $item->request_transfer( >diff --git a/Koha/Item/Checkout/Availability.pm b/Koha/Item/Checkout/Availability.pm >new file mode 100644 >index 0000000000..47a99b65c5 >--- /dev/null >+++ b/Koha/Item/Checkout/Availability.pm >@@ -0,0 +1,122 @@ >+package Koha::Item::Checkout::Availability; >+ >+# Copyright 2026 Koha Development Team >+# >+# This file is part of Koha. >+# >+# Koha is free software; you can redistribute it and/or modify it >+# under the terms of the GNU General Public License as published by >+# the Free Software Foundation; either version 3 of the License, or >+# (at your option) any later version. >+# >+# Koha is distributed in the hope that it will be useful, but >+# WITHOUT ANY WARRANTY; without even the implied warranty of >+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >+# GNU General Public License for more details. >+# >+# You should have received a copy of the GNU General Public License >+# along with Koha; if not, see <https://www.gnu.org/licenses>. >+ >+use Modern::Perl; >+ >+use C4::Circulation qw( CanBookBeIssued ); >+use Koha::Availability::Result; >+ >+=head1 NAME >+ >+Koha::Item::Checkout::Availability - Checkout availability validation for items >+ >+=head1 SYNOPSIS >+ >+ my $availability = Koha::Item::Checkout::Availability->check( $item, >+ { >+ patron => $patron, >+ } >+ ); >+ >+ # Or via instance method >+ my $availability = $item->checkout_availability( { patron => $patron } ); >+ >+=head1 DESCRIPTION >+ >+This class provides validation logic for item checkout operations, wrapping >+C4::Circulation::CanBookBeIssued in a Result object interface. >+ >+The result categorizes conditions as: >+- blockers: Prevent checkout (e.g., item already checked out, patron debarred) >+- confirmations: Require user confirmation (e.g., item on hold for another patron) >+- warnings: Informational (e.g., patron has many checkouts) >+ >+=head1 API >+ >+=head2 Class methods >+ >+=head3 check >+ >+ my $availability = Koha::Item::Checkout::Availability->check( $item, >+ { >+ patron => $patron, >+ } >+ ); >+ >+Validates checkout availability for an item. >+ >+Parameters: >+ $item - Koha::Item object (required) >+ $params - hashref with: >+ patron => $patron (required) >+ >+Returns a Koha::Availability::Result object with: >+ blockers => {} # Conditions that prevent checkout >+ confirmations => {} # Conditions requiring confirmation >+ warnings => {} # Informational messages >+ context => { >+ patron => $patron # Koha::Patron object >+ item => $item # Koha::Item object >+ } >+ >+=cut >+ >+sub check { >+ my ( $class, $item, $params ) = @_; >+ >+ my $patron = $params->{patron}; >+ >+ my $result = Koha::Availability::Result->new(); >+ >+ # Set context >+ $result->set_context( patron => $patron ); >+ $result->set_context( item => $item ); >+ >+ # Call CanBookBeIssued >+ my ( $impossible, $confirmation, $alerts, $messages ) = >+ CanBookBeIssued( $patron, undef, undef, 0, 0, { item => $item } ); >+ >+ # Map impossible to blockers >+ for my $key ( keys %{$impossible} ) { >+ $result->add_blocker( $key => $impossible->{$key} ); >+ } >+ >+ # Map confirmation to confirmations >+ for my $key ( keys %{$confirmation} ) { >+ $result->add_confirmation( $key => $confirmation->{$key} ); >+ } >+ >+ # Map alerts and messages to warnings >+ for my $key ( keys %{$alerts} ) { >+ $result->add_warning( $key => $alerts->{$key} ); >+ } >+ for my $key ( keys %{$messages} ) { >+ $result->add_warning( $key => $messages->{$key} ); >+ } >+ >+ return $result; >+} >+ >+=head1 AUTHOR >+ >+Koha Development Team <https://koha-community.org/> >+ >+=cut >+ >+1; >diff --git a/t/db_dependent/Koha/Item/Checkout/Availability.t b/t/db_dependent/Koha/Item/Checkout/Availability.t >new file mode 100644 >index 0000000000..32d82461cd >--- /dev/null >+++ b/t/db_dependent/Koha/Item/Checkout/Availability.t >@@ -0,0 +1,82 @@ >+#!/usr/bin/perl >+ >+# Copyright 2026 Koha Development Team >+# >+# This file is part of Koha >+# >+# Koha is free software; you can redistribute it and/or modify it >+# under the terms of the GNU General Public License as published by >+# the Free Software Foundation; either version 3 of the License, or >+# (at your option) any later version. >+# >+# Koha is distributed in the hope that it will be useful, but >+# WITHOUT ANY WARRANTY; without even the implied warranty of >+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >+# GNU General Public License for more details. >+# >+# You should have received a copy of the GNU General Public License >+# along with Koha; if not, see <https://www.gnu.org/licenses>. >+ >+use Modern::Perl; >+ >+use Test::More tests => 3; >+use Test::NoWarnings; >+ >+use t::lib::TestBuilder; >+use t::lib::Mocks; >+ >+use Koha::Database; >+ >+my $schema = Koha::Database->new->schema; >+my $builder = t::lib::TestBuilder->new; >+ >+subtest 'check() - available item' => sub { >+ >+ plan tests => 4; >+ >+ $schema->storage->txn_begin; >+ >+ my $library = $builder->build_object( { class => 'Koha::Libraries' } ); >+ my $patron = $builder->build_object( { class => 'Koha::Patrons' } ); >+ my $item = $builder->build_sample_item(); >+ >+ my $result = $item->checkout_availability( >+ { >+ patron => $patron, >+ } >+ ); >+ >+ is( keys %{ $result->blockers }, 0, 'no blockers for available item' ); >+ is( keys %{ $result->confirmations }, 0, 'no confirmations for available item' ); >+ is( $result->context->{patron}->id, $patron->id, 'patron in context' ); >+ is( $result->context->{item}->itemnumber, $item->itemnumber, 'item in context' ); >+ >+ $schema->storage->txn_rollback; >+}; >+ >+subtest 'check() - patron debarred' => sub { >+ >+ plan tests => 3; >+ >+ $schema->storage->txn_begin; >+ >+ my $patron = $builder->build_object( >+ { >+ class => 'Koha::Patrons', >+ value => { debarred => '9999-12-31' } >+ } >+ ); >+ my $item = $builder->build_sample_item(); >+ >+ my $result = $item->checkout_availability( >+ { >+ patron => $patron, >+ } >+ ); >+ >+ is( $result->blockers->{DEBARRED}, 1, 'DEBARRED blocker set' ); >+ is( $result->blockers->{USERBLOCKEDNOENDDATE}, '9999-12-31', 'USERBLOCKEDNOENDDATE blocker set' ); >+ ok( !$result->available, 'not available when patron debarred' ); >+ >+ $schema->storage->txn_rollback; >+}; >-- >2.50.1 (Apple Git-155) >
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 41728
:
192130
|
192131
|
192132
| 192133