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

(-)a/C4/Reserves.pm (+1 lines)
Lines 163-168 BEGIN { Link Here
163
            itemnumber       => $itemnumber,
163
            itemnumber       => $itemnumber,
164
            found            => $found,
164
            found            => $found,
165
            itemtype         => $itemtype,
165
            itemtype         => $itemtype,
166
            item_gorup_id    => $item_group_id
166
        }
167
        }
167
    );
168
    );
168
169
(-)a/Koha/Hold.pm (+14 lines)
Lines 471-476 sub item { Link Here
471
    return $self->{_item};
471
    return $self->{_item};
472
}
472
}
473
473
474
=head3 item_group
475
476
Returns the related Koha::Biblio::ItemGroup object for this Hold
477
478
=cut
479
480
sub item_group {
481
    my ($self) = @_;
482
483
    my $item_group_rs = $self->_result->item_group;
484
    return unless $item_group_rs;
485
    return Koha::Biblio::ItemGroup->_new_from_dbic($item_group_rs);
486
}
487
474
=head3 branch
488
=head3 branch
475
489
476
Returns the related Koha::Library object for this Hold
490
Returns the related Koha::Library object for this Hold
(-)a/Koha/Holds.pm (+3 lines)
Lines 85-90 sub forced_hold_level { Link Here
85
    my $item_level_count = $self->search( { itemnumber => { '!=' => undef } } )->count();
85
    my $item_level_count = $self->search( { itemnumber => { '!=' => undef } } )->count();
86
    return 'item' if $item_level_count > 0;
86
    return 'item' if $item_level_count > 0;
87
87
88
    my $item_group_level_count = $self->search( { item_group_id => { '!=' => undef } } )->count();
89
    return 'item_group' if $item_group_level_count > 0;
90
88
    my $record_level_count = $self->search( { itemnumber => undef } )->count();
91
    my $record_level_count = $self->search( { itemnumber => undef } )->count();
89
    return 'record' if $record_level_count > 0;
92
    return 'record' if $record_level_count > 0;
90
93
(-)a/koha-tmpl/intranet-tmpl/prog/en/includes/holds_table.inc (+2 lines)
Lines 171-176 Link Here
171
                    [%- ELSE -%]
171
                    [%- ELSE -%]
172
                        [%- IF hold.itemtype -%]
172
                        [%- IF hold.itemtype -%]
173
                            <em>Next available [% ItemTypes.GetDescription( hold.itemtype ) | html %] item</em>
173
                            <em>Next available [% ItemTypes.GetDescription( hold.itemtype ) | html %] item</em>
174
                        [%- ELSIF hold.object.item_group -%]
175
                            <em>Next available item from group <strong>[% hold.object.item_group.description | html %]</strong></em>
174
                        [%- ELSE -%]
176
                        [%- ELSE -%]
175
                            <em>Next available</em>
177
                            <em>Next available</em>
176
                        [%- END -%]
178
                        [%- END -%]
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt (-4 / +76 lines)
Lines 533-539 Link Here
533
                            [% UNLESS ( multi_hold ) %]
533
                            [% UNLESS ( multi_hold ) %]
534
                                <li>
534
                                <li>
535
                                    <label for="requestany">Hold next available item </label>
535
                                    <label for="requestany">Hold next available item </label>
536
                                    [% IF force_hold_level == 'item' %]
536
                                    [% IF force_hold_level == 'item' || force_hold_level == 'item_group'  %]
537
                                        <input type="checkbox" id="requestany" name="request" disabled="true" />
537
                                        <input type="checkbox" id="requestany" name="request" disabled="true" />
538
                                    [% ELSIF force_hold_level == 'record' %]
538
                                    [% ELSIF force_hold_level == 'record' %]
539
                                        <input type="checkbox" id="requestany" checked="checked" value="Any" disabled="true"/>
539
                                        <input type="checkbox" id="requestany" checked="checked" value="Any" disabled="true"/>
Lines 592-597 Link Here
592
                                [% END %]
592
                                [% END %]
593
                            </ol>
593
                            </ol>
594
594
595
                            <!-- ItemGroup level holds -->
596
                            [% IF Koha.Preference('EnableItemGroupHolds') && biblio.object.item_groups.count %]
597
                                <h2 style="padding: 0 1em;">
598
                                    Hold next available item from an item group
599
                                    [% IF force_hold_level == 'item_group' %]
600
                                        <span class="error"><i>(Required)</i></span>
601
                                    [% END %]
602
                                </h2>
603
604
                                [% IF force_hold_level == 'record' # Patron has placed a record level hold previously for this record %]
605
                                    <span class="error">
606
                                        <i class="fa fa-times fa-lg" title="Cannot be put on hold"></i>
607
                                        Hold must be record level
608
                                    </span>
609
                                [% ELSIF force_hold_level == 'item' # Patron has placed an item level hold previously for this record %]
610
                                    <span class="error">
611
                                        <i class="fa fa-times fa-lg" title="Cannot be put on hold"></i>
612
                                        Hold must be item level
613
                                    </span>
614
                                [% ELSE %]
615
                                    <table>
616
                                        <thead>
617
                                            <tr>
618
                                                <th>Hold</th>
619
                                                <th>Item group</th>
620
                                            </tr>
621
                                        </thead>
622
                                        <tbody>
623
                                            [% FOREACH g IN biblio.object.item_groups.search({}, { order_by => ['display_order'] }) %]
624
                                                [% IF g.items %]
625
                                                    <tr>
626
                                                        <td>
627
                                                            <input id="item_group_id_[% g.id | html %]" type="radio" name="item_group_id" value="[% g.id | html %]" />
628
                                                        </td>
629
                                                        <td>
630
                                                            <label for="item_group_id_[% g.id | html %]">[% g.description | html %]</label>
631
                                                        </td>
632
                                                    </tr>
633
                                                [% END %]
634
                                            [% END %]
635
                                        </tbody>
636
                                    </table>
637
                                [% END %]
638
                            [% END %]
639
                            <!-- /ItemGroup level holds -->
640
595
                            <h2 style="padding: 0 1em;">
641
                            <h2 style="padding: 0 1em;">
596
                                Place a hold on a specific item
642
                                Place a hold on a specific item
597
                                [% IF force_hold_level == 'item' %]
643
                                [% IF force_hold_level == 'item' %]
Lines 608-613 Link Here
608
                                            <th>Item type</th>
654
                                            <th>Item type</th>
609
                                        [% END %]
655
                                        [% END %]
610
                                        <th>Barcode</th>
656
                                        <th>Barcode</th>
657
                                        [% IF Koha.Preference('EnableItemGroupHolds') && biblio.object.item_groups.count %]
658
                                            <th>Item group</th>
659
                                        [% END %]
611
                                        <th>Home library</th>
660
                                        <th>Home library</th>
612
                                        <th>Last location</th>
661
                                        <th>Last location</th>
613
                                        [% IF itemdata_ccode %]
662
                                        [% IF itemdata_ccode %]
Lines 632-637 Link Here
632
                                                            <i class="fa fa-times fa-lg" title="Cannot be put on hold"></i>
681
                                                            <i class="fa fa-times fa-lg" title="Cannot be put on hold"></i>
633
                                                            Hold must be record level
682
                                                            Hold must be record level
634
                                                        </span>
683
                                                        </span>
684
                                                    [% ELSIF force_hold_level == 'item_group' %]
685
                                                        <span class="error">
686
                                                            <i class="fa fa-times fa-lg" title="Cannot be put on hold"></i>
687
                                                            Hold must be item group level
688
                                                        </span>
635
                                                    [% ELSIF ( itemloo.available ) %]
689
                                                    [% ELSIF ( itemloo.available ) %]
636
                                                        <input type="radio" name="checkitem" value="[% itemloo.itemnumber | html %]" />
690
                                                        <input type="radio" name="checkitem" value="[% itemloo.itemnumber | html %]" />
637
                                                    [% ELSIF ( itemloo.override ) %]
691
                                                    [% ELSIF ( itemloo.override ) %]
Lines 701-706 Link Here
701
                                                <td>
755
                                                <td>
702
                                                    [% itemloo.barcode | html %]
756
                                                    [% itemloo.barcode | html %]
703
                                                </td>
757
                                                </td>
758
                                                [% IF Koha.Preference('EnableItemGroupHolds') && biblio.object.item_groups.count %]
759
                                                    <td>
760
                                                        [% itemloo.object.item_group.description | html %]
761
                                                    </td>
762
                                                [% END %]
704
                                                <td>
763
                                                <td>
705
                                                    [% Branches.GetName( itemloo.homebranch ) | html %]
764
                                                    [% Branches.GetName( itemloo.homebranch ) | html %]
706
                                                </td>
765
                                                </td>
Lines 1268-1273 Link Here
1268
                };
1327
                };
1269
                if($('input[name="checkitem"]:checked').length)
1328
                if($('input[name="checkitem"]:checked').length)
1270
                    data.item_id = $('input[name="checkitem"]:checked').val();
1329
                    data.item_id = $('input[name="checkitem"]:checked').val();
1330
                if($('input[name="item_group_id"]:checked').length)
1331
                    data.item_group_id = $('input[name="item_group_id"]:checked').val();
1271
                if($('input[name="borrowernumber"]').length)
1332
                if($('input[name="borrowernumber"]').length)
1272
                    data.patron_id = $('input[name="borrowernumber"]').val();
1333
                    data.patron_id = $('input[name="borrowernumber"]').val();
1273
                if($('textarea[name="notes"]').length)
1334
                if($('textarea[name="notes"]').length)
Lines 1313-1320 Link Here
1313
            });
