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

(-)a/C4/Reserves.pm (-8 / +24 lines)
Lines 192-197 sub AddReserve { Link Here
192
    my $itemtype               = $params->{itemtype};
192
    my $itemtype               = $params->{itemtype};
193
    my $non_priority           = $params->{non_priority};
193
    my $non_priority           = $params->{non_priority};
194
    my $item_group_id          = $params->{item_group_id};
194
    my $item_group_id          = $params->{item_group_id};
195
    my $hold_group_id          = $params->{hold_group_id};
195
196
196
    $resdate ||= dt_from_string;
197
    $resdate ||= dt_from_string;
197
198
Lines 254-259 sub AddReserve { Link Here
254
            itemtype               => $itemtype,
255
            itemtype               => $itemtype,
255
            item_level_hold        => $checkitem    ? 1 : 0,
256
            item_level_hold        => $checkitem    ? 1 : 0,
256
            non_priority           => $non_priority ? 1 : 0,
257
            non_priority           => $non_priority ? 1 : 0,
258
            hold_group_id          => $hold_group_id,
257
        }
259
        }
258
    )->store();
260
    )->store();
259
    $hold->set_waiting() if $found && $found eq 'W';
261
    $hold->set_waiting() if $found && $found eq 'W';
Lines 567-587 sub CanItemBeReserved { Link Here
567
                borrowernumber => $patron->borrowernumber,
569
                borrowernumber => $patron->borrowernumber,
568
                biblionumber   => $item->biblionumber,
570
                biblionumber   => $item->biblionumber,
569
            };
571
            };
570
            my $holds = Koha::Holds->search($search_params);
572
            my $holds_count = Koha::Holds->count_holds($search_params);
571
            return _cache { status => "tooManyHoldsForThisRecord", limit => $holds_per_record }
573
            return _cache { status => "tooManyHoldsForThisRecord", limit => $holds_per_record }
572
                if $holds->count() >= $holds_per_record;
574
                if $holds_count >= $holds_per_record;
573
        }
575
        }
574
    }
576
    }
575
577
576
    if ( !$params->{ignore_hold_counts} && defined $holds_per_day && $holds_per_day ne '' ) {
578
    if ( !$params->{ignore_hold_counts} && defined $holds_per_day && $holds_per_day ne '' ) {
577
        my $today_holds = Koha::Holds->search(
579
        my $today_holds_count = Koha::Holds->count_holds(
578
            {
580
            {
579
                borrowernumber => $patron->borrowernumber,
581
                borrowernumber => $patron->borrowernumber,
580
                reservedate    => dt_from_string->date
582
                reservedate    => dt_from_string->date
581
            }
583
            }
582
        );
584
        );
583
        return _cache { status => 'tooManyReservesToday', limit => $holds_per_day }
585
        return _cache { status => 'tooManyReservesToday', limit => $holds_per_day }
584
            if $today_holds->count() >= $holds_per_day;
586
            if $today_holds_count >= $holds_per_day;
585
    }
587
    }
586
588
587
    # we check if it's ok or not
589
    # we check if it's ok or not
