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

(-)a/Koha/ArticleRequest.pm (-2 / +2 lines)
Lines 83-92 sub complete { Link Here
83
=cut
83
=cut
84
84
85
sub cancel {
85
sub cancel {
86
    my ( $self, $notes ) = @_;
86
    my ( $self, $cancellation_reason ) = @_;
87
87
88
    $self->status(Koha::ArticleRequest::Status::Canceled);
88
    $self->status(Koha::ArticleRequest::Status::Canceled);
89
    $self->notes($notes) if $notes;
89
    $self->cancellation_reason($cancellation_reason) if $cancellation_reason;
90
    $self->store();
90
    $self->store();
91
    $self->notify();
91
    $self->notify();
92
    return $self;
92
    return $self;
(-)a/Koha/Exceptions/ArticleRequests.pm (+17 lines)
Line 0 Link Here
1
package Koha::Exceptions::ArticleRequests;
2
3
use Modern::Perl;
4
5
use Exception::Class (
6
7
    'Koha::Exceptions::ArticleRequests' => {
8
        description => 'Something went wrong!',
9
    },
10
    'Koha::Exceptions::ArticleRequests::FailedCancel' => {
11
        isa => 'Koha::Exceptions::ArticleRequests',
12
        description => 'Failed to cancel article request'
13
    }
14
15
);
16
17
1;
(-)a/Koha/REST/V1/ArticleRequests.pm (+75 lines)
Line 0 Link Here
1
package Koha::REST::V1::ArticleRequests;
2
3
# This file is part of Koha.
4
#
5
# Koha is free software; you can redistribute it and/or modify it
6
# under the terms of the GNU General Public License as published by
7
# the Free Software Foundation; either version 3 of the License, or
8
# (at your option) any later version.
9
#
10
# Koha is distributed in the hope that it will be useful, but
11
# WITHOUT ANY WARRANTY; without even the implied warranty of
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
# GNU General Public License for more details.
14
#
15
# You should have received a copy of the GNU General Public License
16
# along with Koha; if not, see <http://www.gnu.org/licenses>.
17
18
use Modern::Perl;
19
20
use Mojo::Base 'Mojolicious::Controller';
21
22
use Koha::Database;
23
use Koha::ArticleRequests;
24
25
use Scalar::Util qw( blessed );
26
use Try::Tiny qw( catch try );
27
28
=head1 NAME
29
30
Koha::REST::V1::ArticleRequests
31
32
=head1 API
33
34
=head2 Methods
35
36
=head3 cancel
37
38
Controller function that handles cancelling a Koha::ArticleRequest object
39
40
=cut
41
42
sub cancel {
43
    my $c = shift->openapi->valid_input or return;
44
45
    my $ar = Koha::ArticleRequests->find( $c->validation->param('ar_id') );
46
47
    unless ( $ar ) {
48
        return $c->render(
49
            status  => 404,
50
            openapi => { error => "Article request not found" }
51
        );
52
    }
53
54
    my $reason = $c->validation->param('cancellation_reason');
55
56
    return try {
57
58
        $ar->cancel($reason);
59
        return $c->render(
60
            status  => 204,
61
            openapi => q{}
62
        );
63
    } catch {
64
        if ( blessed $_ && $_->isa('Koha::Exceptions::ArticleRequests::FailedCancel') ) {
65
            return $c->render(
66
                status  => 403,
67
                openapi => { error => "Article request cannot be canceled" }
68
            );
69
        }
70
71
        $c->unhandled_exception($_);
72
    };
73
}
74
75
1;
(-)a/Koha/REST/V1/Patrons.pm (+48 lines)
Lines 419-422 sub guarantors_can_see_checkouts { Link Here
419
    };
419
    };
420
}
420
}
421
421
422
=head3 cancel_article_request
423
424
Controller function that handles cancelling a patron's Koha::ArticleRequest object
425
426
=cut
427
428
sub cancel_article_request {
429
    my $c = shift->openapi->valid_input or return;
430
431
    my $patron = Koha::Patrons->find( $c->validation->param('patron_id') );
432
433
    unless ( $patron ) {
434
        return $c->render(
435
            status  => 404,
436
            openapi => { error => "Patron not found" }
437
        );
438
    }
439
440
    my $ar = $patron->article_requests->find( $c->validation->param('ar_id') );
441
442
    unless ( $ar ) {
443
        return $c->render(
444
            status  => 404,
445
            openapi => { error => "Article request not found" }
446
        );
447
    }
448
449
    my $reason = $c->validation->param('cancellation_reason');
450
451
    return try {
452
453
        $ar->cancel($reason);
454
        return $c->render(
455
            status  => 204,
456
            openapi => q{}
457
        );
458
    } catch {
459
        if ( blessed $_ && $_->isa('Koha::Exceptions::ArticleRequests::FailedCancel') ) {
460
            return $c->render(
461
                status  => 403,
462
                openapi => { error => "Article request cannot be canceled" }
463
            );
464
        }
465
466
        $c->unhandled_exception($_);
467
    };
468
}
469
422
1;
470
1;
(-)a/api/v1/swagger/parameters.json (+6 lines)
Lines 56-61 Link Here
56
  "cashup_id_pp": {
56
  "cashup_id_pp": {
57
    "$ref": "parameters/cashup.json#/cashup_id_pp"
57
    "$ref": "parameters/cashup.json#/cashup_id_pp"
58
  },
58
  },