1374
            });
1314
1375
1315
            [% UNLESS ( multi_hold ) %]
1376
            [% UNLESS ( multi_hold ) %]
1316
                $("#hold-request-form").on("submit", function(){
1377
                $("#hold-request-form").on("submit", function(e){
1317
                    return check($(this));
1378
                    return check(e, $(this));
1318
                });
1379
                });
1319
            [% ELSE %]
1380
            [% ELSE %]
1320
                $("#hold-request-form").on("submit", function(){
1381
                $("#hold-request-form").on("submit", function(){
Lines 1358-1364 Link Here
1358
            });
1419
            });
1359
        });
1420
        });
1360
1421
1361
        function check( table ) {
1422
        function check( e, table ) {
1362
1423
1363
            var msg = "";
1424
            var msg = "";
1364
1425
Lines 1384-1389 Link Here
1384
                $('#hold-request-form').preventDoubleFormSubmit();
1445
                $('#hold-request-form').preventDoubleFormSubmit();
1385
                return(true);
1446
                return(true);
1386
            } else {
1447
            } else {
1448
                e.preventDefault();
1387
                alert(msg);
1449
                alert(msg);
1388
                return(false);
1450
                return(false);
1389
            }
1451
            }
Lines 1565-1570 Link Here
1565
                stickyClass: "floating"