Lines 1237-1242 sub ModReserveAffect { Link Here
1237
1239
1238
    $hold->itemnumber($itemnumber);
1240
    $hold->itemnumber($itemnumber);
1239
1241
1242
    my @reserve_ids;
1243
    push @reserve_ids, $hold->reserve_id;
1244
1240
    if ($transferToDo) {
1245
    if ($transferToDo) {
1241
        $hold->set_transfer();
1246
        $hold->set_transfer();
1242
    } elsif ( C4::Context->preference('HoldsNeedProcessingSIP')
1247
    } elsif ( C4::Context->preference('HoldsNeedProcessingSIP')
Lines 1251-1256 sub ModReserveAffect { Link Here
1251
        # Complete transfer if one exists
1256
        # Complete transfer if one exists
1252
        my $transfer = $hold->item->get_transfer;
1257
        my $transfer = $hold->item->get_transfer;
1253
        $transfer->receive if $transfer;
1258
        $transfer->receive if $transfer;
1259
1260
        # if this hold was part of a group, cancel other holds in the group
1261
        if ( $hold->hold_group_id ) {
1262
            my @holds = $hold->hold_group->holds->as_list;
1263
            foreach my $h (@holds) {
1264
                push @reserve_ids, $h->reserve_id;
1265
                $h->cancel unless $h->reserve_id == $hold->reserve_id;
1266
            }
1267
        }
1254
    }
1268
    }
1255
1269
1256
    _koha_notify_hold_changed($hold) if $notify_library;
1270
    _koha_notify_hold_changed($hold) if $notify_library;
Lines 1264-1271 sub ModReserveAffect { Link Here
1264
        CartToShelf($itemnumber);
1278
        CartToShelf($itemnumber);
1265
    }
1279
    }
1266
1280
1267
    my $std = $dbh->prepare(
1281
    foreach my $id (@reserve_ids) {
1268
        q{
1282
        my $std = $dbh->prepare(
1283
            q{
1269
        DELETE  q, t
1284
        DELETE  q, t
1270
        FROM    tmp_holdsqueue q
1285
        FROM    tmp_holdsqueue q
1271
        INNER JOIN hold_fill_targets t
1286
        INNER JOIN hold_fill_targets t
Lines 1275-1283 sub ModReserveAffect { Link Here
1275
            AND q.item_level_request = t.item_level_request
1290
            AND q.item_level_request = t.item_level_request
1276
            AND q.holdingbranch = t.source_branchcode
1291
            AND q.holdingbranch = t.source_branchcode
1277
        WHERE t.reserve_id = ?
1292
        WHERE t.reserve_id = ?
1293
            }
1294
        );
1295
        $std->execute($id);
1278
    }
1296
    }
1279
    );
1280
    $std->execute( $hold->reserve_id );
1281
1297
1282
    logaction( 'HOLDS', 'MODIFY', $hold->reserve_id, $hold, undef, $original )
1298
    logaction( 'HOLDS', 'MODIFY', $hold->reserve_id, $hold, undef, $original )
1283
        if C4::Context->preference('HoldsLog');
1299
        if C4::Context->preference('HoldsLog');
(-)a/Koha/Hold.pm (+28 lines)
Lines 40-45 use Koha::Plugins; Link Here
40
use Koha::BackgroundJob::BatchUpdateBiblioHoldsQueue;
40
use Koha::BackgroundJob::BatchUpdateBiblioHoldsQueue;
41
41
42
use Koha::Exceptions;
42
use Koha::Exceptions;
43
use Koha::HoldGroups;
43
use Koha::Exceptions::Hold;
44
use Koha::Exceptions::Hold;
44
45
45
use base qw(Koha::Object);
46
use base qw(Koha::Object);
Lines 881-886 sub fill { Link Here
881
            C4::Log::logaction( 'HOLDS', 'FILL', $self->id, $self, undef, $original )
882
            C4::Log::logaction( 'HOLDS', 'FILL', $self->id, $self, undef, $original )
882
                if C4::Context->preference('HoldsLog');
883
                if C4::Context->preference('HoldsLog');
883
884
885
            # if this hold was part of a group, cancel other holds in the group
886
            if ( $self->hold_group_id ) {
887
                my @holds = $self->hold_group->holds->as_list;
888
                foreach my $h (@holds) {
889
                    $h->cancel unless $h->reserve_id == $self->id;
890
                }
891
            }
892
884
            Koha::BackgroundJob::BatchUpdateBiblioHoldsQueue->new->enqueue(
893
            Koha::BackgroundJob::BatchUpdateBiblioHoldsQueue->new->enqueue(
885
                { biblio_ids => [ $old_me->biblionumber ] } )
894
                { biblio_ids => [ $old_me->biblionumber ] } )
886
                if C4::Context->preference('RealTimeHoldsQueue');
895
                if C4::Context->preference('RealTimeHoldsQueue');
Lines 1046-1051 sub _set_default_expirationdate { Link Here
1046
    }
1055
    }
1047
}
1056
}
1048
1057
1058
=head3 hold_group
1059
1060
    my $hold_group = $hold->hold_group;
