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

(-)a/C4/Reserves.pm (+5 lines)
Lines 342-347 sub CanBookBeReserved{ Link Here
342
         { status => libraryNotPickupLocation },   if given branchcode is not configured to be a pickup location
342
         { status => libraryNotPickupLocation },   if given branchcode is not configured to be a pickup location
343
         { status => cannotBeTransferred }, if branch transfer limit applies on given item and branchcode
343
         { status => cannotBeTransferred }, if branch transfer limit applies on given item and branchcode
344
         { status => pickupNotInHoldGroup }, pickup location is not in hold group, and pickup locations are only allowed from hold groups.
344
         { status => pickupNotInHoldGroup }, pickup location is not in hold group, and pickup locations are only allowed from hold groups.
345
         { status => recall }, if the borrower has already placed a recall on this item
345
346
346
=cut
347
=cut
347
348
Lines 375-380 sub CanItemBeReserved { Link Here
375
    return { status =>'itemAlreadyOnHold' }
376
    return { status =>'itemAlreadyOnHold' }
376
      if Koha::Holds->search( { borrowernumber => $borrowernumber, itemnumber => $itemnumber } )->count();
377
      if Koha::Holds->search( { borrowernumber => $borrowernumber, itemnumber => $itemnumber } )->count();
377
378
379
    # check if a recall exists on this item from this borrower
380
    return { status => 'recall' }
381
      if Koha::Recalls->search({ borrowernumber => $borrowernumber, itemnumber => $itemnumber, old => undef })->count;
382
378
    my $controlbranch = C4::Context->preference('ReservesControlBranch');
383
    my $controlbranch = C4::Context->preference('ReservesControlBranch');
379
384
380
    my $querycount = q{
385
    my $querycount = q{
(-)a/koha-tmpl/opac-tmpl/bootstrap/en/includes/item-status.inc (+1 lines)
Lines 38-43 Link Here
38
            <span class="item-status checkedout">Checked out</span>
38
            <span class="item-status checkedout">Checked out</span>
39
        [% END %]
39
        [% END %]
40
    [% END %]
40
    [% END %]
41
    [% IF item.avail_for_recall %]<a href="/cgi-bin/koha/opac-recall.pl?itemnumber=[% item.itemnumber %]" class="btn btn-default btn-xs">Recall</a>[% END %]
41
[% END %]
42
[% END %]
42
43
43
[% IF NOT ( item.isa('Koha::Item') ) AND item.transfertwhen %] [%# transfertwhen is set in C4::Search, do not have it for course reserves %]
44
[% IF NOT ( item.isa('Koha::Item') ) AND item.transfertwhen %] [%# transfertwhen is set in C4::Search, do not have it for course reserves %]
(-)a/koha-tmpl/opac-tmpl/bootstrap/en/includes/opac-detail-sidebar.inc (+5 lines)
Lines 11-16 Link Here
11
        [% END %]
11
        [% END %]
12
    [% END %]
12
    [% END %]
13
13
14
    [% IF Koha.Preference('UseRecalls') %]
15
        <li><a class="recall btn btn-link btn-lg" href="/cgi-bin/koha/opac-recall.pl?biblionumber=[% biblio.biblionumber | html %]"><i class="fa fa-fw fa-bookmark-o"></i>
16
        Place recall</a></li>
17
    [% END %]
18
14
    <li><a class="print-large btn btn-link btn-lg" href="#"><i class="fa fa-fw fa-print" aria-hidden="true"></i> Print</a></li>
19
    <li><a class="print-large btn btn-link btn-lg" href="#"><i class="fa fa-fw fa-print" aria-hidden="true"></i> Print</a></li>
15
20
16
    [% IF Koha.Preference( 'opacuserlogin' ) == 1 %]
21
    [% IF Koha.Preference( 'opacuserlogin' ) == 1 %]
(-)a/koha-tmpl/opac-tmpl/bootstrap/en/includes/usermenu.inc (+9 lines)
Lines 131-136 Link Here
131
                <a href="/cgi-bin/koha/opac-illrequests.pl">your interlibrary loan requests</a></li>
131
                <a href="/cgi-bin/koha/opac-illrequests.pl">your interlibrary loan requests</a></li>
132
            [% END %]
132
            [% END %]
133
133
134
            [% IF Koha.Preference('UseRecalls') %]
135
                [% IF ( recallsview ) %]
136
                    <li class="active">
137
                [% ELSE %]
138
                    <li>
139
                [% END %]
140
                <a href="/cgi-bin/koha/opac-recalls.pl">your recalls history</a>
141
            [% END %]
142
134
        </ul>
143
        </ul>
135
    </div>
144
    </div>
136
[% END %]
145
[% END %]
(-)a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-course-details.tt (-1 / +1 lines)
Lines 76-82 Link Here
76
                                    <td>[% AuthorisedValues.GetByCode( 'CCODE', cr.item.ccode, 1 ) | html %]</td>
76
                                    <td>[% AuthorisedValues.GetByCode( 'CCODE', cr.item.ccode, 1 ) | html %]</td>
77
                                    <td>[% cr.item.itemcallnumber | html %]</td>
77
                                    <td>[% cr.item.itemcallnumber | html %]</td>
78
                                    <td>[% cr.item.copynumber | html %]</td>
78
                                    <td>[% cr.item.copynumber | html %]</td>
79
                                    <td>[% INCLUDE 'item-status.inc' item=cr.item issue=cr.issue %]</td>
79
                                    <td>[% INCLUDE 'item-status.inc' item=cr.course_item issue=cr.issue %]</td>
80
                                    <td><span title="[% cr.issue.date_due | html %]">[% cr.issue.date_due | $KohaDates  as_due_date => 1 %]</span></td>
80
                                    <td><span title="[% cr.issue.date_due | html %]">[% cr.issue.date_due | $KohaDates  as_due_date => 1 %]</span></td>
81
                                    <td>[% IF ( cr.public_note ) %]
81
                                    <td>[% IF ( cr.public_note ) %]
82
                                            [% cr.public_note | $raw %]
82
                                            [% cr.public_note | $raw %]
(-)a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-recall.tt (+195 lines)
Line 0 Link Here
1
[% USE Koha %]
2
[% USE KohaDates %]
3
[% USE Branches %]
4
[% USE ItemTypes %]
5
[% USE AuthorisedValues %]
6
[% SET footerjs = 1 %]
7
[% INCLUDE 'doc-head-open.inc' %]
8
<title>[% IF ( LibraryNameTitle ) %][% LibraryNameTitle %][% ELSE %]Koha online[% END %] catalog &rsaquo; Recall</title>
9
[% INCLUDE 'doc-head-close.inc' %]
10
[% BLOCK cssinclude %][% END %]
11
</head>
12
<body id="opac-recall" class="scrollto">
13
[% INCLUDE 'masthead.inc' %]
14
15
<div class="main">
16
    <ul class="breadcrumb">
17
        <li><a href="/cgi-bin/koha/opac-main.pl">Home</a> <span class="divider">&rsaquo;</span></li>
18
        <li><a href="/cgi-bin/koha/opac-detail.pl?biblionumber=[% biblio.biblionumber %]">Details for: [% biblio.title %]</a> <span class="divider">&rsaquo;</span></li>
19
        <li><a href="/cgi-bin/koha/opac-recall.pl?biblionumber=[% biblio.biblionumber %]">Place recall</a></li>
20
    </ul>
21
22
    <div class="container-fluid">
23
        <div class="row-fluid">
24
            <div class="span2">
25
                <div id="navigation">
26
                    [% INCLUDE 'navigation.inc' IsPatronPage=1 %]
27
                </div>
28
            </div>
29
            <div class="span10">
30
                <div id="recall" class="maincontent">
31
                    <h1>Confirm recalls for: [% INCLUDE 'patron-title.inc' patron = logged_in_user %] ([% logged_in_user.cardnumber | html %])</h1>
32
                    [% IF nosyspref %]
33
                        Recalls have not been enabled. Please contact your library.
34
                    [% ELSIF error == 'unavailable' %]
35
                        There are no items available for recall.
36
                        <a href="/cgi-bin/koha/opac-detail.pl?biblionumber=[% biblio.biblionumber %]">Return to [% biblio.title %]</a>
37
                    [% ELSE %]
38
                        [% IF error %]
39
                            <div class="dialog alert">
40
                                [% IF error == 'notloggedin' %]
41
                                    Please log in to place a recall.
42
                                [% ELSIF error == 'duplicate' %]
43
                                    You have reached the maximum number of recalls on this record.
44
                                [% ELSIF error == 'unavailable' %]
45
                                    There are no items available for recall.
46
                                [% ELSE %]
47
                                    An error has occurred while attempting to place a recall. Please contact your library.
48
                                [% END %]
49
                            </div>
50
                        [% END %]
51
52
                        [% IF success %]
53
                            <p>Your recall has been placed. The patron the item is currently checked out to has been asked to return the item within [% due_interval %] days, by [% due_date | $KohaDates %].</p>
54
                            <p>You will be notified when your item is waiting to be picked up at the library.</p>
55
                        [% ELSIF not error %]
56
                            <p>All borrowable material is subject to recall if checked out and needed by someone else. We will ask the person who has checked out this item to return it so you may use it.</p>
57
                            [% IF loggedinusername %]
58
                                <div class="dialog">
59
60
                                    <form id="recallform" action="/cgi-bin/koha/opac-recall.pl" method="get">
61
                                        <fieldset class="rows" id="options">
62
                                            <legend>Place a recall on <b>[% biblio.title %]</b> ([% biblio.author %])?</legend>
63
                                            <ul>
64
65
                                            [% UNLESS ( single_branch_mode ) %]<li>
66
                                                <label for="pickup">Pick up location:</label>
67
                                                <select name="pickup" id="pickup">
68
                                                    [% FOREACH branch IN branches %]
69
                                                        [% IF branch.branchcode == logged_in_user.branchcode %]
70
                                                            <option value="[% branch.branchcode %]" selected>[% Branches.GetName( branch.branchcode ) | html %]</option>
71
                                                        [% ELSE %]
72
                                                            <option value="[% branch.branchcode %]">[% Branches.GetName( branch.branchcode ) | html %]</option>
73
                                                        [% END %]
74
                                                    [% END %]
75
                                                </select>
76
                                            </li>[% END %]
77
78
                                            <li><label for="expirationdate">Recall not needed after:</label> <input type="text" name="expirationdate" id="expirationdate" size="20"> <a id="cleartext" style="display:none;">Clear text</a><span id="expiration-hint">[% INCLUDE 'date-format.inc' %]</span></li>
79
                                            <li class="level-option" style="display:none;"><label for="bibliolevel">Recall next available item</label> <input type="radio" name="type" id="bibliolevel" value="bibliolevel" checked></li>
80
                                            <li class="level-option" style="display:none;"><label for="itemlevel">Recall a specific item</label> <input type="radio" name="type" id="itemlevel" value="itemlevel"></li>
81
82
                                            <table class="table table-bordered table-striped" id="items">
83
                                                <caption>Select a specific item:</caption>
84
                                                <tr>
85
                                                    <th>&nbsp;</th>
86
                                                    <th>Item type</th>
87
                                                    <th>Barcode</th>
88
                                                    [% UNLESS ( single_branch_mode ) %]
89
                                                        <th>Home library</th>
90
                                                        <th>Last location</th>
91
                                                    [% END %]
92
                                                    <th>Collection</th>
93
                                                    <th>Call number</th>
94
                                                    <th>Copy number</th>
95
                                                    <th>Vol info</th>
96
                                                    <th>Information</th>
97
                                                </tr>
98
                                                [% FOREACH item IN items %]<tr>
99
                                                <td>
100
                                                    [% IF item.can_be_recalled({ patron => logged_in_user }) %]
101
                                                        <input type="radio" class="itemnumber" name="itemnumber" value="[% item.itemnumber | html %]">
102
                                                    [% ELSE %]
103
                                                        <input disabled="disabled" type="radio" class="itemnumber" name="itemnumber" value="[% item.itemnumber | html %]" style="display:none;" />
104
                                                        <img src="[% interface | html %]/lib/famfamfam/cross.png" alt="Cannot be recalled" title="Cannot be recalled" />
105
                                                    [% END %]
106
                                                    </td>
107
                                                    <td>[% ItemTypes.GetDescription( item.get_effective_itemtype ) %]</td>
108
                                                    <td>[% item.barcode %]</td>
109
                                                    [% UNLESS ( single_branch_mode ) %]
110
                                                        <td>[% Branches.GetName( item.homebranch ) | html %]</td>
111
                                                        <td>[% Branches.GetName( item.holdingbranch) | html %]</td>
112
                                                    [% END %]
113
                                                    <td>[% AuthorisedValues.GetByCode( 'CCODE', item.ccode, 1 ) | html %]</td>
114
                                                    <td>[% item.itemcallnumber %]</td>
115
                                                    <td>[% item.copynumber %]</td>
116
                                                    <td>[% item.enumchron %]</td>
117
                                                    <td>
118
                                                        [% IF ( item.checkout ) %]
119
                                                            <span class="checkedout">Due [% item.checkout.date_due | $KohaDates %]</span>
120
                                                        [% ELSIF ( item.get_transfer ) %]
121
                                                            <span class="intransit">In transit from [% Branches.GetName( item.get_transfer.frombranch ) | html %] to [% Branches.GetName( item.get_transfer.tobranch ) | html %] since [% item.get_transfer.datesent | $KohaDates %]</span>
122
                                                        [% END %]
123
                                                        [% IF ( item.itemlost || item.withdrawn ) %]
124
                                                            <span class="lost">Unavailable (lost or missing)</span>
125
                                                        [% END %]
126
                                                        [% IF ( item.notforloan ) %]
127
                                                            <span class="notforloan">Not for loan ([% item.notforloan | html %])</span>
128
                                                        [% END %]
129
                                                        [% hold = item.current_holds.next %]
130
                                                        [% IF ( item.recall ) %]
131
                                                            <span class="waiting">
132
                                                            [% IF ( item.recall.waitingdate ) %]
133
                                                                Waiting for patron at [% Branches.GetName( item.recall.branchcode ) | html %] since [% item.recall.waitingdate | $KohaDates %].
134
                                                            [% ELSE %]
135
                                                                Recalled by patron expected at [% Branches.GetName( item.recall.branchcode ) | html %] since [% item.recall.recalldate | $KohaDates %].
136
                                                            [% END %]
137
                                                            </span>
138
                                                        [% ELSIF ( hold ) %]
139
                                                            <span class="waiting">
140
                                                                Waiting for patron at [% Branches.GetName( hold.branchcode ) | html %] since [% hold.waitingdate | $KohaDates %].
141
                                                            </span>
142
                                                        [% END # / IF ( item.recall or hold ) %]
143
                                                    </td>
144
                                                </tr>[% END %]
145
                                            </table>
146
                                        </fieldset>
147
                                        <fieldset class="action">
148
                                            <input type="hidden" name="op" value="request">
149
                                            <input type="hidden" name="biblionumber" value="[% biblio.biblionumber %]">
150
                                            <input type="submit" class="btn" value="Confirm">
151
                                            <a href="/cgi-bin/koha/opac-detail.pl?biblionumber=[% biblio.biblionumber %]" class="cancel">Cancel</a>
152
                                        </fieldset>
153
                                    </form>
154
155
                                </div>
156
                            [% ELSE %]
157
                                <div class="dialog alert">You must be logged in to place a recall.</div>
158
                            [% END %]
159
                        [% END %]
160
                    [% END %] <!-- norecalls -->
161
                </div> <!-- / #recall -->
162
            </div> <!-- / .span10 -->
163
        </div> <!-- / .row-fluid -->
164
    </div>  <!-- / .container-fluid -->
165
</div> <!-- / .main -->
166
167
[% INCLUDE 'opac-bottom.inc' %]
168
[% BLOCK jsinclude %]
169
[% INCLUDE 'calendar.inc' %]
170
<script>
171
    $(document).ready(function(){
172
        $(".level-option").show();
173
        $("#cleartext").show();
174
        $("#items").hide();
175
        $("#expiration-hint").hide();
176
        $("#cleartext").click(function(){
177
            $(this).siblings("input").val("");
178
        });
179
        $("#itemlevel").click(function(){
180
            if ( $("#itemlevel").is(':checked') ){
181
                $("#items").show();
182
                $("input:radio[name='itemnumber']:not(:disabled)").first().attr("checked", "checked"); // selects first item in table
183
            }
184
        });
185
        $("#bibliolevel").click(function(){
186
            if ( $("#bibliolevel").is(':checked') ){
187
                $("#items").hide();
188
            }
189
        });
190
        $("#expirationdate").datepicker({
191
            minDate: 0,
192
        });
193
    });
194
</script>
195
[% END %]
(-)a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-reserve.tt (+2 lines)
Lines 193-198 Link Here
193
                                    [% END %]
193
                                    [% END %]
194
                                    [% IF ( bibitemloo.already_reserved ) %]
194
                                    [% IF ( bibitemloo.already_reserved ) %]
195
                                        <div class="alert">You have already requested this title.</div>
195
                                        <div class="alert">You have already requested this title.</div>
196
                                    [% ELSIF ( bibitemloo.recall ) %]
197
                                        <div class="alert">You have already placed a recall on this title.</div>
196
                                    [% ELSE %]
198
                                    [% ELSE %]
197
                                        [% UNLESS ( bibitemloo.bib_available ) %]
199
                                        [% UNLESS ( bibitemloo.bib_available ) %]
198
                                            <div class="alert">There are no items that can be placed on hold.</div>
200
                                            <div class="alert">There are no items that can be placed on hold.</div>
(-)a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-user.tt (+82 lines)
Lines 202-207 Link Here
202
                            [% END %]
202
                            [% END %]
203
203
204
                            [% IF ( RESERVES.count ) %]<li><a href="#opac-user-holds">Holds ([% RESERVES.count | html %])</a></li>[% END %]
204
                            [% IF ( RESERVES.count ) %]<li><a href="#opac-user-holds">Holds ([% RESERVES.count | html %])</a></li>[% END %]
205
                            [% IF Koha.Preference('UseRecalls') && RECALLS.count %]<li><a href="#opac-user-recalls">Recalls ([% RECALLS.count | html %])</a></li>[% END %]
205
                            [% IF Koha.Preference('ArticleRequests') && logged_in_user.article_requests_current %]<li><a href="#opac-user-article-requests">Article requests ([% logged_in_user.article_requests_current.count | html %])</a></li>[% END %]
206
                            [% IF Koha.Preference('ArticleRequests') && logged_in_user.article_requests_current %]<li><a href="#opac-user-article-requests">Article requests ([% logged_in_user.article_requests_current.count | html %])</a></li>[% END %]
206
                            [% IF ( OverDriveCirculation ) %]
207
                            [% IF ( OverDriveCirculation ) %]
207
                            <li><a href="#opac-user-overdrive">OverDrive Account</a></li>
208
                            <li><a href="#opac-user-overdrive">OverDrive Account</a></li>
Lines 300-305 Link Here
300
                                                    [% IF ( Koha.Preference('OpacStarRatings') == 'all' ) %]
301
                                                    [% IF ( Koha.Preference('OpacStarRatings') == 'all' ) %]
301
                                                        [% INCLUDE 'user-star-ratings.inc' item=ISSUE %]
302
                                                        [% INCLUDE 'user-star-ratings.inc' item=ISSUE %]
302
                                                    [% END %]
303
                                                    [% END %]
304
305
                                                    [% IF ( ISSUE.recall ) %]<br><i>This item has been recalled. Please return by the new due date.</i>[% END %]
303
                                                </td>
306
                                                </td>
304
307
305
                                                <td class="author">[% ISSUE.author | html %]</td>
308
                                                <td class="author">[% ISSUE.author | html %]</td>
Lines 654-659 Link Here
654
657
655
                        [% PROCESS 'holds-table.inc' HOLDS = RESERVES, SuspendHoldsOpac = SuspendHoldsOpac, showpriority = showpriority, AutoResumeSuspendedHolds = AutoResumeSuspendedHolds %]
658
                        [% PROCESS 'holds-table.inc' HOLDS = RESERVES, SuspendHoldsOpac = SuspendHoldsOpac, showpriority = showpriority, AutoResumeSuspendedHolds = AutoResumeSuspendedHolds %]
656
659
660
                        [% IF Koha.Preference('UseRecalls') && RECALLS.count %]
661
                            <div id="opac-user-recalls">
662
                                <table id="recalls-table" class="table table-bordered table-striped">
663
                                    <caption>Recalls <span class="count">([% RECALLS.count %])</span></caption>
664
                                    <thead>
665
                                        <tr>
666
                                            <th class="anti-the">Title</th>
667
                                            <th class="psort title-string">Placed on</th>
668
                                            <th class="title-string">Expires on</th>
669
                                            <th>Pickup location</th>
670
                                            <th>Status</th>
671
                                            <th class="nosort">&nbsp;</th>
672
                                        </tr>
673
                                    </thead>
674
                                    <tbody>
675
                                        [% FOREACH RECALL IN RECALLS %]
676
                                        <tr>
677
                                            <td class="title">
678
                                                <a class="title" href="/cgi-bin/koha/opac-detail.pl?biblionumber=[% RECALL.biblionumber %]">
679
                                                    [% RECALL.biblio.title %]
680
                                                    [% FOREACH s IN RECALL.biblio.subtitles %]
681
                                                        [% s %]
682
                                                    [% END %]
683
                                                    [% RECALL.item.enumchron %]
684
                                                </a>
685
                                                [% RECALL.biblio.author %]
686
                                            </td>
687
                                            <td class="recalldate">
688
                                                <span title="[% RECALL.recalldate %]">
689
                                                    <span class="tdlabel">Recall date:</span>
690
                                                    [% RECALL.recalldate | $KohaDates %]
691
                                                </span>
692
                                            </td>
693
                                            <td class="expirationdate">
694
                                                [% IF ( RECALL.expirationdate ) %]
695
                                                    <span title="[% RECALL.expirationdate %]">
696
                                                        <span class="tdlabel">Expiration:</span>
697
                                                        [% RECALL.expirationdate | $KohaDates %]
698
                                                    </span>
699
                                                [% ELSE %]
700
                                                    <span title="0000-00-00">
701
                                                        <span class="tdlabel">Expiration:</span>
702
                                                        Never expires
703
                                                    </span>
704
                                                [% END %]
705
                                            </td>
706
                                            <td class="branch">
707
                                                <span class="tdlabel">Pick up location:</span>
708
                                                [% RECALL.library.branchname %]
709
                                            </td>
710
                                            <td class="status">
711
                                                <span class="tdlabel">Status:</span>
712
                                                [% IF ( RECALL.requested ) %]
713
                                                    Requested
714
                                                [% ELSIF ( RECALL.waiting ) %]
715
                                                    Ready for pickup
716
                                                [% END %]
717
                                            </td>
718
                                            <td class="cancelrecall">
719
                                                [% IF ( !RECALL.cancellationdate && ( RECALL.requested || RECALL.overdue ) ) %]
720
                                                    <form action="/cgi-bin/koha/opac-recall.pl" method="post">
721
                                                        <input type="hidden" name="op" value="cancel">
722
                                                        <input type="hidden" name="recall_id" value="[% RECALL.recall_id %]">
723
                                                        <input type="hidden" name="biblionumber" value="[% RECALL.biblionumber %]">
724
                                                        <button type="submit" name="submit" class="btn btn-sm btn-danger" id="cancel_recall"><i class="icon-remove icon-white"></i> Cancel</button>
725
                                                    </form>
726
                                                [% END %]
727
                                            </td>
728
                                        [% END %]
729
                                        </tr>
730
                                    </tbody>
731
                                </table>
732
                            </div>
733
                        [% END # / # RECALLS.count %]
734
657
                        [% IF Koha.Preference('ArticleRequests') %]
735
                        [% IF Koha.Preference('ArticleRequests') %]
658
                            <div id="opac-user-article-requests">
736
                            <div id="opac-user-article-requests">
659
                                [% IF logged_in_user.article_requests_current.count %]
737
                                [% IF logged_in_user.article_requests_current.count %]
Lines 965-970 Link Here
965
                    $('#opac-user-clubs').load('/cgi-bin/koha/clubs/clubs-tab.pl?borrowernumber=[% borrowernumber | html %]');
1043
                    $('#opac-user-clubs').load('/cgi-bin/koha/clubs/clubs-tab.pl?borrowernumber=[% borrowernumber | html %]');
966
                });
1044
                });
967
            }
1045
            }
1046
1047
            $("#cancel_recall").click(function(e){
1048
                return confirmDelete(_("Are you sure you want to undo this recall?"));
1049
            });
968
        });