59
  "ar_id_pp": {
60
    "$ref": "parameters/article_request.json#/ar_id_pp"
61
  },
62
  "ar_reason_qp": {
63
    "$ref": "parameters/article_request.json#/ar_reason_qp"
64
  },
59
  "match": {
65
  "match": {
60
    "name": "_match",
66
    "name": "_match",
61
    "in": "query",
67
    "in": "query",
(-)a/api/v1/swagger/parameters/article_request.json (+16 lines)
Line 0 Link Here
1
{
2
  "ar_id_pp": {
3
    "name": "ar_id",
4
    "in": "path",
5
    "description": "Article request identifier",
6
    "required": true,
7
    "type": "integer"
8
  },
9
  "ar_reason_qp": {
10
    "name": "cancellation_reason",
11
    "in": "query",
12
    "description": "Article request cancellation reason",
13
    "required": false,
14
    "type": "string"
15
  }
16
}
(-)a/api/v1/swagger/paths.json (-1 / +7 lines)
Lines 17-22 Link Here
17
  "/acquisitions/funds": {
17
  "/acquisitions/funds": {
18
    "$ref": "paths/acquisitions_funds.json#/~1acquisitions~1funds"
18
    "$ref": "paths/acquisitions_funds.json#/~1acquisitions~1funds"
19
  },
19
  },
20
  "/article_requests/{ar_id}": {
21
    "$ref": "paths/article_requests.json#/~1article_requests~1{ar_id}"
22
  },
20
  "/biblios/{biblio_id}": {
23
  "/biblios/{biblio_id}": {
21
    "$ref": "paths/biblios.json#/~1biblios~1{biblio_id}"
24
    "$ref": "paths/biblios.json#/~1biblios~1{biblio_id}"
22
  },
25
  },
Lines 134-140 Link Here
134
  "/patrons/{patron_id}/extended_attributes/{extended_attribute_id}": {
137
  "/patrons/{patron_id}/extended_attributes/{extended_attribute_id}": {
135
    "$ref": "paths/patrons_extended_attributes.json#/~1patrons~1{patron_id}~1extended_attributes~1{extended_attribute_id}"
138
    "$ref": "paths/patrons_extended_attributes.json#/~1patrons~1{patron_id}~1extended_attributes~1{extended_attribute_id}"
136
  },
139
  },
137
   "/patrons/{patron_id}/holds": {
140
  "/patrons/{patron_id}/holds": {
138
    "$ref": "paths/patrons_holds.json#/~1patrons~1{patron_id}~1holds"
141
    "$ref": "paths/patrons_holds.json#/~1patrons~1{patron_id}~1holds"
139
  },
142
  },
140
  "/patrons/{patron_id}/password": {
143
  "/patrons/{patron_id}/password": {
Lines 170-175 Link Here
170
  "/public/patrons/{patron_id}/guarantors/can_see_checkouts": {
173
  "/public/patrons/{patron_id}/guarantors/can_see_checkouts": {
171
    "$ref": "paths/public_patrons.json#/~1public~1patrons~1{patron_id}~1guarantors~1can_see_checkouts"
174
    "$ref": "paths/public_patrons.json#/~1public~1patrons~1{patron_id}~1guarantors~1can_see_checkouts"
172
  },
175
  },
176
  "/public/patrons/{patron_id}/article_requests/{ar_id}": {
177
    "$ref": "paths/public_patrons.json#/~1public~1patrons~1{patron_id}~1article_requests~1{ar_id}"
178
  },
173
  "/quotes": {
179
  "/quotes": {
174
    "$ref": "paths/quotes.json#/~1quotes"
180
    "$ref": "paths/quotes.json#/~1quotes"
175
  },
181
  },
(-)a/api/v1/swagger/paths/article_requests.json (+67 lines)
Line 0 Link Here
1
{
2
    "/article_requests/{ar_id}": {
3
        "delete": {
4
            "x-mojo-to": "ArticleRequests#cancel",
5
            "operationId": "cancelArticleRequest",
6
            "tags": [
7
                "article_requests"
8
            ],
9
            "summary": "Cancel article requests",
10
            "parameters": [
11
                {
12
                    "$ref": "../parameters.json#/ar_id_pp"
13
                },
14
                {
15
                    "$ref": "../parameters.json#/ar_reason_qp"
16
                }
17
            ],
18
            "produces": ["application/json"],
19
            "responses": {
20
                "204": {
21
                    "description": "Article request canceled"
22
                },
23
                "400": {
24
                    "description": "Bad request",
25
                    "schema": {
26
                        "$ref": "../definitions.json#/error"
27
                    }
28
                },
29
                "401": {
30
                    "description": "Authentication required",
31
                    "schema": {
32
                        "$ref": "../definitions.json#/error"
33
                    }
34
                },
35
                "403": {
36
                    "description": "Access forbidden",
37
                    "schema": {
38
                        "$ref": "../definitions.json#/error"
39
                    }
40
                },
41
                "404": {
42
                    "description": "Patron not found",
43
                    "schema": {
44
                        "$ref": "../definitions.json#/error"
45
                    }
46
                },
47
                "500": {
48
                    "description": "Internal server error",
49
                    "schema": {
50
                        "$ref": "../definitions.json#/error"
51
                    }
52
                },
53
                "503": {
54
                    "description": "Under maintenance",
55
                    "schema": {
56
                        "$ref": "../definitions.json#/error"
57
                    }
58
                }
59
            },
60
            "x-koha-authorization": {
61
                "permissions": {
62
                    "reserveforothers": "1"
63
                  }
64
            }
65
        }
66
    }
67
}
(-)a/api/v1/swagger/paths/public_patrons.json (+67 lines)
Lines 242-246 Link Here
242
                "allow-owner": true
242
                "allow-owner": true
243
            }
243
            }
244
        }
244
        }
