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 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 1336-1341 Link Here
1336
                };
1395
                };
1337
                if($('input[name="checkitem"]:checked').length)
1396
                if($('input[name="checkitem"]:checked').length)
1338
                    data.item_id = $('input[name="checkitem"]:checked').val();
1397
                    data.item_id = $('input[name="checkitem"]:checked').val();
1398
                if($('input[name="item_group_id"]:checked').length)
1399
                    data.item_group_id = $('input[name="item_group_id"]:checked').val();
1339
                if($('input[name="borrowernumber"]').length)
1400
                if($('input[name="borrowernumber"]').length)
1340
                    data.patron_id = $('input[name="borrowernumber"]').val();
1401
                    data.patron_id = $('input[name="borrowernumber"]').val();
1341
                if($('textarea[name="notes"]').length)
1402
                if($('textarea[name="notes"]').length)
Lines 1381-1388 Link Here
1381
            });
1442
            });
1382
1443
1383
            [% UNLESS ( multi_hold ) %]
1444
            [% UNLESS ( multi_hold ) %]
1384
                $("#hold-request-form").on("submit", function(){
1445
                $("#hold-request-form").on("submit", function(e){
1385
                    return check($(this));
1446
                    return check(e, $(this));
1386
                });
1447
                });
1387
            [% ELSE %]
1448
            [% ELSE %]
1388
                $("#hold-request-form").on("submit", function(){
1449
                $("#hold-request-form").on("submit", function(){
Lines 1426-1432 Link Here
1426
            });
1487
            });
1427
        });
1488
        });
1428
1489
1429
        function check( table ) {
1490
        function check( e, table ) {
1430
1491
1431
            var msg = "";
1492
            var msg = "";
1432
1493
Lines 1457-1462 Link Here
1457
                $('#hold-request-form').preventDoubleFormSubmit();
1518
                $('#hold-request-form').preventDoubleFormSubmit();
1458
                return(true);
1519
                return(true);
1459
            } else {
1520
            } else {
1521
                e.preventDefault();
1460
                alert(msg);
1522
                alert(msg);
1461
                return(false);
1523
                return(false);
1462
            }
1524
            }
Lines 1610-1615 Link Here
1610
                stickyClass: "floating"
1672
                stickyClass: "floating"
1611
            });
1673
            });
1612
1674
1675
            [% IF Koha.Preference('EnableItemGroupHolds') %]
1676
                $(':radio[name="item_group_id"]').change(function(){
1677
                    $(':radio[name="checkitem"]').prop('checked', false);
1678
                });
1679
1680
                $(':radio[name="checkitem"]').change(function(){
1681
                    $(':radio[name="item_group_id"]').prop('checked', false);
1682
                });
1683
            [% END %]
1684
1613
            if(!localStorage.selectedHolds  || document.referrer.replace(/\?.*/, '') !== document.location.origin+document.location.pathname) {
1685
            if(!localStorage.selectedHolds  || document.referrer.replace(/\?.*/, '') !== document.location.origin+document.location.pathname) {
1614
                localStorage.selectedHolds = [];
1686
                localStorage.selectedHolds = [];
1615
            }
1687
            }
(-)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