1050
        });
969
        //]]>
1051
        //]]>
970
        var borrowernumber = "[% borrowernumber | html %]";
1052
        var borrowernumber = "[% borrowernumber | html %]";
(-)a/opac/opac-course-details.pl (+6 lines)
Lines 46-51 die("No course_id given") unless ($course_id); Link Here
46
my $course = GetCourse($course_id);
46
my $course = GetCourse($course_id);
47
my $course_reserves = GetCourseReserves( course_id => $course_id, include_items => 1, include_count => 1 );
47
my $course_reserves = GetCourseReserves( course_id => $course_id, include_items => 1, include_count => 1 );
48
48
49
foreach my $cr ( @$course_reserves ) {
50
    if ( $cr->{'issue'}->{date_due} and $cr->{'issue'}->{borrowernumber} and $borrowernumber != $cr->{'issue'}->{borrowernumber} and C4::Context->preference('UseRecalls') ) {
51
        $cr->{'course_item'}->{avail_for_recall} = 1;
52
    }
53
}
54
49
$template->param(
55
$template->param(
50
    course          => $course,
56
    course          => $course,
51
    course_reserves => $course_reserves,
57
    course_reserves => $course_reserves,
(-)a/opac/opac-detail.pl (-1 / +2 lines)
Lines 703-709 if ( not $viewallitems and @items > $max_items_to_display ) { Link Here
703
    }
703
    }
704
704
705
     my $reserve_status = C4::Reserves::GetReserveStatus($itm->{itemnumber});
705
     my $reserve_status = C4::Reserves::GetReserveStatus($itm->{itemnumber});
706
      if( $reserve_status eq "Waiting"){ $itm->{'waiting'} = 1; }
706
     my $recall_status = Koha::Recalls->find({ itemnumber => $itm->{itemnumber}, status => 'W', old => undef });
707
      if( $reserve_status eq "Waiting" or defined $recall_status ){ $itm->{'waiting'} = 1; }
707
      if( $reserve_status eq "Reserved"){ $itm->{'onhold'} = 1; }
708
      if( $reserve_status eq "Reserved"){ $itm->{'onhold'} = 1; }
708
    
709
    
709
     my ( $transfertwhen, $transfertfrom, $transfertto ) = GetTransfers($itm->{itemnumber});
710
     my ( $transfertwhen, $transfertfrom, $transfertto ) = GetTransfers($itm->{itemnumber});
(-)a/opac/opac-recall.pl (+190 lines)
Line 0 Link Here
1
#!/usr/bin/perl
2
3
# This file is part of Koha.
4
#
5
# Copyright 2020 Aleisha Amohia <aleisha@catalyst.net.nz>
6
#
7
# Koha is free software; you can redistribute it and/or modify it
8
# under the terms of the GNU General Public License as published by
9
# the Free Software Foundation; either version 3 of the License, or
10
# (at your option) any later version.
11
#
12
# Koha is distributed in the hope that it will be useful, but
13
# WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
# GNU General Public License for more details.
16
#
17
# You should have received a copy of the GNU General Public License
18
# along with Koha; if not, see <http://www.gnu.org/licenses>.
19
20
use Modern::Perl;
21
use CGI qw ( -utf8 );
22
use DateTime;
23
use C4::Auth;
24
use C4::Output;
25
use C4::Context;
26
use C4::Letters;
27
use C4::Stats;
28
use Koha::Items;
29
use Koha::Recall;
30
use Koha::Recalls;
31
use Koha::DateUtils;
32
use Koha::Patrons;
33
34
my $query = new CGI;
35
my ( $template, $borrowernumber, $cookie ) = get_template_and_user(
36
    {
37
        template_name   => "opac-recall.tt",
38
        query           => $query,
39
        type            => "opac",
40
        authnotrequired => 0,
41
    }
42
);
43
44
my $op = $query->param('op') || '';
45
my $biblionumber = $query->param('biblionumber');
46
47
unless ( C4::Context->preference('UseRecalls') ) {
48
    print $query->redirect("/cgi-bin/koha/opac-recall.pl?biblionumber=$biblionumber&nosyspref=1");
49
    exit;
50
}
51
52
my $biblio = Koha::Biblios->find($biblionumber);
53
my $borrower = Koha::Patrons->find($borrowernumber);
54
my $error;
55
56
unless ( $biblio->can_be_recalled({ patron => $borrower }) ) { $error = 'unavailable'; }
57
58
my $items = Koha::Items->search({ biblionumber => $biblionumber });
59
60
# check if already recalled
61
my $recalled = Koha::Recalls->search({ biblionumber => $biblionumber, borrowernumber => $borrowernumber, old => undef })->count;
62
if ( defined $recalled ) {
63
    my $recalls_per_record = Koha::CirculationRules->get_effective_rule({ categorycode => $borrower->categorycode, branchcode => undef, itemtype => undef, rule_name => 'recalls_per_record' });
64
65
    if ( defined $recalls_per_record and $recalled >= $recalls_per_record->{rule_value} ){
66
        $error = 'duplicate';
67
    }
68
}
69
70
# submitting recall request
71
if ($op eq 'request'){
72
73
    if (!defined $borrowernumber){
74
        # can't place recall if not logged in
75
        $error = 'notloggedin';
76
        print $query->redirect("/cgi-bin/koha/opac-detail.pl?biblionumber=$biblionumber");
77
78
    } elsif ( defined $error and $error eq 'unavailable' ){
79
        # no items available for recall
80
        print $query->redirect("/cgi-bin/koha/opac-recall.pl?biblionumber=$biblionumber&error=unavailable");
81
82
    } elsif ( !defined $error ){
83
        # can recall
84
85
        # check if bib-level or item-level recall
86
        my $level = $query->param('type');
87
        my $itemnumber;
88
        if ( $level eq 'itemlevel' ) { $itemnumber = $query->param('itemnumber'); }
89
90
        my $expirationdate = scalar $query->param('expirationdate');
91
        if ( $expirationdate ){
92
            my $now = dt_from_string;
93
            $expirationdate = dt_from_string($expirationdate)->set({ hour => $now->hour, minute => $now->minute, second => $now->second });
94
        }
95
96
        my $pickup = $query->param('pickup') || $borrower->branchcode;
97
98
        # attempt recall
99
        my $recall_request;
100
        if ( $item->can_be_recalled({ patron => $borrower }) ) {
101
            $recall_request = Koha::Recall->new({
102
                borrowernumber => $borrowernumber,
103
                recalldate => dt_from_string(),
104
                biblionumber => $biblio->biblionumber,
105
                branchcode => $pickup,
106
                status => 'R',
107
                itemnumber => defined $itemnumber ? $itemnumber : undef,
108
                itemtype => $item->itype,
109
                expirationdate => $expirationdate,
110
                item_level_recall => defined $itemnumber ? 1 : 0
111
            })->store;
112
        }
113
114
        if (defined $recall_request->recall_id){ # successful recall
115
            my $recall = Koha::Recalls->find($recall_request->recall_id);
116
117
            # set up vars
118
            my $timestamp = dt_from_string( $recall->timestamp );
119
            my $due_date;
120
            my $checkout_borrower;
121
122
            # get checkout and adjust due date
123
            my $checkout = $recall->checkout;
124
            my $recall_due_date_interval = Koha::CirculationRules->get_effective_rule({
125
                categorycode => $checkout->patron->categorycode,
126
                itemtype => $checkout->item->effective_itemtype,
127
                branchcode => C4::Context->userenv->{'branch'},
128
                rule_name => 'recall_due_date_interval',
129
            });
130
            unless ( defined $recall_due_date_interval ) { $recall_due_date_interval->{rule_value} = 5 };
131
            $due_date = $timestamp->add( days => $recall_due_date_interval->{rule_value} );
132
            $checkout->update({ date_due => $due_date });
133
            unless ( $recall->item_level_recall ) { $itemnumber = $checkout->itemnumber; }
134
135
            # send notice to user with recalled item checked out
136
            my $letter = C4::Letters::GetPreparedLetter (
137
                module => 'circulation',
138
                letter_code => 'RETURN_RECALLED_ITEM',
139
                branchcode => $recall->branchcode,
140
                tables => {
141
                    biblio => $biblio->biblionumber,
142
                    borrowers => $checkout->borrowernumber,
143
                    items => $itemnumber,
144
                    issues => $itemnumber,
145
                },
146
            );
147
148
            C4::Message->enqueue($letter, $checkout->patron->unblessed, 'email');
149
150
            my $item = Koha::Items->find($itemnumber);
151
            # add to statistics table
152
            UpdateStats({
153
                branch => C4::Context->userenv->{'branch'},
154
                type => 'recall',
155
                itemnumber => $itemnumber,
156
                borrowernumber => $borrowernumber,
157
                itemtype => $item->effective_itemtype,
158
                ccode => $item->ccode,
159
            });
160
161
            # add action log
162
            C4::Log::logaction( 'RECALLS', 'CREATE', $recall->recall_id, "Recall requested by borrower #" . $recall->borrowernumber, 'OPAC') if ( C4::Context->preference('RecallsLog') );
163
            $template->param(
164
                success => 1,
165
                due_interval => $recall_due_date_interval->{rule_value},
166
                due_date => $checkout->date_due,
167
            );
168
        } else {
169
            $error = 'failed';
170
        }
171
    }
172
} elsif ($op eq 'cancel'){
173
    my $recall_id = $query->param('recall_id');
174
    Koha::Recalls->find($recall_id)->set_cancelled;
175
    print $query->redirect('/cgi-bin/koha/opac-user.pl');
176
}
177
178
my $branches = Koha::Libraries->search();
179
my $single_branch_mode = $branches->count == 1;
180
181
$template->param(
182
    biblio => $biblio,
183
    error => $error,
184
    items => $items,
185
    single_branch_mode => $single_branch_mode,
186
    branches => $branches,
187
);
188
189
output_with_http_headers $query, $cookie, $template->output, 'html';
190
(-)a/opac/opac-reserve.pl (+4 lines)
Lines 623-628 foreach my $biblioNum (@biblionumbers) { Link Here
623
623
624
    $biblioLoopIter{holdable} &&= CanBookBeReserved( $borrowernumber, $biblioNum )->{status} eq 'OK';
624
    $biblioLoopIter{holdable} &&= CanBookBeReserved( $borrowernumber, $biblioNum )->{status} eq 'OK';
625
625
626
    if ( CanBookBeReserved( $borrowernumber, $biblioNum )->{status} eq 'recall' ){
627
        $biblioLoopIter{recall} = 1;
628
    }
629
626
    # For multiple holds per record, if a patron has previously placed a hold,
630
    # For multiple holds per record, if a patron has previously placed a hold,
627
    # the patron can only place more holds of the same type. That is, if the
631
    # the patron can only place more holds of the same type. That is, if the
628
    # patron placed a record level hold, all the holds the patron places must
632
    # patron placed a record level hold, all the holds the patron places must
(-)a/opac/opac-user.pl (-1 / +7 lines)
Lines 297-302 if ( $pending_checkouts->count ) { # Useless test Link Here
297
                    $issue->{biblionumber} ? $my_summary_html =~ s/{BIBLIONUMBER}/$issue->{biblionumber}/g : $my_summary_html =~ s/{BIBLIONUMBER}//g;
297
                    $issue->{biblionumber} ? $my_summary_html =~ s/{BIBLIONUMBER}/$issue->{biblionumber}/g : $my_summary_html =~ s/{BIBLIONUMBER}//g;
298
                    $issue->{MySummaryHTML} = $my_summary_html;
298
                    $issue->{MySummaryHTML} = $my_summary_html;
299
                }
299
                }
300
301
        my $recall = Koha::Recalls->find({ itemnumber => $issue->{itemnumber}, old => undef });
302
        if ( defined $recall ) {
303
            $issue->{recalled} = 1;
304
        }
300
    }
305
    }
301
}
306
}
302
my $overduesblockrenewing = C4::Context->preference('OverduesBlockRenewing');
307
my $overduesblockrenewing = C4::Context->preference('OverduesBlockRenewing');
Lines 318-327 $template->param( show_barcode => 1 ) if $show_barcode; Link Here
318
323
319
# now the reserved items....
324
# now the reserved items....
320
my $reserves = Koha::Holds->search( { borrowernumber => $borrowernumber } );
325
my $reserves = Koha::Holds->search( { borrowernumber => $borrowernumber } );
326
my $recalls = Koha::Recalls->search({ borrowernumber => $borrowernumber, old => undef });
321
327
322
$template->param(
328
$template->param(
323
    RESERVES       => $reserves,
329
    RESERVES       => $reserves,
324
    showpriority   => $show_priority,
330
    showpriority   => $show_priority,
331
    RECALLS        => $recalls,
325
);
332
);
326
333
327
if (C4::Context->preference('BakerTaylorEnabled')) {
334
if (C4::Context->preference('BakerTaylorEnabled')) {
328
- 

Return to bug 19532