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

(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/batch_extend_due_dates.tt (+269 lines)
Line 0 Link Here
1
[% USE raw %]
2
[% USE Asset %]
3
[% SET footerjs = 1 %]
4
[% USE Branches %]
5
[% USE Categories %]
6
[% USE KohaDates %]
7
[% USE ItemTypes %]
8
[% PROCESS 'html_helpers.inc' %]
9
10
[% INCLUDE 'doc-head-open.inc' %]
11
<title>Koha &rsaquo; Tools &rsaquo; Batch extend due dates</title>
12
[% INCLUDE 'doc-head-close.inc' %]
13
[% Asset.css("css/humanmsg.css") | $raw %]
14
</head>
15
16
<body id="tools_batch_extend_due_dates" class="tools">
17
    [% INCLUDE 'header.inc' %]
18
    [% INCLUDE 'cat-search.inc' %]
19
20
    <div id="breadcrumbs">
21
        <a href="/cgi-bin/koha/mainpage.pl">Home</a> &rsaquo;
22
        <a href="/cgi-bin/koha/tools/tools-home.pl">Tools</a> &rsaquo;
23
        <a href="/cgi-bin/koha/tools/batch_extend_due_dates.pl">Batch extend due dates</a>
24
    </div>
25
26
    <div class="main container-fluid">
27
        <div class="row">
28
            <div class="col-sm-10 col-sm-push-2">
29
                <main>
30
31
                    <h1>Batch extend due dates</h1>
32
33
                    [% IF ( messages ) %]
34
                        <div class="dialog message">
35
36
                            [% FOREACH message IN messages %]
37
                                [% IF message.type == 'success' %]
38
                                    <div><i class="fa fa-check success"></i>
39
                                [% ELSIF message.type == 'warning' %]
40
                                    <div><i class="fa fa-warning warn"></i>
41
                                [% ELSIF message.type == 'error' %]
42
                                    <div><i class="fa fa-exclamation error"></i>
43
                                [% END %]
44
                                [% IF message.error %]
45
                                    (The error was: [% message.error | html %]. See the Koha logfile for more information).
46
                                [% END %]
47
                                </div>
48
                            [% END %]
49
50
                        </div> <!-- .dialog.message -->
51
                    [% END %]
52
53
                    [% IF view == 'form' %]
54
                        <form method="post" enctype="multipart/form-data" action="/cgi-bin/koha/tools/batch_extend_due_dates.pl" id="extend_due_dates_form">
55
                            <fieldset class="rows">
56
                                <legend>Checkout criteria:</legend>
57
                                <ol>
58
                                    <li>
59
                                        <label for="categorycodes">Patrons' categories: </label>
60
                                        [% SET categories = Categories.all() %]
61
                                        <select id="categorycodes" name="categorycodes" multiple="multiple">
62
                                            [% FOREACH cat IN categories %]
63
                                                <option value="[% cat.categorycode | html %]">[% cat.description | html %]</option>
64
                                            [% END %]
65
                                        </select>
66
                                    </li>
67
68
                                    <li>
69
                                        <label for="branchcodes">Libraries: </label>
70
                                        <select name="branchcodes" id="branchcodes" multiple="multiple">
71
                                            [% PROCESS options_for_libraries libraries => Branches.all() %]
72
                                        </select>
73
                                    </li>
74
75
                                    <li>
76
                                        <label for="from_due_date">Due date from: </label>
77
                                        <input type="text" size="10" id="from" name="from_due_date" class="datepickerfrom" />
78
                                    </li>
79
80
                                    <li>
81
                                        <label for="to_due_date">Due date to:</label>
82
                                        <input type="text" size="10" id="to" name="to_due_date" class="datepickerto" />
83
                                    </li>
84
                                </ol>
85
                            </fieldset>
86
                            <fieldset class="rows">
87
                                <legend>New due date:</legend>
88
                                <ol>
89
                                    <li>
90
                                        <label for="new_hard_due_date">Hard due date: </label>
91
                                        <input type="text" size="10" id="new_hard_due_date" name="new_hard_due_date" class="datepicker" />
92
                                    </li>
93
94
                                    <li>
95
                                        <label for="due_date_days">Or add number of days:</label>
96
                                        <input type="text" size="10" id="due_date_days" name="due_date_days"/>
97
                                    </li>
98
                                </ol>
99
                            </fieldset>
100
                            <fieldset class="action">
101
                                <input type="hidden" name="op" value="list" />
102
                                <input type="submit" value="Continue" class="button" />
103
                                <a class="cancel" href="/cgi-bin/koha/tools/tools-home.pl">Cancel</a>
104
                            </fieldset>
105
                        </form> <!-- /#extend_due_dates_form -->
106
                    [% ELSIF view == 'list' %]
107
                        [% IF checkouts.count %]
108
                            <form action="/cgi-bin/koha/tools/batch_extend_due_dates.pl" method="post" id="process">
109
                                <div id="toolbar">
110
                                    <a id="selectall" href="#"><i class="fa fa-check"></i> Select all</a>
111
                                    | <a id="clearall" href="#"><i class="fa fa-remove"></i> Clear all</a>
112
                                </div>
113
                                <table id="checkouts">
114
                                    <thead>
115
                                        <tr>
116
                                            <th>&nbsp;</th>
117
                                            <th>Due date</th>
118
                                            <th>Title</th>
119
                                            <th>Item type</th>
120
                                            <th>Home library</th>
121
                                            <th>Checked out on</th>
122
                                            <th>Checked out from</th>
123
                                            <th>New due date</th>
124
                                        </tr>
125
                                    </thead>
126
                                    <tbody>
127
                                        [% FOR checkout IN checkouts %]
128
                                            <tr>
129
                                                <td><input type="checkbox" name="issue_id" value="[% checkout.issue_id | html %]" /></td>
130
                                                <td>[% checkout.date_due | $KohaDates as_due_date => 1 %]</td>
131
                                                <td><a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=[% checkout.item.biblio.biblionumber | uri %]">[% checkout.item.biblio.title | html %]</a></td>
132
                                                <td>[% ItemTypes.GetDescription( checkout.item.effective_itemtype ) | html %]</td>
133
                                                <td>[% checkout.item.home_branch.branchname | html %]</td>
134
                                                <td>[% checkout.issuedate | $KohaDates %]</td>
135
                                                <td>[% Branches.GetName( checkout.branchcode ) | html %]</td>
136
                                                <td>
137
                                                    [% IF new_hard_due_date %]
138
                                                        [% new_hard_due_date | $KohaDates %]
139
                                                    [% ELSE %]
140
                                                        [% new_due_dates.shift | $KohaDates %]
141
                                                    [% END %]
142
                                                </td>
143
                                            </tr>
144
                                        [% END %]
145
                                    </tbody>
146
                                </table> <!-- /#checkouts -->
147
                                <div class="note"><i class="fa fa-exclamation"></i> Reminder: this action will modify all selected checkouts!</div>
148
                                <fieldset class="action">
149
                                    <input type="hidden" name="op" value="modify" />
150
                                    <input type="hidden" name="new_hard_due_date" value="[% new_hard_due_date | $KohaDates %]" />
151
                                    <input type="hidden" name="due_date_days" value="[% due_date_days | html %]" />
152
                                    <input type="submit" value="Modify selected checkouts" class="button" />
153
                                    <a class="cancel" href="/cgi-bin/koha/tools/batch_extend_due_dates.pl">Cancel</a>
154
                                </fieldset>
155
                            </form> <!-- /#process -->
156
                        [% ELSE %]
157
                            <div class="dialog message">
158
                                No checkouts for the selected filters.
159
                            </div>
160
                        [% END %]
161
                    [% ELSIF view == 'report' %]
162
                        <div class="dialog message">
163
                            Due dates have been modified!
164
                        </div>
165
166
                        <table id="checkouts_result">
167
                            <thead>
168
                                <tr>
169
                                    <th>Due date</th>
170
                                    <th>Title</th>
171
                                    <th>Item type</th>
172
                                    <th>Home library</th>
173
                                    <th>Checked out on</th>
174
                                    <th>Checked out from</th>
175
                                </tr>
176
                            </thead>
177
                            <tbody>
178
                                [% FOR checkout IN checkouts %]
179
                                    <tr>
180
                                        <td>[% checkout.date_due | $KohaDates as_due_date => 1 %]</td>
181
                                        <td><a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=[% checkout.item.biblio.biblionumber | uri %]">[% checkout.item.biblio.title | html %]</a></td>
182
                                        <td>[% ItemTypes.GetDescription( checkout.item.effective_itemtype ) | html %]</td>
183
                                        <td>[% checkout.item.home_branch.branchname | html %]</td>
184
                                        <td>[% checkout.issuedate | $KohaDates %]</td>
185
                                        <td>[% Branches.GetName( checkout.branchcode ) | html %]</td>
186
                                    </tr>
187
                                [% END %]
188
                            </tbody>
189
                        </table> <!-- /#checkouts_result -->
190
                    [% END %]
191
                </main>
192
            </div> <!-- /.col-sm-10.col-sm-push-2 -->
193
194
            <div class="col-sm-2 col-sm-pull-10">
195
                <aside>
196
                    [% INCLUDE 'tools-menu.inc' %]
197
                </aside>
198
            </div> <!-- /.col-sm-2.col-sm-pull-10 -->
199
        </div> <!-- /.row -->
200
201
[% MACRO jsinclude BLOCK %]
202
    [% Asset.js("js/tools-menu.js") | $raw %]
203
    [% INCLUDE 'calendar.inc' %]
204
    [% INCLUDE 'datatables.inc' %]
205
    [% Asset.js("lib/jquery/plugins/jquery.checkboxes.min.js") | $raw %]
206
    [% Asset.js("lib/jquery/plugins/humanmsg.js") | $raw %]
207
    <script>
208
        $(document).ready(function() {
209
210
            $("#selectall").click(function(e) {
211
                e.preventDefault();
212
                $("#checkouts").checkCheckboxes();
213
            });
214
            $("#clearall").click(function(e) {
215
                e.preventDefault();
216
                $("#checkouts").unCheckCheckboxes();
217
            });
218
            $("#selectall").click();
219
220
            $("table#checkouts").dataTable($.extend(true, {}, dataTablesDefaults, {
221
                "aoColumnDefs": [
222
                    { "aTargets": [0, 3], "bSortable": false, "bSearchable": false },
223
                    { "aTargets": [1], "sType": "num-html" }
224
                ],
225
                "sDom": 't',
226
                "aaSorting": [],
227
                "bPaginate": false
228
            }));
229
230
            $("table#checkouts_result").dataTable($.extend(true, {}, dataTablesDefaults, {
231
                "aoColumnDefs": [
232
                    { "aTargets": [0, 3], "bSortable": false, "bSearchable": false },
233
                    { "aTargets": [1], "sType": "num-html" }
234
                ],
235
                "sDom": 't',
236
                "aaSorting": [],
237
                "bPaginate": false
238
            }));
239
240
            $("#extend_due_dates_form").on('submit', function(e) {
241
                var new_hard_due_date = $("#new_hard_due_date").val();
242
                var due_date_days = $("#due_date_days").val();
243
                if (new_hard_due_date && due_date_days ) {
244
                    e.preventDefault();
245
                    alert(_("You must fill only one of the two due date options"));
246
                    return false;
247
                } else if ( !new_hard_due_date && !due_date_days ) {
248
                    e.preventDefault();
249
                    alert(_("You must fill at least one of the two due date options"));
250
                    return false;
251
                }
252
253
                return true;
254
            });
255
256
            $("#process").on('submit', function(e) {
257
                if ($("input[type=checkbox][name='issue_id']:checked").length == 0) {
258
                    e.preventDefault();
259
                    alert(_("Please select at least one checkout to process"));
260
                    return false;
261
                }
262
                return true;
263
            });
264
265
        });
266
    </script>
267
[% END %]
268
269
[% INCLUDE 'intranet-bottom.inc' %]
(-)a/tools/batch_extend_due_dates.pl (-1 / +146 lines)
Line 0 Link Here
0
- 
1
#!/usr/bin/perl
2
3
# This file is part of Koha.
4
#
5
# Copyright 2020 Koha Development Team
6
#
7
# Koha is free software; you can redistribute it and/or modify
8
# it under the terms of the GNU General Public License as
9
# published by the Free Software Foundation; either version 3
10
# of the License, or (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
18
# Public License along with Koha; if not, see
19
# <http://www.gnu.org/licenses>
20
21
use Modern::Perl;
22
23
use CGI;
24
25
use C4::Auth qw( get_template_and_user );
26
use C4::Output qw( output_html_with_http_headers );
27
use Koha::Checkouts;
28
use Koha::DateUtils qw( dt_from_string );
29
30
my $input = new CGI;
31
my $op = $input->param('op') // q|form|;
32
33
my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
34
    {
35
        template_name   => 'tools/batch_extend_due_dates.tt',
36
        query           => $input,
37
        type            => "intranet",
38
        authnotrequired => 0,
39
        flagsrequired   => { tools => 'batch_extend_due_dates' },
40
    }
41
);
42
43
if ( $op eq 'form' ) {
44
    $template->param( view => 'form', );
45
}
46
elsif ( $op eq 'list' ) {
47
48
    my @categorycodes     = $input->multi_param('categorycodes');
49
    my @branchcodes       = $input->multi_param('branchcodes');
50
    my $from_due_date     = $input->param('from_due_date');
51
    my $to_due_date       = $input->param('to_due_date');
52
    my $new_hard_due_date = $input->param('new_hard_due_date');
53
    my $due_date_days     = $input->param('due_date_days');
54
55
    my $dtf = Koha::Database->new->schema->storage->datetime_parser;
56
    my $search_params;
57
    if (@categorycodes) {
58
        $search_params->{'borrower.categorycode'} = { -in => \@categorycodes };
59
    }
60
    if (@branchcodes) {
61
        $search_params->{'me.branchcode'} = { -in => \@branchcodes };
62
    }
63
    if ( $from_due_date and $to_due_date ) {
64
        my $to_due_date_endday = dt_from_string($to_due_date);
65
        $to_due_date_endday
66
          ->set(  # We set last second of day to see all checkouts from that day
67
            hour   => 23,
68
            minute => 59,
69
            second => 59
70
          );
71
        $search_params->{'me.date_due'} = {
72
            -between => [
73
                $dtf->format_datetime( dt_from_string($from_due_date) ),
74
                $dtf->format_datetime($to_due_date_endday),
75
            ]
76
        };
77
    }
78
    elsif ($from_due_date) {
79
        $search_params->{'me.date_due'} =
80
          { '>=' => $dtf->format_datetime( dt_from_string($from_due_date) ) };
81
    }
82
    elsif ($to_due_date) {
83
        my $to_due_date_endday = dt_from_string($to_due_date);
84
        $to_due_date_endday
85
          ->set(  # We set last second of day to see all checkouts from that day
86
            hour   => 23,
87
            minute => 59,
88
            second => 59
89
          );
90
        $search_params->{'me.date_due'} =
91
          { '<=' => $dtf->format_datetime($to_due_date_endday) };
92
    }
93
94
    my $checkouts = Koha::Checkouts->search(
95
        $search_params,
96
        {
97
            join => [ 'item', 'borrower' ]
98
        }
99
    );
100
101
    my @new_due_dates;
102
    if ( not $new_hard_due_date && $due_date_days ) {
103
        while ( my $checkout = $checkouts->next ) {
104
            my $due_date = dt_from_string( $checkout->date_due );
105
            push @new_due_dates, $due_date->add( days => $due_date_days );
106
        }
107
    }
108
    $template->param(
109
        checkouts         => $checkouts,
110
        new_hard_due_date => $new_hard_due_date
111
        ? dt_from_string($new_hard_due_date)
112
        : undef,
113
        due_date_days => $due_date_days,
114
        new_due_dates => \@new_due_dates,
115
        view          => 'list',
116
    );
117
}
118
elsif ( $op eq 'modify' ) {
119
120
    # We want to modify selected checkouts!
121
    my @issue_ids         = $input->multi_param('issue_id');
122
    my $new_hard_due_date = $input->param('new_hard_due_date');
123
    my $due_date_days     = $input->param('due_date_days');
124
125
    $new_hard_due_date &&= dt_from_string($new_hard_due_date);
126
    my $checkouts =
127
      Koha::Checkouts->search( { issue_id => { -in => \@issue_ids } } );
128
    while ( my $checkout = $checkouts->next ) {
129
        if ($new_hard_due_date) {
130
            $checkout->date_due($new_hard_due_date)->store;
131
        }
132
        else {
133
            my $dt = dt_from_string( $checkout->date_due )
134
              ->add( days => $due_date_days );
135
            warn $dt;
136
            $checkout->date_due($dt)->store;
137
        }
138
    }
139
140
    $template->param(
141
        view      => 'report',
142
        checkouts => $checkouts,
143
    );
144
}
145
146
output_html_with_http_headers $input, $cookie, $template->output;

Return to bug 24846