1061
    my $hold_group_id = $hold_group->id if $hold_group;
1062
1063
Return the Koha::HoldGroup object of a hold if part of a hold group
1064
1065
=cut
1066
1067
sub hold_group {
1068
    my ($self) = @_;
1069
1070
    if ( $self->hold_group_id ) {
1071
        return Koha::HoldGroups->find( $self->hold_group_id );
1072
    }
1073
1074
    return;
1075
}
1076
1049
=head3 _move_to_old
1077
=head3 _move_to_old
1050
1078
1051
my $is_moved = $hold->_move_to_old;
1079
my $is_moved = $hold->_move_to_old;
(-)a/Koha/HoldGroup.pm (+63 lines)
Line 0 Link Here
1
package Koha::HoldGroup;
2
3
# Copyright 2020 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 <http://www.gnu.org/licenses>.
19
20
use Modern::Perl;
21
22
use base qw(Koha::Object);
23
24
=head1 NAME
25
26
Koha::HoldGroup - Koha Hold Group object class
27
28
=head1 API
29
30
=head2 Class Methods
31
32
=cut
33
34
=head3 holds
35
36
    $holds = $hold_group->holds
37
38
Return all holds associated with this group
39
40
=cut
41
42
sub holds {
43
    my ($self) = @_;
44
45
    my $holds_rs = $self->_result->reserves->search;
46
    return Koha::Holds->_new_from_dbic($holds_rs);
47
}
48
49
=head3 _type
50
51
=cut
52
53
sub _type {
54
    return 'HoldGroup';
55
}
56
57
=head1 AUTHORS
58
59
Josef Moravec <josef.moravec@gmail.com>
60
61
=cut
62
63
1;
(-)a/Koha/HoldGroups.pm (+60 lines)
Line 0 Link Here
1
package Koha::HoldGroups;
2
3
# Copyright Koha Development team 2020
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 <http://www.gnu.org/licenses>.
19
20
use Modern::Perl;
21
22
use Koha::Database;
23
24
use Koha::HoldGroup;
25
26
use base qw(Koha::Objects);
27
28
=head1 NAME
29
30
Koha::HoldGroups - Koha Hold Group object set class
31
32
=head1 API
33
34
=head2 Class Methods
35
36
=cut
37
38
=head3 _type
39
40
=cut
41
42
sub _type {
43
    return 'HoldGroup';
44
}
45
46
=head3 object_class
47
48
=cut
49
50
sub object_class {
51
    return 'Koha::HoldGroup';
52
}
53
54
=head1 AUTHOR
55
56
Josef Moravec <josef.moravec@gmail.com>
57
58
=cut
59
60
1;
(-)a/Koha/Holds.pm (+26 lines)
Lines 206-211 sub filter_out_has_cancellation_requests { Link Here
206
    );
206
    );
207
}
207
}
208
208
209
=head3 count_holds
210
211
    $holds->count_holds( $search_params );
212
213
This overwrites the default count().
214
215
Return the number of holds, where a hold group is counted as one hold.
216
217
=cut
218
219
sub count_holds {
220
    my ( $self, $search_params ) = @_;
221
222
    $search_params = {
223
        hold_group_id => undef,
224
    };
225
    my $holds_without_group_count = $self->search($search_params)->count();
226
227
    $search_params = {
228
        hold_group_id => { '!=', undef },
229
    };
230
    my $hold_groups_count = $self->search( $search_params, { group_by => 'me.hold_group_id' } )->count();
231
232
    return $holds_without_group_count + $hold_groups_count;
233
}
234
209
=head2 Internal methods
235
=head2 Internal methods
210
236
211
=head3 _type
237
=head3 _type
(-)a/t/db_dependent/Koha/Holds.t (+89 lines)
Lines 1068-1073 subtest 'Test Koha::Hold::item_group' => sub { Link Here
1068
    );
1068
    );
