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

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

Return to bug 15565