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

(-)a/C4/Reserves.pm (+71 lines)
Lines 2211-2216 sub GetReservesControlBranch { Link Here
2211
    return $branchcode;
2211
    return $branchcode;
2212
}
2212
}
2213
2213
2214
=head2 GetMandatoryNoteReason
2215
2216
  my $reason= GetMandatoryNoteReason( $biblionumber, $marcrecord )
2217
2218
  Returns an integer representing the reason for a mandatory holds note.
2219
  Returns zero if the note is not mandatory or OPACHoldNotes is disabled.
2220
2221
  The reasons are listed in the opac-reserve template.
2222
2223
=cut
2224
2225
sub GetMandatoryNoteReason {
2226
    my ($biblionumber, $marcrecord) = @_;
2227
2228
    my $mandatoryReasons= C4::Context->preference('OPACMandatoryHoldNotes');
2229
    my $shownotes= C4::Context->preference('OPACHoldNotes');
2230
    return 0 if !$mandatoryReasons || !$shownotes;
2231
2232
    my ($res,$first);
2233
    my @subexpr= split ',',$mandatoryReasons;
2234
    #contains a list of numbered reasons in the form of 1,3&4,2,5&4,6
2235
    #meaning check 1, or 3 and 4, or 2, or 5 and 4, or 6 ..
2236
    #for a combined check 3&4, the firstmentioned reason (3) is returned
2237
    foreach my $expr (@subexpr) {
2238
        my @checks= split '&', $expr;
2239
        $first=0;
2240
        foreach my $check (@checks) {
2241
            next if $check!~/(\d+)/;
2242
            $first=$1 if !$first;
2243
            $res= _CheckReason($biblionumber, $marcrecord, $1);
2244
            last if !$res;
2245
        }
2246
        return $first if $res;
2247
    }
2248
    return 0; #nothing found to justify a mandatory note
2249
}
2250
2251
sub _CheckReason {
2252
#Returns false if the condition is not met or an error occurred
2253
    my ($biblionumber, $marcrecord, $check)= @_;
2254
2255
    if($check==1) { #MARC21: 300a contains ref to multiple parts/volumes
2256
        if(my $f=$marcrecord->field('300') ) {
2257
            if($f->subfield('a') && $f->subfield('a')=~ /(\d+)\s*(v\.|vol|dl|delen|bd|tle|parts|pts|t\.|tome)/i) {
2258
            #FIXME: Actually a cataloging language dependent test
2259
                return 1 if $1>1;
2260
            }
2261
        }
2262
    }
2263
    elsif($check==2) { #Number of items==1
2264
        my $sql="select count(*) from items where biblionumber=?";
2265
        my $dbh= C4::Context->dbh;
2266
        my @c=$dbh->selectrow_array($sql,undef,($biblionumber));
2267
        return 1 if @c && $c[0]==1;
2268
        #if @c does not have rows, something went very wrong: return false
2269
    }
2270
    elsif($check==3) { #Added for UNIMARC testing: Title contains test
2271
        if(my $f=$marcrecord->field('200') ) {
2272
            if($f->subfield('a')) {
2273
                return 1 if $f->subfield('a')=~/test/i;
2274
            }
2275
        }
2276
    }
2277
    elsif($check==4) { #MARC21: Leader pos 07 equals c (collection)
2278
        if(my $ldr=$marcrecord->leader) {
2279
            return 1 if substr($ldr,7,1) eq 'c';
2280
        }
2281
    }
2282
    return 0;
2283
}
2284
2214
=head1 AUTHOR
2285
=head1 AUTHOR
2215
2286
2216
Koha Development Team <http://koha-community.org/>
2287
Koha Development Team <http://koha-community.org/>
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/mandatory-hold-notes.tt (+18 lines)
Line 0 Link Here
1
The following reasons can be used:
2
3
1) MARC21 300$a contains a term indicating multiple volumes or parts (like v. or vol or pts).
4
2) The biblio record only has one item. This reason is only meant for use in combination with another reason like number 1.
5
3) UNIMARC 200$a contains the word 'test'. Added for test purposes.
6
4) MARC21 leader position 7 contains c for collection.
7
8
How do you specify the reasons you want to use?
9
Just add them in your preferred order between commas in preference OPACMandatoryHoldNotes.
10
When you want to include an additional subcondition like number 2, use an expression like 1&2 indicating that you check for 1 AND 2.
11
So, as an example, you could write 4,1&2,3 meaning check reason 4 first, then check on 1 and 2, and finally check 3.
12
13
For developers: How do you add a mandatory hold notes reason?
14
1) Pick the next free number from opac-reserves.tt: add an entry to the ForceHoldNotesReasons array.
15
2) Add your new reason to this documentation file: koha-tmpl/intranet-tmpl/prog/en/modules/admin/mandatory-hold-notes.tt.
16
3) Add the code for this reason to sub _CheckReason in Reserves.pm.
17
4) Submit a patch!
18
5) Edit pref OPACMandatoryHoldNotes and add the new number.
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref (+4 lines)
Lines 510-515 OPAC: Link Here
510
                  no: "Don't allow"