1627
                stickyClass: "floating"
1566
            });
1628
            });
1567
1629
1630
            [% IF Koha.Preference('EnableItemGroupHolds') %]
1631
                $(':radio[name="item_group_id"]').change(function(){
1632
                    $(':radio[name="checkitem"]').prop('checked', false);
1633
                });
1634
1635
                $(':radio[name="checkitem"]').change(function(){
1636
                    $(':radio[name="item_group_id"]').prop('checked', false);
1637
                });
1638
            [% END %]
1639
1568
            if(!localStorage.selectedHolds  || document.referrer.replace(/\?.*/, '') !== document.location.origin+document.location.pathname) {
1640
            if(!localStorage.selectedHolds  || document.referrer.replace(/\?.*/, '') !== document.location.origin+document.location.pathname) {
1569
                localStorage.selectedHolds = [];
1641
                localStorage.selectedHolds = [];
1570
            }
1642
            }
(-)a/reserve/placerequest.pl (+2 lines)
Lines 45-50 my $startdate = $input->param('reserve_date') || ''; Link Here
45
my @rank           = $input->multi_param('rank-request');
45
my @rank           = $input->multi_param('rank-request');
46
my $title          = $input->param('title');
46
my $title          = $input->param('title');
47
my $checkitem      = $input->param('checkitem');
47
my $checkitem      = $input->param('checkitem');
48
my $item_group_id  = $input->param('item_group_id');
48
my $expirationdate = $input->param('expiration_date');
49
my $expirationdate = $input->param('expiration_date');
49
my $itemtype       = $input->param('itemtype') || undef;
50
my $itemtype       = $input->param('itemtype') || undef;
50
my $non_priority   = $input->param('non_priority');
51
my $non_priority   = $input->param('non_priority');
Lines 139-144 if ( $patron ) { Link Here
139
                            found            => $found,
140
                            found            => $found,
140
                            itemtype         => $itemtype,
141
                            itemtype         => $itemtype,
141
                            non_priority     => $non_priority,
142
                            non_priority     => $non_priority,
143
                            item_group_id    => $item_group_id,
142
                        }
