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

(-)a/Koha/IssuingRules.pm (-202 lines)
Lines 1-202 Link Here
1
package Koha::IssuingRules;
2
3
# Copyright Vaara-kirjastot 2015
4
# Copyright Koha Development Team 2016
5
#
6
# This file is part of Koha.
7
#
8
# Koha is free software; you can redistribute it and/or modify it under the
9
# terms of the GNU General Public License as published by the Free Software
10
# Foundation; either version 3 of the License, or (at your option) any later
11
# version.
12
#
13
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
14
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
15
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
16
#
17
# You should have received a copy of the GNU General Public License along
18
# with Koha; if not, write to the Free Software Foundation, Inc.,
19
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20
21
use Modern::Perl;
22
23
use Koha::Database;
24
use Koha::Caches;
25
26
use Koha::IssuingRule;
27
28
use base qw(Koha::Objects);
29
30
use constant GUESSED_ITEMTYPES_KEY => 'Koha_IssuingRules_last_guess';
31
32
=head1 NAME
33
34
Koha::IssuingRules - Koha IssuingRule Object set class
35
36
=head1 API
37
38
=head2 Class Methods
39
40
=cut
41
42
sub get_effective_issuing_rule {
43
    my ( $self, $params ) = @_;
44
45
    my $default      = '*';
46
    my $categorycode = $params->{categorycode};
47
    my $itemtype     = $params->{itemtype};
48
    my $branchcode   = $params->{branchcode};
49
50
    my $search_categorycode = $default;
51
    my $search_itemtype     = $default;
52
    my $search_branchcode   = $default;
53
54
    if ($categorycode) {
55
        $search_categorycode = { 'in' => [ $categorycode, $default ] };
56
    }
57
    if ($itemtype) {
58
        $search_itemtype = { 'in' => [ $itemtype, $default ] };
59
    }
60
    if ($branchcode) {
61
        $search_branchcode = { 'in' => [ $branchcode, $default ] };
62
    }
63
64
    my $rule = $self->search({
65
        categorycode => $search_categorycode,
66
        itemtype     => $search_itemtype,
67
        branchcode   => $search_branchcode,
68
    }, {
69
        order_by => {
70
            -desc => ['branchcode', 'categorycode', 'itemtype']
71
        },
72
        rows => 1,
73
    })->single;
74
    return $rule;
75
}
76
77
=head3 get_opacitemholds_policy
78
79
my $can_place_a_hold_at_item_level = Koha::IssuingRules->get_opacitemholds_policy( { patron => $patron, item => $item } );
80
81
Return 'Y' or 'F' if the patron can place a hold on this item according to the issuing rules
82
and the "Item level holds" (opacitemholds).
83
Can be 'N' - Don't allow, 'Y' - Allow, and 'F' - Force
84
85
=cut
86
87
sub get_opacitemholds_policy {
88
    my ( $class, $params ) = @_;
89
90
    my $item   = $params->{item};
91
    my $patron = $params->{patron};
92
93
    return unless $item or $patron;
94
95
    my $issuing_rule = Koha::IssuingRules->get_effective_issuing_rule(
96
        {
97
            categorycode => $patron->categorycode,
98
            itemtype     => $item->effective_itemtype,
99
            branchcode   => $item->homebranch,
100
        }
101
    );
102
103
    return $issuing_rule ? $issuing_rule->opacitemholds : undef;
104
}
105
106
=head3 get_onshelfholds_policy
107
108
    my $on_shelf_holds = Koha::IssuingRules->get_onshelfholds_policy({ item => $item, patron => $patron });
109
110
=cut
111
112
sub get_onshelfholds_policy {
113
    my ( $class, $params ) = @_;
114
    my $item = $params->{item};
115
    my $itemtype = $item->effective_itemtype;
116
    my $patron = $params->{patron};
117
    my $issuing_rule = Koha::IssuingRules->get_effective_issuing_rule(
118
        {
119
            ( $patron ? ( categorycode => $patron->categorycode ) : () ),
120
            itemtype   => $itemtype,
121
            branchcode => $item->holdingbranch
122
        }
123
    );
124
    return $issuing_rule ? $issuing_rule->onshelfholds : undef;
125
}
126
127
=head3 article_requestable_rules
128
129
    Return rules that allow article requests, optionally filtered by
130
    patron categorycode.
131
132
    Use with care; see guess_article_requestable_itemtypes.
133
134
=cut
135
136
sub article_requestable_rules {
137
    my ( $class, $params ) = @_;
138
    my $category = $params->{categorycode};
139
140
    return if !C4::Context->preference('ArticleRequests');
141
    return $class->search({
142
        $category ? ( categorycode => [ $category, '*' ] ) : (),
143
        article_requests => { '!=' => 'no' },
144
    });
145
}
146
147
=head3 guess_article_requestable_itemtypes
148
149
    Return item types in a hashref that are likely possible to be
150
    'article requested'. Constructed by an intelligent guess in the
151
    issuing rules (see article_requestable_rules).
152
153
    Note: pref ArticleRequestsLinkControl overrides the algorithm.
154
155
    Optional parameters: categorycode.
156
157
    Note: the routine is used in opac-search to obtain a reasonable