245
    },
246
    "/public/patrons/{patron_id}/article_requests/{ar_id}": {
247
        "delete": {
248
            "x-mojo-to": "Patrons#cancel_article_request",
249
            "operationId": "cancelPatronArticleRequest",
250
            "tags": [
251
                "patrons",
252
                "article_requests"
253
            ],
254
            "summary": "Cancel patron's article requests",
255
            "parameters": [
256
                {
257
                    "$ref": "../parameters.json#/patron_id_pp"
258
                },
259
                {
260
                    "$ref": "../parameters.json#/ar_id_pp"
261
                },
262
                {
263
                    "$ref": "../parameters.json#/ar_reason_qp"
264
                }
265
            ],
266
            "produces": ["application/json"],
267
            "responses": {
268
                "204": {
269
                    "description": "Patron's article request canceled"
270
                },
271
                "400": {
272
                    "description": "Bad request",
273
                    "schema": {
274
                        "$ref": "../definitions.json#/error"
275
                    }
276
                },
277
                "401": {
278
                    "description": "Authentication required",
279
                    "schema": {
280
                        "$ref": "../definitions.json#/error"
281
                    }
282
                },
283
                "403": {
284
                    "description": "Access forbidden",
285
                    "schema": {
286
                        "$ref": "../definitions.json#/error"
287
                    }
288
                },
289
                "404": {
290
                    "description": "Patron not found",
291
                    "schema": {
292
                        "$ref": "../definitions.json#/error"
293
                    }
294
                },
295
                "500": {
296
                    "description": "Internal server error",
297
                    "schema": {
298
                        "$ref": "../definitions.json#/error"
299
                    }
300
                },
301
                "503": {
302
                    "description": "Under maintenance",
303
                    "schema": {
304
                        "$ref": "../definitions.json#/error"
305
                    }
306
                }
307
            },
308
            "x-koha-authorization": {
309
                "allow-owner": true
310
            }
311
        }
245
    }
