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

(-)a/C4/Reserves.pm (+1 lines)
Lines 162-167 BEGIN { Link Here
162
            itemnumber       => $itemnumber,
162
            itemnumber       => $itemnumber,
163
            found            => $found,
163
            found            => $found,
164
            itemtype         => $itemtype,
164
            itemtype         => $itemtype,
165
            item_gorup_id    => $item_group_id
165
        }
166
        }
166
    );
167
    );
167
168
(-)a/Koha/Hold.pm (+14 lines)
Lines 525-530 sub item { Link Here
525
    return $self->{_item};
525
    return $self->{_item};
526
}
526
}
527
527
528
=head3 item_group
529
530
Returns the related Koha::Biblio::ItemGroup object for this Hold
531
532
=cut
533
534
sub item_group {
535
    my ($self) = @_;
536
537
    my $item_group_rs = $self->_result->item_group;
538
    return unless $item_group_rs;
539
    return Koha::Biblio::ItemGroup->_new_from_dbic($item_group_rs);
540
}
541
528
=head3 branch
542
=head3 branch
529
543
530
Returns the related Koha::Library object for this Hold
544
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 179-184 Link Here
179
                    [%- ELSE -%]
179
                    [%- ELSE -%]
180
                        [%- IF hold.itemtype -%]
180
                        [%- IF hold.itemtype -%]
181
                            <em>Next available [% ItemTypes.GetDescription( hold.itemtype ) | html %] item</em>
181
                            <em>Next available [% ItemTypes.GetDescription( hold.itemtype ) | html %] item</em>
182
                        [%- ELSIF hold.object.item_group -%]
183
                            <em>Next available item from group <strong>[% hold.object.item_group.description | html %]</strong></em>
182
                        [%- ELSE -%]
184
                        [%- ELSE -%]
183
                            <em>Next available</em>
185
                            <em>Next available</em>
184
                        [%- END -%]
186
                        [%- END -%]
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt (-4 / +76 lines)
Lines 599-605 Link Here
599
                            [% UNLESS ( multi_hold ) %]
599
                            [% UNLESS ( multi_hold ) %]
600
                                <li>
600
                                <li>
601
                                    <label for="requestany">Hold next available item </label>
601
                                    <label for="requestany">Hold next available item </label>
602
                                    [% IF force_hold_level == 'item' %]
602
                                    [% IF force_hold_level == 'item' || force_hold_level == 'item_group'  %]
603
                                        <input type="checkbox" id="requestany" name="request" disabled="true" />
603
                                        <input type="checkbox" id="requestany" name="request" disabled="true" />
604
                                    [% ELSIF force_hold_level == 'record' %]
604
                                    [% ELSIF force_hold_level == 'record' %]
605
                                        <input type="checkbox" id="requestany" checked="checked" value="Any" disabled="true"/>
605
                                        <input type="checkbox" id="requestany" checked="checked" value="Any" disabled="true"/>
Lines 658-663 Link Here
658
                                [% END %]
658
                                [% END %]
659
                            </ol>
659
                            </ol>
660
660
661
                            <!-- ItemGroup level holds -->
662
                            [% IF Koha.Preference('EnableItemGroupHolds') && biblio.object.item_groups.count %]
663
                                <h2 style="padding: 0 1em;">
664
                                    Hold next available item from an item group
665
                                    [% IF force_hold_level == 'item_group' %]
666
                                        <span class="error"><i>(Required)</i></span>
667
                                    [% END %]
668
                                </h2>