144
                        }
143
                    );
145
                    );
144
                }
146
                }
(-)a/reserve/request.pl (+4 lines)
Lines 301-312 if ( ( $findborrower && $borrowernumber_hold || $findclub && $club_hold ) Link Here
301
        my %biblioloopiter = ();
301
        my %biblioloopiter = ();
302
302
303
        my $biblio = Koha::Biblios->find( $biblionumber );
303
        my $biblio = Koha::Biblios->find( $biblionumber );
304
304
        unless ($biblio) {
305
        unless ($biblio) {
305
            $biblioloopiter{noitems} = 1;
306
            $biblioloopiter{noitems} = 1;
306
            $template->param('nobiblio' => 1);
307
            $template->param('nobiblio' => 1);
307
            last;
308
            last;
308
        }
309
        }
309
310
311
        $biblioloopiter{object} = $biblio;
312
310
        if ( $patron ) {
313
        if ( $patron ) {
311
            { # CanBookBeReserved
314
            { # CanBookBeReserved
312
                my $canReserve = CanBookBeReserved( $patron->borrowernumber, $biblionumber );
315
                my $canReserve = CanBookBeReserved( $patron->borrowernumber, $biblionumber );
Lines 399-404 if ( ( $findborrower && $borrowernumber_hold || $findclub && $club_hold ) Link Here
399
            for my $item_object ( @items ) {
402
            for my $item_object ( @items ) {
400
                my $do_check;
403
                my $do_check;
401
                my $item = $item_object->unblessed;
404
                my $item = $item_object->unblessed;
405
                $item->{object} = $item_object;
402
                if ( $patron ) {
406
                if ( $patron ) {
403
                    $do_check = $patron->do_check_for_previous_checkout($item) if $wants_check;
407
                    $do_check = $patron->do_check_for_previous_checkout($item) if $wants_check;
404
                    if ( $do_check && $wants_check ) {
408
                    if ( $do_check && $wants_check ) {
(-)a/t/db_dependent/Koha/Holds.t (-2 / +28 lines)
Lines 19-30 Link Here
19
19
20
use Modern::Perl;
20
use Modern::Perl;
21
21
22
use Test::More tests => 7;
22
use Test::More tests => 8;
23
use Test::Warn;
23
use Test::Warn;
24
24
25
use C4::Circulation qw( AddIssue );
25
use C4::Circulation qw( AddIssue );
26
use C4::Reserves qw( AddReserve ModReserve ModReserveCancelAll );
26
use C4::Reserves qw( AddReserve ModReserve ModReserveCancelAll );
27
use Koha::AuthorisedValueCategory;
27
use Koha::AuthorisedValueCategory;
28
use Koha::Biblio::ItemGroups;
28
use Koha::Database;
29
use Koha::Database;
29
use Koha::DateUtils qw( dt_from_string );
30
use Koha::DateUtils qw( dt_from_string );
30
use Koha::Holds;
31
use Koha::Holds;
Lines 635-640 subtest 'set_waiting+patron_expiration_date' => sub { Link Here
635
    };
636
    };
636
};
637
};
637
638
639
subtest 'Test Koha::Hold::item_group' => sub {
640
    plan tests => 1;
641
    my $library    = $builder->build_object( { class => 'Koha::Libraries' } );
642
    my $patron = $builder->build_object({ class => 'Koha::Patrons' });
643
    my $item = $builder->build_sample_item;
644
    my $item_group = $builder->build_object(
645
        {
646
            class => 'Koha::Biblio::ItemGroups',
647
            value => { biblionumber => $item->biblionumber }
648
        }
649
    );
650
    my $reserve_id = AddReserve(
651
        {
652
            branchcode       => $library->branchcode,
653
            borrowernumber   => $patron->borrowernumber,
654
            biblionumber     => $item->biblionumber,
655
            itemnumber       => $item->itemnumber,
656
            item_group_id    => $item_group->id,
657
        }
658
    );
659
660
    my $hold = Koha::Holds->find($reserve_id);
661
    is( $hold->item_group_id, $item_group->id,
662
        'Koha::Hold::item_group returns the correct item_group' );
663
};
664
638
665
639
$schema->storage->txn_rollback;
666
$schema->storage->txn_rollback;
640
667
641
- 

Return to bug 24860