312
    }
246
}
313
}
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/article-requests.tt (-23 / +65 lines)
Lines 36-42 Link Here
36
                    Complete request
36
                    Complete request
37
                </a>
37
                </a>
38
38
39
                <a class="ar-cancel-request" href="#" onclick="HandleMulti( Cancel, [% id_arg | html %], $(this) ); return false;">
39
                <a class="ar-cancel-request" href="#" onclick="Cancel( [% id_arg | html %], $(this) ); return false;">
40
                    <i class="fa fa-minus-circle"></i>
40
                    <i class="fa fa-minus-circle"></i>
41
                    Cancel request
41
                    Cancel request
42
                </a>
42
                </a>
Lines 75-80 Link Here
75
      </div>
75
      </div>
76
    </div>
76
    </div>
77
[% END %]
77
[% END %]
78
[% BLOCK cancel_modal %]
79
    <div id="cancelModal" class="modal" tabindex="-1" role="dialog" aria-hidden="true">
80
        <div class="modal-dialog" role="document">
81
            <div class="modal-content">
82
                <div class="modal-header">
83
                    <button type="button" class="closebtn" data-dismiss="modal" aria-hidden="true">×</button>
84
                    <h3>Confirm deletion</h3>
85
                </div>
86
87
                <div class="modal-body">
88
                    <p>Are you sure you want to cancel this article request?</p>
89
90
                    <fieldset class="action">
91
                        [% SET ar_cancellation = AuthorisedValues.GetAuthValueDropbox('AR_CANCELLATION') %]
92
                        [% IF ar_cancellation %]
93
                            <label for="cancellation-reason">Cancellation reason: </label>
94
                            <select class="cancellation-reason" name="modal-cancellation-reason" id="modal-cancellation-reason">
95
                                <option value="">No reason given</option>
96
                                [% FOREACH reason IN ar_cancellation %]
97
                                    <option value="[% reason.authorised_value | html %]">[% reason.lib | html %]</option>
98
                                [% END %]
99
                            </select>
100
                        [% END %]
101
                    </fieldset>
102
                </div>
103
104
                <div class="modal-footer">
105
                    <button id="cancelModalConfirmBtn" type="button" class="btn btn-danger" data-dismiss="modal">Confirm cancellation</button>
106
                    <a href="#" data-dismiss="modal">Cancel</a>
107
                </div>
108
            </div>
109
        </div>
110
    </div>
111
[% END %]
78
112
79
<body id="circ_article-requests" class="circ">
113
<body id="circ_article-requests" class="circ">
80
    [% INCLUDE 'header.inc' %]
114
    [% INCLUDE 'header.inc' %]
Lines 346-351 Link Here
346
            </div>
380
            </div>
347
        </div>
381
        </div>
348
    </div>
382
    </div>
383
    [% PROCESS cancel_modal %]
349
384
350
[% MACRO jsinclude BLOCK %]
385
[% MACRO jsinclude BLOCK %]
351
    [% INCLUDE 'datatables.inc' %]