1069
};
1069
};
1070
1070
1071
subtest 'count_holds' => sub {
1072
    plan tests => 3;
1073
    $schema->storage->txn_begin;
1074
1075
    my $patron = $builder->build_object(
1076
        {
1077
            class => 'Koha::Patrons',
1078
        }
1079
    );
1080
    my $patron_id = $patron->borrowernumber;
1081
1082
    my $hold1 = $builder->build_object(
1083
        {
1084
            class => 'Koha::Holds',
1085
            value => {
1086
                borrowernumber => $patron_id,
1087
                hold_group_id  => undef,
1088
            },
1089
        }
1090
    );
1091
1092
    is( $patron->holds->count_holds, 1, 'Test patron has 1 hold.' );
1093
1094
    my $hold_group = $builder->build_object(
1095
        {
1096
            class => 'Koha::HoldGroups',
1097
        }
1098
    );
1099
1100
    my $hold2 = $builder->build_object(
1101
        {
1102
            class => 'Koha::Holds',
1103
            value => {
1104
                borrowernumber => $patron_id,
1105
                hold_group_id  => $hold_group->hold_group_id,
1106
            }
1107
        }
1108
    );
1109
    my $hold3 = $builder->build_object(
1110
        {
1111
            class => 'Koha::Holds',
1112
            value => {
1113
                borrowernumber => $patron_id,
1114
                hold_group_id  => $hold_group->hold_group_id,
1115
            }
1116
        }
1117
    );
1118
1119
    is( $patron->holds->count_holds, 2, 'Test patron has 2 holds.' );
1120
1121
    my $hold_group2 = $builder->build_object(
1122
        {
1123
            class => 'Koha::HoldGroups',
1124
        }
1125
    );
1126
1127
    my $hold4 = $builder->build_object(
1128
        {
1129
            class => 'Koha::Holds',
1130
            value => {
1131
                borrowernumber => $patron_id,
1132
                hold_group_id  => $hold_group2->hold_group_id,
1133
            }
1134
        }
1135
    );
1136
    my $hold5 = $builder->build_object(
1137
        {
1138
            class => 'Koha::Holds',
1139
            value => {
1140
                borrowernumber => $patron_id,
1141
                hold_group_id  => $hold_group2->hold_group_id,
1142
            }
1143
        }
1144
    );
1145
    my $hold6 = $builder->build_object(
1146
        {
1147
            class => 'Koha::Holds',
1148
            value => {
1149
                borrowernumber => $patron_id,
1150
                hold_group_id  => $hold_group2->hold_group_id,
1151
            }
1152
        }
1153
    );
1154
1155
    is( $patron->holds->count_holds, 3, 'Test patron has 3 holds.' );
1156
1157
    $schema->storage->txn_rollback;
1158
};
1159
1071
$schema->storage->txn_rollback;
1160
$schema->storage->txn_rollback;
1072
1161
1073
subtest 'filter_by_found() tests' => sub {
1162
subtest 'filter_by_found() tests' => sub {
(-)a/t/db_dependent/Reserves/HoldGroup.t (-1 / +53 lines)
Line 0 Link Here
0
- 
1
#!/usr/bin/perl
2
3
# Copyright 2020 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 <http://www.gnu.org/licenses>.
19
20
use Modern::Perl;
21
22
use Test::More tests => 1;
23
24
use t::lib::TestBuilder;
25
26
my $schema  = Koha::Database->new->schema;
27
my $builder = t::lib::TestBuilder->new;
28
29
subtest 'holds tests' => sub {
30
31
    plan tests => 2;
32
33
    $schema->storage->txn_begin;
34
35
    my $patron     = $builder->build_object( { class => 'Koha::Patrons' } );
36
    my $hold_group = $builder->build_object( { class => 'Koha::HoldGroups' } );
37
    my $hold       = $builder->build_object(
38
        {
39
            class => 'Koha::Holds',
40
            value => {
41
                borrowernumber => $patron->borrowernumber,
42
                hold_group_id  => $hold_group->hold_group_id,
43
            }
44
        }
45
    );
46
47
    my $holds = $hold_group->holds;
48
    is( ref($holds), 'Koha::Holds', 'Right type' );
49
    my $hold_from_group = $holds->next;
50
    is( $hold_from_group->id, $hold->id, 'Right object' );
51
52
    $schema->storage->txn_rollback;
53
};

Return to bug 15516