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 176-181 Link Here
176
                    [%- ELSE -%]
176
                    [%- ELSE -%]
177
                        [%- IF hold.itemtype -%]
177
                        [%- IF hold.itemtype -%]
178
                            <em>Next available [% ItemTypes.GetDescription( hold.itemtype ) | html %] item</em>
178
                            <em>Next available [% ItemTypes.GetDescription( hold.itemtype ) | html %] item</em>
179
                        [%- ELSIF hold.object.item_group -%]
180
                            <em>Next available item from group <strong>[% hold.object.item_group.description | html %]</strong></em>
179
                        [%- ELSE -%]
181
                        [%- ELSE -%]
180
                            <em>Next available</em>
182
                            <em>Next available</em>
181
                        [%- END -%]
183
                        [%- END -%]
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt (-4 / +76 lines)
Lines 596-602 Link Here
596
                            [% UNLESS ( multi_hold ) %]
596
                            [% UNLESS ( multi_hold ) %]
597
                                <li>
597
                                <li>
598
                                    <label for="requestany">Hold next available item </label>
598
                                    <label for="requestany">Hold next available item </label>
599
                                    [% IF force_hold_level == 'item' %]
599
                                    [% IF force_hold_level == 'item' || force_hold_level == 'item_group'  %]
600
                                        <input type="checkbox" id="requestany" name="request" disabled="true" />
600
                                        <input type="checkbox" id="requestany" name="request" disabled="true" />
601
                                    [% ELSIF force_hold_level == 'record' %]
601
                                    [% ELSIF force_hold_level == 'record' %]
602
                                        <input type="checkbox" id="requestany" checked="checked" value="Any" disabled="true"/>
602
                                        <input type="checkbox" id="requestany" checked="checked" value="Any" disabled="true"/>
Lines 655-660 Link Here
655
                                [% END %]
655
                                [% END %]
656
                            </ol>
656
                            </ol>
657
657
658
                            <!-- ItemGroup level holds -->
659
                            [% IF Koha.Preference('EnableItemGroupHolds') && biblio.object.item_groups.count %]
660
                                <h2 style="padding: 0 1em;">
661
                                    Hold next available item from an item group
662
                                    [% IF force_hold_level == 'item_group' %]
663
                                        <span class="error"><i>(Required)</i></span>
664
                                    [% END %]
665
                                </h2>
666
667
                                [% IF force_hold_level == 'record' # Patron has placed a record level hold previously for this record %]
668
                                    <span class="error">
669
                                        <i class="fa fa-times fa-lg" title="Cannot be put on hold"></i>
670
                                        Hold must be record level
671
                                    </span>
672
                                [% ELSIF force_hold_level == 'item' # Patron has placed an item level hold previously for this record %]
673
                                    <span class="error">
674
                                        <i class="fa fa-times fa-lg" title="Cannot be put on hold"></i>
675
                                        Hold must be item level
676
                                    </span>
677
                                [% ELSE %]
678
                                    <table>
679
                                        <thead>
680
                                            <tr>
681
                                                <th>Hold</th>
682
                                                <th>Item group</th>
683
                                            </tr>
684
                                        </thead>
685
                                        <tbody>
686
                                            [% FOREACH g IN biblio.object.item_groups.search({}, { order_by => ['display_order'] }) %]
687
                                                [% IF g.items %]
688
                                                    <tr>
689
                                                        <td>
690
                                                            <input id="item_group_id_[% g.id | html %]" type="radio" name="item_group_id" value="[% g.id | html %]" />
691
                                                        </td>
692
                                                        <td>
693
                                                            <label for="item_group_id_[% g.id | html %]">[% g.description | html %]</label>
694
                                                        </td>
695
                                                    </tr>
696
                                                [% END %]
697
                                            [% END %]
698
                                        </tbody>
699
                                    </table>
700
                                [% END %]
701
                            [% END %]
702
                            <!-- /ItemGroup level holds -->
703
658
                            <h2 style="padding: 0 1em;">
704
                            <h2 style="padding: 0 1em;">
659
                                Place a hold on a specific item
705
                                Place a hold on a specific item
660
                                [% IF force_hold_level == 'item' %]
706
                                [% IF force_hold_level == 'item' %]
Lines 671-676 Link Here
671
                                            <th>Item type</th>
717
                                            <th>Item type</th>
672
                                        [% END %]
718
                                        [% END %]
673
                                        <th>Barcode</th>
719
                                        <th>Barcode</th>
720
                                        [% IF Koha.Preference('EnableItemGroupHolds') && biblio.object.item_groups.count %]
721
                                            <th>Item group</th>
722
                                        [% END %]
674
                                        <th>Home library</th>
723
                                        <th>Home library</th>
675
                                        <th>Last location</th>
724
                                        <th>Last location</th>
676
                                        [% IF itemdata_ccode %]
725
                                        [% IF itemdata_ccode %]
Lines 695-700 Link Here
695
                                                            <i class="fa fa-times fa-lg" title="Cannot be put on hold"></i>
744
                                                            <i class="fa fa-times fa-lg" title="Cannot be put on hold"></i>
696
                                                            Hold must be record level
745
                                                            Hold must be record level
697
                                                        </span>
746
                                                        </span>
747
                                                    [% ELSIF force_hold_level == 'item_group' %]
748
                                                        <span class="error">
749
                                                            <i class="fa fa-times fa-lg" title="Cannot be put on hold"></i>
750
                                                            Hold must be item group level
751
                                                        </span>
698
                                                    [% ELSIF ( itemloo.available ) %]
752
                                                    [% ELSIF ( itemloo.available ) %]
699
                                                        <input type="radio" name="checkitem" value="[% itemloo.itemnumber | html %]" />
753
                                                        <input type="radio" name="checkitem" value="[% itemloo.itemnumber | html %]" />
700
                                                    [% ELSIF ( itemloo.override ) %]
754
                                                    [% ELSIF ( itemloo.override ) %]
Lines 764-769 Link Here
764
                                                <td>
818
                                                <td>
765
                                                    [% itemloo.barcode | html %]
819
                                                    [% itemloo.barcode | html %]
766
                                                </td>
820
                                                </td>
821
                                                [% IF Koha.Preference('EnableItemGroupHolds') && biblio.object.item_groups.count %]
822
                                                    <td>
823
                                                        [% itemloo.object.item_group.description | html %]
824
                                                    </td>
825
                                                [% END %]
767
                                                <td>
826
                                                <td>
768
                                                    [% Branches.GetName( itemloo.homebranch ) | html %]
827
                                                    [% Branches.GetName( itemloo.homebranch ) | html %]
769
                                                </td>
828
                                                </td>
Lines 1330-1335 Link Here
1330
                };
1389
                };