386
    [% INCLUDE 'datatables.inc' %]
Lines 442-471 Link Here
442
            window.open(link, 'popup', 'width=600,height=400,resizable=1,toolbar=0,scrollbars=1,top');
477
            window.open(link, 'popup', 'width=600,height=400,resizable=1,toolbar=0,scrollbars=1,top');
443
        }
478
        }
444
479
480
        // Confirm cancellation of article requests
481
        let cancel_id;
482
        let cancel_a;
483
        $("#cancelModalConfirmBtn").on("click",function(e) {
484
            let reason = $("#modal-cancellation-reason").val();
485
486
            HandleMulti(function(id, a) {
487
                var table_row = a.closest('tr');
488
                table_row.find('.ar-process-request').remove();
489
                table_row.find('input[type="checkbox"]').prop('checked', false);
490
491
492
                a.closest('td').prepend('<img src="[% interface | html %]/[% theme | html %]/img/spinner-small.gif"/>').find('div.dropdown').hide();
493
494
                $.ajax({
495
                    type: "DELETE",
496
                    url: '/api/v1/article_requests/'+id+'?cancellation_reason='+reason,
497
                    success: function( data ) {
498
                        active_datatable.row( a.closest('tr') ).remove().draw();
499
                        UpdateTabCounts();
500
                        activateBatchActions( active_tab );
501
                    }
502
                });
503
            }, cancel_id, cancel_a)
504
        });
505
445
        function Cancel( id, a ) {
506
        function Cancel( id, a ) {
446
            // last_cancel_reason: undefined means 'prompt for new reason'
507
            cancel_id = id;
447
            // a null value indicates that prompt was cancelled
508
            cancel_a = a;
448
            if( last_cancel_reason === undefined ) last_cancel_reason = prompt(_("Please specify the reason for cancelling selected item(s):"));
449
            if ( last_cancel_reason === null ) {
450
                return;
451
            }
452
509
453
            a.closest('td').prepend('<img src="[% interface | html %]/[% theme | html %]/img/spinner-small.gif"/>').find('div.dropdown').hide();
510
            $('#cancelModal').modal();
454
            $.ajax({
455
                type: "POST",
456
                url: '/cgi-bin/koha/svc/article_request',
457
                data: {
458
                    action: 'cancel',
459
                    id: id,
460
                    notes: last_cancel_reason
461
                },
462
                success: function( data ) {
463
                    active_datatable.row( a.closest('tr') ).remove().draw();
464
                    UpdateTabCounts();
465
                    activateBatchActions( active_tab );
466
                },
467
                dataType: 'json'
468
            });
469
        }
511
        }
