Bug 23678: Allow cancel holds in bulk
[koha.git] / koha-tmpl / intranet-tmpl / prog / en / modules / circ / waitingreserves.tt
1 [% USE raw %]
2 [% USE Asset %]
3 [% USE Koha %]
4 [% USE KohaDates %]
5 [% USE Branches %]
6 [% USE TablesSettings %]
7 [% USE AuthorisedValues %]
8 [% SET footerjs = 1 %]
9 [% INCLUDE 'doc-head-open.inc' %]
10 <title>Holds awaiting pickup &rsaquo; Circulation &rsaquo; Koha</title>
11 [% INCLUDE 'doc-head-close.inc' %]
12 </head>
13
14 <body id="circ_waitingreserves" class="circ">
15 [% INCLUDE 'header.inc' %]
16 [% INCLUDE 'circ-search.inc' %]
17
18 <nav id="breadcrumbs" aria-label="Breadcrumb" class="breadcrumb">
19     <ol>
20         <li>
21             <a href="/cgi-bin/koha/mainpage.pl">Home</a>
22         </li>
23         <li>
24             <a href="/cgi-bin/koha/circ/circulation-home.pl">Circulation</a>
25         </li>
26         <li>
27             <a href="#" aria-current="page">Holds awaiting pickup</a>
28         </li>
29     </ol>
30 </nav>
31
32 <div class="main container-fluid">
33     <div class="row">
34         <div class="col-sm-12">
35             <main>
36                 <div class="row">
37
38                 [% IF Koha.Preference('CircSidebar') %]
39                     <div class="col-sm-10 col-sm-push-2">
40                 [% ELSE %]
41                     <div class="col-sm-12">
42                 [% END %]
43
44         <h2>Holds awaiting pickup for your library on: [% show_date | $KohaDates %]
45             [% IF ( all_branches_link ) %]
46             <span style="margin-left:20px"><a href="[% all_branches_link | url %]">
47             View all libraries</a></span>
48             [% END %]
49         </h2>
50     [% IF ( cancel_result ) %]
51         [% FOREACH cancel_result %]
52             [% IF ( messagetransfert ) %]
53                 <div class="dialog message">
54                     <h2>This item is on hold for pick-up at [% Branches.GetName( branchname ) | html %]</h2>
55                     <p><strong>[% nextreservtitle | html %]</strong> is on hold for <strong> [% nextreservsurname | html %], [% nextreservfirstname | html %]</strong>.
56                     Please retain this item and check it in to process the hold.
57                     </p>
58                     <form name="cancelReservewithtransfert" action="waitingreserves.pl#[% tab | html %]" method="post">
59                         <button type="submit" class="approve"><i class="fa fa-fw fa-check"></i> OK</button>
60                     </form>
61                 </div>
62             [% END %]
63             [% IF ( waiting ) %]
64                 <div class="dialog message">
65                     <h2>This item is on hold for pick-up at your library</h2>
66                     <p><strong>[% nextreservtitle | html %]</strong> is on hold for <strong>[% nextreservsurname | html %], [% nextreservfirstname | html %]</strong>.
67                     Please retain this item and check it in to process the hold.
68                     </p>
69                     <form name="cancelReservewithwaiting" action="waitingreserves.pl#[% tab | html %]" method="post">
70                         <button type="submit" class="approve"><i class="fa fa-fw fa-check"></i> OK</button>
71                     </form>
72                 </div>
73             [% END %]
74         [% END %]
75     [% ELSE %]
76         [% IF enqueued %]
77             <div class="dialog message">
78                 <p>The job has been enqueued! It will be processed as soon as possible.</p>
79                 <p><a href="/cgi-bin/koha/admin/background_jobs.pl?op=view&id=[% job_id | uri %]" title="View detail of the enqueued job">View detail of the enqueued job</a></p>
80             </div>
81         [% END %]
82         <div id="resultlist" class="toptabs">
83             <ul>
84                 <li><a href="#holdswaiting">Holds waiting: [% reservecount | html %]</a></li>
85                 <li>
86                     <a href="#holdsover">
87                         Holds waiting over [% Koha.Preference('ReservesMaxPickUpDelay') | html %] days: [% overcount | html %]
88                     </a>
89                 </li>
90             </ul>
91             <div id="holdswaiting">
92         [% IF ( reserveloop ) %]
93             <div id="toolbar" class="btn-toolbar">
94                 <button class="cancel_selected_holds" data-bulk="true"></button>
95             </div>
96             [% INCLUDE waiting_holds.inc select_column='1' table_name='holdst' reserveloop=reserveloop tab='holdwaiting' %]
97         [% ELSE %]
98             <div class="dialog message">No holds found.</div>
99         [% END %]
100         </div>
101         <div id="holdsover">
102             [% IF ( ReservesMaxPickUpDelay ) %]<p>Holds listed here have been awaiting pickup for more than [% ReservesMaxPickUpDelay | html %] days.</p>[% END %]
103             [% IF ( overloop ) %]
104                 <span id="holdsover-cancel-all">
105                    <button class="cancel_selected_holds" data-bulk="true"></button>
106                    <form name="cancelAllReserve" action="waitingreserves.pl" method="post">
107                        <input type="hidden" name="cancelall" value="1" />
108                        <input type="hidden" name="allbranches" value="[% allbranches | html %]" />
109                        <input type="hidden" name="tab" value="holdsover">
110                        [% IF TransferWhenCancelAllWaitingHolds %]
111                            <input type="submit" value="Cancel and Transfer all" />
112                        [% ELSE %]
113                            <input type="submit" value="Cancel all" />
114                        [% END %]
115                    </form>
116                    [% UNLESS TransferWhenCancelAllWaitingHolds %]
117                         Only items that need not be transferred will be cancelled (TransferWhenCancelAllWaitingHolds syspref)
118                    [% END %]
119
120                 </span>
121                [% INCLUDE waiting_holds.inc select_column='1' table_name='holdso' reserveloop=overloop tab='holdsover' %]
122             [% ELSE %]
123                 <div class="dialog message">No holds found.</div>
124             [% END %]
125         </div>
126         </div>
127     [% END %]
128
129                     [% IF Koha.Preference('CircSidebar') %]
130                             </div> <!-- /.col-sm-10.col-sm-push-2 -->
131                             <div class="col-sm-2 col-sm-pull-10">
132                                 <aside>
133                                     [% INCLUDE 'circ-nav.inc' %]
134                                 </aside>
135                             </div> <!-- /.col-sm-2.col-sm-pull-10 -->
136                         </div> <!-- /.row -->
137                     [% END %]
138
139             </main>
140         </div> <!-- /.col-sm-12 -->
141     </div> <!-- /.row -->
142
143     <div id="cancelModal" class="modal" tabindex="-1" role="dialog" aria-hidden="true">
144         <div class="modal-dialog" role="document">
145             <div class="modal-content">
146                 <div class="modal-header">
147                     <button type="button" class="closebtn" data-dismiss="modal" aria-hidden="true">×</button>
148                     <h3>Confirm deletion</h3>
149                 </div>
150
151                 <div class="modal-body">
152                     <p>Are you sure you want to cancel this hold?</p>
153
154                     <fieldset class="action">
155                         [% SET hold_cancellation = AuthorisedValues.GetAuthValueDropbox('HOLD_CANCELLATION') %]
156                         [% IF hold_cancellation %]
157                             <label for="cancellation-reason">Cancellation reason: </label>
158                             <select class="cancellation-reason" name="modal-cancellation-reason" id="modal-cancellation-reason">
159                                 <option value="">No reason given</option>
160                                 [% FOREACH reason IN hold_cancellation %]
161                                     <option value="[% reason.authorised_value | html %]">[% reason.lib | html %]</option>
162                                 [% END %]
163                             </select>
164                         [% END %]
165                     </fieldset>
166                 </div>
167
168                 <div class="modal-footer">
169                     <button id="cancelModalConfirmBtn" type="button" class="btn btn-danger">Confirm cancellation</button>
170                     <a href="#" data-dismiss="modal">Cancel</a>
171                 </div>
172             </div>
173         </div>
174     </div>
175
176 [% MACRO jsinclude BLOCK %]
177     [% INCLUDE 'datatables.inc' %]
178     [% INCLUDE 'columns_settings.inc' %]
179     <script>
180         var MSG_CANCEL_SELECTED = _("Cancel selected (%s)");
181         var holdst_columns_settings = [% TablesSettings.GetColumns( 'circ', 'holds_awaiting_pickup', 'holdst', 'json' ) | $raw %];
182         var holdso_columns_settings = [% TablesSettings.GetColumns( 'circ', 'holds_awaiting_pickup', 'holdso', 'json' ) | $raw %];
183
184         $(document).ready(function() {
185
186             KohaTable("holdst", {
187                 "sPaginationType": "full",
188                 "order": [[1, 'asc']]
189             }, holdst_columns_settings);
190
191             KohaTable("holdso", {
192                 "sPaginationType": "full",
193                 "order": [[1, 'asc']]
194             }, holdso_columns_settings);
195
196             $('#resultlist').tabs();
197
198             let cancel_link;
199
200             $("#cancelModalConfirmBtn").on("click",function(e) {
201                 var ids = cancel_link.data('ids');
202                 localStorage.selectedWaitingHolds = JSON.stringify(JSON.parse(localStorage.selectedWaitingHolds).filter(id => !ids.includes(id)));
203                 let link = `waitingreserves.pl?cancelBulk=1&amp;ids=${ids.join(',')}`;
204                 let reason = $("#modal-cancellation-reason").val();
205                 if ( reason ) {
206                     link += "&amp;cancellation-reason=" + reason
207                 }
208                 window.location.href = link;
209                 return false;
210             });
211
212             if(!localStorage.selectedWaitingHolds || document.referrer.replace(/\?.*/, '') !== document.location.origin+document.location.pathname) {
213                 localStorage.selectedWaitingHolds = '[]';
214             }
215
216             try {
217                 JSON.parse(localStorage.selectedWaitingHolds);
218             } catch(e) {
219                 localStorage.selectedWaitingHolds = '[]';
220             }
221
222             $('.holds_table .select_hold').each(function() {
223                 if(JSON.parse(localStorage.selectedWaitingHolds).includes($(this).data('id'))) {
224                     $(this).prop('checked', true);
225                 }
226             });
227
228             $('.holds_table').each(function() {
229               var table = $(this);
230               var parent = table.parents('.ui-tabs-panel');
231
232               $('.holds_table .select_hold_all', parent).each(function() {
233                   var count = $('.select_hold:not(:checked)', table).length;
234                   $('.select_hold_all', table).prop('checked', !count);
235               });
236
237               $('.cancel_selected_holds', parent).html(MSG_CANCEL_SELECTED.format($('.holds_table .select_hold:checked', parent).length));
238
239               $('.holds_table .select_hold_all', parent).click(function() {
240                   var count = $('.select_hold:checked', table).length;
241                   $('.select_hold', table).prop('checked', !count);
242                   $(this).prop('checked', !count);
243                   $('.cancel_selected_holds', parent).data('ids', $('.holds_table .select_hold:checked', parent).toArray().map(el => $(el).data('id'))).html(MSG_CANCEL_SELECTED.format($('.holds_table .select_hold:checked', parent).length));
244                   localStorage.selectedWaitingHolds = JSON.stringify($('.holds_table .select_hold:checked').toArray().map(el => $(el).data('id')));
245               });
246
247               $('.holds_table .select_hold', parent).click(function() {
248                   var count = $('.select_hold:not(:checked)', table).length;
249                   $('.select_hold_all', table).prop('checked', !count);
250                   $('.cancel_selected_holds', parent).data('ids', $('.holds_table .select_hold:checked', parent).toArray().map(el => $(el).data('id'))).html(MSG_CANCEL_SELECTED.format($('.holds_table .select_hold:checked', parent).length));
251                   localStorage.selectedWaitingHolds = JSON.stringify($('.holds_table .select_hold:checked').toArray().map(el => $(el).data('id')));
252               });
253
254               $('.cancel_selected_holds', parent).click(function(e) {
255                   e.preventDefault();
256                   if($('.select_hold:checked', table).length) {
257                       cancel_link = $(this);
258                       $('#cancelModal').modal();
259                   }
260                   return false;
261               });
262             });
263
264
265         });
266     </script>
267 [% END %]
268
269 [% INCLUDE 'intranet-bottom.inc' %]