1331
                if($('input[name="checkitem"]:checked').length)
1390
                if($('input[name="checkitem"]:checked').length)
1332
                    data.item_id = $('input[name="checkitem"]:checked').val();
1391
                    data.item_id = $('input[name="checkitem"]:checked').val();
1392
                if($('input[name="item_group_id"]:checked').length)
1393
                    data.item_group_id = $('input[name="item_group_id"]:checked').val();
1333
                if($('input[name="borrowernumber"]').length)
1394
                if($('input[name="borrowernumber"]').length)
1334
                    data.patron_id = $('input[name="borrowernumber"]').val();
1395
                    data.patron_id = $('input[name="borrowernumber"]').val();
1335
                if($('textarea[name="notes"]').length)
1396
                if($('textarea[name="notes"]').length)
Lines 1375-1382 Link Here
1375
            });
1436
            });
1376
1437
1377
            [% UNLESS ( multi_hold ) %]
1438
            [% UNLESS ( multi_hold ) %]
1378
                $("#hold-request-form").on("submit", function(){
1439
                $("#hold-request-form").on("submit", function(e){
1379
                    return check($(this));
1440
                    return check(e, $(this));
1380
                });
1441
                });
1381
            [% ELSE %]
1442
            [% ELSE %]
1382
                $("#hold-request-form").on("submit", function(){
1443
                $("#hold-request-form").on("submit", function(){
Lines 1420-1426 Link Here
1420
            });
1481
            });
1421
        });
1482
        });
1422
1483
1423
        function check( table ) {
1484
        function check( e, table ) {
1424
1485
1425
            var msg = "";
1486
            var msg = "";
1426
1487
Lines 1451-1456 Link Here
1451
                $('#hold-request-form').preventDoubleFormSubmit();
1512
                $('#hold-request-form').preventDoubleFormSubmit();
1452
                return(true);
1513
                return(true);
1453
            } else {
1514
            } else {
1515
                e.preventDefault();
1454
                alert(msg);
1516
                alert(msg);
1455
                return(false);
1517
                return(false);
1456
            }
1518
            }
Lines 1604-1609 Link Here
1604
                stickyClass: "floating"
1666
                stickyClass: "floating"
1605
            });
1667
            });
1606
1668
1669
            [% IF Koha.Preference('EnableItemGroupHolds') %]
1670
                $(':radio[name="item_group_id"]').change(function(){
1671
                    $(':radio[name="checkitem"]').prop('checked', false);
1672
                });
1673
1674
                $(':radio[name="checkitem"]').change(function(){
1675
                    $(':radio[name="item_group_id"]').prop('checked', false);
1676
                });
1677
            [% END %]
1678
1607
            if(!localStorage.selectedHolds  || document.referrer.replace(/\?.*/, '') !== document.location.origin+document.location.pathname) {
1679
            if(!localStorage.selectedHolds  || document.referrer.replace(/\?.*/, '') !== document.location.origin+document.location.pathname) {
1608
                localStorage.selectedHolds = [];
1680
                localStorage.selectedHolds = [];
1609
            }
1681
            }
(-)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 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 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