669
670
                                [% IF force_hold_level == 'record' # Patron has placed a record level hold previously for this record %]
671
                                    <span class="error">
672
                                        <i class="fa fa-times fa-lg" title="Cannot be put on hold"></i>
673
                                        Hold must be record level
674
                                    </span>
675
                                [% ELSIF force_hold_level == 'item' # Patron has placed an item level hold previously for this record %]
676
                                    <span class="error">
677
                                        <i class="fa fa-times fa-lg" title="Cannot be put on hold"></i>
678
                                        Hold must be item level
679
                                    </span>
680
                                [% ELSE %]
681
                                    <table>
682
                                        <thead>
683
                                            <tr>
684
                                                <th>Hold</th>
685
                                                <th>Item group</th>
686
                                            </tr>
687
                                        </thead>
688
                                        <tbody>
689
                                            [% FOREACH g IN biblio.object.item_groups.search({}, { order_by => ['display_order'] }) %]
690
                                                [% IF g.items %]
691
                                                    <tr>
692
                                                        <td>
693
                                                            <input id="item_group_id_[% g.id | html %]" type="radio" name="item_group_id" value="[% g.id | html %]" />
694
                                                        </td>
695
                                                        <td>
696
                                                            <label for="item_group_id_[% g.id | html %]">[% g.description | html %]</label>
697
                                                        </td>
698
                                                    </tr>
699
                                                [% END %]
700
                                            [% END %]
701
                                        </tbody>
702
                                    </table>
703
                                [% END %]
704
                            [% END %]
705
                            <!-- /ItemGroup level holds -->
706
661
                            <h2 style="padding: 0 1em;">
707
                            <h2 style="padding: 0 1em;">
662
                                Place a hold on a specific item
708
                                Place a hold on a specific item
663
                                [% IF force_hold_level == 'item' %]
709
                                [% IF force_hold_level == 'item' %]
Lines 674-679 Link Here
674
                                            <th>Item type</th>
720
                                            <th>Item type</th>
675
                                        [% END %]
721
                                        [% END %]
676
                                        <th>Barcode</th>
722
                                        <th>Barcode</th>
723
                                        [% IF Koha.Preference('EnableItemGroupHolds') && biblio.object.item_groups.count %]
724
                                            <th>Item group</th>
725
                                        [% END %]
677
                                        <th>Home library</th>
726
                                        <th>Home library</th>
678
                                        <th>Last location</th>
727
                                        <th>Last location</th>
679
                                        [% IF itemdata_ccode %]
728
                                        [% IF itemdata_ccode %]
Lines 698-703 Link Here
698
                                                            <i class="fa fa-times fa-lg" title="Cannot be put on hold"></i>
747
                                                            <i class="fa fa-times fa-lg" title="Cannot be put on hold"></i>
699
                                                            Hold must be record level
748
                                                            Hold must be record level
700
                                                        </span>
749
                                                        </span>
750
                                                    [% ELSIF force_hold_level == 'item_group' %]
751
                                                        <span class="error">
752
                                                            <i class="fa fa-times fa-lg" title="Cannot be put on hold"></i>
753
                                                            Hold must be item group level
754
                                                        </span>
701
                                                    [% ELSIF ( itemloo.available ) %]
755
                                                    [% ELSIF ( itemloo.available ) %]
702
                                                        <input type="radio" name="checkitem" value="[% itemloo.itemnumber | html %]" />
756
                                                        <input type="radio" name="checkitem" value="[% itemloo.itemnumber | html %]" />
703
                                                    [% ELSIF ( itemloo.override ) %]
757
                                                    [% ELSIF ( itemloo.override ) %]
Lines 767-772 Link Here
767
                                                <td>
821
                                                <td>
768
                                                    [% itemloo.barcode | html %]
822
                                                    [% itemloo.barcode | html %]
769
                                                </td>
823
                                                </td>
824
                                                [% IF Koha.Preference('EnableItemGroupHolds') && biblio.object.item_groups.count %]
825
                                                    <td>
826
                                                        [% itemloo.object.item_group.description | html %]
827
                                                    </td>
828
                                                [% END %]
770
                                                <td>
829
                                                <td>
771
                                                    [% Branches.GetName( itemloo.homebranch ) | html %]
830
                                                    [% Branches.GetName( itemloo.homebranch ) | html %]
772
                                                </td>
831
                                                </td>
Lines 1339-1344 Link Here
1339
                };
1398
                };
1340
                if($('input[name="checkitem"]:checked').length)
1399
                if($('input[name="checkitem"]:checked').length)
1341
                    data.item_id = $('input[name="checkitem"]:checked').val();
1400
                    data.item_id = $('input[name="checkitem"]:checked').val();
1401
                if($('input[name="item_group_id"]:checked').length)
1402
                    data.item_group_id = $('input[name="item_group_id"]:checked').val();
1342
                if($('input[name="borrowernumber"]').length)
1403
                if($('input[name="borrowernumber"]').length)
1343
                    data.patron_id = $('input[name="borrowernumber"]').val();
1404
                    data.patron_id = $('input[name="borrowernumber"]').val();
1344
                if($('textarea[name="notes"]').length)
1405
                if($('textarea[name="notes"]').length)
Lines 1384-1391 Link Here
1384
            });
1445
            });
1385
1446
1386
            [% UNLESS ( multi_hold ) %]
1447
            [% UNLESS ( multi_hold ) %]
1387
                $("#hold-request-form").on("submit", function(){
1448
                $("#hold-request-form").on("submit", function(e){
1388
                    return check($(this));
1449
                    return check(e, $(this));
1389
                });
1450
                });
1390
            [% ELSE %]
1451
            [% ELSE %]
1391
                $("#hold-request-form").on("submit", function(){
1452
                $("#hold-request-form").on("submit", function(){
Lines 1429-1435 Link Here
1429
            });
1490
            });
1430
        });
1491
        });
1431
1492
1432
        function check( table ) {
1493
        function check( e, table ) {
1433
1494
1434
            var msg = "";
1495
            var msg = "";
1435
1496
Lines 1460-1465 Link Here
1460
                $('#hold-request-form').preventDoubleFormSubmit();
1521
                $('#hold-request-form').preventDoubleFormSubmit();
1461
                return(true);
1522
                return(true);
1462
            } else {
1523
            } else {
1524
                e.preventDefault();
1463
                alert(msg);
1525
                alert(msg);
1464
                return(false);
1526
                return(false);
1465
            }
1527
            }
