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

(-)a/Koha/Recall.pm (+26 lines)
Lines 123-128 sub is_requested { Link Here
123
    return $status && $status eq 'R';
123
    return $status && $status eq 'R';
124
}
124
}
125
125
126
=head3 is_overdue
127
128
Returns true if recall is overdue
129
130
=cut
131
132
sub is_overdue {
133
    my ($self) = @_;
134
135
    my $status = $self->status;
136
    return $status && $status eq 'O';
137
}
138
139
=head3 is_cancelled
140
141
Returns true if recall is cancelled
142
143
=cut
144
145
sub is_cancelled {
146
    my ($self) = @_;
147
148
    my $status = $self->status;
149
    return $status && $status eq 'C';
150
}
151
126
=head1 AUTHOR
152
=head1 AUTHOR
127
153
128
Aleisha Amohia <aleisha@catalyst.net.nz>
154
Aleisha Amohia <aleisha@catalyst.net.nz>
(-)a/circ/circulation.pl (-1 / +6 lines)
Lines 55-60 use Koha::Patron::Messages; Link Here
55
use Koha::SearchEngine;
55
use Koha::SearchEngine;
56
use Koha::SearchEngine::Search;
56
use Koha::SearchEngine::Search;
57
use Koha::Patron::Modifications;
57
use Koha::Patron::Modifications;
58
use Koha::Recalls;
58
59
59
use Date::Calc qw(
60
use Date::Calc qw(
60
  Today
61
  Today
Lines 458-470 if (@$barcodes) { Link Here
458
459
459
##################################################################################
460
##################################################################################
460
# BUILD HTML
461
# BUILD HTML
461
# show all reserves of this borrower, and the position of the reservation ....
462
# show all recalls and reserves of this borrower, and the position of the reservation ....
462
if ($patron) {
463
if ($patron) {
463
    my $holds = Koha::Holds->search( { borrowernumber => $borrowernumber } ); # FIXME must be Koha::Patron->holds
464
    my $holds = Koha::Holds->search( { borrowernumber => $borrowernumber } ); # FIXME must be Koha::Patron->holds
464
    my $waiting_holds = $holds->waiting;
465
    my $waiting_holds = $holds->waiting;
466
467
    my $recalls = Koha::Recalls->search({ borrowernumber => $borrowernumber });
468
465
    $template->param(
469
    $template->param(
466
        holds_count  => $holds->count(),
470
        holds_count  => $holds->count(),
467
        WaitingHolds => $waiting_holds,
471
        WaitingHolds => $waiting_holds,
472
        recalls => $recalls
468
    );
473
    );
469
}
474
}
470
475
(-)a/koha-tmpl/intranet-tmpl/prog/en/includes/recalls.inc (+76 lines)
Line 0 Link Here
1
<div id="recalls">
2
[% IF recalls.count %]
3
    <table id="recalls-table" class="table table-bordered table-striped">
4
        <thead>
5
            <tr>
6
                <th class="recall-title anti-the">Title</th>
7
                <th class="recall-date psort title-string">Placed on</th>
8
                <th class="recall-expiry title-string">Expires on</th>
9
                <th class="recall-branch">Pickup location</th>
10
                <th class="recall-status">Status</th>
11
                <th class="recall-cancel">Cancel</th>
12
            </tr>
13
        </thead>
14
15
        <tbody>
16
            [% FOREACH recall IN recalls %]
17
                <tr>
18
                    <td class="recall-title">
19
                        <a class="recall-title" href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=[% recall.biblionumber %]">
20
                            [% recall.biblio.title %]
21
                            [% FOREACH s IN recall.biblio.subtitles %]
22
                                [% s %]
23
                            [% END %]
24
                            [% recall.item.enumchron %]
25
                        </a>
26
                        [% recall.biblio.author %]
27
                    </td>
28
29
                    <td class="recall-date">
30
                        [% recall.recalldate | $KohaDates %]
31
                    </td>
32
33
                    <td class="recall-expiry">
34
                        [% IF ( recall.is_waiting ) %]
35
                            [% IF ( recall.expirationdate ) %]
36
                                [% recall.expirationdate | $KohaDates %]
37
                            [% ELSE %]
38
                                Never expires
39
                            [% END %]
40
                        [% ELSIF ( recall.has_expired && recall.expirationdate ) %]
41
                            [% recall.expirationdate | $KohaDates %]
42
                        [% ELSE %]
43
                            -
44
                        [% END %]
45
                    </td>
46
47
                    <td class="recall-branch">
48
                        [% recall.branch.branchname %]
49
                    </td>
50
51
                    <td class="recall-status">
52
                        [% IF ( recall.is_requested ) %]
53
                            Requested
54
                        [% ELSIF ( recall.is_waiting ) %]
55
                            Ready for pickup
56
                        [% ELSIF ( recall.has_expired ) %]
57
                            Expired
58
                        [% END %]
59
                    </td>
60
61
                    <td class="recall-cancel">
62
                        [% IF ( !recall.cancellationdate ) %]
63
                            <a class="btn btn-sm btn-danger" id="cancel_recall" data-id="[% recall.recall_id %]"><i class="fa fa-times"></i> Cancel</a>
64
                        [% ELSE %]
65
                            Cancelled
66
                        [% END %]
67
                    </td>
68
69
                </tr>
70
            [% END %]
71
        </tbody>
72
    </table>
73
    [% ELSE %]
74
        Patron has no current recalls.
75
    [% END %]
76
</div>
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt (+9 lines)
Lines 818-823 No patron matched <span class="ex">[% message | html %]</span> Link Here
818
        [% END %]
818
        [% END %]
819
    </li>
819
    </li>
820
820
821
    [% IF recalls.count %]
822
        <li><a href="#recalls" id+"recalls-tab">[% recalls.count %] Recall(s)</a></li>
823
    [% END %]
824
821
    [% IF Koha.Preference('ArticleRequests') %]
825
    [% IF Koha.Preference('ArticleRequests') %]
822
        <li>
826
        <li>
823
            <a href="#article-requests" id="article-requests-tab"> [% patron.article_requests_current.count %] Article requests</a>
827
            <a href="#article-requests" id="article-requests-tab"> [% patron.article_requests_current.count %] Article requests</a>
Lines 928-933 No patron matched <span class="ex">[% message | html %]</span> Link Here
928
[% END %]
932
[% END %]
929
</div> <!-- reservesloop -->
933
</div> <!-- reservesloop -->
930
934
935
[% IF recalls.count %]
936
    [% INCLUDE 'recalls.inc' %]
937
[% END %]
938
931
[% IF Koha.Preference('ArticleRequests') %]
939
[% IF Koha.Preference('ArticleRequests') %]
932
    [% INCLUDE 'patron-article-requests.inc' %]
940
    [% INCLUDE 'patron-article-requests.inc' %]
933
[% END %]
941
[% END %]
Lines 984-989 No patron matched <span class="ex">[% message | html %]</span> Link Here
984
    <script type="text/javascript" src="[% interface %]/[% theme %]/js/checkouts_[% KOHA_VERSION %].js"></script>
992
    <script type="text/javascript" src="[% interface %]/[% theme %]/js/checkouts_[% KOHA_VERSION %].js"></script>
985
    <script type="text/javascript" src="[% interface %]/[% theme %]/js/holds_[% KOHA_VERSION %].js"></script>
993
    <script type="text/javascript" src="[% interface %]/[% theme %]/js/holds_[% KOHA_VERSION %].js"></script>
986
    <script type="text/javascript" src="[% interface %]/[% theme %]/js/circ-patron-search-results_[% KOHA_VERSION %].js"></script>
994
    <script type="text/javascript" src="[% interface %]/[% theme %]/js/circ-patron-search-results_[% KOHA_VERSION %].js"></script>
995
    <script type="text/javascript" src="[% interface %]/[% theme %]/js/recalls_[% KOHA_VERSION %].js"></script>
987
    <script type="text/javascript">
996
    <script type="text/javascript">
988
        /* Set some variable needed in circulation.js */
997
        /* Set some variable needed in circulation.js */
989
        var MSG_DT_LOADING_RECORDS = _("Loading... you may continue scanning.");
998
        var MSG_DT_LOADING_RECORDS = _("Loading... you may continue scanning.");
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember.tt (+7 lines)
Lines 415-420 Link Here
415
                <a href="#reserves" id="holds-tab">0 Holds</a>
415
                <a href="#reserves" id="holds-tab">0 Holds</a>
416
            [% END %]
416
            [% END %]
417
        </li>
417
        </li>
418
        [% IF recalls.count %]
419
            <li><a href="#recalls" id+"recalls-tab">[% recalls.count %] Recall(s)</a></li>
420
        [% END %]
418
        [% IF Koha.Preference('ArticleRequests') %]
421
        [% IF Koha.Preference('ArticleRequests') %]
419
            <li>
422
            <li>
420
                <a href="#article-requests" id="article-requests-tab"> [% patron.article_requests_current.count %] Article requests</a>
423
                <a href="#article-requests" id="article-requests-tab"> [% patron.article_requests_current.count %] Article requests</a>
Lines 527-532 Link Here
527
    [% ELSE %]<p>Patron has nothing on hold.</p>[% END %]
530
    [% ELSE %]<p>Patron has nothing on hold.</p>[% END %]
528
	</div>
531
	</div>
529
532
533
[% IF recalls %]
534
    [% INCLUDE 'recalls.inc' %]
535
[% END %]
530
536
531
[% IF Koha.Preference('ArticleRequests') %]
537
[% IF Koha.Preference('ArticleRequests') %]
532
    [% INCLUDE 'patron-article-requests.inc' %]
538
    [% INCLUDE 'patron-article-requests.inc' %]
Lines 555-560 Link Here
555
    <script type="text/javascript" src="[% interface %]/[% theme %]/js/holds_[% KOHA_VERSION %].js"></script>
561
    <script type="text/javascript" src="[% interface %]/[% theme %]/js/holds_[% KOHA_VERSION %].js"></script>
556
    <script type="text/javascript" src="[% interface %]/[% theme %]/js/members-menu_[% KOHA_VERSION %].js"></script>
562
    <script type="text/javascript" src="[% interface %]/[% theme %]/js/members-menu_[% KOHA_VERSION %].js"></script>
557
    <script type="text/javascript" src="[% interface %]/[% theme %]/js/messaging-preference-form_[% KOHA_VERSION %].js"></script>
563
    <script type="text/javascript" src="[% interface %]/[% theme %]/js/messaging-preference-form_[% KOHA_VERSION %].js"></script>
564
    <script type="text/javascript" src="[% interface %]/[% theme %]/js/recalls_[% KOHA_VERSION %].js"></script>
558
    <script type="text/javascript">
565
    <script type="text/javascript">
559
        /* Set some variable needed in circulation.js */
566
        /* Set some variable needed in circulation.js */
560
        var interface = "[% interface %]";
567
        var interface = "[% interface %]";
(-)a/koha-tmpl/intranet-tmpl/prog/js/recalls.js (+29 lines)
Line 0 Link Here
1
$(document).ready(function() {
2
3
        $("#cancel_recall").click(function(e){
4
            if (confirmDelete(_("Are you sure you want to remove this recall?"))){
5
                var $self = $(this);
6
                var $recall_id = $(this).data('id');
7
                var ajaxData = {
8
                    'recall_id': $recall_id,
9
                };
10
11
                $.ajax({
12
                    url: '/cgi-bin/koha/svc/recall',
13
                    type: 'POST',
14
                    dataType: 'json',
15
                    data: ajaxData,
16
                })
17
                .done(function(data) {
18
                    var message = "";
19
                    if(data.success == 0) {
20
                        message = "The recall may have already been cancelled. Please refresh the page.";
21
                    } else {
22
                        message = "Cancelled"
23
                    }
24
                    $self.parent().html(message);
25
                });
26
            }
27
        });
28
29
});
(-)a/members/moremember.pl (-2 / +6 lines)
Lines 55-60 use Koha::AuthorisedValues; Link Here
55
use Koha::CsvProfiles;
55
use Koha::CsvProfiles;
56
use Koha::Patron::Debarments qw(GetDebarments);
56
use Koha::Patron::Debarments qw(GetDebarments);
57
use Koha::Patron::Messages;
57
use Koha::Patron::Messages;
58
use Koha::Recalls;
58
use Module::Load;
59
use Module::Load;
59
if ( C4::Context->preference('NorwegianPatronDBEnable') && C4::Context->preference('NorwegianPatronDBEnable') == 1 ) {
60
if ( C4::Context->preference('NorwegianPatronDBEnable') && C4::Context->preference('NorwegianPatronDBEnable') == 1 ) {
60
    load Koha::NorwegianPatronDB, qw( NLGetSyncDataFromBorrowernumber );
61
    load Koha::NorwegianPatronDB, qw( NLGetSyncDataFromBorrowernumber );
Lines 242-252 if ( $data->{dateofbirth} ) { Link Here
242
243
243
### ###############################################################################
244
### ###############################################################################
244
# BUILD HTML
245
# BUILD HTML
245
# show all reserves of this borrower, and the position of the reservation ....
246
# show all recalls and reserves of this borrower, and the position of the reservation ....
246
if ($borrowernumber) {
247
if ($borrowernumber) {
248
    my $recalls = Koha::Recalls->search({ borrowernumber => $borrowernumber });
247
    $template->param(
249
    $template->param(
248
        holds_count => Koha::Database->new()->schema()->resultset('Reserve')
250
        holds_count => Koha::Database->new()->schema()->resultset('Reserve')
249
          ->count( { borrowernumber => $borrowernumber } ) );
251
          ->count( { borrowernumber => $borrowernumber } ),
252
        recalls => $recalls
253
    );
250
}
254
}
251
255
252
# current alert subscriptions
256
# current alert subscriptions
(-)a/opac/opac-recall.pl (-2 / +3 lines)
Lines 53-60 if ($op eq 'request'){ Link Here
53
    # can't place recall if not logged in
53
    # can't place recall if not logged in
54
        $error = 'notloggedin';
54
        $error = 'notloggedin';
55
        print $query->redirect('/cgi-bin/koha/opac-detail.pl?biblionumber='.$item->biblionumber);
55
        print $query->redirect('/cgi-bin/koha/opac-detail.pl?biblionumber='.$item->biblionumber);
56
    } elsif (defined $recalled && $recalled->borrowernumber == $borrowernumber){
56
    } elsif ( defined $recalled && $recalled->borrowernumber == $borrowernumber && ($recalled->is_requested || $recalled->is_waiting || $recalled->is_overdue) ){
57
    # can't place a recall on an item that this borrower has already recalled
57
    # can't place a recall on an item that this borrower has already recalled
58
    # if recall is expired or cancelled, user may recall again
58
        $error = 'duplicate';
59
        $error = 'duplicate';
59
    } else {
60
    } else {
60
    # can recall
61
    # can recall
Lines 87-93 if ($op eq 'request'){ Link Here
87
    }
88
    }
88
} elsif ($op eq 'cancel'){
89
} elsif ($op eq 'cancel'){
89
    my $recall_id = $query->param('recall_id');
90
    my $recall_id = $query->param('recall_id');
90
    Koha::Recalls->find($recall_id)->delete;
91
    Koha::Recalls->find($recall_id)->update({ cancellationdate => dt_from_string(), status => 'C' });
91
    print $query->redirect('/cgi-bin/koha/opac-user.pl');
92
    print $query->redirect('/cgi-bin/koha/opac-user.pl');
92
}
93
}
93
94
(-)a/svc/recall (-1 / +51 lines)
Line 0 Link Here
0
- 
1
#!/usr/bin/perl
2
3
# Copyright 2017 Aleisha Amohia <aleisha@catalyst.net.nz>
4
#
5
# This file is part of Koha.
6
#
7
# Koha is free software; you can redistribute it and/or modify it under the
8
# terms of the GNU General Public License as published by the Free Software
9
# Foundation; either version 3 of the License, or (at your option) any later
10
# version.
11
#
12
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
13
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
14
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
15
#
16
# You should have received a copy of the GNU General Public License along
17
# with Koha; if not, write to the Free Software Foundation, Inc.,
18
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
20
use Modern::Perl;
21
22
use CGI;
23
use JSON qw(encode_json);
24
25
use C4::Context;
26
use C4::Auth qw(check_cookie_auth);
27
use C4::Output qw(output_with_http_headers);
28
use Koha::Recalls;
29
use Koha::DateUtils;
30
31
my $input = new CGI;
32
33
my ( $auth_status, $sessionID ) =
34
  check_cookie_auth( $input->cookie('CGISESSID'), { circulate => 'circulate_remaining_permissions' } );
35
36
if ( $auth_status ne "ok" ) {
37
    print $input->header(-type => 'text/plain', -status => '403 Forbidden');
38
    exit 0;
39
}
40
41
my $recall_id = $input->param('recall_id');
42
my $recall = Koha::Recalls->find($recall_id);
43
unless ($recall) {
44
    my $json = encode_json( { success => 0 } );
45
    output_with_http_headers( $input, undef, $json, "json" );
46
    exit;
47
}
48
49
$recall->update({ cancellationdate => dt_from_string(), status => 'C' });
50
my $json = encode_json( { success => 1 } );
51
output_with_http_headers( $input, undef, $json, "json" );

Return to bug 19532