470
512
471
        function Process( id, a ) {
513
        function Process( id, a ) {
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/request-article.tt (-21 / +56 lines)
Lines 3-8 Link Here
3
[% USE KohaDates %]
3
[% USE KohaDates %]
4
[% USE Branches %]
4
[% USE Branches %]
5
[% USE ItemTypes %]
5
[% USE ItemTypes %]
6
[% USE AuthorisedValues %]
6
[% SET footerjs = 1 %]
7
[% SET footerjs = 1 %]
7
[% SET article_requests_view = 1 %]
8
[% SET article_requests_view = 1 %]
8
[% SET biblionumber = biblio.biblionumber %]
9
[% SET biblionumber = biblio.biblionumber %]
Lines 11-16 Link Here
11
[% INCLUDE 'doc-head-close.inc' %]
12
[% INCLUDE 'doc-head-close.inc' %]
12
</head>
13
</head>
13
14
15
[% BLOCK cancel_modal %]
16
    <div id="cancelModal" class="modal" tabindex="-1" role="dialog" aria-hidden="true">
17
        <div class="modal-dialog" role="document">
18
            <div class="modal-content">
19
                <div class="modal-header">
20
                    <button type="button" class="closebtn" data-dismiss="modal" aria-hidden="true">×</button>
21
                    <h3>Confirm deletion</h3>
22
                </div>
23
24
                <div class="modal-body">
25
                    <p>Are you sure you want to cancel this article request?</p>
26
27
                    <fieldset class="action">
28
                        [% SET ar_cancellation = AuthorisedValues.GetAuthValueDropbox('AR_CANCELLATION') %]
29
                        [% IF ar_cancellation %]
30
                            <label for="cancellation-reason">Cancellation reason: </label>
31
                            <select class="cancellation-reason" name="modal-cancellation-reason" id="modal-cancellation-reason">
32
                                <option value="">No reason given</option>
33
                                [% FOREACH reason IN ar_cancellation %]
34
                                    <option value="[% reason.authorised_value | html %]">[% reason.lib | html %]</option>
35
                                [% END %]
36
                            </select>
37
                        [% END %]
38
                    </fieldset>
39
                </div>
40
41
                <div class="modal-footer">
42
                    <button id="cancelModalConfirmBtn" type="button" class="btn btn-danger" data-dismiss="modal">Confirm cancellation</button>
43
                    <a href="#" data-dismiss="modal">Cancel</a>
44
                </div>
45
            </div>
46
        </div>
47
    </div>
48
[% END %]
49
14
<body id="circ_request-article" class="circ">
50
<body id="circ_request-article" class="circ">
15
    [% INCLUDE 'header.inc' %]
51
    [% INCLUDE 'header.inc' %]
16
    [% INCLUDE 'circ-search.inc' %]
52
    [% INCLUDE 'circ-search.inc' %]
Lines 310-315 Link Here
310
                                [% END %]
346
                                [% END %]
311
                            </table>
347
                            </table>
312
                        </fieldset>
348
                        </fieldset>
349
                        [% PROCESS cancel_modal %]
313
                    [% END %]
350
                    [% END %]
314
351
315
            </main>
352
            </main>
Lines 394-422 Link Here
394
                }
431
                }
395
            });
432
            });
396
433
397
            $(".ar-cancel-request").on("click", function(){
434
            let cancel_a;
398
                var a = $(this);
435
            $("#cancelModalConfirmBtn").on("click",function(e) {
399
                var notes = prompt(_("Reason for cancellation:"));
436
                var id = cancel_a.attr('id').split("cancel-")[1];
437
                $("#cancel-processing-" + id ).hide('slow');
438
                $("#cancel-processing-spinner-" + id ).show('slow');
400
439
401
                if ( notes != null ) {
440
                let reason = $("#modal-cancellation-reason").val();
402
                    var id = this.id.split("cancel-")[1];
403
                    $("#cancel-processing-" + id ).hide('slow');
404
                    $("#cancel-processing-spinner-" + id ).show('slow');
405
441
406
                    $.ajax({
442
                $.ajax({
407
                        type: "POST",
443
                    type: "DELETE",
408
                        url: '/cgi-bin/koha/svc/article_request',
444
                    url: '/api/v1/article_requests/'+id+'?cancellation_reason='+reason,
409
                        data: {
445
                    success: function( data ) {
410
                            action: 'cancel',
446
                        cancel_a.parents('tr').hide('slow');
411
                            id: id,
447
                    }
412
                            notes: notes
448
                });
413
                        },
449
            });
414
                        success: function( data ) {
450
415
                            a.parents('tr').hide('slow');
451
416
                        },
452
            $(".ar-cancel-request").on("click", function(){
417
                        dataType: 'json'
453
                cancel_a = $(this);
418
                    });
454
                $('#cancelModal').modal();
419
                }
420
            });
455
            });
421
456
422
            // Initialize format(s)
457
            // Initialize format(s)
(-)a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-user.tt (-12 / +34 lines)
Lines 5-10 Link Here
5
[% USE Branches %]
5
[% USE Branches %]
6
[% USE ItemTypes %]
6
[% USE ItemTypes %]
7
[% USE Price %]
7
[% USE Price %]
8
[% USE AuthorisedValues %]
8
[% SET AdlibrisEnabled = Koha.Preference('AdlibrisCoversEnabled') %]
9
[% SET AdlibrisEnabled = Koha.Preference('AdlibrisCoversEnabled') %]
9
[% SET AdlibrisURL = Koha.Preference('AdlibrisCoversURL') %]
10
[% SET AdlibrisURL = Koha.Preference('AdlibrisCoversURL') %]
10
11
Lines 715-721 Link Here
715
                            <div id="opac-user-article-requests">