510
                  no: "Don't allow"
511
                  yes: Allow
511
                  yes: Allow
512
            - opac users to share private lists with other patrons. This feature is not active yet but will be released soon
512
            - opac users to share private lists with other patrons. This feature is not active yet but will be released soon
513
        -
514
            - You can specify which conditions make hold notes mandatory. This pref is only active when OPACHoldNotes is enabled. For more information, click <a href="/intranet-tmpl/prog/en/modules/admin/mandatory-hold-notes.tt" target="_blank">here</a>.
515
            - pref: OPACMandatoryHoldNotes
516
              type: textarea
513
517
514
    Privacy:
518
    Privacy:
515
        -
519
        -
(-)a/koha-tmpl/opac-tmpl/prog/en/modules/opac-reserve.tt (-3 / +22 lines)
Lines 5-13 Link Here
5
<script type="text/javascript">
5
<script type="text/javascript">
6
// <![CDATA[
6
// <![CDATA[
7
 var MSG_NO_COPY_SELECTED = _("Expecting a specific copy selection.");
7
 var MSG_NO_COPY_SELECTED = _("Expecting a specific copy selection.");
8
 var MSG_EMPTY_MAND_NOTE = _("Please enter mandatory hold notes.");
8
 var ForceHoldNotesReasons=new Array(
9
 var ForceHoldNotesReasons=new Array(
9
    _("This title consists of multiple volumes/parts. Please indicate which part you need. Clicking on specific copy information may be helpful."),
10
    _("This title consists of multiple volumes/parts. Please indicate which part you need. Looking at the specific copy information may be helpful."), // R 1
10
    "*** Add a new reason above this line ***" ); // NOTE: Do not renumber reasons; this will affect use of existing ones.
11
    "This title has one item.", // R 2 (meant only for combining with R 1; no translation)
12
    "UNIMARC test: Title contains 'test'.", // R 3 (unimarc testing; no translation)
13
    _("This title represents a collection. Please indicate which part you need."), // R 4 (MARC21 leader: collection)
14
    "*** Add a new reason above this line ***" ); // NOTE: Do not renumber reasons; this will affect use of existing ones. Add the _() for translation!
