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 25-30 var override_items = {[% FOREACH bibitemloo IN bibitemloop %][% FOREACH itemloo Link Here
25
[% END %][% END %][% END %]
25
[% END %][% END %][% END %]
26
};
26
};
27
var MSG_NO_ITEMS_AVAILABLE = _("A hold cannot be requested on any of these items.");
27
var MSG_NO_ITEMS_AVAILABLE = _("A hold cannot be requested on any of these items.");
28
var MSG_EXCEEDED_HOLDS_PER_RECORD = _("Patron has exceeded the number of holds for this record.");
29
var remainingHolds = "[% remaining_holds_for_record %]";
28
30
29
$(document).ready(function() {
31
$(document).ready(function() {
30
    function ToggleHoldsToPlace() {
32
    function ToggleHoldsToPlace() {
Lines 149-165 function checkMultiHold() { Link Here
149
        }
151
        }
150
    });
152
    });
151
    $("input[name=checkitem]").click(function() {
153
    $("input[name=checkitem]").click(function() {
152
        onechecked = 0;
154
        numchecked = 0;
153
        $("input[name=checkitem]").each(function() {
155
        $("input[name=checkitem]").each(function() {
154
            if(this.checked){
156
            if(this.checked){
155
                onechecked = 1;
157
                numchecked = 1;
156
            }
158
            }
157
        });
159
        });
158
        if(onechecked == 1){
160
        if(numchecked > 0){
159
            $("#requestany").prop("checked", false);
161
            $("#requestany").prop("checked", false);
160
        } else {
162
        } else {
161
            $("#requestany").prop("checked",true);
163
            $("#requestany").prop("checked",true);
162
        }
164
        }
165
166
        if (remainingHolds - numchecked < 0) {
167
            alert(MSG_EXCEEDED_HOLDS_PER_RECORD);
168
        }
163
    });
169
    });
164
170
165
    $(".clear-date").on("click",function(e){
171
    $(".clear-date").on("click",function(e){
Lines 495-503 function checkMultiHold() { Link Here
495
                        Hold must be record level
501
                        Hold must be record level
496
                    </span>
502
                    </span>
497
                [% ELSIF ( itemloo.available ) %]
503
                [% ELSIF ( itemloo.available ) %]
498
                    <input type="radio" name="checkitem" value="[% itemloo.itemnumber %]" />
504
                    <input type="checkbox" name="checkitem" value="[% itemloo.itemnumber %]" />
499
                [% ELSIF ( itemloo.override ) %]
505
                [% ELSIF ( itemloo.override ) %]
500
                    <input type="radio" name="checkitem" class="needsoverride" value="[% itemloo.itemnumber %]" />
506
                    <input type="checkbox" name="checkitem" class="needsoverride" value="[% itemloo.itemnumber %]" />
501
                    <i class="fa fa-exclamation-triangle fa-lg" style="color:gold" alt="Requires override of hold policy"/></i>
507
                    <i class="fa fa-exclamation-triangle fa-lg" style="color:gold" alt="Requires override of hold policy"/></i>
502
                [% ELSE %]
508
                [% ELSE %]
503
                    <span class="error">
509
                    <span class="error">
(-)a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-reserve.tt (-99 / +89 lines)
Lines 134-153 Link Here
134
                        <form action="/cgi-bin/koha/opac-reserve.pl" method="post" id="hold-request-form">
134
                        <form action="/cgi-bin/koha/opac-reserve.pl" method="post" id="hold-request-form">
135
                            <input type="hidden" name="place_reserve" value="1"/>
135
                            <input type="hidden" name="place_reserve" value="1"/>
136
                            <!-- These values are set dynamically by js -->
136
                            <!-- These values are set dynamically by js -->
137
                            <input type="hidden" name="biblionumbers" id="biblionumbers"/>
138
                            <input type="hidden" name="selecteditems" id="selections"/>
139
                            <div id="bigloop">
137
                            <div id="bigloop">
140
138
141
                                [% FOREACH bibitemloo IN bibitemloop %]
139
                                [% FOREACH bibitemloo IN bibitemloop %]
142
                                    <div class="holdrow">
140
                                    <div class="holdrow">
141
                                        <input id="remaining_holds_[% bibitemloo.biblionumber %]" type="hidden" value="[% bibitemloo.remaining_holds_for_record %]"/>
143
                                        <p>
142
                                        <p>
144
                                            [% IF ( bibitemloo.holdable ) %]
143
                                            [% IF ( bibitemloo.holdable ) %]
145
                                                <input class="reserve_mode" name="reserve_mode" type="hidden" value="single"/>
144
                                                <span title="[% bibitemloo.biblionumber %]" style="padding:.3em">
146
                                                <input class="single_bib" name="single_bib" type="hidden" value="[% bibitemloo.biblionumber %]"/>
145
                                                    <label>
147
                                                <span class="confirmjs_hold" title="[% bibitemloo.biblionumber %]" style="padding:.3em"></span>
146
                                                        <input class="biblionumbers" name="biblionumbers" type="checkbox" value="[% bibitemloo.biblionumber %]" checked="checked">
148
                                                <span class="confirm_nonjs">
147
                                                        Place a hold on
149
                                                    <input type="radio" class="confirmbox checkitem [% bibitemloo.biblionumber %]" name="[% bibitemloo.biblionumber %]" checked="checked" id="single_[% bibitemloo.biblionumber %]" value="any" />
148
                                                    </label>
150
                                                    <label class="confirm_label" for="single_[% bibitemloo.biblionumber %]">Place a hold on </label>
151
                                                </span>
149
                                                </span>
152
                                            [% END # / bibitemloo.holdable %]
150
                                            [% END # / bibitemloo.holdable %]
153
151
Lines 214-224 Link Here
214
                                                            <li class="branch">
212
                                                            <li class="branch">
215
                                                                <label for="branch_[% bibitemloo.biblionumber %]">Pick up location:</label>
213
                                                                <label for="branch_[% bibitemloo.biblionumber %]">Pick up location:</label>
216
                                                                [% UNLESS ( bibitemloo.holdable ) %]
214
                                                                [% UNLESS ( bibitemloo.holdable ) %]
217
                                                                    <select name="branch" id="branch_[% bibitemloo.biblionumber %]" disabled="disabled">
215
                                                                    <select name="branch_[% bibitemloo.biblionumber %]" id="branch_[% bibitemloo.biblionumber %]" disabled="disabled">
218
                                                                        [% PROCESS options_for_libraries libraries => Branches.all( selected => branch ) %]
216
                                                                        [% PROCESS options_for_libraries libraries => Branches.all( selected => branch ) %]
219
                                                                    </select>
217
                                                                    </select>
220
                                                                [% ELSE %]
218
                                                                [% ELSE %]
221
                                                                    <select name="branch" id="branch_[% bibitemloo.biblionumber %]">
219
                                                                    <select name="branch_[% bibitemloo.biblionumber %]" id="branch_[% bibitemloo.biblionumber %]">
222
                                                                        [% PROCESS options_for_libraries libraries => Branches.all( selected => branch ) %]
220
                                                                        [% PROCESS options_for_libraries libraries => Branches.all( selected => branch ) %]
223
                                                                    </select>
221
                                                                    </select>
224
                                                                [% END # / UNLESS bibitemloo.holdable %]
222
                                                                [% END # / UNLESS bibitemloo.holdable %]
Lines 273-301 Link Here
273
                                                            </li>
271
                                                            </li>
274
                                                        [% END # / IF OpacHoldNotes %]
272
                                                        [% END # / IF OpacHoldNotes %]
275
273
276
                                                        [% IF bibitemloo.itemholdable %]
274
                                                        <!-- ITEM HOLDS -->
277
                                                            <!-- ITEM HOLDS -->
275
                                                        <li class="lradio place_on_type" style="display:none;">
278
                                                            <li class="lradio place_on_type" style="display:none;">
276
                                                                <label class="radio inline" for="reqany_[% bibitemloo.biblionumber %]">Next available item</label>
279
                                                                [% IF NOT bibitemloo.force_hold %]
280
                                                                    <label class="radio inline" for="reqany_[% bibitemloo.biblionumber %]">Next available item</label>
281
                                                                    <input type="radio" name="reqtype_[% bibitemloo.biblionumber %]"
282
                                                                            id="reqany_[% bibitemloo.biblionumber %]"
283
                                                                            class="selectany"
284
                                                                            value="Any"
285
                                                                            checked="checked"
286
                                                                    />
287
                                                                [% END %]
288
                                                                <label class="radio inline" for="reqspecific_[% bibitemloo.biblionumber %]">A specific item</label>
289
                                                                <input type="radio" name="reqtype_[% bibitemloo.biblionumber %]"
277
                                                                <input type="radio" name="reqtype_[% bibitemloo.biblionumber %]"
290
                                                                       id="reqspecific_[% bibitemloo.biblionumber %]"
278
                                                                        id="reqany_[% bibitemloo.biblionumber %]"
291
                                                                       class="selectspecific"
279
                                                                        class="selectany"
292
                                                                       value="Specific"
280
                                                                        value="Any"
281
                                                                        checked="checked"
293
                                                                />
282
                                                                />
294
                                                            </li>
283
                                                            <label class="radio inline" for="reqspecific_[% bibitemloo.biblionumber %]">A specific item</label>
295
                                                        [% END # / IF bibitemloo.itemholdable %]
284
                                                            <input type="radio" name="reqtype_[% bibitemloo.biblionumber %]"
285
                                                                   id="reqspecific_[% bibitemloo.biblionumber %]"
286
                                                                   class="selectspecific"
287
                                                                   value="Specific"
288
                                                            />
289
                                                        </li>
296
                                                    </ul>
290
                                                    </ul>
297
291
298
                                                    [% IF bibitemloo.itemholdable %]
292
                                                    [% IF bibitemloo.remaining_holds_for_record > 1 %]
293
                                                        [% SET count = 1 %]
294
                                                        <div id="holds_to_place_[% bibitemloo.biblionumber %]" class="hold-options holds-to-place">
295
                                                            <label>Holds to place (count)</label>
296
                                                            <select name="holds_to_place_count_[% bibitemloo.biblionumber %]">
297
                                                            [% WHILE count <= bibitemloo.remaining_holds_for_record %]
298
                                                                <option value="[% count %]">[% count %]</option>
299
                                                                [% SET count = count + 1 %]
300
                                                            [% END %]
301
                                                            </select>
302
                                                        </div>
303
                                                    [% ELSE %]
304
                                                        <input type="hidden" name="holds_to_place_count_[% bibitemloo.biblionumber %]" value="1" />
305
                                                    [% END %]
306
299
                                                        <table class="copiesrow table table-bordered table-striped" id="copiesrow_[% bibitemloo.biblionumber %]">
307
                                                        <table class="copiesrow table table-bordered table-striped" id="copiesrow_[% bibitemloo.biblionumber %]">
300
                                                            <caption>Select a specific item:</caption>
308
                                                            <caption>Select a specific item:</caption>
301
                                                            <tr>
309
                                                            <tr>
Lines 319-327 Link Here
319
                                                                <tr class="[% itemLoo.backgroundcolor %]">
327
                                                                <tr class="[% itemLoo.backgroundcolor %]">
320
                                                                    <td class="copynumber">
328
                                                                    <td class="copynumber">
321
                                                                        [% IF ( itemLoo.available ) %]
329
                                                                        [% IF ( itemLoo.available ) %]
322
                                                                            <input type="radio" class="checkitem checkitem_[% bibitemloo.biblionumber %]" name="checkitem_[% bibitemloo.biblionumber %]" value="[% itemLoo.itemnumber %]" />
330
                                                                            <input type="checkbox" class="checkitem checkitem_[% bibitemloo.biblionumber %]" name="checkitem_[% bibitemloo.biblionumber %]" value="[% itemLoo.itemnumber %]" />
323
                                                                        [% ELSE %]
331
                                                                        [% ELSE %]
324
                                                                            <input disabled="disabled" type="radio" class="checkitem" name="checkitem" value="[% itemLoo.itemnumber %]"
332
                                                                            <input disabled="disabled" type="checkbox" class="checkitem" name="checkitem" value="[% itemLoo.itemnumber %]"
325
                                                                                   style="display:none;" />
333
                                                                                   style="display:none;" />
326
                                                                            <img src="[% interface %]/lib/famfamfam/silk/cross.png" alt="Cannot be put on hold" title="Cannot be put on hold" />
334
                                                                            <img src="[% interface %]/lib/famfamfam/silk/cross.png" alt="Cannot be put on hold" title="Cannot be put on hold" />
327
                                                                        [% END %]
335
                                                                        [% END %]
Lines 395-401 Link Here
395
                                                                </tr>
403
                                                                </tr>
396
                                                            [% END # / FOREACH itemLoo IN bibitemloo.itemLoop%]
404
                                                            [% END # / FOREACH itemLoo IN bibitemloo.itemLoop%]
397
                                                        </table> <!-- / #copiesrow_[% bibitemloo.biblionumber %] -->
405
                                                        </table> <!-- / #copiesrow_[% bibitemloo.biblionumber %] -->
398
                                                    [% END # / IF ( bibitemloo.itemholdable )%]
399
                                                </div> <!-- / #hold-options-[% bibitemloo.biblionumber %] -->
406
                                                </div> <!-- / #hold-options-[% bibitemloo.biblionumber %] -->
400
                                            </fieldset>
407
                                            </fieldset>
401
                                        [% END # / IF ( bibitemloo.holdable ) %]
408
                                        [% END # / IF ( bibitemloo.holdable ) %]
Lines 418-423 Link Here
418
<script type="text/javascript">
425
<script type="text/javascript">
419
// <![CDATA[
426
// <![CDATA[
420
    var MSG_NO_ITEM_SELECTED = _("Expecting a specific item selection.");
427
    var MSG_NO_ITEM_SELECTED = _("Expecting a specific item selection.");
428
    var MSG_MAX_HOLDS_EXCEEDED = _("Maximum number of reserve exceded.");
421
    var ForceHoldNotesReasons=new Array(
429
    var ForceHoldNotesReasons=new Array(
422
       _("This title consists of multiple volumes/parts. Please indicate which part you need. Clicking on specific item information may be helpful."),
430
       _("This title consists of multiple volumes/parts. Please indicate which part you need. Clicking on specific item information may be helpful."),
423
       "*** Add a new reason above this line ***" );
431
       "*** Add a new reason above this line ***" );
Lines 431-438 Link Here
431
439
432
    // Select the first item available
440
    // Select the first item available
433
    function select_first_available(id){
441
    function select_first_available(id){
434
        var radios = $("input:radio[name='checkitem_" + id + "']");
442
        var checkboxes = $("input:checkbox[name='checkitem_" + id + "']");
435
        $(radios).first().attr("checked", "checked");
443
        $(checkboxes).first().attr("checked", "checked");
436
    }
444
    }
437
445
438
    $(document).ready(function() {
446
    $(document).ready(function() {
Lines 453-466 Link Here
453
            }
461
            }
454
        });
462
        });
455
463
456
        // click on a first td check the confirmjs checkbox
464
        $('.checkitem').click(function(e) {
457
        $("td.hold").click(function(e){
465
            var bibNum = suffixOf($(this).attr("name"), "_");
458
          if(e.target.tagName.toLowerCase() == 'td'){
466
            var nbCheked = $("input[name='checkitem_"+bibNum+"']:checked").length;
459
            $(this).find("input.confirmjs").each( function() {
467
            var remaining = $("input[id='remaining_holds_"+bibNum+"']").val();
460
               $(this).attr('checked', !$(this).attr('checked'));
468
            if (nbCheked >= remaining) {
461
               $(this).change();
469
                $("input[name='checkitem_"+bibNum+"']:not(:checked)").attr('disabled', 'disabled');
462
            });
470
            }
463
          }
471
            else {
472
                $('.checkitem_'+bibNum).attr('disabled', false);
473
            }
464
        });
474
        });
465
475
466
        $(".toggle-hold-options").on("click",function(e){
476
        $(".toggle-hold-options").on("click",function(e){
Lines 475-486 Link Here
475
        // Hides all 'specific copy' table rows on load.
485
        // Hides all 'specific copy' table rows on load.
476
        $(".copiesrow").hide();
486
        $(".copiesrow").hide();
477
487
488
        $(".holds-to-place").show();
478
        [% FOREACH bibitemloo IN bibitemloop %]
489
        [% FOREACH bibitemloo IN bibitemloop %]
479
          [% IF bibitemloo.force_hold %]
490
            [% IF bibitemloo.force_hold %]
480
            $("#toggle-hold-options-[% bibitemloo.biblionumber %]").click();
491
                [% IF bibitemloo.force_hold == 'item' %]
481
            $("#reqspecific_[% bibitemloo.biblionumber %]").click();
492
                    $("#toggle-hold-options-[% bibitemloo.biblionumber %]").click();
482
            $("#copiesrow_[% bibitemloo.biblionumber %]").show();
493
                    $("#reqspecific_[% bibitemloo.biblionumber %]").attr('checked', true);
483
          [% END %]
494
                    $("#holds_to_place_[% bibitemloo.biblionumber %]").hide();
495
                    $("#copiesrow_[% bibitemloo.biblionumber %]").show();
496
                [% ELSIF bibitemloo.force_hold == 'record' %]
497
                    $("#toggle-hold-options-[% bibitemloo.biblionumber %]").click();
498
                    $("#reqany_[% bibitemloo.biblionumber %]").attr('checked', true);
499
                [% END %]
500
                $("#reqany_[% bibitemloo.biblionumber %]").attr('disabled', 'disabled');
501
                $("#reqspecific_[% bibitemloo.biblionumber %]").attr('disabled', 'disabled');
502
            [% END %]
484
        [% END %]
503
        [% END %]
485
504
486
        // Insert reasons for forced hold notes
505
        // Insert reasons for forced hold notes
Lines 506-545 Link Here
506
            $("#" + op + fieldID).val("");
525
            $("#" + op + fieldID).val("");
507
        });
526
        });
508
527
509
        // Replace non-JS single-selection with multi-selection capability.
510
        $(".reserve_mode").val("multi");
511
        $(".confirm_nonjs").remove();
512
        $(".confirmjs_hold").each(function(){
513
            var bib = $(this).attr("title");
514
            var html = "<label><input type =\"checkbox\" class=\"confirmjs\" checked=\"checked\"";
515
            html += "value=\"" + bib + "\" id=\"" + bib + "\" /> " + _("Place a hold on") + " </label> ";
516
            $(this).html(html);
517
        });
518
        $(".confirmjs_nohold").each(function(){
519
            var bib = $(this).attr("title");
520
            var html = "<label><input type =\"checkbox\" class=\"confirmjs\" disabled=\"disabled\"";
521
            html += "value=\"" + bib + "\" id=\"" + bib + "\" />" + _("Place a hold on: ") + "</label>";
522
            $(this).html(html);
523
        });
524
525
        // expand or collapse the copiesrow tr
528
        // expand or collapse the copiesrow tr
526
        function toggle_copiesrow(biblioNum) {
529
        function toggle_copiesrow(biblioNum) {
527
            var checkbox = $("input:checkbox[value='"+biblioNum+"']");
530
            var checkbox = $("input:checkbox[value='"+biblioNum+"']");
528
            newCopiesRowId = "#copiesrow_" + biblioNum;
531
            newCopiesRowId = "#copiesrow_" + biblioNum;
532
            holdsToPlaceCountId = "#holds_to_place_" + biblioNum;
529
            var select_specific = $("#reqspecific_"+biblioNum).is(":checked");
533
            var select_specific = $("#reqspecific_"+biblioNum).is(":checked");
530
            // If the checkbox is checked AND we want a specific item, we display the items block
534
            // If the checkbox is checked AND we want a specific item, we display the items block
531
            if ( $(checkbox).is(":checked") && select_specific ) {
535
            if ( $(checkbox).is(":checked") && select_specific ) {
532
                $(newCopiesRowId).show();
536
                $(newCopiesRowId).show();
537
                $(holdsToPlaceCountId).hide();
533
            } else {
538
            } else {
534
                $(newCopiesRowId).hide();
539
                $(newCopiesRowId).hide();
540
                $(holdsToPlaceCountId).show();
535
             }
541
             }
536
        };
542
        };
537
543
538
        $("#place_on_hdr").show();
544
        function total_requested() {
545
            var total = 0;
546
            $("input[name='biblionumbers']:checked").each(function() {
547
                var biblioNum = $(this).val();
548
                if ($("#reqspecific_" + biblioNum + ":checked").size() > 0) {
549
                    total += parseInt($("input[name='checkitem_'"+biblioNum+"]:checked").length);
550
                } else {
551
                    total += parseInt($("select[name='holds_to_place_count_"+biblioNum+"']").val());
552
                }
553
            });
554
            return total;
555
        }
539
556
540
        $(".place_on_type").show();
557
        $(".place_on_type").show();
541
        // onload, selectany is checked
558
        // onload, selectany is checked
542
        $(".selectany").attr("checked", "checked");
543
559
544
        // If the user is *allowed* to choose a specific item
560
        // If the user is *allowed* to choose a specific item
545
        // The first one is preselected
561
        // The first one is preselected
Lines 548-555 Link Here
548
            select_first_available(id);
564
            select_first_available(id);
549
        });
565
        });
550
566
551
        // On confirmsjs change
567
        // On biblionumbers change
552
        $(".confirmjs").change(function(){
568
        $(".biblionumbers").change(function(){
553
            var id = suffixOf($(this).attr("id"), "_");
569
            var id = suffixOf($(this).attr("id"), "_");
554
            // If I m checked, I enable radio buttons
570
            // If I m checked, I enable radio buttons
555
            if ( $(this).is(":checked") ) {
571
            if ( $(this).is(":checked") ) {
Lines 571-605 Link Here
571
            toggle_copiesrow(id);
587
            toggle_copiesrow(id);
572
        });
588
        });
573
589
574
        // Show or hide holds notes
575
        $(".shownotes").click(function(){
576
            biblioNum = suffixOf($(this).attr("id"), "_");
577
            $("#notesrow_"+biblioNum).toggle();
578
        });
579
580
        // When 'Place Hold' button is clicked
590
        // When 'Place Hold' button is clicked
581
        $(".placehold").click(function(){
591
        $(".placehold").click(function(){
582
            var biblionumbers = "";
592
            if (total_requested() + [% reserves_count %] > [% maxreserves %]) {
583
            var selections = "";
593
                alert(MSG_MAX_HOLDS_EXCEEDED);
584
594
                return false;
585
            [% IF new_reserves_allowed %]
595
            }
586
                if ($(".confirmjs:checked").size() > [% new_reserves_allowed %] ) {
587
                    alert(MSG_MAX_HOLDS_EXCEEDED);
588
                    return false;
589
                }
590
            [% END %]
591
596
592
            if ($(".confirmjs:checked").size() == 0) {
597
            if ($("input[name='biblionumbers']:checked").size() == 0) {
593
                alert(MSG_NO_RECORD_SELECTED);
598
                alert(MSG_NO_RECORD_SELECTED);
594
                return false;
599
                return false;
595
            }
600
            }
596
601
597
            // Find the items with the 'Hold' box checked
602
            // Find the items with the 'Hold' box checked
598
            var badBib = null;
603
            var badBib = null;
599
            $(".confirmjs:checked").each(function() {
604
            $("input[name='biblionumbers']:checked").each(function() {
600
                var biblioNum = $(this).val();
605
                var biblioNum = $(this).val();
601
                biblionumbers += biblioNum + "/";
602
                selections += biblioNum + "/";
603
606
604
                // If the 'specific copy' radio button is checked
607
                // If the 'specific copy' radio button is checked
605
                if ($("#reqspecific_" + biblioNum + ":checked").size() > 0) {
608
                if ($("#reqspecific_" + biblioNum + ":checked").size() > 0) {
Lines 608-625 Link Here
608
                    if ($(item).size() == 0) {
611
                    if ($(item).size() == 0) {
609
                        badBib = biblioNum;
612
                        badBib = biblioNum;
610
                        return false;
613
                        return false;
611
                    } else {
612
                      selections += $(item).val();
613
                    }
614
                    }
614
                }
615
                }
615
                selections += "/";
616
617
                // Add the pickup location
618
                var branchSel = $("#branch_" + biblioNum);
619
                if (branchSel.size() > 0) {
620
                    selections += $(branchSel).val();
621
                }
622
                selections += "/";
623
                return true;
616
                return true;
624
            });
617
            });
625
618
Lines 628-636 Link Here
628
                return false;
621
                return false;
629
            }
622
            }
630
623
631
            $("#selections").val(selections);
632
            $("#biblionumbers").val(biblionumbers);
633
634
            return true;
624
            return true;
635
        });
625
        });
636
626
(-)a/koha-tmpl/opac-tmpl/bootstrap/less/opac.less (+3 lines)
Lines 2370-2375 td img { Link Here
2370
    margin: 1em 0;
2370
    margin: 1em 0;
2371
    padding: .5em;
2371
    padding: .5em;
2372
}
2372
}
2373
.hold-option select {
2374
    width: auto;
2375
}
2373
.copiesrow {
2376
.copiesrow {
2374
    clear : both;
2377
    clear : both;
2375
}
2378
}
(-)a/opac/opac-reserve.pl (-99 / +84 lines)
Lines 90-123 if ($borr->{reservefee} > 0){ Link Here
90
90
91
my $itemTypes = GetItemTypes();
91
my $itemTypes = GetItemTypes();
92
92
93
# There are two ways of calling this script, with a single biblio num
93
# Coming from opac-search biblionumbers param is a string, coming from
94
# or multiple biblio nums.
94
# opac-reserve, it's an array.
95
my $biblionumbers = $query->param('biblionumbers');
95
my @biblionumbers = ref($query->param('biblionumbers')) eq 'Array'
96
my $reserveMode = $query->param('reserve_mode');
96
    ? $query->param('biblionumbers')
97
if ($reserveMode && ($reserveMode eq 'single')) {
97
    : split(/\//, $query->param('biblionumbers'));
98
    my $bib = $query->param('single_bib');
98
99
    $biblionumbers = "$bib/";
99
unless (@biblionumbers) {
100
}
100
    push(@biblionumbers, $query->param('biblionumber'));
101
if (! $biblionumbers) {
102
    $biblionumbers = $query->param('biblionumber');
103
}
104
105
if ((! $biblionumbers) && (! $query->param('place_reserve'))) {
106
    $template->param(message=>1, no_biblionumber=>1);
107
    &get_out($query, $cookie, $template->output);
108
}
101
}
109
102
110
# Pass the numbers to the page so they can be fed back
103
# Pass the numbers to the page so they can be fed back
111
# when the hold is confirmed. TODO: Not necessary?
104
# when the hold is confirmed. TODO: Not necessary?
112
$template->param( biblionumbers => $biblionumbers );
105
$template->param( biblionumbers => @biblionumbers );
113
114
# Each biblio number is suffixed with '/', e.g. "1/2/3/"
115
my @biblionumbers = split /\//, $biblionumbers;
116
if (($#biblionumbers < 0) && (! $query->param('place_reserve'))) {
117
    # TODO: New message?
118
    $template->param(message=>1, no_biblionumber=>1);
119
    &get_out($query, $cookie, $template->output);
120
}
121
106
122
107
123
# pass the pickup branch along....
108
# pass the pickup branch along....
Lines 189-227 if ( $query->param('place_reserve') ) { Link Here
189
        $reserve_cnt = GetReservesFromBorrowernumber( $borrowernumber );
174
        $reserve_cnt = GetReservesFromBorrowernumber( $borrowernumber );
190
    }
175
    }
191
176
192
    # List is composed of alternating biblio/item/branch
193
    my $selectedItems = $query->param('selecteditems');
194
195
    if ($query->param('reserve_mode') eq 'single') {
196
        # This indicates non-JavaScript mode, so there was
197
        # only a single biblio number selected.
198
        my $bib = $query->param('single_bib');
199
        my $item = $query->param("checkitem_$bib");
200
        if ($item eq 'any') {
201
            $item = '';
202
        }
203
        my $branch = $query->param('branch');
204
        $selectedItems = "$bib/$item/$branch/";
205
    }
206
207
    $selectedItems =~ s!/$!!;
208
    my @selectedItems = split /\//, $selectedItems, -1;
209
210
    # Make sure there is a biblionum/itemnum/branch triplet for each item.
211
    # The itemnum can be 'any', meaning next available.
212
    my $selectionCount = @selectedItems;
213
    if (($selectionCount == 0) || (($selectionCount % 3) != 0)) {
214
        $template->param(message=>1, bad_data=>1);
215
        &get_out($query, $cookie, $template->output);
216
    }
217
218
    my $failed_holds = 0;
177
    my $failed_holds = 0;
219
    while (@selectedItems) {
178
    foreach my $biblioNum (@biblionumbers) {
220
        my $biblioNum = shift(@selectedItems);
179
        my $itemNum = $query->param("checkitem_$biblioNum");
221
        my $itemNum   = shift(@selectedItems);
180
        my @itemnumbers = $query->param("checkitem_$biblioNum");
222
        my $branch    = shift(@selectedItems);    # i.e., branch code, not name
181
        my $branch = $query->param("branch_$biblioNum");
223
182
        my $reqtype = $query->param("reqtype_$biblioNum");
224
        my $canreserve = 0;
183
        my $holds_to_place_count = $query->param("holds_to_place_count_$biblioNum") || 1;
184
        my $notes = $query->param('notes_'.$biblioNum) || '';
185
        my $nbRequested = $reqtype eq 'Specific' ? @itemnumbers : $holds_to_place_count;
186
187
        my $canreserve = 1;
188
        if (   $maxreserves
189
            && $reserve_cnt + $nbRequested >= $maxreserves )
190
        {
191
            $canreserve = 0;
192
        }
225
193
226
        my $singleBranchMode = Koha::Libraries->search->count == 1;
194
        my $singleBranchMode = Koha::Libraries->search->count == 1;
227
        if ( $singleBranchMode || !$OPACChooseBranch )
195
        if ( $singleBranchMode || !$OPACChooseBranch )
Lines 229-242 if ( $query->param('place_reserve') ) { Link Here
229
            $branch = $borr->{'branchcode'};
197
            $branch = $borr->{'branchcode'};
230
        }
198
        }
231
199
232
#item may belong to a host biblio, if yes change biblioNum to hosts bilbionumber
233
        if ( $itemNum ne '' ) {
234
            my $hostbiblioNum = GetBiblionumberFromItemnumber($itemNum);
235
            if ( $hostbiblioNum ne $biblioNum ) {
236
                $biblioNum = $hostbiblioNum;
237
            }
238
        }
239
240
        my $biblioData = $biblioDataHash{$biblioNum};
200
        my $biblioData = $biblioDataHash{$biblioNum};
241
        my $found;
201
        my $found;
242
202
Lines 250-294 if ( $query->param('place_reserve') ) { Link Here
250
210
251
        my $expiration_date = $query->param("expiration_date_$biblioNum");
211
        my $expiration_date = $query->param("expiration_date_$biblioNum");
252
212
253
      # If a specific item was selected and the pickup branch is the same as the
213
        # If a specific item was selected and the pickup branch is the same as the
254
      # holdingbranch, force the value $rank and $found.
214
        # holdingbranch, force the value $rank and $found.
255
        my $rank = $biblioData->{rank};
215
        my $rank = $biblioData->{rank};
256
        if ( $itemNum ne '' ) {
216
        if ( $reqtype eq 'Specific') {
257
            $canreserve = 1 if CanItemBeReserved( $borrowernumber, $itemNum ) eq 'OK';
217
            foreach my $itemnumber (@itemnumbers) {
258
            $rank = '0' unless C4::Context->preference('ReservesNeedReturns');
218
                my $biblionumber = $biblioNum;
259
            my $item = GetItem($itemNum);
219
260
            if ( $item->{'holdingbranch'} eq $branch ) {
220
                #item may belong to a host biblio, if yes change biblioNum to hosts bilbionumber
261
                $found = 'W'
221
                my $hostbiblioNum = GetBiblionumberFromItemnumber($itemnumber);
262
                  unless C4::Context->preference('ReservesNeedReturns');
222
                if ( $hostbiblioNum ne $biblioNum ) {
223
                    $biblionumber = $hostbiblioNum;
224
                }
225
226
                $canreserve = 0 unless CanItemBeReserved( $borrowernumber, $itemnumber ) eq 'OK';
227
                $rank = '0' unless C4::Context->preference('ReservesNeedReturns');
228
                my $item = GetItem($itemnumber);
229
                if ( $item->{'holdingbranch'} eq $branch ) {
230
                    $found = 'W'
231
                      unless C4::Context->preference('ReservesNeedReturns');
232
                }
233
234
                if ($canreserve) {
235
                    my $reserve_id = AddReserve(
236
                        $branch,         $borrowernumber,
237
                        $biblionumber,
238
                        [$biblionumber], $rank,
239
                        $startdate,      $expiration_date,
240
                        $notes,          $biblioData->{title},
241
                        $itemnumber,     $found
242
                    );
243
                    $failed_holds++ unless $reserve_id;
244
                    ++$reserve_cnt;
245
                }
263
            }
246
            }
247
            print $query->redirect("/cgi-bin/koha/opac-user.pl?" . ( $failed_holds ? "failed_holds=$failed_holds" : q|| ) . "#opac-user-holds");
248
            exit;
264
        }
249
        }
265
        else {
250
        $canreserve = 0 unless CanBookBeReserved( $borrowernumber, $biblioNum ) eq 'OK';
266
            $canreserve = 1 if CanBookBeReserved( $borrowernumber, $biblioNum ) eq 'OK';
267
268
            # Inserts a null into the 'itemnumber' field of 'reserves' table.
269
            $itemNum = undef;
270
        }
271
        my $notes = $query->param('notes_'.$biblioNum)||'';
272
273
        if (   $maxreserves
274
            && $reserve_cnt >= $maxreserves )
275
        {
276
            $canreserve = 0;
277
        }
278
251
279
        my $itemtype = $query->param('itemtype') || undef;
252
        my $itemtype = $query->param('itemtype') || undef;
280
        $itemtype = undef if $itemNum;
253
        $itemtype = undef if $itemNum;
281
254
282
        # Here we actually do the reserveration. Stage 3.
255
        # Here we actually do the reserveration. Stage 3.
283
        if ($canreserve) {
256
        if ($canreserve) {
284
            my $reserve_id = AddReserve(
257
            for ( my $i = 0 ; $i < $holds_to_place_count ; $i++ ) {
285
                $branch,          $borrowernumber, $biblioNum,
258
                my $reserve_id = AddReserve(
286
                [$biblioNum],     $rank,           $startdate,
259
                    $branch,          $borrowernumber, $biblioNum,
287
                $expiration_date, $notes,          $biblioData->{title},
260
                    [$biblioNum],     $rank,           $startdate,
288
                $itemNum,         $found,          $itemtype,
261
                    $expiration_date, $notes,          $biblioData->{title},
289
            );
262
                    $itemNum,         $found,          $itemtype,
290
            $failed_holds++ unless $reserve_id;
263
                );
291
            ++$reserve_cnt;
264
                $failed_holds++ unless $reserve_id;
265
                ++$reserve_cnt;
266
            }
292
        }
267
        }
293
    }
268
    }
294
269
Lines 347-352 if ( $maxreserves && ( $reserves_count >= $maxreserves ) ) { Link Here
347
}
322
}
348
323
349
unless ( $noreserves ) {
324
unless ( $noreserves ) {
325
    $template->param(
326
        maxreserves => $maxreserves,
327
        reserves_count => $reserves_count
328
    );
350
    my $requested_reserves_count = scalar( @biblionumbers );
329
    my $requested_reserves_count = scalar( @biblionumbers );
351
    if ( $maxreserves && ( $reserves_count + $requested_reserves_count > $maxreserves ) ) {
330
    if ( $maxreserves && ( $reserves_count + $requested_reserves_count > $maxreserves ) ) {
352
        $template->param( new_reserves_allowed => $maxreserves - $reserves_count );
331
        $template->param( new_reserves_allowed => $maxreserves - $reserves_count );
Lines 514-520 foreach my $biblioNum (@biblionumbers) { Link Here
514
            if ( my $hold_allowed = OPACItemHoldsAllowed( $itemInfo, $borr ) ) {
493
            if ( my $hold_allowed = OPACItemHoldsAllowed( $itemInfo, $borr ) ) {
515
                $itemLoopIter->{available} = 1;
494
                $itemLoopIter->{available} = 1;
516
                $numCopiesOPACAvailable++;
495
                $numCopiesOPACAvailable++;
517
                $biblioLoopIter{force_hold} = 1 if $hold_allowed eq 'F';
496
                $biblioLoopIter{force_hold} = 'item' if $hold_allowed eq 'F';
518
            }
497
            }
519
            $numCopiesAvailable++;
498
            $numCopiesAvailable++;
520
        }
499
        }
Lines 552-569 foreach my $biblioNum (@biblionumbers) { Link Here
552
    # patron placed a record level hold, all the holds the patron places must
531
    # patron placed a record level hold, all the holds the patron places must
553
    # be record level. If the patron placed an item level hold, all holds
532
    # be record level. If the patron placed an item level hold, all holds
554
    # the patron places must be item level
533
    # the patron places must be item level
555
    my $forced_hold_level = Koha::Holds->search(
534
    my $holds = Koha::Holds->search(
556
        {
535
        {
557
            borrowernumber => $borrowernumber,
536
            borrowernumber => $borrowernumber,
558
            biblionumber   => $biblioNum,
537
            biblionumber   => $biblioNum,
559
            found          => undef,
538
            found          => undef,
560
        }
539
        }
561
    )->forced_hold_level();
540
    );
541
    my $forced_hold_level = $holds->forced_hold_level();
562
    if ($forced_hold_level) {
542
    if ($forced_hold_level) {
563
        $biblioLoopIter{force_hold}   = 1 if $forced_hold_level eq 'item';
543
        #$biblioLoopIter{force_hold}   = 1 if $forced_hold_level eq 'item';
564
        $biblioLoopIter{itemholdable} = 0 if $forced_hold_level eq 'record';
544
        #$biblioLoopIter{itemholdable} = 0 if $forced_hold_level eq 'record';
545
        $biblioLoopIter{force_hold} = $forced_hold_level;
565
    }
546
    }
566
547
548
    my $max_holds_for_record = GetMaxPatronHoldsForRecord( $borrowernumber, $biblioNum );
549
    my $remaining_holds_for_record = $max_holds_for_record - $holds->count();
550
    $biblioLoopIter{remaining_holds_for_record} = $remaining_holds_for_record;
551
567
552
568
    push @$biblioLoop, \%biblioLoopIter;
553
    push @$biblioLoop, \%biblioLoopIter;
569
554
(-)a/reserve/placerequest.pl (-21 / +14 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 57-62 my $multi_hold = $input->param('multi_hold'); Link Here
57
my $biblionumbers = $multi_hold ? $input->param('biblionumbers') : ($biblionumber . '/');
57
my $biblionumbers = $multi_hold ? $input->param('biblionumbers') : ($biblionumber . '/');
58
my $bad_bibs = $input->param('bad_bibs');
58
my $bad_bibs = $input->param('bad_bibs');
59
my $holds_to_place_count = $input->param('holds_to_place_count') || 1;
59
my $holds_to_place_count = $input->param('holds_to_place_count') || 1;
60
$holds_to_place_count = scalar(@checkitems) if scalar(@checkitems);
60
61
61
my %bibinfos = ();
62
my %bibinfos = ();
62
my @biblionumbers = split '/', $biblionumbers;
63
my @biblionumbers = split '/', $biblionumbers;
Lines 67-83 foreach my $bibnum (@biblionumbers) { Link Here
67
    $bibinfos{$bibnum} = \%bibinfo;
68
    $bibinfos{$bibnum} = \%bibinfo;
68
}
69
}
69
70
70
my $found;
71
my @found;
71
72
72
# if we have an item selectionned, and the pickup branch is the same as the holdingbranch
73
foreach my $checkitem (@checkitems) {
73
# of the document, we force the value $rank and $found .
74
    # if we have an item selectionned, and the pickup branch is the same as the holdingbranch
74
if (defined $checkitem && $checkitem ne ''){
75
    # of the document, we force the value $rank and $found .
75
    $holds_to_place_count = 1;
76
    $rank[0] = '0' unless C4::Context->preference('ReservesNeedReturns');
76
    $rank[0] = '0' unless C4::Context->preference('ReservesNeedReturns');
77
    my $item = $checkitem;
77
    my $item = GetItem($checkitem);
78
    $item = GetItem($item);
79
    if ( $item->{'holdingbranch'} eq $branch ){
78
    if ( $item->{'holdingbranch'} eq $branch ){
80
        $found = 'W' unless C4::Context->preference('ReservesNeedReturns');
79
        push @found, 'W' unless C4::Context->preference('ReservesNeedReturns');
81
    }
80
    }
82
}
81
}
83
82
Lines 97-119 if ( $type eq 'str8' && $borrower ) { Link Here
97
            }
96
            }
98
        }
97
        }
99
98
100
        if ( defined $checkitem && $checkitem ne '' ) {
101
            my $item = GetItem($checkitem);
102
            if ( $item->{'biblionumber'} ne $biblionumber ) {
103
                $biblionumber = $item->{'biblionumber'};
104
            }
105
        }
106
107
        if ($multi_hold) {
99
        if ($multi_hold) {
108
            my $bibinfo = $bibinfos{$biblionumber};
100
            my $bibinfo = $bibinfos{$biblionumber};
109
            AddReserve($branch,$borrower->{'borrowernumber'},$biblionumber,[$biblionumber],
101
            AddReserve( $branch, $borrower->{'borrowernumber'},
110
                       $bibinfo->{rank},$startdate,$expirationdate,$notes,$bibinfo->{title},$checkitem,$found);
102
                        $biblionumber, [$biblionumber],
103
                        $bibinfo->{rank}, $startdate, $expirationdate, $notes,$bibinfo->{title});
111
        } else {
104
        } else {
112
            # place a request on 1st available
105
            # place a request on 1st available
113
            for ( my $i = 0 ; $i < $holds_to_place_count ; $i++ ) {
106
            for ( my $i = 0 ; $i < $holds_to_place_count ; $i++ ) {
107
                my $item = GetItem($checkitems[$i]);
114
                AddReserve( $branch, $borrower->{'borrowernumber'},
108
                AddReserve( $branch, $borrower->{'borrowernumber'},
115
                    $biblionumber, \@realbi, $rank[0], $startdate, $expirationdate, $notes, $title,
109
                    $item->{biblionumber}, \@realbi, $rank[0], $startdate, $expirationdate, $notes, $title,
116
                    $checkitem, $found, $itemtype );
110
                    $checkitems[$i], $found[$i] );
117
            }
111
            }
118
        }
112
        }
119
    }
113
    }
120
- 

Return to bug 15565