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

(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt (-5 / +11 lines)
Lines 15-20 Link Here
15
[% END %]
15
[% END %]
16
[% INCLUDE 'doc-head-close.inc' %]
16
[% INCLUDE 'doc-head-close.inc' %]
17
[% Asset.css("css/datatables.css") | $raw %]
17
[% Asset.css("css/datatables.css") | $raw %]
18
18
</head>
19
</head>
19
20
20
<body id="circ_request" class="catalog">
21
<body id="circ_request" class="catalog">
Lines 316-324 Link Here
316
                        Hold must be record level
317
                        Hold must be record level
317
                    </span>
318
                    </span>
318
                [% ELSIF ( itemloo.available ) %]
319
                [% ELSIF ( itemloo.available ) %]
319
                    <input type="radio" name="checkitem" value="[% itemloo.itemnumber | html %]" />
320
                    <input type="checkbox" name="checkitem" value="[% itemloo.itemnumber %]" />
320
                [% ELSIF ( itemloo.override ) %]
321
                [% ELSIF ( itemloo.override ) %]
321
                    <input type="radio" name="checkitem" class="needsoverride" value="[% itemloo.itemnumber | html %]" />
322
                    <input type="checkbox" name="checkitem" class="needsoverride" value="[% itemloo.itemnumber %]" />
322
                    <i class="fa fa-exclamation-triangle fa-lg" style="color:gold" alt="Requires override of hold policy"/></i>
323
                    <i class="fa fa-exclamation-triangle fa-lg" style="color:gold" alt="Requires override of hold policy"/></i>
323
                [% ELSE %]
324
                [% ELSE %]
324
                    <span class="error">
325
                    <span class="error">
Lines 670-675 Link Here
670
            [% END %][% END %][% END %]
671
            [% END %][% END %][% END %]
671
        };
672
        };
672
        var MSG_NO_ITEMS_AVAILABLE = _("A hold cannot be requested on any of these items.");
673
        var MSG_NO_ITEMS_AVAILABLE = _("A hold cannot be requested on any of these items.");
674
        var MSG_EXCEEDED_HOLDS_PER_RECORD = _("Patron has exceeded the number of holds for this record.");
675
        var remainingHolds = "[% remaining_holds_for_record %]";
673
676
674
        $(document).ready(function() {
677
        $(document).ready(function() {
675
            function ToggleHoldsToPlace() {
678
            function ToggleHoldsToPlace() {
Lines 794-810 Link Here
794
                }
797
                }
795
            });
798
            });
796
            $("input[name=checkitem]").click(function() {
799
            $("input[name=checkitem]").click(function() {
797
                onechecked = 0;
800
                numchecked = 0;
798
                $("input[name=checkitem]").each(function() {
801
                $("input[name=checkitem]").each(function() {
799
                    if(this.checked){
802
                    if(this.checked){
800
                        onechecked = 1;
803
                        numchecked = 1;
801
                    }
804
                    }
802
                });
805
                });
803
                if(onechecked == 1){
806
                if(numchecked == 1){
804
                    $("#requestany").prop("checked", false);
807
                    $("#requestany").prop("checked", false);
805
                } else {
808
                } else {
806
                    $("#requestany").prop("checked",true);
809
                    $("#requestany").prop("checked",true);
807
                }
810
                }
811
                if (remainingHolds - numchecked < 0) {
812
                    alert(MSG_EXCEEDED_HOLDS_PER_RECORD);
813
                }
808
            });
814
            });
809
            var prev_rank_request;
815
            var prev_rank_request;