716
                            <div id="opac-user-article-requests">
716
                                [% IF logged_in_user.article_requests_current.count %]
717
                                [% IF logged_in_user.article_requests_current.count %]
717
                                    <table id="article-requests-table" class="table table-bordered table-striped">
718
                                    <table id="article-requests-table" class="table table-bordered table-striped">
718
                                        <caption>Article requests <span class="count">([% logged_in_user.article_requests_current.count | html %] total)</span></caption>
719
                                        <caption>Article requests <span class="count"></span></caption>
719
                                        <thead>
720
                                        <thead>
720
                                            <tr>
721
                                            <tr>
721
                                                <th class="anti-the article-request-record-title">Record title</th>
722
                                                <th class="anti-the article-request-record-title">Record title</th>
Lines 801-812 Link Here
801
                                                </td>
802
                                                </td>
802
803
803
                                                <td class="article-request-cancel">
804
                                                <td class="article-request-cancel">
804
                                                    <span class="tdlabel">Cancel:</span>
805
                                                    <button data-title="[% ar.biblio.title | html %] [% ar.item.enumchron | html %]" data-article-request_id="[% ar.id | html %]" class="btn btn-sm btn-danger btn-delete-article-request"><i class="fa fa-remove" aria-hidden="true"></i> Cancel</button>
805
                                                    <form action="/cgi-bin/koha/opac-article-request-cancel.pl" id="delete_article_request_[% ar.id | html %]">
806
                                                        <legend class="sr-only">Cancel article request</legend>
807
                                                        <input type="hidden" name="id" value="[% ar.id | html %]" />
808
                                                        <button data-title="[% ar.biblio.title | html %] [% ar.item.enumchron | html %]" data-article-request_id="[% ar.id | html %]" type="submit" class="btn btn-sm btn-danger btn-delete-article-request"><i class="fa fa-remove" aria-hidden="true"></i> Cancel</button>
809
                                                    </form>
810
                                                </td>
806
                                                </td>
811
                                            </tr>
807
                                            </tr>
812
                                        [% END %]
808
                                        [% END %]
Lines 843-848 Link Here
843
    [% INCLUDE 'calendar.inc' %]
839
    [% INCLUDE 'calendar.inc' %]
844
    [% INCLUDE 'datatables.inc' %]
840
    [% INCLUDE 'datatables.inc' %]
845
    <script>
841
    <script>
842
        var AR_CAPTION_COUNT = _("(%s total)");
843
844
846
        function tableInit( tableId ){
845
        function tableInit( tableId ){
847
            if( tableId == "checkoutst" ){
846
            if( tableId == "checkoutst" ){
848
                $(".dt-buttons").append("<button type=\"button\" class=\"dt-button buttons-ical\" id=\"buttons-ics\">iCal</button> ");
847
                $(".dt-buttons").append("<button type=\"button\" class=\"dt-button buttons-ical\" id=\"buttons-ics\">iCal</button> ");
Lines 852-857 Link Here
852
            }
851
            }
853
        }
852
        }
