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

(-)a/C4/Reserves.pm (-8 / +24 lines)
Lines 194-199 sub AddReserve { Link Here
194
    my $itemtype               = $params->{itemtype};
194
    my $itemtype               = $params->{itemtype};
195
    my $non_priority           = $params->{non_priority};
195
    my $non_priority           = $params->{non_priority};
196
    my $item_group_id          = $params->{item_group_id};
196
    my $item_group_id          = $params->{item_group_id};
197
    my $hold_group_id          = $params->{hold_group_id};
197
198
198
    $resdate ||= dt_from_string;
199
    $resdate ||= dt_from_string;
199
200
Lines 256-261 sub AddReserve { Link Here
256
            itemtype               => $itemtype,
257
            itemtype               => $itemtype,
257
            item_level_hold        => $checkitem    ? 1 : 0,
258
            item_level_hold        => $checkitem    ? 1 : 0,
258
            non_priority           => $non_priority ? 1 : 0,
259
            non_priority           => $non_priority ? 1 : 0,
260
            hold_group_id          => $hold_group_id,
259
        }
261
        }
260
    )->store();
262
    )->store();
261
    $hold->set_waiting() if $found && $found eq 'W';
263
    $hold->set_waiting() if $found && $found eq 'W';
Lines 569-589 sub CanItemBeReserved { Link Here
569
                borrowernumber => $patron->borrowernumber,
571
                borrowernumber => $patron->borrowernumber,
570
                biblionumber   => $item->biblionumber,
572
                biblionumber   => $item->biblionumber,
571
            };
573
            };
572
            my $holds = Koha::Holds->search($search_params);
574
            my $holds_count = Koha::Holds->count_holds($search_params);
573
            return _cache { status => "tooManyHoldsForThisRecord", limit => $holds_per_record }
575
            return _cache { status => "tooManyHoldsForThisRecord", limit => $holds_per_record }
574
                if $holds->count() >= $holds_per_record;
576
                if $holds_count >= $holds_per_record;
575
        }
577
        }
576
    }
578
    }
577
579
578
    if ( !$params->{ignore_hold_counts} && defined $holds_per_day && $holds_per_day ne '' ) {
580
    if ( !$params->{ignore_hold_counts} && defined $holds_per_day && $holds_per_day ne '' ) {
579
        my $today_holds = Koha::Holds->search(
581
        my $today_holds_count = Koha::Holds->count_holds(
580
            {
582
            {
581
                borrowernumber => $patron->borrowernumber,
583
                borrowernumber => $patron->borrowernumber,
582
                reservedate    => dt_from_string->date
584
                reservedate    => dt_from_string->date
583
            }
585
            }
584
        );
586
        );
585
        return _cache { status => 'tooManyReservesToday', limit => $holds_per_day }
587
        return _cache { status => 'tooManyReservesToday', limit => $holds_per_day }
586
            if $today_holds->count() >= $holds_per_day;
588
            if $today_holds_count >= $holds_per_day;
587
    }
589
    }
588
590
589
    # we check if it's ok or not
591
    # we check if it's ok or not
Lines 1239-1244 sub ModReserveAffect { Link Here
1239
1241
1240
    $hold->itemnumber($itemnumber);
1242
    $hold->itemnumber($itemnumber);
1241
1243
1244
    my @reserve_ids;
1245
    push @reserve_ids, $hold->reserve_id;
1246
1242
    if ($transferToDo) {
1247
    if ($transferToDo) {
1243
        $hold->set_transfer();
1248
        $hold->set_transfer();
1244
    } elsif ( C4::Context->preference('HoldsNeedProcessingSIP')
1249
    } elsif ( C4::Context->preference('HoldsNeedProcessingSIP')
Lines 1253-1258 sub ModReserveAffect { Link Here
1253
        # Complete transfer if one exists
1258
        # Complete transfer if one exists
1254
        my $transfer = $hold->item->get_transfer;
1259
        my $transfer = $hold->item->get_transfer;
1255
        $transfer->receive if $transfer;
1260
        $transfer->receive if $transfer;
1261
1262
        # if this hold was part of a group, cancel other holds in the group
1263
        if ( $hold->hold_group_id ) {
1264
            my @holds = $hold->hold_group->holds->as_list;
1265
            foreach my $h (@holds) {
1266
                push @reserve_ids, $h->reserve_id;
1267
                $h->cancel unless $h->reserve_id == $hold->reserve_id;
1268
            }
1269
        }
1256
    }
1270
    }
1257
1271
1258
    _koha_notify_hold_changed($hold) if $notify_library;
1272
    _koha_notify_hold_changed($hold) if $notify_library;
Lines 1266-1273 sub ModReserveAffect { Link Here
1266
        CartToShelf($itemnumber);
1280
        CartToShelf($itemnumber);
1267
    }
1281
    }
1268
1282
1269
    my $std = $dbh->prepare(
1283
    foreach my $id (@reserve_ids) {
1270
        q{
1284
        my $std = $dbh->prepare(
1285
            q{
1271
        DELETE  q, t
1286
        DELETE  q, t
1272
        FROM    tmp_holdsqueue q
1287
        FROM    tmp_holdsqueue q
1273
        INNER JOIN hold_fill_targets t
1288
        INNER JOIN hold_fill_targets t
Lines 1277-1285 sub ModReserveAffect { Link Here
1277
            AND q.item_level_request = t.item_level_request
1292
            AND q.item_level_request = t.item_level_request
1278
            AND q.holdingbranch = t.source_branchcode
1293
            AND q.holdingbranch = t.source_branchcode
1279
        WHERE t.reserve_id = ?
1294
        WHERE t.reserve_id = ?
1295
            }
1296
        );
1297
        $std->execute($id);
1280
    }
1298
    }
1281
    );
1282
    $std->execute( $hold->reserve_id );
1283
1299
1284
    logaction( 'HOLDS', 'MODIFY', $hold->reserve_id, $hold, undef, $original )
1300
    logaction( 'HOLDS', 'MODIFY', $hold->reserve_id, $hold, undef, $original )
1285
        if C4::Context->preference('HoldsLog');
1301
        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 993-998 sub _set_default_expirationdate { Link Here
993
    }
1002
    }
994
}
1003
}
995
1004
1005
=head3 hold_group
1006
1007
    my $hold_group = $hold->hold_group;
1008
    my $hold_group_id = $hold_group->id if $hold_group;
1009
1010
Return the Koha::HoldGroup object of a hold if part of a hold group
1011
1012
=cut
1013
1014
sub hold_group {
1015
    my ($self) = @_;
1016
1017
    if ( $self->hold_group_id ) {
1018
        return Koha::HoldGroups->find( $self->hold_group_id );
1019
    }
1020
1021
    return;
1022
}
1023
996
=head3 _move_to_old
1024
=head3 _move_to_old
997
1025
998
my $is_moved = $hold->_move_to_old;
1026
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