158
    estimate within performance borders (not looking at all items but
159
    just using default itemtype). Also we are not looking at the
160
    branchcode here, since home or holding branch of the item is
161
    leading and branch may be unknown too (anonymous opac session).
162
163
=cut
164
165
sub guess_article_requestable_itemtypes {
166
    my ( $class, $params ) = @_;
167
    my $category = $params->{categorycode};
168
    return {} if !C4::Context->preference('ArticleRequests');
169
    return { '*' => 1 } if C4::Context->preference('ArticleRequestsLinkControl') eq 'always';
170
171
    my $cache = Koha::Caches->get_instance;
172
    my $last_article_requestable_guesses = $cache->get_from_cache(GUESSED_ITEMTYPES_KEY);
173
    my $key = $category || '*';
174
    return $last_article_requestable_guesses->{$key}
175
        if $last_article_requestable_guesses && exists $last_article_requestable_guesses->{$key};
176
177
    my $res = {};
178
    my $rules = $class->article_requestable_rules({
179
        $category ? ( categorycode => $category ) : (),
180
    });
181
    return $res if !$rules;
182
    foreach my $rule ( $rules->as_list ) {
183
        $res->{ $rule->itemtype } = 1;
184
    }
185
    $last_article_requestable_guesses->{$key} = $res;
186
    $cache->set_in_cache(GUESSED_ITEMTYPES_KEY, $last_article_requestable_guesses);
187
    return $res;
188
}
189
190
=head3 type
191
192
=cut
193
194
sub _type {
195
    return 'Issuingrule';
196
}
197
198
sub object_class {
199
    return 'Koha::IssuingRule';
200
}
201
202
1;
(-)a/t/db_dependent/Circulation.t (-8 / +9 lines)
Lines 2012-2031 subtest 'AddReturn + suspension_chargeperiod' => sub { Link Here
2012
    )->unblessed;
2012
    )->unblessed;
2013
2013
2014
    # And the issuing rule
2014
    # And the issuing rule
2015
    Koha::IssuingRules->search->delete;
2015
    Koha::CirculationRules->search->delete;
2016
    my $rule = Koha::IssuingRule->new(
2016
    Koha::CirculationRules->set_rules(
2017
        {
2017
        {
2018
            categorycode => '*',
2018
            categorycode => '*',
2019
            itemtype     => '*',
2019
            itemtype     => '*',
2020
            branchcode   => '*',
2020
            branchcode   => '*',
2021
            issuelength  => 1,
2021
            rules        => {
2022
            firstremind  => 0,        # 0 day of grace
2022
                issuelength => 1,
2023
            finedays     => 2,        # 2 days of fine per day of overdue
2023
                firstremind => 0,    # 0 day of grace
2024
            suspension_chargeperiod => 1,
2024
                finedays    => 2,    # 2 days of fine per day of overdue
2025
            lengthunit   => 'days',
2025
                suspension_chargeperiod => 1,
2026
                lengthunit              => 'days',
2027
            }
2026
        }
2028
        }
2027
    );
2029
    );
2028
    $rule->store();
2029
2030
2030
    my $five_days_ago = dt_from_string->subtract( days => 5 );
2031
    my $five_days_ago = dt_from_string->subtract( days => 5 );
2031
    # We want to charge 2 days every day, without grace
2032
    # We want to charge 2 days every day, without grace
(-)a/t/db_dependent/Holds.t (-11 / +12 lines)
Lines 20-26 use Koha::CirculationRules; Link Here
20
use Koha::Database;
20
use Koha::Database;
21
use Koha::DateUtils qw( dt_from_string output_pref );
21
use Koha::DateUtils qw( dt_from_string output_pref );
22
use Koha::Holds;
22
use Koha::Holds;
23
use Koha::IssuingRules;
24
use Koha::Item::Transfer::Limits;
23
use Koha::Item::Transfer::Limits;
25
use Koha::Items;
24
use Koha::Items;
26
use Koha::Libraries;
25
use Koha::Libraries;
Lines 609-624 subtest 'CanItemBeReserved / holds_per_day tests' => sub { Link Here
609
        $biblio_3->biblionumber
608
        $biblio_3->biblionumber
610
    );
609
    );
611
610
612
    Koha::IssuingRules->search->delete;
611
    Koha::CirculationRules->search->delete;
613
    my $issuingrule = Koha::IssuingRule->new(
612
    Koha::CirculationRules->set_rules(
614
        {   categorycode     => '*',
613
        {
615
            branchcode       => '*',
614
            categorycode => '*',
616
            itemtype         => $itemtype->itemtype,
615
            branchcode   => '*',
617
            reservesallowed  => 1,
616
            itemtype     => $itemtype->itemtype,
618
            holds_per_record => 99,
617
            rules        => {
619
            holds_per_day    => 2
618
                reservesallowed  => 1,
619
                holds_per_record => 99,
620
                holds_per_day    => 2
621
            }
620
        }
622
        }
621
    )->store;
623
    );
622
624
623
    is_deeply(
625
    is_deeply(
624
        CanItemBeReserved( $patron->borrowernumber, $itemnumber_1 ),
626
        CanItemBeReserved( $patron->borrowernumber, $itemnumber_1 ),
625
- 

Return to bug 18936