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 2033-2052 subtest 'AddReturn + suspension_chargeperiod' => sub { Link Here
2033
    )->unblessed;
2033
    )->unblessed;
2034
2034
2035
    # And the issuing rule
2035
    # And the issuing rule
2036
    Koha::IssuingRules->search->delete;
2036
    Koha::CirculationRules->search->delete;
2037
    my $rule = Koha::IssuingRule->new(
2037
    Koha::CirculationRules->set_rules(
2038
        {
2038
        {
2039
            categorycode => '*',
2039
            categorycode => '*',
2040
            itemtype     => '*',
2040
            itemtype     => '*',
2041
            branchcode   => '*',
2041
            branchcode   => '*',
2042
            issuelength  => 1,
2042
            rules        => {
2043
            firstremind  => 0,        # 0 day of grace
2043
                issuelength => 1,
2044
            finedays     => 2,        # 2 days of fine per day of overdue
2044
                firstremind => 0,    # 0 day of grace
2045
            suspension_chargeperiod => 1,
2045
                finedays    => 2,    # 2 days of fine per day of overdue
2046
            lengthunit   => 'days',
2046
                suspension_chargeperiod => 1,
2047
                lengthunit              => 'days',
2048
            }
2047
        }
2049
        }
2048
    );
2050
    );
2049
    $rule->store();
2050
2051
2051
    my $five_days_ago = dt_from_string->subtract( days => 5 );
2052
    my $five_days_ago = dt_from_string->subtract( days => 5 );
2052
    # We want to charge 2 days every day, without grace
2053
    # 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 613-628 subtest 'CanItemBeReserved / holds_per_day tests' => sub { Link Here
613
        $biblio_3->biblionumber
612
        $biblio_3->biblionumber
614
    );
613
    );
615
614
616
    Koha::IssuingRules->search->delete;
615
    Koha::CirculationRules->search->delete;
617
    my $issuingrule = Koha::IssuingRule->new(
616
    Koha::CirculationRules->set_rules(
618
        {   categorycode     => '*',
617
        {
619
            branchcode       => '*',
618
            categorycode => '*',
620
            itemtype         => $itemtype->itemtype,
619
            branchcode   => '*',
621
            reservesallowed  => 1,
620
            itemtype     => $itemtype->itemtype,
622
            holds_per_record => 99,
621
            rules        => {
623
            holds_per_day    => 2
622
                reservesallowed  => 1,
623
                holds_per_record => 99,
624
                holds_per_day    => 2
625
            }
624
        }
626
        }
625
    )->store;
627
    );
626
628
627
    is_deeply(
629
    is_deeply(
628
        CanItemBeReserved( $patron->borrowernumber, $itemnumber_1 ),
630
        CanItemBeReserved( $patron->borrowernumber, $itemnumber_1 ),
629
- 

Return to bug 18936