810
            $("select[name=rank-request]").on("focus", function() {
816
            $("select[name=rank-request]").on("focus", function() {
(-)a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-reserve.tt (-105 / +95 lines)
Lines 146-165 Link Here
146
                        <form action="/cgi-bin/koha/opac-reserve.pl" method="post" id="hold-request-form">
146
                        <form action="/cgi-bin/koha/opac-reserve.pl" method="post" id="hold-request-form">
147
                            <input type="hidden" name="place_reserve" value="1"/>
147
                            <input type="hidden" name="place_reserve" value="1"/>
148
                            <!-- These values are set dynamically by js -->
148
                            <!-- These values are set dynamically by js -->
149
                            <input type="hidden" name="biblionumbers" id="biblionumbers"/>
150
                            <input type="hidden" name="selecteditems" id="selections"/>
151
                            <div id="bigloop">
149
                            <div id="bigloop">
152
150
153
                                [% FOREACH bibitemloo IN bibitemloop %]
151
                                [% FOREACH bibitemloo IN bibitemloop %]
154
                                    <div class="holdrow">
152
                                    <div class="holdrow">
153
                                        <input id="remaining_holds_[% bibitemloo.biblionumber %]" type="hidden" value="[% bibitemloo.remaining_holds_for_record %]"/>
155
                                        <p>
154
                                        <p>
156
                                            [% IF ( bibitemloo.holdable ) %]
155
                                            [% IF ( bibitemloo.holdable ) %]
157
                                                <input class="reserve_mode" name="reserve_mode" type="hidden" value="single"/>
156
                                                <span title="[% bibitemloo.biblionumber %]" style="padding:.3em">
158
                                                <input class="single_bib" name="single_bib" type="hidden" value="[% bibitemloo.biblionumber | html %]"/>
157
                                                    <label>
159
                                                <span class="confirmjs_hold" title="[% bibitemloo.biblionumber | html %]" style="padding:.3em"></span>
158
                                                        <input class="biblionumbers" name="biblionumbers" type="checkbox" value="[% bibitemloo.biblionumber %]" checked="checked">
160
                                                <span class="confirm_nonjs">
159
                                                        Place a hold on
161
                                                    <input type="radio" class="confirmbox checkitem [% bibitemloo.biblionumber | html %]" name="[% bibitemloo.biblionumber | html %]" checked="checked" id="single_[% bibitemloo.biblionumber | html %]" value="any" />
160
                                                    </label>
162
                                                    <label class="confirm_label" for="single_[% bibitemloo.biblionumber | html %]">Place a hold on </label>
163
                                                </span>
161
                                                </span>
164
                                            [% END # / bibitemloo.holdable %]
162
                                            [% END # / bibitemloo.holdable %]
165
163
Lines 226-232 Link Here
226
                                                            <li class="branch">
224
                                                            <li class="branch">
227
                                                                <label for="branch_[% bibitemloo.biblionumber | html %]">Pick up location:</label>
225
                                                                <label for="branch_[% bibitemloo.biblionumber | html %]">Pick up location:</label>
228
                                                                [% UNLESS ( bibitemloo.holdable ) %]
226
                                                                [% UNLESS ( bibitemloo.holdable ) %]
229
                                                                    <select name="branch" id="branch_[% bibitemloo.biblionumber | html %]" disabled="disabled">
227
                                                                    <select name="branch_[% bibitemloo.biblionumber %]" id="branch_[% bibitemloo.biblionumber | html %]" disabled="disabled">
230
                                                                        [% PROCESS options_for_libraries libraries => Branches.all({ search_params => { pickup_location => 1 }, selected => branch }) %]
228
                                                                        [% PROCESS options_for_libraries libraries => Branches.all({ search_params => { pickup_location => 1 }, selected => branch }) %]
231
                                                                    </select>
229
                                                                    </select>
232
                                                                [% ELSE %]
230
                                                                [% ELSE %]
Lines 300-329 Link Here
300
                                                            </li>
298
                                                            </li>
301
                                                        [% END # / IF OpacHoldNotes %]
299
                                                        [% END # / IF OpacHoldNotes %]
302
300
303
                                                        [% IF bibitemloo.itemholdable %]
301
                                                        <!-- ITEM HOLDS -->
304
                                                            <!-- ITEM HOLDS -->
302
                                                        <li class="lradio place_on_type" style="display:none;">
305
                                                            <li class="lradio place_on_type" style="display:none;">
303
                                                                <label class="radio inline" for="reqany_[% bibitemloo.biblionumber %]">Next available item</label>
306
                                                                [% IF NOT bibitemloo.force_hold %]
304
                                                                <input type="radio" name="reqtype_[% bibitemloo.biblionumber %]"
307
                                                                    <label class="radio inline" for="reqany_[% bibitemloo.biblionumber | html %]">Next available item</label>
305
                                                                        id="reqany_[% bibitemloo.biblionumber %]"
308
                                                                    <input type="radio" name="reqtype_[% bibitemloo.biblionumber | html %]"
306
                                                                        class="selectany"
309
                                                                            id="reqany_[% bibitemloo.biblionumber | html %]"
307
                                                                        value="Any"
310
                                                                            class="selectany"
308
                                                                        checked="checked"
311
                                                                            value="Any"
312
                                                                            checked="checked"
313
                                                                    />
314
                                                                [% END %]
315
                                                                <label class="radio inline" for="reqspecific_[% bibitemloo.biblionumber | html %]">A specific item</label>
316
                                                                <input type="radio" name="reqtype_[% bibitemloo.biblionumber | html %]"
317
                                                                       id="reqspecific_[% bibitemloo.biblionumber | html %]"
318
                                                                       class="selectspecific"
319
                                                                       value="Specific"
320
                                                                />
309
                                                                />
321
                                                            </li>
310
                                                            <label class="radio inline" for="reqspecific_[% bibitemloo.biblionumber %]">A specific item</label>
322
                                                        [% END # / IF bibitemloo.itemholdable %]
311
                                                            <input type="radio" name="reqtype_[% bibitemloo.biblionumber %]"
312
                                                                   id="reqspecific_[% bibitemloo.biblionumber %]"
313
                                                                   class="selectspecific"
314
                                                                   value="Specific"
315
                                                            />
316
                                                        </li>
323
                                                    </ul>
317
                                                    </ul>
324
318
325
                                                    [% IF bibitemloo.itemholdable %]
319
                                                    [% IF bibitemloo.remaining_holds_for_record > 1 %]
326
                                                        <table class="copiesrow table table-bordered table-striped" id="copiesrow_[% bibitemloo.biblionumber | html %]">
320
                                                        [% SET count = 1 %]
321
                                                        <div id="holds_to_place_[% bibitemloo.biblionumber %]" class="hold-options holds-to-place">
322
                                                            <label>Holds to place (count)</label>
323
                                                            <select name="holds_to_place_count_[% bibitemloo.biblionumber %]">
324
                                                            [% WHILE count <= bibitemloo.remaining_holds_for_record %]
325
                                                                <option value="[% count %]">[% count %]</option>
326
                                                                [% SET count = count + 1 %]
327
                                                            [% END %]
328
                                                            </select>
329
                                                        </div>
330
                                                    [% ELSE %]
331
                                                        <input type="hidden" name="holds_to_place_count_[% bibitemloo.biblionumber %]" value="1" />
332
                                                    [% END %]
333
334
                                                        <table class="copiesrow table table-bordered table-striped" id="copiesrow_[% bibitemloo.biblionumber %]">
327
                                                            <caption>Select a specific item:</caption>
335
                                                            <caption>Select a specific item:</caption>
328
                                                            <tr>
336
                                                            <tr>
329
                                                                <th>Copy number</th>
337
                                                                <th>Copy number</th>
Lines 349-357 Link Here
349
                                                                <tr class="[% itemLoo.backgroundcolor | html %]">
357
                                                                <tr class="[% itemLoo.backgroundcolor | html %]">
350
                                                                    <td class="copynumber">
358
                                                                    <td class="copynumber">
351
                                                                        [% IF ( itemLoo.available ) %]
359
                                                                        [% IF ( itemLoo.available ) %]
352
                                                                            <input type="radio" class="checkitem checkitem_[% bibitemloo.biblionumber | html %]" name="checkitem_[% bibitemloo.biblionumber | html %]" value="[% itemLoo.itemnumber | html %]" />
360
                                                                            <input type="checkbox" class="checkitem checkitem_[% bibitemloo.biblionumber %]" name="checkitem_[% bibitemloo.biblionumber %]" value="[% itemLoo.itemnumber %]" />
353
                                                                        [% ELSE %]
361
                                                                        [% ELSE %]
354
                                                                            <input disabled="disabled" type="radio" class="checkitem" name="checkitem" value="[% itemLoo.itemnumber | html %]"
362
                                                                            <input disabled="disabled" type="checkbox" class="checkitem" name="checkitem" value="[% itemLoo.itemnumber %]"
355
                                                                                   style="display:none;" />
363
                                                                                   style="display:none;" />
356
                                                                            <img src="[% interface | html %]/lib/famfamfam/silk/cross.png" alt="Cannot be put on hold" title="Cannot be put on hold" />
364
                                                                            <img src="[% interface | html %]/lib/famfamfam/silk/cross.png" alt="Cannot be put on hold" title="Cannot be put on hold" />
357
                                                                        [% END %]
365
                                                                        [% END %]
Lines 427-435 Link Here
427
                                                                    </td>
435
                                                                    </td>
428
                                                                </tr>
436
                                                                </tr>
429
                                                            [% END # / FOREACH itemLoo IN bibitemloo.itemLoop%]
437
                                                            [% END # / FOREACH itemLoo IN bibitemloo.itemLoop%]
430
                                                        </table> <!-- / #copiesrow_[% bibitemloo.biblionumber | html %] -->
438
                                                        </table> <!-- / #copiesrow_[% bibitemloo.biblionumber %] -->
431
                                                    [% END # / IF ( bibitemloo.itemholdable )%]
439
                                                </div> <!-- / #hold-options-[% bibitemloo.biblionumber %] -->
432
                                                </div> <!-- / #hold-options-[% bibitemloo.biblionumber | html %] -->
433
                                            </fieldset>
440
                                            </fieldset>
434
                                        [% END # / IF ( bibitemloo.holdable ) %]
441
                                        [% END # / IF ( bibitemloo.holdable ) %]
435
                                    </div> <!-- / .holdrow -->
442
                                    </div> <!-- / .holdrow -->
Lines 451-456 Link Here
451
<script>
458
<script>
452
// <![CDATA[
459
// <![CDATA[
453
    var MSG_NO_ITEM_SELECTED = _("Expecting a specific item selection.");
460
    var MSG_NO_ITEM_SELECTED = _("Expecting a specific item selection.");
461
    var MSG_MAX_HOLDS_EXCEEDED = _("Maximum number of reserve exceded.");
454
462
455
        // Clear the contents of an input field
463
        // Clear the contents of an input field
456
        $(".clearfield").on("click",function(e){
464
        $(".clearfield").on("click",function(e){
Lines 460-467 Link Here
460
468
461
    // Select the first item available
469
    // Select the first item available
462
    function select_first_available(id){
470
    function select_first_available(id){
463
        var radios = $("input:radio[name='checkitem_" + id + "']");
471
        var checkboxes = $("input:checkbox[name='checkitem_" + id + "']");
464
        $(radios).first().attr("checked", "checked");
472
        $(checkboxes).first().attr("checked", "checked");
465
    }
473
    }
466
474
467
    $(document).ready(function() {
475
    $(document).ready(function() {
Lines 482-495 Link Here
482
            }
490
            }
483
        });
491
        });
484
492
485
        // click on a first td check the confirmjs checkbox
493
        $('.checkitem').click(function(e) {
486
        $("td.hold").click(function(e){
494
            var bibNum = suffixOf($(this).attr("name"), "_");
487
          if(e.target.tagName.toLowerCase() == 'td'){
495
            var nbCheked = $("input[name='checkitem_"+bibNum+"']:checked").length;
488
            $(this).find("input.confirmjs").each( function() {
496
            var remaining = $("input[id='remaining_holds_"+bibNum+"']").val();
489
               $(this).attr('checked', !$(this).attr('checked'));
497
            if (nbCheked >= remaining) {
490
               $(this).change();
498
                $("input[name='checkitem_"+bibNum+"']:not(:checked)").attr('disabled', 'disabled');
491
            });
499
            }
492
          }
500
            else {
501
                $('.checkitem_'+bibNum).attr('disabled', false);
502
            }
493
        });
503
        });
494
504
495
        $(".toggle-hold-options").on("click",function(e){
505
        $(".toggle-hold-options").on("click",function(e){
Lines 504-518 Link Here
504
        // Hides all 'specific copy' table rows on load.
514
        // Hides all 'specific copy' table rows on load.
505
        $(".copiesrow").hide();
515
        $(".copiesrow").hide();
506
516
517
        $(".holds-to-place").show();
507
        [% FOREACH bibitemloo IN bibitemloop %]
518
        [% FOREACH bibitemloo IN bibitemloop %]
508
          [% IF bibitemloo.force_hold %]
519
            [% IF bibitemloo.force_hold %]
509
            $("#toggle-hold-options-[% bibitemloo.biblionumber | html %]").click();
520
                [% IF bibitemloo.force_hold == 'item' %]
510
            $("#reqspecific_[% bibitemloo.biblionumber | html %]").click();
521
                    $("#toggle-hold-options-[% bibitemloo.biblionumber %]").click();
511
            $("#copiesrow_[% bibitemloo.biblionumber | html %]").show();
522
                    $("#reqspecific_[% bibitemloo.biblionumber %]").attr('checked', true);
512
          [% END %]
523
                    $("#holds_to_place_[% bibitemloo.biblionumber %]").hide();
513
          [% IF bibitemloo.reqholdnotes %]
524
                    $("#copiesrow_[% bibitemloo.biblionumber %]").show();
514
              $("#holdnotes_[% bibitemloo.biblionumber | html %]").attr( 'required', true );
525
                [% ELSIF bibitemloo.force_hold == 'record' %]
515
          [% END %]
526
                    $("#toggle-hold-options-[% bibitemloo.biblionumber %]").click();
527
                    $("#reqany_[% bibitemloo.biblionumber %]").attr('checked', true);
528
                [% END %]
529
                $("#reqany_[% bibitemloo.biblionumber %]").attr('disabled', 'disabled');
530
                $("#reqspecific_[% bibitemloo.biblionumber %]").attr('disabled', 'disabled');
531
            [% END %]
532
            [% IF bibitemloo.reqholdnotes %]
533
                $("#holdnotes_[% bibitemloo.biblionumber %]").attr( 'required', true );
534
            [% END %]
516
        [% END %]
535
        [% END %]
517
536
518
        $(".date-format").each(function(){
537
        $(".date-format").each(function(){
Lines 529-568 Link Here
529
            $("#" + op + fieldID).val("");
548
            $("#" + op + fieldID).val("");
530
        });
549
        });
531
550
532
        // Replace non-JS single-selection with multi-selection capability.
533
        $(".reserve_mode").val("multi");
534
        $(".confirm_nonjs").remove();
535
        $(".confirmjs_hold").each(function(){
536
            var bib = $(this).attr("title");
537
            var html = "<label><input type =\"checkbox\" class=\"confirmjs\" checked=\"checked\"";
538
            html += "value=\"" + bib + "\" id=\"" + bib + "\" /> " + _("Place a hold on") + " </label> ";
539
            $(this).html(html);
540
        });
541
        $(".confirmjs_nohold").each(function(){
542
            var bib = $(this).attr("title");
543
            var html = "<label><input type =\"checkbox\" class=\"confirmjs\" disabled=\"disabled\"";
544
            html += "value=\"" + bib + "\" id=\"" + bib + "\" />" + _("Place a hold on: ") + "</label>";
545
            $(this).html(html);
546
        });
547
548
        // expand or collapse the copiesrow tr
551
        // expand or collapse the copiesrow tr
549
        function toggle_copiesrow(biblioNum) {
552
        function toggle_copiesrow(biblioNum) {
550
            var checkbox = $("input:checkbox[value='"+biblioNum+"']");
553
            var checkbox = $("input:checkbox[value='"+biblioNum+"']");
551
            newCopiesRowId = "#copiesrow_" + biblioNum;
554
            newCopiesRowId = "#copiesrow_" + biblioNum;
555
            holdsToPlaceCountId = "#holds_to_place_" + biblioNum;
552
            var select_specific = $("#reqspecific_"+biblioNum).is(":checked");
556
            var select_specific = $("#reqspecific_"+biblioNum).is(":checked");
553
            // If the checkbox is checked AND we want a specific item, we display the items block
557
            // If the checkbox is checked AND we want a specific item, we display the items block
554
            if ( $(checkbox).is(":checked") && select_specific ) {
558
            if ( $(checkbox).is(":checked") && select_specific ) {
555
                $(newCopiesRowId).show();
559
                $(newCopiesRowId).show();
560
                $(holdsToPlaceCountId).hide();
556
            } else {
561
            } else {
557
                $(newCopiesRowId).hide();
562
                $(newCopiesRowId).hide();
563
                $(holdsToPlaceCountId).show();
558
             }
564
             }
559
        };
565
        };
560
566
561
        $("#place_on_hdr").show();
567
        function total_requested() {
568
            var total = 0;
569
            $("input[name='biblionumbers']:checked").each(function() {
570
                var biblioNum = $(this).val();
571
                if ($("#reqspecific_" + biblioNum + ":checked").size() > 0) {
572
                    total += parseInt($("input[name='checkitem_'"+biblioNum+"]:checked").length);
573
                } else {
574
                    total += parseInt($("select[name='holds_to_place_count_"+biblioNum+"']").val());
575
                }
576
            });
577
            return total;
578
        }
562
579
563
        $(".place_on_type").show();
580
        $(".place_on_type").show();
564
        // onload, selectany is checked
581
        // onload, selectany is checked
565
        $(".selectany").attr("checked", "checked");
566
582
567
        // If the user is *allowed* to choose a specific item
583
        // If the user is *allowed* to choose a specific item
568
        // The first one is preselected
584
        // The first one is preselected
Lines 571-578 Link Here
571
            select_first_available(id);
587
            select_first_available(id);
572
        });
588
        });
573
589
574
        // On confirmsjs change
590
        // On biblionumbers change
575
        $(".confirmjs").change(function(){
591
        $(".biblionumbers").change(function(){
576
            var id = suffixOf($(this).attr("id"), "_");
592
            var id = suffixOf($(this).attr("id"), "_");
577
            // If I m checked, I enable radio buttons
593
            // If I m checked, I enable radio buttons
578
            if ( $(this).is(":checked") ) {
594
            if ( $(this).is(":checked") ) {
Lines 594-628 Link Here
594
            toggle_copiesrow(id);
610
            toggle_copiesrow(id);
595
        });
611
        });
596
612
597
        // Show or hide holds notes
598
        $(".shownotes").click(function(){
599
            biblioNum = suffixOf($(this).attr("id"), "_");
600
            $("#notesrow_"+biblioNum).toggle();
601
        });
602
603
        // When 'Place Hold' button is clicked
613
        // When 'Place Hold' button is clicked
604
        $(".placehold").click(function(){
614
        $(".placehold").click(function(){
605
            var biblionumbers = "";
615
            if (total_requested() + [% reserves_count %] > [% maxreserves %]) {
606
            var selections = "";
616
                alert(MSG_MAX_HOLDS_EXCEEDED);
607
617
                return false;
608
            [% IF new_reserves_allowed %]
618
            }
609
                if ($(".confirmjs:checked").size() > [% new_reserves_allowed | html %] ) {
610
                    alert(MSG_MAX_HOLDS_EXCEEDED);
611
                    return false;
612
                }
613
            [% END %]
614
619
615
            if ($(".confirmjs:checked").size() == 0) {
620
            if ($("input[name='biblionumbers']:checked").size() == 0) {
616
                alert(MSG_NO_RECORD_SELECTED);
621
                alert(MSG_NO_RECORD_SELECTED);
617
                return false;
622
                return false;
618
            }
623
            }
619
624
620
            // Find the items with the 'Hold' box checked
625
            // Find the items with the 'Hold' box checked
621
            var badBib = null;
626
            var badBib = null;
622
            $(".confirmjs:checked").each(function() {
627
            $("input[name='biblionumbers']:checked").each(function() {
623
                var biblioNum = $(this).val();
628
                var biblioNum = $(this).val();
624
                biblionumbers += biblioNum + "/";
625
                selections += biblioNum + "/";
626
629
627
                // If required hold note is empty, make it visible
630
                // If required hold note is empty, make it visible
628
                if( $("#holdnotes_"+biblioNum).attr( 'required' ) && $("#holdnotes_"+biblioNum).val() == '' ) {
631
                if( $("#holdnotes_"+biblioNum).attr( 'required' ) && $("#holdnotes_"+biblioNum).val() == '' ) {
Lines 639-656 Link Here
639
                        alert(MSG_NO_ITEM_SELECTED);
642
                        alert(MSG_NO_ITEM_SELECTED);
640
                        badBib = biblioNum;
643
                        badBib = biblioNum;
641
                        return false;
644
                        return false;
642
                    } else {
643
                      selections += $(item).val();
644
                    }
645
                    }
645
                }
646
                }
646
                selections += "/";
647
648
                // Add the pickup location
649
                var branchSel = $("#branch_" + biblioNum);
650
                if (branchSel.size() > 0) {
651
                    selections += $(branchSel).val();
652
                }
653
                selections += "/";
654
                return true;
647
                return true;
655
            });
648
            });
656
649
Lines 658-666 Link Here
658
                return false;
651
                return false;
659
            }
652
            }
660
653
661
            $("#selections").val(selections);
662
            $("#biblionumbers").val(biblionumbers);
663
664
            return true;
654
            return true;
665
        });
655
        });
666
656
(-)a/opac/opac-reserve.pl (-83 / +83 lines)
Lines 106-139 if ( $reservefee > 0){ Link Here
106
106
107
my $itemtypes = { map { $_->{itemtype} => $_ } @{ Koha::ItemTypes->search_with_localization->unblessed } };
107
my $itemtypes = { map { $_->{itemtype} => $_ } @{ Koha::ItemTypes->search_with_localization->unblessed } };
108
108
109
# There are two ways of calling this script, with a single biblio num
109
# Coming from opac-search biblionumbers param is a string, coming from
110
# or multiple biblio nums.
110
# opac-reserve, it's an array.
111
my $biblionumbers = $query->param('biblionumbers');
111
my @biblionumbers = ref($query->param('biblionumbers')) eq 'Array'
112
my $reserveMode = $query->param('reserve_mode');
112
    ? $query->param('biblionumbers')
113
if ($reserveMode && ($reserveMode eq 'single')) {
113
    : split(/\//, $query->param('biblionumbers'));
114
    my $bib = $query->param('single_bib');
114
115
    $biblionumbers = "$bib/";
115
unless (@biblionumbers) {
116
}
116
    push(@biblionumbers, $query->param('biblionumber'));
117
if (! $biblionumbers) {
118
    $biblionumbers = $query->param('biblionumber');
119
}
120
121
if ((! $biblionumbers) && (! $query->param('place_reserve'))) {
122
    $template->param(message=>1, no_biblionumber=>1);
123
    &get_out($query, $cookie, $template->output);
124
}
117
}
125
118
126
# Pass the numbers to the page so they can be fed back
119
# Pass the numbers to the page so they can be fed back
127
# when the hold is confirmed. TODO: Not necessary?
120
# when the hold is confirmed. TODO: Not necessary?
128
$template->param( biblionumbers => $biblionumbers );
121
$template->param( biblionumbers => @biblionumbers );
129
130
# Each biblio number is suffixed with '/', e.g. "1/2/3/"
131
my @biblionumbers = split /\//, $biblionumbers;
132
if (($#biblionumbers < 0) && (! $query->param('place_reserve'))) {
133
    # TODO: New message?
134
    $template->param(message=>1, no_biblionumber=>1);
135
    &get_out($query, $cookie, $template->output);
136
}
137
122
138
123
139
# pass the pickup branch along....
124
# pass the pickup branch along....
Lines 200-238 if ( $query->param('place_reserve') ) { Link Here
200
        $reserve_cnt = $patron->holds->count;
185
        $reserve_cnt = $patron->holds->count;
201
    }
186
    }
202
187
203
    # List is composed of alternating biblio/item/branch
204
    my $selectedItems = $query->param('selecteditems');
205
206
    if ($query->param('reserve_mode') eq 'single') {
207
        # This indicates non-JavaScript mode, so there was
208
        # only a single biblio number selected.
209
        my $bib = $query->param('single_bib');
210
        my $item = $query->param("checkitem_$bib");
211
        if ($item eq 'any') {
212
            $item = '';
213
        }
214
        my $branch = $query->param('branch');
215
        $selectedItems = "$bib/$item/$branch/";
216
    }
217
218
    $selectedItems =~ s!/$!!;
219
    my @selectedItems = split /\//, $selectedItems, -1;
220
221
    # Make sure there is a biblionum/itemnum/branch triplet for each item.
222
    # The itemnum can be 'any', meaning next available.
223
    my $selectionCount = @selectedItems;
224
    if (($selectionCount == 0) || (($selectionCount % 3) != 0)) {
225
        $template->param(message=>1, bad_data=>1);
226
        &get_out($query, $cookie, $template->output);
227
    }
228
229
    my $failed_holds = 0;
188
    my $failed_holds = 0;
230
    while (@selectedItems) {
189
    foreach my $biblioNum (@biblionumbers) {
231
        my $biblioNum = shift(@selectedItems);
190
        my $itemNum = $query->param("checkitem_$biblioNum");
232
        my $itemNum   = shift(@selectedItems);
191
        my @itemnumbers = $query->param("checkitem_$biblioNum");
233
        my $branch    = shift(@selectedItems);    # i.e., branch code, not name
192
        my $branch = $query->param("branch_$biblioNum");
234
193
        my $reqtype = $query->param("reqtype_$biblioNum");
235
        my $canreserve = 0;
194
        my $holds_to_place_count = $query->param("holds_to_place_count_$biblioNum") || 1;
195
        my $notes = $query->param('notes_'.$biblioNum) || '';
196
        my $nbRequested = $reqtype eq 'Specific' ? @itemnumbers : $holds_to_place_count;
197
198
        my $canreserve = 1;
199
        if (   $maxreserves
200
            && $reserve_cnt + $nbRequested >= $maxreserves )
201
        {
202
            $canreserve = 0;
203
        }
236
204
237
        my $singleBranchMode = Koha::Libraries->search->count == 1;
205
        my $singleBranchMode = Koha::Libraries->search->count == 1;
238
        if ( $singleBranchMode || ! C4::Context->preference("OPACAllowUserToChooseBranch") )
206
        if ( $singleBranchMode || ! C4::Context->preference("OPACAllowUserToChooseBranch") )
Lines 240-246 if ( $query->param('place_reserve') ) { Link Here
240
            $branch = $patron->branchcode;
208
            $branch = $patron->branchcode;
241
        }
209
        }
242
210
243
#item may belong to a host biblio, if yes change biblioNum to hosts bilbionumber
244
        if ( $itemNum ne '' ) {
211
        if ( $itemNum ne '' ) {
245
            my $item = Koha::Items->find( $itemNum );
212
            my $item = Koha::Items->find( $itemNum );
246
            my $hostbiblioNum = $item->biblio->biblionumber;
213
            my $hostbiblioNum = $item->biblio->biblionumber;
Lines 262-284 if ( $query->param('place_reserve') ) { Link Here
262
229
263
        my $expiration_date = $query->param("expiration_date_$biblioNum");
230
        my $expiration_date = $query->param("expiration_date_$biblioNum");
264
231
232
        # If a specific item was selected and the pickup branch is the same as the
233
        # holdingbranch, force the value $rank and $found.
265
        my $rank = $biblioData->{rank};
234
        my $rank = $biblioData->{rank};
266
        if ( $itemNum ne '' ) {
235
        if ( $reqtype eq 'Specific') {
267
            $canreserve = 1 if CanItemBeReserved( $borrowernumber, $itemNum )->{status} eq 'OK';
236
            foreach my $itemnumber (@itemnumbers) {
268
        }
237
                my $biblionumber = $biblioNum;
269
        else {
238
270
            $canreserve = 1 if CanBookBeReserved( $borrowernumber, $biblioNum )->{status} eq 'OK';
239
                #item may belong to a host biblio, if yes change biblioNum to hosts bilbionumber
240
                my $hostbiblioNum = GetBiblionumberFromItemnumber($itemnumber);
241
                if ( $hostbiblioNum ne $biblioNum ) {
242
                    $biblionumber = $hostbiblioNum;
243
                }
271
244
272
            # Inserts a null into the 'itemnumber' field of 'reserves' table.
245
                $canreserve = 0 unless CanItemBeReserved( $borrowernumber, $itemnumber ) eq 'OK';
273
            $itemNum = undef;
246
                $rank = '0' unless C4::Context->preference('ReservesNeedReturns');
274
        }
247
                my $item = GetItem($itemnumber);
275
        my $notes = $query->param('notes_'.$biblioNum)||'';
248
                if ( $item->{'holdingbranch'} eq $branch ) {
249
                    $found = 'W'
250
                      unless C4::Context->preference('ReservesNeedReturns');
251
                }
276
252
277
        if (   $maxreserves
253
                if ($canreserve) {
278
            && $reserve_cnt >= $maxreserves )
254
                    my $reserve_id = AddReserve(
279
        {
255
                        $branch,         $borrowernumber,
280
            $canreserve = 0;
256
                        $biblionumber,
257
                        [$biblionumber], $rank,
258
                        $startdate,      $expiration_date,
259
                        $notes,          $biblioData->{title},
260
                        $itemnumber,     $found
261
                    );
262
                    $failed_holds++ unless $reserve_id;
263
                    ++$reserve_cnt;
264
                }
265
            }
266
            print $query->redirect("/cgi-bin/koha/opac-user.pl?" . ( $failed_holds ? "failed_holds=$failed_holds" : q|| ) . "#opac-user-holds");
267
            exit;
281
        }
268
        }
269
        $canreserve = 0 unless CanBookBeReserved( $borrowernumber, $biblioNum ) eq 'OK';
282
270
283
        unless ( $can_place_hold_if_available_at_pickup ) {
271
        unless ( $can_place_hold_if_available_at_pickup ) {
284
            my $items_in_this_library = Koha::Items->search({ biblionumber => $biblioNum, holdingbranch => $branch });
272
            my $items_in_this_library = Koha::Items->search({ biblionumber => $biblioNum, holdingbranch => $branch });
Lines 294-307 if ( $query->param('place_reserve') ) { Link Here
294
282
295
        # Here we actually do the reserveration. Stage 3.
283
        # Here we actually do the reserveration. Stage 3.
296
        if ($canreserve) {
284
        if ($canreserve) {
297
            my $reserve_id = AddReserve(
285
            for ( my $i = 0 ; $i < $holds_to_place_count ; $i++ ) {
298
                $branch,          $borrowernumber, $biblioNum,
286
                my $reserve_id = AddReserve(
299
                [$biblioNum],     $rank,           $startdate,
287
                    $branch,          $borrowernumber, $biblioNum,
300
                $expiration_date, $notes,          $biblioData->{title},
288
                    [$biblioNum],     $rank,           $startdate,
301
                $itemNum,         $found,          $itemtype,
289
                    $expiration_date, $notes,          $biblioData->{title},
302
            );
290
                    $itemNum,         $found,          $itemtype,
303
            $failed_holds++ unless $reserve_id;
291
                );
304
            ++$reserve_cnt;
292
                $failed_holds++ unless $reserve_id;
293
                ++$reserve_cnt;
294
            }
305
        }
295
        }
306
    }
296
    }
307
297
Lines 361-366 if ( $maxreserves && ( $reserves_count >= $maxreserves ) ) { Link Here
361
}
351
}
362
352
363
unless ( $noreserves ) {
353
unless ( $noreserves ) {
354
    $template->param(
355
        maxreserves => $maxreserves,
356
        reserves_count => $reserves_count
357
    );
364
    my $requested_reserves_count = scalar( @biblionumbers );
358
    my $requested_reserves_count = scalar( @biblionumbers );
365
    if ( $maxreserves && ( $reserves_count + $requested_reserves_count > $maxreserves ) ) {
359
    if ( $maxreserves && ( $reserves_count + $requested_reserves_count > $maxreserves ) ) {
366
        $template->param( new_reserves_allowed => $maxreserves - $reserves_count );
360
        $template->param( new_reserves_allowed => $maxreserves - $reserves_count );
Lines 529-535 foreach my $biblioNum (@biblionumbers) { Link Here
529
            if ( $opac_hold_policy ne 'N' ) { # If Y or F
523
            if ( $opac_hold_policy ne 'N' ) { # If Y or F
530
                $itemLoopIter->{available} = 1;
524
                $itemLoopIter->{available} = 1;
531
                $numCopiesOPACAvailable++;
525
                $numCopiesOPACAvailable++;
532
                $biblioLoopIter{force_hold} = 1 if $opac_hold_policy eq 'F';
526
                $biblioLoopIter{force_hold} = 'item' if $opac_hold_policy eq 'F';
533
            }
527
            }
534
            $numCopiesAvailable++;
528
            $numCopiesAvailable++;
535
529
Lines 596-613 foreach my $biblioNum (@biblionumbers) { Link Here
596
    # patron placed a record level hold, all the holds the patron places must
590
    # patron placed a record level hold, all the holds the patron places must
597
    # be record level. If the patron placed an item level hold, all holds
591
    # be record level. If the patron placed an item level hold, all holds
598
    # the patron places must be item level
592
    # the patron places must be item level
599
    my $forced_hold_level = Koha::Holds->search(
593
    my $holds = Koha::Holds->search(
600
        {
594
        {
601
            borrowernumber => $borrowernumber,
595
            borrowernumber => $borrowernumber,
602
            biblionumber   => $biblioNum,
596
            biblionumber   => $biblioNum,
603
            found          => undef,
597
            found          => undef,
604
        }
598
        }
605
    )->forced_hold_level();
599
    );
600
    my $forced_hold_level = $holds->forced_hold_level();
606
    if ($forced_hold_level) {
601
    if ($forced_hold_level) {
607
        $biblioLoopIter{force_hold}   = 1 if $forced_hold_level eq 'item';
602
        #$biblioLoopIter{force_hold}   = 1 if $forced_hold_level eq 'item';
608
        $biblioLoopIter{itemholdable} = 0 if $forced_hold_level eq 'record';
603
        #$biblioLoopIter{itemholdable} = 0 if $forced_hold_level eq 'record';
604
        $biblioLoopIter{force_hold} = $forced_hold_level;
609
    }
605
    }
610
606
607
    my $max_holds_for_record = GetMaxPatronHoldsForRecord( $borrowernumber, $biblioNum );
608
    my $remaining_holds_for_record = $max_holds_for_record - $holds->count();
609
    $biblioLoopIter{remaining_holds_for_record} = $remaining_holds_for_record;
610
611
611
612
    push @$biblioLoop, \%biblioLoopIter;
612
    push @$biblioLoop, \%biblioLoopIter;
613
613
(-)a/reserve/placerequest.pl (-14 / +19 lines)
Lines 47-53 my $startdate = $input->param('reserve_date') || ''; Link Here
47
my @rank           = $input->multi_param('rank-request');
47
my @rank           = $input->multi_param('rank-request');
48
my $type           = $input->param('type');
48
my $type           = $input->param('type');
49
my $title          = $input->param('title');
49
my $title          = $input->param('title');
50
my $checkitem      = $input->param('checkitem');
50
my @checkitems     = $input->param('checkitem');
51
my $expirationdate = $input->param('expiration_date');
51
my $expirationdate = $input->param('expiration_date');
52
my $itemtype       = $input->param('itemtype') || undef;
52
my $itemtype       = $input->param('itemtype') || undef;
53
53
Lines 58-63 my $multi_hold = $input->param('multi_hold'); Link Here
58
my $biblionumbers = $multi_hold ? $input->param('biblionumbers') : ($biblionumber . '/');
58
my $biblionumbers = $multi_hold ? $input->param('biblionumbers') : ($biblionumber . '/');
59
my $bad_bibs = $input->param('bad_bibs');
59
my $bad_bibs = $input->param('bad_bibs');
60
my $holds_to_place_count = $input->param('holds_to_place_count') || 1;
60
my $holds_to_place_count = $input->param('holds_to_place_count') || 1;
61
$holds_to_place_count = scalar(@checkitems) if scalar(@checkitems);
61
62
62
my %bibinfos = ();
63
my %bibinfos = ();
63
my @biblionumbers = split '/', $biblionumbers;
64
my @biblionumbers = split '/', $biblionumbers;
Lines 68-74 foreach my $bibnum (@biblionumbers) { Link Here
68
    $bibinfos{$bibnum} = \%bibinfo;
69
    $bibinfos{$bibnum} = \%bibinfo;
69
}
70
}
70
71
71
my $found;
72
my @found;
73
74
foreach my $checkitem (@checkitems) {
75
    # if we have an item selectionned, and the pickup branch is the same as the holdingbranch
76
    # of the document, we force the value $rank and $found .
77
    $rank[0] = '0' unless C4::Context->preference('ReservesNeedReturns');
78
    my $item = GetItem($checkitem);
79
    if ( $item->{'holdingbranch'} eq $branch ){
80
        push @found, 'W' unless C4::Context->preference('ReservesNeedReturns');
81
    }
82
}
72
83
73
if ( $type eq 'str8' && $borrower ) {
84
if ( $type eq 'str8' && $borrower ) {
74
85
Lines 86-108 if ( $type eq 'str8' && $borrower ) { Link Here
86
            }
97
            }
87
        }
98
        }
88
99
89
        if ( defined $checkitem && $checkitem ne '' ) {
90
            my $item = GetItem($checkitem);
91
            if ( $item->{'biblionumber'} ne $biblionumber ) {
92
                $biblionumber = $item->{'biblionumber'};
93
            }
94
        }
95
96
        if ($multi_hold) {
100
        if ($multi_hold) {
97
            my $bibinfo = $bibinfos{$biblionumber};
101
            my $bibinfo = $bibinfos{$biblionumber};
98
            AddReserve($branch,$borrower->{'borrowernumber'},$biblionumber,[$biblionumber],
102
            AddReserve( $branch, $borrower->{'borrowernumber'},
99
                       $bibinfo->{rank},$startdate,$expirationdate,$notes,$bibinfo->{title},$checkitem,$found);
103
                        $biblionumber, [$biblionumber],
104
                        $bibinfo->{rank}, $startdate, $expirationdate, $notes,$bibinfo->{title});
100
        } else {
105
        } else {
101
            # place a request on 1st available
106
            # place a request on 1st available
102
            for ( my $i = 0 ; $i < $holds_to_place_count ; $i++ ) {
107
            for ( my $i = 0 ; $i < $holds_to_place_count ; $i++ ) {
108
                my $item = GetItem($checkitems[$i]);
103
                AddReserve( $branch, $borrower->{'borrowernumber'},
109
                AddReserve( $branch, $borrower->{'borrowernumber'},
104
                    $biblionumber, \@realbi, $rank[0], $startdate, $expirationdate, $notes, $title,
110
                    $item->{biblionumber}, \@realbi, $rank[0], $startdate, $expirationdate, $notes, $title,
105
                    $checkitem, $found, $itemtype );
111
                    $checkitems[$i], $found[$i] );
106
            }
112
            }
107
        }
113
        }
108
    }
114
    }
109
- 

Return to bug 15565