854
        $(document).ready(function(){
853
        $(document).ready(function(){
854
            $('#opac-user-article-requests caption .count').html(AR_CAPTION_COUNT.format('[% logged_in_user.article_requests_current.count | html %]'));
855
            $('#opac-user-views').tabs();
855
            $('#opac-user-views').tabs();
856
            $(".modal-nojs").addClass("modal").addClass("hide").removeClass("modal-nojs");
856
            $(".modal-nojs").addClass("modal").addClass("hide").removeClass("modal-nojs");
857
            $(".suspend-until").prop("readonly",1);
857
            $(".suspend-until").prop("readonly",1);
Lines 861-866 Link Here
861
                var hold_title = $(this).data("title");
861
                var hold_title = $(this).data("title");
862
                var reserve_id = $(this).data("reserve_id");
862
                var reserve_id = $(this).data("reserve_id");
863
                confirmModal( hold_title, _("Are you sure you want to cancel this hold?"), _("Yes, cancel hold"), _("No, do not cancel hold"), function( result ){
863
                confirmModal( hold_title, _("Are you sure you want to cancel this hold?"), _("Yes, cancel hold"), _("No, do not cancel hold"), function( result ){
864
                        $("#bootstrap-confirm-box-modal").remove()
864
                        if( result ){
865
                        if( result ){
865
                            $("#delete_hold_" + reserve_id ).submit();
866
                            $("#delete_hold_" + reserve_id ).submit();
866
                        }
867
                        }
Lines 872-883 Link Here
872
                e.preventDefault();
873
                e.preventDefault();
873
                var article_request = $(this).data("title");
874
                var article_request = $(this).data("title");
874
                var article_request_id = $(this).data("article-request_id");
875
                var article_request_id = $(this).data("article-request_id");
875
                confirmModal( article_request, _("Are you sure you want to cancel this article request?"), _("Yes, cancel article request"), _("No, do not cancel article request"), function( result ){
876
                (function(row){
877
                    var doCancel = function( result ){
878
                        $("#bootstrap-confirm-box-modal").remove();
876
                        if( result ){
879
                        if( result ){
877
                            $("#delete_article_request_" + article_request_id ).submit();
880
                            $.ajax({
881
                                type: "DELETE",
882
                                url: '/api/v1/public/patrons/'+borrowernumber+'/article_requests/'+article_request_id,
883
                                success: function( data ) {
884
                                    row.parents('tr').hide({
885
                                        duration: 'slow',
886
                                        complete: function() {
887
                                            var ar_tab = $('a[href="#opac-user-article-requests"');
888
                                            var ar_table = $('#article-requests-table');
889
                                            var ar_length = $('tbody tr:visible', ar_table).length;
890
                                            var ar_count = $('caption .count', ar_table);
891
892
                                            ar_tab.html(ar_tab.html().replace(/\(\d+\)/, '('+ar_length+')'));
893
                                            ar_count.html(AR_CAPTION_COUNT.format(ar_length));
894
                                        }
895
                                    });
896
                                }
897
                            });
878
                        }
898
                        }
879
                    }
899
                    };
880
                );
900
                    confirmModal( article_request, _("Are you sure you want to cancel this article request?"), _("Yes, cancel article request"), _("No, do not cancel article request"), doCancel);
901
                })($(this))
881
            });
902
            });
882
903
883
            $("#suspend_all_submit").on("click", function(e){
904
            $("#suspend_all_submit").on("click", function(e){
Lines 885-890 Link Here
885
                var title = _("Are you sure you want to suspend all holds?");
906
                var title = _("Are you sure you want to suspend all holds?");
886
                var body = _("All holds will be suspended.");
907
                var body = _("All holds will be suspended.");
887
                confirmModal( body, title, _("Yes, suspend all holds"), "", function( result ){
908
                confirmModal( body, title, _("Yes, suspend all holds"), "", function( result ){
909
                        $("#bootstrap-confirm-box-modal").remove()
888
                        if( result ){
910
                        if( result ){
889
                            $("#suspend_all_holds").submit();
911
                            $("#suspend_all_holds").submit();
890
                        }
912
                        }
Lines 897-902 Link Here
897
                var title = _("Are you sure you want to resume all suspended holds?");
919
                var title = _("Are you sure you want to resume all suspended holds?");
898
                var body = _("All holds will resume.");
920
                var body = _("All holds will resume.");
899
                confirmModal( body, title, _("Yes, resume all holds"), _("No, do not resume holds"), function( result ){
921
                confirmModal( body, title, _("Yes, resume all holds"), _("No, do not resume holds"), function( result ){
922
                        $("#bootstrap-confirm-box-modal").remove()
900
                        if( result ){
923
                        if( result ){
901
                            $("#resume_all_holds").submit();
924
                            $("#resume_all_holds").submit();
902
                        }
925
                        }
903
- 

Return to bug 27947