11
15
12
 function prefixOf (s, tok) {
16
 function prefixOf (s, tok) {
13
     var index = s.indexOf(tok);
17
     var index = s.indexOf(tok);
Lines 133-143 Link Here
133
137
134
        // Find the items with the 'Hold' box checked
138
        // Find the items with the 'Hold' box checked
135
        var badBib = null;
139
        var badBib = null;
140
        var emptyMandNote=0;
136
        $(".confirmjs:checked").each(function() {
141
        $(".confirmjs:checked").each(function() {
137
            var biblioNum = $(this).val();
142
            var biblioNum = $(this).val();
138
            biblionumbers += biblioNum + "/";
143
            biblionumbers += biblioNum + "/";
139
            selections += biblioNum + "/";
144
            selections += biblioNum + "/";
140
145
146
            // Check mandatory notes
147
            if($("#notesmandatory_"+biblioNum).val()>0) {
148
                if($.trim($("#notes_"+biblioNum).val())==='') {
149
                    emptyMandNote= biblioNum;
150
                    return false;
151
                }
152
            }
153
141
            // If the 'specific copy' radio button is checked
154
            // If the 'specific copy' radio button is checked
142
            if ($("#reqspecific_" + biblioNum + ":checked").size() > 0) {
155
            if ($("#reqspecific_" + biblioNum + ":checked").size() > 0) {
143
                // Find the selected copy
156
                // Find the selected copy
Lines 164-169 Link Here
164
            alert(MSG_NO_COPY_SELECTED);
177
            alert(MSG_NO_COPY_SELECTED);
165
            return false;
178
            return false;
166
        }
179
        }
180
        else if(emptyMandNote>0) {
181
            alert(MSG_EMPTY_MAND_NOTE);
182
            $(".notesrow").hide();
183
            $("#notesrow_"+emptyMandNote).show();
184
            return false;
185
        }
167
186
168
        $("#selections").val(selections);
187
        $("#selections").val(selections);
169
        $("#biblionumbers").val(biblionumbers);
188
        $("#biblionumbers").val(biblionumbers);
Lines 445-451 Link Here
445
                      <td colspan="[% itemtable_colspan %]">
464
                      <td colspan="[% itemtable_colspan %]">
446
                          <label for="holdnotes">Hold notes:</label>&nbsp;
465
                          <label for="holdnotes">Hold notes:</label>&nbsp;
447
                          <span id="forcenotesreason_[% bibitemloo.biblionumber %]" class="forcenotesreason"></span>
466
                          <span id="forcenotesreason_[% bibitemloo.biblionumber %]" class="forcenotesreason"></span>
448
                          <textarea name="notes_[% bibitemloo.biblionumber %]">[% bibitemloo.holdnotes %]</textarea>
467
                          <textarea id="notes_[% bibitemloo.biblionumber %]" name="notes_[% bibitemloo.biblionumber %]">[% bibitemloo.holdnotes %]</textarea>
449
                          <input type="hidden" id="notesmandatory_[% bibitemloo.biblionumber %]" value="[% bibitemloo.mandatorynotes %]"/>
468
                          <input type="hidden" id="notesmandatory_[% bibitemloo.biblionumber %]" value="[% bibitemloo.mandatorynotes %]"/>
450
                      </td>
469
                      </td>
451
                  </tr>
470
                  </tr>
(-)a/opac/opac-reserve.pl (-2 / +1 lines)
Lines 373-379 foreach my $biblioNum (@biblionumbers) { Link Here
373
    $biblioLoopIter{rank} = $biblioData->{rank};
373
    $biblioLoopIter{rank} = $biblioData->{rank};
374
    $biblioLoopIter{reservecount} = $biblioData->{reservecount};
374
    $biblioLoopIter{reservecount} = $biblioData->{reservecount};
375
    $biblioLoopIter{already_reserved} = $biblioData->{already_reserved};
375
    $biblioLoopIter{already_reserved} = $biblioData->{already_reserved};
376
    $biblioLoopIter{mandatorynotes}=0; #FIXME: For future use
376
    $biblioLoopIter{mandatorynotes}= C4::Reserves::GetMandatoryNoteReason($biblioNum, $record); #zero means that note is not mandatory
377
377
378
    if (!$itemLevelTypes && $biblioData->{itemtype}) {
378
    if (!$itemLevelTypes && $biblioData->{itemtype}) {
379
        $biblioLoopIter{description} = $itemTypes->{$biblioData->{itemtype}}{description};
379
        $biblioLoopIter{description} = $itemTypes->{$biblioData->{itemtype}}{description};
380
- 

Return to bug 9743