Lines 1613-1618 Link Here
1613
                stickyClass: "floating"
1675
                stickyClass: "floating"
1614
            });
1676
            });
1615
1677
1678
            [% IF Koha.Preference('EnableItemGroupHolds') %]
1679
                $(':radio[name="item_group_id"]').change(function(){
1680
                    $(':radio[name="checkitem"]').prop('checked', false);
1681
                });
1682
1683
                $(':radio[name="checkitem"]').change(function(){
1684
                    $(':radio[name="item_group_id"]').prop('checked', false);
1685
                });
1686
            [% END %]
1687
1616
            if(!localStorage.selectedHolds  || document.referrer.replace(/\?.*/, '') !== document.location.origin+document.location.pathname) {
1688
            if(!localStorage.selectedHolds  || document.referrer.replace(/\?.*/, '') !== document.location.origin+document.location.pathname) {
1617
                localStorage.selectedHolds = [];
1689
                localStorage.selectedHolds = [];
1618
            }
1690
            }
(-)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 140-145 if ( $patron ) { Link Here
140
                            found            => $found,
141
                            found            => $found,
141
                            itemtype         => $itemtype,
142
                            itemtype         => $itemtype,
142
                            non_priority     => $non_priority,
143
                            non_priority     => $non_priority,
144
                            item_group_id    => $item_group_id,
143
                        }
145
                        }
144
                    );
146
                    );
145
                }
147
                }
(-)a/reserve/request.pl (+4 lines)
Lines 299-310 if ( ( $findborrower && $borrowernumber_hold || $findclub && $club_hold ) Link Here
299
        my %biblioloopiter = ();
299
        my %biblioloopiter = ();
300
300
301
        my $biblio = Koha::Biblios->find( $biblionumber );
301
        my $biblio = Koha::Biblios->find( $biblionumber );
302
302
        unless ($biblio) {
303
        unless ($biblio) {
303
            $biblioloopiter{noitems} = 1;
304
            $biblioloopiter{noitems} = 1;
304
            $template->param('nobiblio' => 1);
305
            $template->param('nobiblio' => 1);
305
            last;
306
            last;
306
        }
307
        }
307
308
309
        $biblioloopiter{object} = $biblio;
310
308
        if ( $patron ) {
311
        if ( $patron ) {
309
            { # CanBookBeReserved
312
            { # CanBookBeReserved
310
                my $canReserve = CanBookBeReserved( $patron->borrowernumber, $biblionumber );
313
                my $canReserve = CanBookBeReserved( $patron->borrowernumber, $biblionumber );
Lines 397-402 if ( ( $findborrower && $borrowernumber_hold || $findclub && $club_hold ) Link Here
397
            for my $item_object ( @items ) {
400
            for my $item_object ( @items ) {
398
                my $do_check;
401
                my $do_check;
399
                my $item = $item_object->unblessed;
402
                my $item = $item_object->unblessed;
403
                $item->{object} = $item_object;
400
                if ( $patron ) {
404
                if ( $patron ) {
401
                    $do_check = $patron->do_check_for_previous_checkout($item) if $wants_check;
405
                    $do_check = $patron->do_check_for_previous_checkout($item) if $wants_check;
402
                    if ( $do_check && $wants_check ) {
406
                    if ( $do_check && $wants_check ) {
(-)a/t/db_dependent/Koha/Holds.t (-1 / +27 lines)
Lines 25-30 use Test::Warn; Link Here
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 641-646 subtest 'set_waiting+patron_expiration_date' => sub { Link Here
641
    };
642
    };
642
};
643
};
643
644
645
subtest 'Test Koha::Hold::item_group' => sub {
646
    plan tests => 1;
647
    my $library    = $builder->build_object( { class => 'Koha::Libraries' } );
648
    my $patron = $builder->build_object({ class => 'Koha::Patrons' });
649
    my $item = $builder->build_sample_item;
650
    my $item_group = $builder->build_object(
651
        {
652
            class => 'Koha::Biblio::ItemGroups',
653
            value => { biblionumber => $item->biblionumber }
654
        }
655
    );
656
    my $reserve_id = AddReserve(
657
        {
658
            branchcode       => $library->branchcode,
659
            borrowernumber   => $patron->borrowernumber,
660
            biblionumber     => $item->biblionumber,
661
            itemnumber       => $item->itemnumber,
662
            item_group_id    => $item_group->id,
663
        }
664
    );
665
666
    my $hold = Koha::Holds->find($reserve_id);
667
    is( $hold->item_group_id, $item_group->id,
668
        'Koha::Hold::item_group returns the correct item_group' );
669
};
670
644
671
645
$schema->storage->txn_rollback;
672
$schema->storage->txn_rollback;
646
673
647
- 

Return to bug 24860