View | Details | Raw Unified | Return to bug 41728
Collapse All | Expand All

(-)a/Koha/Item.pm (+29 lines)
Lines 807-812 sub checkin_availability { Link Here
807
    return Koha::Item::Checkin::Availability->check( $self, $params );
807
    return Koha::Item::Checkin::Availability->check( $self, $params );
808
}
808
}
809
809
810
=head3 checkout_availability
811
812
    my $availability = $item->checkout_availability(
813
        {
814
            patron => $patron,
815
        }
816
    );
817
818
Returns checkout availability information for this item.
819
820
This is a convenience method that calls Koha::Item::Checkout::Availability->check().
821
822
Returns a Koha::Availability::Result object with methods:
823
    available()         # Boolean: true if checkout allowed
824
    needs_confirmation()# Boolean: true if confirmation required
825
    blockers()          # Hashref of blocking conditions
826
    confirmations()     # Hashref of conditions requiring confirmation
827
    warnings()          # Hashref of warning messages
828
    context()           # Hashref with patron and item objects
829
830
=cut
831
832
sub checkout_availability {
833
    my ( $self, $params ) = @_;
834
835
    require Koha::Item::Checkout::Availability;
836
    return Koha::Item::Checkout::Availability->check( $self, $params );
837
}
838
810
=head3 request_transfer
839
=head3 request_transfer
811
840
812
  my $transfer = $item->request_transfer(
841
  my $transfer = $item->request_transfer(
(-)a/Koha/Item/Checkout/Availability.pm (+122 lines)
Line 0 Link Here
1
package Koha::Item::Checkout::Availability;
2
3
# Copyright 2026 Koha Development Team
4
#
5
# This file is part of Koha.
6
#
7
# Koha is free software; you can redistribute it and/or modify it
8
# under the terms of the GNU General Public License as published by
9
# the Free Software Foundation; either version 3 of the License, or
10
# (at your option) any later version.
11
#
12
# Koha is distributed in the hope that it will be useful, but
13
# WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
# GNU General Public License for more details.
16
#
17
# You should have received a copy of the GNU General Public License
18
# along with Koha; if not, see <https://www.gnu.org/licenses>.
19
20
use Modern::Perl;
21
22
use C4::Circulation qw( CanBookBeIssued );
23
use Koha::Availability::Result;
24
25
=head1 NAME
26
27
Koha::Item::Checkout::Availability - Checkout availability validation for items
28
29
=head1 SYNOPSIS
30
31
    my $availability = Koha::Item::Checkout::Availability->check( $item,
32
        {
33
            patron => $patron,
34
        }
35
    );
36
37
    # Or via instance method
38
    my $availability = $item->checkout_availability( { patron => $patron } );
39
40
=head1 DESCRIPTION
41
42
This class provides validation logic for item checkout operations, wrapping
43
C4::Circulation::CanBookBeIssued in a Result object interface.
44
45
The result categorizes conditions as:
46
- blockers: Prevent checkout (e.g., item already checked out, patron debarred)
47
- confirmations: Require user confirmation (e.g., item on hold for another patron)
48
- warnings: Informational (e.g., patron has many checkouts)
49
50
=head1 API
51
52
=head2 Class methods
53
54
=head3 check
55
56
    my $availability = Koha::Item::Checkout::Availability->check( $item,
57
        {
58
            patron => $patron,
59
        }
60
    );
61
62
Validates checkout availability for an item.
63
64
Parameters:
65
    $item   - Koha::Item object (required)
66
    $params - hashref with:
67
        patron => $patron (required)
68
69
Returns a Koha::Availability::Result object with:
70
    blockers      => {}       # Conditions that prevent checkout
71
    confirmations => {}       # Conditions requiring confirmation
72
    warnings      => {}       # Informational messages
73
    context       => {
74
        patron => $patron     # Koha::Patron object
75
        item   => $item       # Koha::Item object
76
    }
77
78
=cut
79
80
sub check {
81
    my ( $class, $item, $params ) = @_;
82
83
    my $patron = $params->{patron};
84
85
    my $result = Koha::Availability::Result->new();
86
87
    # Set context
88
    $result->set_context( patron => $patron );
89
    $result->set_context( item   => $item );
90
91
    # Call CanBookBeIssued
92
    my ( $impossible, $confirmation, $alerts, $messages ) =
93
        CanBookBeIssued( $patron, undef, undef, 0, 0, { item => $item } );
94
95
    # Map impossible to blockers
96
    for my $key ( keys %{$impossible} ) {
97
        $result->add_blocker( $key => $impossible->{$key} );
98
    }
99
100
    # Map confirmation to confirmations
101
    for my $key ( keys %{$confirmation} ) {
102
        $result->add_confirmation( $key => $confirmation->{$key} );
103
    }
104
105
    # Map alerts and messages to warnings
106
    for my $key ( keys %{$alerts} ) {
107
        $result->add_warning( $key => $alerts->{$key} );
108
    }
109
    for my $key ( keys %{$messages} ) {
110
        $result->add_warning( $key => $messages->{$key} );
111
    }
112
113
    return $result;
114
}
115
116
=head1 AUTHOR
117
118
Koha Development Team <https://koha-community.org/>
119
120
=cut
121
122
1;
(-)a/t/db_dependent/Koha/Item/Checkout/Availability.t (-1 / +82 lines)
Line 0 Link Here
0
- 
1
#!/usr/bin/perl
2
3
# Copyright 2026 Koha Development Team
4
#
5
# This file is part of Koha
6
#
7
# Koha is free software; you can redistribute it and/or modify it
8
# under the terms of the GNU General Public License as published by
9
# the Free Software Foundation; either version 3 of the License, or
10
# (at your option) any later version.
11
#
12
# Koha is distributed in the hope that it will be useful, but
13
# WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
# GNU General Public License for more details.
16
#
17
# You should have received a copy of the GNU General Public License
18
# along with Koha; if not, see <https://www.gnu.org/licenses>.
19
20
use Modern::Perl;
21
22
use Test::More tests => 3;
23
use Test::NoWarnings;
24
25
use t::lib::TestBuilder;
26
use t::lib::Mocks;
27
28
use Koha::Database;
29
30
my $schema  = Koha::Database->new->schema;
31
my $builder = t::lib::TestBuilder->new;
32
33
subtest 'check() - available item' => sub {
34
35
    plan tests => 4;
36
37
    $schema->storage->txn_begin;
38
39
    my $library = $builder->build_object( { class => 'Koha::Libraries' } );
40
    my $patron  = $builder->build_object( { class => 'Koha::Patrons' } );
41
    my $item    = $builder->build_sample_item();
42
43
    my $result = $item->checkout_availability(
44
        {
45
            patron => $patron,
46
        }
47
    );
48
49
    is( keys %{ $result->blockers },          0,                 'no blockers for available item' );
50
    is( keys %{ $result->confirmations },     0,                 'no confirmations for available item' );
51
    is( $result->context->{patron}->id,       $patron->id,       'patron in context' );
52
    is( $result->context->{item}->itemnumber, $item->itemnumber, 'item in context' );
53
54
    $schema->storage->txn_rollback;
55
};
56
57
subtest 'check() - patron debarred' => sub {
58
59
    plan tests => 3;
60
61
    $schema->storage->txn_begin;
62
63
    my $patron = $builder->build_object(
64
        {
65
            class => 'Koha::Patrons',
66
            value => { debarred => '9999-12-31' }
67
        }
68
    );
69
    my $item = $builder->build_sample_item();
70
71
    my $result = $item->checkout_availability(
72
        {
73
            patron => $patron,
74
        }
75
    );
76
77
    is( $result->blockers->{DEBARRED},             1,            'DEBARRED blocker set' );
78
    is( $result->blockers->{USERBLOCKEDNOENDDATE}, '9999-12-31', 'USERBLOCKEDNOENDDATE blocker set' );
79
    ok( !$result->available, 'not available when patron debarred' );
80
81
    $schema->storage->txn_rollback;
82
};

Return to bug 41728