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

(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/reports/reports-home.tmpl (+1 lines)
Lines 34-39 Link Here
34
		<li><a href="/cgi-bin/koha/reports/catalogue_stats.pl">Catalog</a></li>
34
		<li><a href="/cgi-bin/koha/reports/catalogue_stats.pl">Catalog</a></li>
35
		<li><a href="/cgi-bin/koha/reports/issues_stats.pl">Circulation</a></li>
35
		<li><a href="/cgi-bin/koha/reports/issues_stats.pl">Circulation</a></li>
36
		<li><a href="/cgi-bin/koha/reports/serials_stats.pl">Serials</a></li>
36
		<li><a href="/cgi-bin/koha/reports/serials_stats.pl">Serials</a></li>
37
		<li><a href="/cgi-bin/koha/reports/reserves_stats.pl">Reserves</a></li>
37
	</ul></div>
38
	</ul></div>
38
39
39
	<div class="yui-u"><h2>Top Lists</h2>
40
	<div class="yui-u"><h2>Top Lists</h2>
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/reports/reserves_stats.tmpl (+549 lines)
Line 0 Link Here
1
<!-- TMPL_INCLUDE NAME="doc-head-open.inc" -->
2
<title>Koha &rsaquo; Reports &rsaquo; Checkout statistics <!-- TMPL_IF NAME="do_it" -->&rsaquo; Results<!-- /TMPL_IF --></title>
3
<!-- TMPL_INCLUDE NAME="doc-head-close.inc" -->
4
<!-- TMPL_INCLUDE NAME="calendar.inc" -->
5
<style type="text/css">
6
	.sql {display:none;}
7
</style>
8
</head>
9
<body>
10
<!-- TMPL_INCLUDE NAME="header.inc" -->
11
<!-- TMPL_INCLUDE NAME="cat-search.inc" -->
12
13
<div id="breadcrumbs"><a href="/cgi-bin/koha/mainpage.pl">Home</a> &rsaquo; <a href="/cgi-bin/koha/reports/reports-home.pl">Reports</a> <!-- TMPL_IF NAME="do_it" -->&rsaquo; <a href="/cgi-bin/koha/reports/reserves_stats.pl">Reserves statistics</a> &rsaquo; Results <!-- TMPL_ELSE -->&rsaquo; Reserves statistics<!-- /TMPL_IF --></div>
14
15
<div id="doc3" class="yui-t2">
16
17
   <div id="bd">
18
	<div id="yui-main">
19
	<div class="yui-b">
20
21
<!-- TMPL_IF NAME="do_it" -->
22
    <!-- TMPL_IF NAME="mainloop" -->
23
        <h1>Reserves statistics</h1>
24
        <!-- TMPL_IF NAME="loopfilter" -->
25
            <p>Filtered on</p>
26
            <ul>
27
            <!-- TMPL_LOOP NAME="loopfilter" -->
28
                <!-- TMPL_IF NAME="err" --><li class="error">Error:
29
				<!-- TMPL_ELSIF NAME="sql" --><li class="sql">
30
				<!-- TMPL_ELSE --><li>
31
				<!--/TMPL_IF -->
32
					<!-- TMPL_VAR NAME="crit"--> <!-- TMPL_VAR NAME="filter"-->
33
				</li>
34
            <!-- /TMPL_LOOP -->
35
            </ul>
36
        <!-- /TMPL_IF -->
37
		
38
    <!-- TMPL_LOOP NAME="mainloop" -->
39
        
40
        <table> 
41
            <tr>
42
                <th><!-- TMPL_VAR name="line" --> / <!-- TMPL_VAR name="column" --></th>
43
                <!-- TMPL_LOOP NAME="loopcol" -->
44
                    <th><!-- TMPL_VAR ESCAPE="HTML" NAME="coltitle_display" --></th>
45
                <!-- /TMPL_LOOP -->
46
                <th>TOTAL</th>
47
                </tr>
48
                <!-- TMPL_LOOP NAME="looprow" -->
49
                    <tr<!-- TMPL_UNLESS NAME="__odd__" --> class="highlight"<!-- /TMPL_UNLESS -->>
50
                        <td><!-- TMPL_VAR ESCAPE="HTML" NAME="rowtitle_display" DEFAULT="UNKNOWN VALUE" --></td>
51
                    <!-- TMPL_LOOP NAME="loopcell" -->
52
						<td align="center">
53
						<!--TMPL_IF Name="url_complement"--><a href="reserves_stats.pl?output=<!--TMPL_VAR Name=output-->&amp;<!--TMPL_VAR Name="url_complement"-->"><!-- TMPL_VAR NAME="value" DEFAULT="&nbsp;" --></a><!--TMPL_ELSE--><!-- TMPL_VAR NAME="value" DEFAULT="&nbsp;" --><!--/TMPL_IF-->
54
						</td>
55
                    <!-- /TMPL_LOOP -->
56
						<td align="center"><!-- TMPL_VAR NAME="totalrow" --></td>
57
                    </tr>
58
                <!-- /TMPL_LOOP -->
59
            <tr>
60
                <th>TOTAL</th>
61
                <!-- TMPL_LOOP NAME="loopfooter" -->
62
                <th><!-- TMPL_VAR NAME="totalcol" --></th>
63
                <!-- /TMPL_LOOP -->
64
                <th><!-- TMPL_VAR NAME="total" --></th>
65
            </tr>
66
        </table>
67
    <!-- /TMPL_LOOP -->
68
    <!-- /TMPL_IF -->
69
<!-- TMPL_ELSE -->
70
71
    <form method="post" action="/cgi-bin/koha/reports/reserves_stats.pl">
72
    <fieldset class="rows">
73
	<legend>Reserve statistics</legend><table>
74
        <thead>
75
            <tr>
76
                <th>Title</th>
77
                <th>Row</th>
78
                <th>Column</th>
79
                <th>Filter</th>
80
            </tr>
81
        </thead>
82
        <tbody>
83
        	<tr >
84
                <td>Reserve status </td>
85
                <td><input type="radio" name="Line" value="reservestatus" /></td>
86
                <td><input type="radio" name="Column" value="reservestatus" checked="checked" /></td>
87
                <td>
88
				<input type="checkbox" name="filter_reservestatus_or_1" value="1">Asked</input>
89
				<input type="checkbox" name="filter_reservestatus_or_2" value="2"> Processing</input>
90
				<input type="checkbox" name="filter_reservestatus_or_3" value="3">Waiting</input>
91
				<input type="checkbox" name="filter_reservestatus_or_4" value="4">Satisfied</input>
92
				<input type="checkbox" name="filter_reservestatus_or_5" value="5">cancelled</input>
93
				</td>
94
             </tr>
95
             <tr class="highlight">
96
                <td>reserve date</td>
97
                <td><input type="radio" name="Line" value="reservedate" /></td>
98
                <td><input type="radio" name="Column" value="reservedate" /></td>
99
                <td><label for="reservedate_begin">From</label> <input type="text"  size="10" id="filter_reservedate_begin" name="filter_reservedate_begin" />
100
                    <img src="<!-- TMPL_VAR Name="themelang" -->/lib/calendar/cal.gif" alt="Show Calendar" border="0" id="openreservedateFrom" style="cursor: pointer;" />
101
                   <script type="text/javascript">
102
				   //<![CDATA[ 
103
				   function validate1(date) {
104
                        var day = date.getDate();
105
                        var month = date.getMonth() + 1;
106
                        var year = date.getFullYear();
107
                        var weekDay = date.getDay();
108
                        var dayMonth = month + '-' + day;
109
                        var dateString = year + '-' + month + '-' + day;
110
                        var dateTo = document.getElementById('filter_reservedate_end').value.split("-");
111
                        var limitDate = new Date(dateTo[0], (dateTo[1] - 1), dateTo[2]);
112
                        if (date > limitDate) {
113
                             return true;
114
                        } else {
115
                             return false;
116
                        }
117
                    }
118
                    Calendar.setup({
119
                            inputField : "filter_reservedate_begin",
120
                            ifFormat : "<!-- TMPL_VAR NAME="DHTMLcalendar_dateformat" -->",
121
                            button : "openreservedateFrom",
122
                            disableFunc : validate1,
123
                            dateStatusFunc : validate1
124
                    });
125
					//]]>
126
					</script>
127
                    <label for="filter_reservedate_end">To</label> <input size="10" id="filter_reservedate_end" name="filter_reservedate_end" value="" type="text" />
128
                    <img src="<!-- TMPL_VAR Name="themelang" -->/lib/calendar/cal.gif" alt="Show Calendar" id="openreservedateTo" style="cursor: pointer;" border="0" />
129
                    <script type="text/javascript">
130
					//<![CDATA[  
131
					function validate2(date) {
132
                         var day = date.getDate();
133
                         var month = date.getMonth() + 1;
134
                         var year = date.getFullYear();
135
                         var weekDay = date.getDay();
136
                         var dayMonth = month + '-' + day;
137
                         var dateString = year + '-' + month + '-' + day;
138
                         var dateFrom = document.getElementById('filter_reservedate_begin').value.split("-");
139
                         var limitDate = new Date(dateFrom[0], (dateFrom[1] - 1), dateFrom[2]);
140
                         if (limitDate > date) {
141
                              return true;
142
                         } else {
143
                              return false;
144
                         }
145
                     }
146
                     Calendar.setup({
147
                             inputField : "filter_reservedate_end",
148
                             ifFormat : "<!-- TMPL_VAR NAME="DHTMLcalendar_dateformat" -->",
149
                             button : "openreservedateTo",
150
                             disableFunc : validate2,
151
                             dateStatusFunc : validate2
152
                     });
153
					//]]>
154
					</script>
155
                    </td>
156
                </tr>
157
            <tr>
158
                <td>notification date</td>
159
                <td><input type="radio" name="Line" value="notificationdate" /></td>
160
                <td><input type="radio" name="Column" value="notificationdate" /></td>
161
                <td><label for="filter_notificationdate_begin">From</label> <input type="text"  size="10" id="filter_notificationdate_begin" name="filter_notificationdate_begin" />
162
                    <img src="<!-- TMPL_VAR Name="themelang" -->/lib/calendar/cal.gif" alt="Show Calendar" border="0" id="opennotificationdateFrom" style="cursor: pointer;" />
163
                   <script type="text/javascript">
164
				   //<![CDATA[ 
165
				   function validate1(date) {
166
                        var day = date.getDate();
167
                        var month = date.getMonth() + 1;
168
                        var year = date.getFullYear();
169
                        var weekDay = date.getDay();
170
                        var dayMonth = month + '-' + day;
171
                        var dateString = year + '-' + month + '-' + day;
172
                        var dateTo = document.getElementById('filter_notificationdate_end').value.split("-");
173
                        var limitDate = new Date(dateTo[0], (dateTo[1] - 1), dateTo[2]);
174
                        if (date > limitDate) {
175
                             return true;
176
                        } else {
177
                             return false;
178
                        }
179
                    }
180
                    Calendar.setup({
181
                            inputField : "filter_notificationdate_begin",
182
                            ifFormat : "<!-- TMPL_VAR NAME="DHTMLcalendar_dateformat" -->",
183
                            button : "opennotificationdateFrom",
184
                            disableFunc : validate1,
185
                            dateStatusFunc : validate1
186
                    });
187
					//]]>
188
					</script>
189
                    <label for="filter_notificationdate_end">To</label> <input  size="10" id="filter_notificationdate_end" name="filter_notificationdate_end" value="" type="text" />
190
                    <img src="<!-- TMPL_VAR Name="themelang" -->/lib/calendar/cal.gif" alt="Show Calendar" id="opennotificationdateTo" style="cursor: pointer;" border="0" />
191
                    <script type="text/javascript">
192
					//<![CDATA[  
193
					function validate2(date) {
194
                         var day = date.getDate();
195
                         var month = date.getMonth() + 1;
196
                         var year = date.getFullYear();
197
                         var weekDay = date.getDay();
198
                         var dayMonth = month + '-' + day;
199
                         var dateString = year + '-' + month + '-' + day;
200
                         var dateFrom = document.getElementById('filter_notificationdate_begin').value.split("-");
201
                         var limitDate = new Date(dateFrom[0], (dateFrom[1] - 1), dateFrom[2]);
202
                         if (limitDate > date) {
203
                              return true;
204
                         } else {
205
                              return false;
206
                         }
207
                     }
208
                     Calendar.setup({
209
                             inputField : "filter_notificationdate_end",
210
                             ifFormat : "<!-- TMPL_VAR NAME="DHTMLcalendar_dateformat" -->",
211
                             button : "opennotificationdateTo",
212
                             disableFunc : validate2,
213
                             dateStatusFunc : validate2
214
                     });
215
					//]]>
216
					</script>
217
                    </td>
218
             </tr>
219
            <tr>
220
                <td>Reminder date</td>
221
                <td><input type="radio" name="Line" value="reminderdate" /></td>
222
                <td><input type="radio" name="Column" value="reminderdate" /></td>
223
                <td><label for="filter_reminderdate_begin">From</label> <input type="text"  size="10" id="filter_reminderdate_begin" name="Filter" />
224
                    <img src="<!-- TMPL_VAR Name="themelang" -->/lib/calendar/cal.gif" alt="Show Calendar" border="0" id="openreminderdateFrom" style="cursor: pointer;" />
225
                   <script type="text/javascript">
226
				   //<![CDATA[ 
227
				   function validate1(date) {
228
                        var day = date.getDate();
229
                        var month = date.getMonth() + 1;
230
                        var year = date.getFullYear();
231
                        var weekDay = date.getDay();
232
                        var dayMonth = month + '-' + day;
233
                        var dateString = year + '-' + month + '-' + day;
234
                        var dateTo = document.getElementById('filter_reminderdate_end').value.split("-");
235
                        var limitDate = new Date(dateTo[0], (dateTo[1] - 1), dateTo[2]);
236
                        if (date > limitDate) {
237
                             return true;
238
                        } else {
239
                             return false;
240
                        }
241
                    }
242
                    Calendar.setup({
243
                            inputField : "filter_reminderdate_begin",
244
                            ifFormat : "<!-- TMPL_VAR NAME="DHTMLcalendar_dateformat" -->",
245
                            button : "openreminderdateFrom",
246
                            disableFunc : validate1,
247
                            dateStatusFunc : validate1
248
                    });
249
					//]]>
250
					</script>
251
                    <label for="filter_reminderdate_end">To</label> <input size="10" id="filter_reminderdate_end" name="filter_reminderdate_end" value="" type="text" />
252
                    <img src="<!-- TMPL_VAR Name="themelang" -->/lib/calendar/cal.gif" alt="Show Calendar" id="openreminderdateTo" style="cursor: pointer;" border="0" />
253
                    <script type="text/javascript">
254
					//<![CDATA[  
255
					function validate2(date) {
256
                         var day = date.getDate();
257
                         var month = date.getMonth() + 1;
258
                         var year = date.getFullYear();
259
                         var weekDay = date.getDay();
260
                         var dayMonth = month + '-' + day;
261
                         var dateString = year + '-' + month + '-' + day;
262
                         var dateFrom = document.getElementById('filter_reminderdate_begin').value.split("-");
263
                         var limitDate = new Date(dateFrom[0], (dateFrom[1] - 1), dateFrom[2]);
264
                         if (limitDate > date) {
265
                              return true;
266
                         } else {
267
                              return false;
268
                         }
269
                     }
270
                     Calendar.setup({
271
                             inputField : "filter_reminderdate_end",
272
                             ifFormat : "<!-- TMPL_VAR NAME="DHTMLcalendar_dateformat" -->",
273
                             button : "openreminderdateTo",
274
                             disableFunc : validate2,
275
                             dateStatusFunc : validate2
276
                     });
277
					//]]>
278
					</script>
279
                    </td>
280
             </tr>
281
            <tr>
282
                <td>Waiting date</td>
283
                <td><input type="radio" name="Line" value="waitingdate" /></td>
284
                <td><input type="radio" name="Column" value="waitingdate" /></td>
285
                <td><label for="filter_waitingdate_begin">From</label> <input type="text"  size="10" id="filter_waitingdate_begin" name="filter_waitingdate_begin" />
286
                    <img src="<!-- TMPL_VAR Name="themelang" -->/lib/calendar/cal.gif" alt="Show Calendar" border="0" id="openwaitingdateFrom" style="cursor: pointer;" />
287
                   <script type="text/javascript">
288
				   //<![CDATA[ 
289
				   function validate1(date) {
290
                        var day = date.getDate();
291
                        var month = date.getMonth() + 1;
292
                        var year = date.getFullYear();
293
                        var weekDay = date.getDay();
294
                        var dayMonth = month + '-' + day;
295
                        var dateString = year + '-' + month + '-' + day;
296
                        var dateTo = document.getElementById('filter_waitingdate_end').value.split("-");
297
                        var limitDate = new Date(dateTo[0], (dateTo[1] - 1), dateTo[2]);
298
                        if (date > limitDate) {
299
                             return true;
300
                        } else {
301
                             return false;
302
                        }
303
                    }
304
                    Calendar.setup({
305
                            inputField : "filter_waitingdate_begin",
306
                            ifFormat : "<!-- TMPL_VAR NAME="DHTMLcalendar_dateformat" -->",
307
                            button : "openwaitingdateFrom",
308
                            disableFunc : validate1,
309
                            dateStatusFunc : validate1
310
                    });
311
					//]]>
312
					</script>
313
                    <label for="filter_waitingdate_end">To</label> <input  size="10" id="filter_waitingdate_end" name="filter_waitingdate_end" value="" type="text" />
314
                    <img src="<!-- TMPL_VAR Name="themelang" -->/lib/calendar/cal.gif" alt="Show Calendar" id="openwaitingdateTo" style="cursor: pointer;" border="0" />
315
                    <script type="text/javascript">
316
					//<![CDATA[  
317
					function validate2(date) {
318
                         var day = date.getDate();
319
                         var month = date.getMonth() + 1;
320
                         var year = date.getFullYear();
321
                         var weekDay = date.getDay();
322
                         var dayMonth = month + '-' + day;
323
                         var dateString = year + '-' + month + '-' + day;
324
                         var dateFrom = document.getElementById('filter_waitingdate_begin').value.split("-");
325
                         var limitDate = new Date(dateFrom[0], (dateFrom[1] - 1), dateFrom[2]);
326
                         if (limitDate > date) {
327
                              return true;
328
                         } else {
329
                              return false;
330
                         }
331
                     }
332
                     Calendar.setup({
333
                             inputField : "filter_waitingdate_end",
334
                             ifFormat : "<!-- TMPL_VAR NAME="DHTMLcalendar_dateformat" -->",
335
                             button : "openwaitingdateTo",
336
                             disableFunc : validate2,
337
                             dateStatusFunc : validate2
338
                     });
339
					//]]>
340
					</script>
341
                    </td>
342
             </tr>
343
			 <tr>
344
                <td>cancellation date</td>
345
                <td><input type="radio" name="Line" value="cancellationdate" /></td>
346
                <td><input type="radio" name="Column" value="cancellationdate" /></td>
347
                <td><label for="filter_cancellationdate_begin">From</label> <input type="text"  size="10" id="filter_cancellationdate_begin" name="filter_cancellationdate_begin" />
348
                    <img src="<!-- TMPL_VAR Name="themelang" -->/lib/calendar/cal.gif" alt="Show Calendar" border="0" id="opencancellationdateFrom" style="cursor: pointer;" />
349
                   <script type="text/javascript">
350
				   //<![CDATA[ 
351
				   function validate1(date) {
352
                        var day = date.getDate();
353
                        var month = date.getMonth() + 1;
354
                        var year = date.getFullYear();
355
                        var weekDay = date.getDay();
356
                        var dayMonth = month + '-' + day;
357
                        var dateString = year + '-' + month + '-' + day;
358
                        var dateTo = document.getElementById('filter_cancellationdate_end').value.split("-");
359
                        var limitDate = new Date(dateTo[0], (dateTo[1] - 1), dateTo[2]);
360
                        if (date > limitDate) {
361
                             return true;
362
                        } else {
363
                             return false;
364
                        }
365
                    }
366
                    Calendar.setup({
367
                            inputField : "filter_cancellationdate_begin",
368
                            ifFormat : "<!-- TMPL_VAR NAME="DHTMLcalendar_dateformat" -->",
369
                            button : "opencancellationdateFrom",
370
                            disableFunc : validate1,
371
                            dateStatusFunc : validate1
372
                    });
373
					//]]>
374
					</script>
375
                    <label for="filter_cancellationdate_end">To</label> <input  size="10" id="filter_cancellationdate_end" name="filter_cancellationdate_end" value="" type="text" />
376
                    <img src="<!-- TMPL_VAR Name="themelang" -->/lib/calendar/cal.gif" alt="Show Calendar" id="opencancellationdateTo" style="cursor: pointer;" border="0" />
377
                    <script type="text/javascript">
378
					//<![CDATA[  
379
					function validate2(date) {
380
                         var day = date.getDate();
381
                         var month = date.getMonth() + 1;
382
                         var year = date.getFullYear();
383
                         var weekDay = date.getDay();
384
                         var dayMonth = month + '-' + day;
385
                         var dateString = year + '-' + month + '-' + day;
386
                         var dateFrom = document.getElementById('filter_cancellationdate_begin').value.split("-");
387
                         var limitDate = new Date(dateFrom[0], (dateFrom[1] - 1), dateFrom[2]);
388
                         if (limitDate > date) {
389
                              return true;
390
                         } else {
391
                              return false;
392
                         }
393
                     }
394
                     Calendar.setup({
395
                             inputField : "filter_cancellationdate_end",
396
                             ifFormat : "<!-- TMPL_VAR NAME="DHTMLcalendar_dateformat" -->",
397
                             button : "opencancellationdateTo",
398
                             disableFunc : validate2,
399
                             dateStatusFunc : validate2
400
                     });
401
					//]]>
402
					</script>
403
                    </td>
404
             </tr>
405
        <tr>
406
            <td>Patron Category</td>
407
            <td><input type="radio" name="Line" value="borrowers.categorycode" /></td>
408
            <td><input type="radio" name="Column" value="borrowers.categorycode" /></td>
409
           <td><select name="filter_categorycode" id="borcat">
410
               <option value=""> </option>
411
               <!-- TMPL_LOOP NAME="categoryloop" -->
412
                 <!-- TMPL_IF NAME="selected" --><option value="<!-- TMPL_VAR NAME="categorycode" -->" selected="selected"><!-- TMPL_VAR NAME="description" --></option><!-- TMPL_ELSE --><option value="<!-- TMPL_VAR NAME="categorycode" -->"><!-- TMPL_VAR NAME="description" --></option><!-- /TMPL_IF -->
413
               <!-- /TMPL_LOOP -->
414
               </select>
415
             </td> 
416
        </tr>
417
        <tr class="highlight">
418
            <td>Item Type</td>
419
            <td><input type="radio" name="Line" value="items.itype" /></td>
420
            <td><input type="radio" name="Column" value="items.itype" /></td>
421
           <td><select name="filter_items.itype" id="itype">
422
               <option value=""> </option>
423
               <!-- TMPL_LOOP NAME="itypeloop" -->
424
                 <!-- TMPL_IF NAME="selected" --><option value="<!-- TMPL_VAR NAME="code" -->" selected="selected"><!-- TMPL_VAR NAME="description" --></option><!-- TMPL_ELSE --><option value="<!-- TMPL_VAR NAME="code" -->"><!-- TMPL_VAR NAME="description" --></option><!-- /TMPL_IF -->
425
               <!-- /TMPL_LOOP -->
426
               </select>
427
             </td> 
428
        </tr>
429
        <tr>
430
            <td>Pickup Library</td>
431
            <td><input type="radio" name="Line" value="reserves.branchcode" checked="checked" /></td>
432
            <td><input type="radio" name="Column" value="reserves.branchcode" /></td>
433
            <td><select name="filter_reserves.branchcode" id="resbranchcode">
434
               <option value=""> </option>
435
               <!-- TMPL_LOOP NAME="branchloop" -->
436
<!-- TMPL_IF NAME="selected" --><option value="<!-- TMPL_VAR NAME="value" -->" selected="selected"><!-- TMPL_VAR NAME="branchname" --></option><!-- TMPL_ELSE --><option value="<!-- TMPL_VAR NAME="value" -->"><!-- TMPL_VAR NAME="branchname" --></option><!-- /TMPL_IF -->
437
				<!-- /TMPL_LOOP -->
438
               </select>
439
             </td> 
440
        </tr>
441
        <tr class="highlight">
442
            <td>Holding Library</td>
443
            <td><input type="radio" name="Line" value="holdingbranch" /></td>
444
            <td><input type="radio" name="Column" value="holdingbranch" /></td>
445
            <td><select name="filter_holdingbranch" id="holdingbranch">
446
               <option value=""> </option>
447
               <!-- TMPL_LOOP NAME="branchloop" -->
448
<!-- TMPL_IF NAME="selected" --><option value="<!-- TMPL_VAR NAME="value" -->" selected="selected"><!-- TMPL_VAR NAME="branchname" --></option><!-- TMPL_ELSE --><option value="<!-- TMPL_VAR NAME="value" -->"><!-- TMPL_VAR NAME="branchname" --></option><!-- /TMPL_IF -->
449
				<!-- /TMPL_LOOP -->
450
               </select>
451
             </td> 
452
        </tr>
453
        <tr>
454
            <td>Home Library</td>
455
            <td><input type="radio" name="Line" value="homebranch" /></td>
456
            <td><input type="radio" name="Column" value="homebranch" /></td>
457
            <td><select name="filter_homebranch" id="homebranch">
458
               <option value=""> </option>
459
               <!-- TMPL_LOOP NAME="branchloop" -->
460
<!-- TMPL_IF NAME="selected" --><option value="<!-- TMPL_VAR NAME="value" -->" selected="selected"><!-- TMPL_VAR NAME="branchname" --></option><!-- TMPL_ELSE --><option value="<!-- TMPL_VAR NAME="value" -->"><!-- TMPL_VAR NAME="branchname" --></option><!-- /TMPL_IF -->
461
				<!-- /TMPL_LOOP -->
462
               </select>
463
             </td> 
464
        </tr>
465
        <tr class="highlight">
466
            <td>Collection</td>
467
            <td><input type="radio" name="Line"   value="items.ccode" /></td>
468
            <td><input type="radio" name="Column" value="items.ccode" /></td>
469
            <td><select name="filter_items.ccode" id="ccode">
470
                <option value=""> </option>
471
                <!-- TMPL_LOOP NAME="ccodeloop" -->
472
					<!-- TMPL_IF NAME="selected" --> <option value="<!-- TMPL_VAR NAME="code" -->" selected="selected"><!-- TMPL_VAR NAME="description" --></option><!-- TMPL_ELSE --><option value="<!-- TMPL_VAR NAME="code" -->"><!-- TMPL_VAR NAME="description" --></option><!-- /TMPL_IF -->
473
                <!-- /TMPL_LOOP -->
474
                </select>
475
            </td>
476
        </tr>
477
        <tr>
478
            <td>Shelving Location</td>
479
            <td><input type="radio" name="Line" value="items.location" /></td>
480
            <td><input type="radio" name="Column" value="items.location" /></td>
481
            <td><select name="filter_items.location" id="location">
482
                <option value=""> </option>
483
                <!-- TMPL_LOOP NAME="locationloop" -->
484
					<!-- TMPL_IF NAME="selected" --><option value="<!-- TMPL_VAR NAME="code" -->" selected="selected"><!-- TMPL_VAR NAME="description" --></option><!-- TMPL_ELSE --><option value="<!-- TMPL_VAR NAME="code" -->"><!-- TMPL_VAR NAME="description" --></option><!-- /TMPL_IF -->
485
				<!-- /TMPL_LOOP -->
486
               </select>
487
            </td> 
488
        </tr>
489
        <tr class="highlight">
490
            <td>Item Call Number</td>
491
            <td></td>
492
            <td></td>
493
            <td>From <input type="text" name="filter_itemcallnumber" size="10" /> (inclusive) to <input type="text" name="fiter_itemcallnumber" size="10" /> (exclusive) </td>
494
        </tr>
495
        <!-- TMPL_IF Name="hassort1" -->
496
        <tr><td>Patron sort1</td>
497
			<td><input type="radio" name="Line" value="borrowers.sort1" /></td>
498
			<td><input type="radio" name="Column" value="borrowers.sort1" /></td>
499
			<td><select name="filter_borrowers.sort1" id="sort1">
500
               <option value=""> </option>
501
               <!-- TMPL_LOOP NAME="Bsort1" -->
502
			   <!-- TMPL_IF NAME="selected" --><option value="<!-- TMPL_VAR NAME="authorised_value" -->" selected="selected"><!-- TMPL_VAR NAME="lib" --></option><!-- TMPL_ELSE --><option value="<!-- TMPL_VAR NAME="authorised_value" -->" ><!-- TMPL_VAR NAME="lib" --></option><!-- /TMPL_IF -->
503
               <!-- /TMPL_LOOP -->
504
               </select>
505
            </td> 
506
        </tr>
507
        <!-- /TMPL_IF -->
508
        <!-- TMPL_IF Name="hassort2" -->
509
        <tr class="highlight"><td>Patron sort2</td>
510
            <td><input type="radio" name="Line" value="borrowers.sort2" /></td>
511
            <td><input type="radio" name="Column" value="borrowers.sort2" /></td>
512
           	<td><select name="filter_borrowers.sort2" id="sort2">
513
               <option value=""> </option>
514
               <!-- TMPL_LOOP NAME="Bsort2" -->
515
			   <!-- TMPL_IF NAME="selected" --><option value="<!-- TMPL_VAR NAME="authorised_value" -->" selected="selected"><!-- TMPL_VAR NAME="lib" --></option><!-- TMPL_ELSE --><option value="<!-- TMPL_VAR NAME="authorised_value" -->" ><!-- TMPL_VAR NAME="lib" --></option><!-- /TMPL_IF -->
516
               <!-- /TMPL_LOOP -->
517
               </select>
518
            </td> 
519
        </tr>
520
        <!-- /TMPL_IF -->
521
        </tbody>
522
    </table><br /></fieldset>
523
524
<fieldset class="rows"><legend>Cell value </legend><ol><li><label for="cellvalue1">Count reserves</label> <input type="radio" name="Cellvalue" value="1" id="cellvalue1" checked="checked" /> </li>
525
            <li><label for="cellvalue2">Count unique borrowers</label> <input type="radio" name="Cellvalue" value="2" id="cellvalue2" /> </li><li><label for="cellvalue3">Count unique items</label> <input type="radio" name="Cellvalue" id="cellvalue3" value="3" /> </li><li><label for="cellvalue4">Count unique biblios</label> <input type="radio" name="Cellvalue" id="cellvalue4" value="4" /> </li></ol></fieldset>
526
			
527
	<fieldset class="rows">
528
	<legend>Output</legend>
529
<ol><li><label for="outputscreen">To screen into the browser: </label><input type="radio" checked="checked" name="output" id="outputscreen" value="screen" /> </li>
530
<li><label for="outputfile">To a file:</label> <input type="radio" name="output" value="file" id="outputfile" /> <label class="inline" for="basename">Named: </label><input type="text" name="basename" id="basename" value="Export" /> <label class="inline" for="MIME">Into an application  
531
		</label><!-- TMPL_VAR NAME="CGIextChoice" -->
532
		<!-- TMPL_VAR NAME="CGIsepChoice" --></li></ol>
533
	</fieldset>
534
535
	<fieldset class="action">
536
	<input type="submit" value="Submit" />
537
	<input type="hidden" name="report_name" value="<!--TMPL_VAR NAME="report_name" -->" />
538
	<input type="hidden" name="do_it" value="1" />
539
	</fieldset>
540
	</form>
541
<!-- /TMPL_IF -->
542
543
</div>
544
</div>
545
<div class="yui-b">
546
<!-- TMPL_INCLUDE NAME="reports-menu.inc" -->
547
</div>
548
</div>
549
<!-- TMPL_INCLUDE NAME="intranet-bottom.inc" -->
(-)a/reports/reserves_stats.pl (-1 / +382 lines)
Line 0 Link Here
0
- 
1
#!/usr/bin/perl
2
3
4
# Copyright 2000-2002 Katipo Communications
5
#
6
# This file is part of Koha.
7
#
8
# Koha is free software; you can redistribute it and/or modify it under the
9
# terms of the GNU General Public License as published by the Free Software
10
# Foundation; either version 2 of the License, or (at your option) any later
11
# version.
12
#
13
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
14
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
15
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
16
#
17
# You should have received a copy of the GNU General Public License along with
18
# Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
19
# Suite 330, Boston, MA  02111-1307 USA
20
21
use strict;
22
23
use CGI;
24
25
use C4::Auth;
26
use C4::Debug;
27
use C4::Context;
28
use C4::Branch; # GetBranches
29
use C4::Koha;
30
use C4::Output;
31
use C4::Reports;
32
use C4::Members;
33
use C4::Dates qw/format_date format_date_in_iso/;
34
use C4::Category;
35
use List::MoreUtils qw/any/;
36
use YAML;
37
38
=head1 NAME
39
40
plugin that shows circulation stats
41
42
=head1 DESCRIPTION
43
44
=over 2
45
46
=cut
47
48
# my $debug = 1;	# override for now.
49
my $input = new CGI;
50
my $fullreportname = "reports/reserves_stats.tmpl";
51
my $do_it    = $input->param('do_it');
52
my $line     = $input->param("Line");
53
my $column   = $input->param("Column");
54
my $podsp    = $input->param("DisplayBy");
55
my $type     = $input->param("PeriodTypeSel");
56
my $daysel   = $input->param("PeriodDaySel");
57
my $monthsel = $input->param("PeriodMonthSel");
58
my $calc     = $input->param("Cellvalue");
59
my $output   = $input->param("output");
60
my $basename = $input->param("basename");
61
my $mime     = $input->param("MIME");
62
my $hash_params = $input->Vars;
63
my $filter_hashref;
64
foreach my $filter (grep {$_ =~/^filter/} keys %$hash_params){
65
	my $filterstring=$filter;
66
	$filterstring=~s/^filter_//g;
67
	$$filter_hashref{$filterstring}=$$hash_params{$filter} if (defined $$hash_params{$filter} && $$hash_params{$filter} ne "");
68
}
69
my ($template, $borrowernumber, $cookie) = get_template_and_user({
70
	template_name => $fullreportname,
71
	query => $input,
72
	type => "intranet",
73
	authnotrequired => 0,
74
	flagsrequired => {reports => '*'},
75
	debug => 0,
76
});
77
our $sep     = $input->param("sep");
78
$sep = "\t" if ($sep eq 'tabulation');
79
$template->param(do_it => $do_it,
80
	DHTMLcalendar_dateformat => C4::Dates->DHTMLcalendar(),
81
);
82
83
my $itemtypes = GetItemTypes();
84
my $categoryloop = GetBorrowercategoryList;
85
86
my $ccodes    = GetKohaAuthorisedValues("items.ccode");
87
my $locations = GetKohaAuthorisedValues("items.location");
88
my $authvalue = GetKohaAuthorisedValues("items.authvalue");
89
90
my $Bsort1 = GetAuthorisedValues("Bsort1");
91
my $Bsort2 = GetAuthorisedValues("Bsort2");
92
my ($hassort1,$hassort2);
93
$hassort1=1 if $Bsort1;
94
$hassort2=1 if $Bsort2;
95
96
97
if ($do_it) {
98
# Displaying results
99
	my $results = calculate($line, $column,  $calc, $filter_hashref);
100
	if ($output eq "screen"){
101
# Printing results to screen
102
		$template->param(mainloop => $results);
103
		output_html_with_http_headers $input, $cookie, $template->output;
104
	} else {
105
# Printing to a csv file
106
        print $input->header(-type => 'application/vnd.sun.xml.calc',
107
                            -encoding    => 'utf-8',
108
                            -attachment=>"$basename.csv",
109
                            -filename=>"$basename.csv" );
110
		my $cols  = @$results[0]->{loopcol};
111
		my $lines = @$results[0]->{looprow};
112
# header top-right
113
		print @$results[0]->{line} ."/". @$results[0]->{column} .$sep;
114
# Other header
115
		foreach my $col ( @$cols ) {
116
			print $col->{coltitle}.$sep;
117
		}
118
		print "Total\n";
119
# Table
120
		foreach my $line ( @$lines ) {
121
			my $x = $line->{loopcell};
122
			print $line->{rowtitle}.$sep;
123
			print map {$_->{value}.$sep} @$x;
124
			print $line->{totalrow}, "\n";
125
		}
126
# footer
127
        print "TOTAL";
128
        $cols = @$results[0]->{loopfooter};
129
		print map {$sep.$_->{totalcol}} @$cols;
130
        print $sep.@$results[0]->{total};
131
	}
132
	exit(1); # exit either way after $do_it
133
}
134
135
my $dbh = C4::Context->dbh;
136
my @values;
137
my %labels;
138
my %select;
139
140
# create itemtype arrayref for <select>.
141
my @itemtypeloop;
142
for my $itype ( sort {$itemtypes->{$a}->{description} cmp $itemtypes->{$b}->{description}} keys(%$itemtypes)) {
143
	push @itemtypeloop, { code => $itype , description => $itemtypes->{$itype}->{description} } ;
144
}
145
146
    # location list
147
my @locations;
148
foreach (sort keys %$locations) {
149
	push @locations, { code => $_, description => "$_ - " . $locations->{$_} };
150
}
151
    
152
my @ccodes;
153
foreach (sort {$ccodes->{$a} cmp $ccodes->{$b}} keys %$ccodes) {
154
	push @ccodes, { code => $_, description => $ccodes->{$_} };
155
}
156
157
# various
158
my @mime = (C4::Context->preference("MIME"));
159
160
my $CGIextChoice=CGI::scrolling_list(
161
	-name     => 'MIME',
162
	-id       => 'MIME',
163
	-values   => \@mime,
164
	-size     => 1,
165
	-multiple => 0 );
166
    
167
my $CGIsepChoice=GetDelimiterChoices;
168
 
169
$template->param(
170
	categoryloop => $categoryloop,
171
	itemtypeloop => \@itemtypeloop,
172
	   ccodeloop => \@ccodes,
173
	  branchloop => GetBranchesLoop(C4::Context->userenv->{'branch'}),
174
	hassort1=> $hassort1,
175
	hassort2=> $hassort2,
176
	Bsort1 => $Bsort1,
177
	Bsort2 => $Bsort2,
178
	CGIextChoice => $CGIextChoice,
179
	CGIsepChoice => $CGIsepChoice,
180
);
181
output_html_with_http_headers $input, $cookie, $template->output;
182
183
sub calculate {
184
	my ($linefield, $colfield, $process, $filters_hashref) = @_;
185
	my @loopfooter;
186
	my @loopcol;
187
	my @loopline;
188
	my @looprow;
189
	my %globalline;
190
	my $grantotal =0;
191
# extract parameters
192
	my $dbh = C4::Context->dbh;
193
194
# Filters
195
# Checking filters
196
#
197
	my @loopfilter;
198
	foreach my $filter (keys %$filters_hashref){
199
		$$filters_hashref{$filter} =~s/\*/%/;
200
		$$filters_hashref{$filter} = format_date_in_iso($$filters_hashref{$_}) if ($_=~/date/);
201
	}
202
	#display
203
	@loopfilter= map{{ crit=>$_ ,filter=>($_=~/date/?
204
											format_date($$filters_hashref{$_})
205
											:$$filters_hashref{$_}
206
										  )
207
					  }
208
					} sort keys %$filters_hashref;
209
210
211
212
213
	my $linesql=changeifreservestatus($linefield);
214
	my $colsql=changeifreservestatus($colfield);
215
	#Initialization of cell values.....
216
217
	# preparing calculation
218
    my $strcalc = "(SELECT $linesql line, $colsql col, ";
219
        $strcalc .= ($process == 1) ? " COUNT(*)  calculation"                                 :
220
					($process == 2) ? "(COUNT(DISTINCT reserves.borrowernumber)) calculation"  :
221
        			($process == 3) ? "(COUNT(DISTINCT reserves.itemnumber)) calculation"      : 
222
        			($process == 4) ? "(COUNT(DISTINCT reserves.biblionumber)) calculation"    : '*';
223
	$strcalc .= "
224
        FROM reserves
225
        LEFT JOIN borrowers USING (borrowernumber)
226
	";
227
	$strcalc .= "LEFT JOIN biblio ON reserves.biblionumber=biblio.biblionumber "
228
        if ($linefield =~ /^biblio\./ or $colfield =~ /^biblio\./ or any {$_=~/biblio/}keys %$filters_hashref);
229
	$strcalc .= "LEFT JOIN items ON reserves.itemnumber=items.itemnumber "
230
        if ($linefield =~ /^items\./ or $colfield =~ /^items\./ or any {$_=~/items/}keys %$filters_hashref);
231
        
232
	my @sqlparams;
233
	my @sqlorparams;
234
	my @sqlor;
235
	my @sqlwhere;
236
	($debug) and print STDERR Dump($filters_hashref);
237
	foreach my $filter (keys %$filters_hashref){
238
		my $string;
239
		my $stringfield=$filter;
240
		$stringfield=~s/\_[a-z_]+$//;
241
		warn $stringfield;
242
		if ($filter=~/ /){
243
			$string=$stringfield;
244
		}
245
		elsif ($filter=~/_or/){
246
			 push @sqlor, qq{( }.changeifreservestatus($filter)." = ? ) ";
247
			 push @sqlorparams, $$filters_hashref{$filter};
248
		}
249
		elsif ($filter=~/_end$/){
250
			$string = " $stringfield <= ? ";
251
		}
252
		elsif ($filter=~/_begin$/){
253
			$string = " $stringfield >= ? ";
254
		}
255
		else {
256
			$string = " $stringfield LIKE ? ";
257
		}
258
		if ($string){
259
			push @sqlwhere, $string;
260
			push @sqlparams, $$filters_hashref{$filter};
261
		}
262
	}
263
264
	$strcalc .= " WHERE ".join(" AND ",@sqlwhere) if (@sqlwhere);
265
	$strcalc .= " AND (".join(" OR ",@sqlor).")" if (@sqlor);
266
	$strcalc .= " GROUP BY line, col )";
267
	my $strcalc_old=$strcalc;
268
	$strcalc_old=~s/reserves/old_reserves/g;
269
	$strcalc.=qq{ UNION $strcalc_old ORDER BY line, col};
270
	($debug) and print STDERR $strcalc;
271
	my $dbcalc = $dbh->prepare($strcalc);
272
	push @loopfilter, {crit=>'SQL =', sql=>1, filter=>$strcalc};
273
	@sqlparams=(@sqlparams,@sqlorparams);
274
	$dbcalc->execute(@sqlparams,@sqlparams);
275
	my ($emptycol,$emptyrow); 
276
	my $data = $dbcalc->fetchall_hashref([qw(line col)]);
277
	my @loopline;
278
	my %cols_hash;
279
	foreach my $row (keys %$data){
280
		push @loopline, $row;
281
		foreach my $col (keys %{$$data{$row}}){
282
			$$data{$row}{totalrow}+=$$data{$row}{$col}{calculation};
283
			$grantotal+=$$data{$row}{$col}{calculation};
284
			$cols_hash{$col}=1 ;
285
		}
286
	}
287
	my $urlbase="do_it=1&amp;".join("&amp;",map{"filter_$_=$$filters_hashref{$_}"} keys %$filters_hashref);
288
	foreach my $row (sort @loopline) {
289
		my @loopcell;
290
		#@loopcol ensures the order for columns is common with column titles
291
		# and the number matches the number of columns
292
		foreach my $col (sort keys %cols_hash) {
293
			push @loopcell, {value =>( $$data{$row}{$col}{calculation} or ""),
294
	#						url_complement=>($urlbase=~/&amp;$/?$urlbase."&amp;":$urlbase)."filter_$linefield=$row&amp;filter_$colfield=$col"
295
							}
296
		}
297
		push @looprow, {
298
			'rowtitle_display' => display_value($linefield,$row),
299
			'rowtitle' => $row,
300
			'loopcell' => \@loopcell,
301
			'totalrow' => $$data{$row}{totalrow}
302
		};
303
	}
304
	for my $col ( sort keys %cols_hash ) {
305
		my $total = 0;
306
		foreach my $row (@loopline) {
307
			$total += $$data{$row}{$col}{calculation};
308
			$debug and warn "value added ".$$data{$row}{$col}{calculation}. "for line ".$row;
309
		}
310
		push @loopfooter, {'totalcol' => $total};
311
		push @loopcol, {'coltitle' => $col,
312
						coltitle_display=>display_value($colfield,$col)};
313
	}
314
315
	# the header of the table
316
	$globalline{loopfilter}=\@loopfilter;
317
	# the core of the table
318
	$globalline{looprow} = \@looprow;
319
	$globalline{loopcol} = \@loopcol;
320
	# 	# the foot (totals by borrower type)
321
	$globalline{loopfooter} = \@loopfooter;
322
	$globalline{total}  = $grantotal;
323
	$globalline{line}   = $linefield;
324
	$globalline{column} = $colfield;
325
	return [(\%globalline)];
326
}
327
328
sub null_to_zzempty ($) {
329
	my $string = shift;
330
	defined($string)    or  return 'zzEMPTY';
331
	($string eq "NULL") and return 'zzEMPTY';
332
	return $string;		# else return the valid value
333
}
334
sub display_value{
335
	my ($crit,$value)=@_;
336
	my $display_value =
337
		($crit =~ /ccode/   ) ? $ccodes->{$value}    :
338
		($crit =~ /location/) ? $locations->{$value} :
339
		($crit =~ /itemtype/) ? $itemtypes->{$value}->{description} :
340
		($crit =~ /branch/) ? GetBranchName($value):
341
		($crit =~ /reservestatus/) ? reservestatushuman($value):
342
		$value; # default fallback
343
	if ($crit =~ /(sort1|sort2)/) {
344
		$display_value=GetAuthorisedValues("B$_",$value);
345
	} elsif ($crit =~ /category/) {
346
		my $element=any{$value eq $_->{categorycode}} @$categoryloop;
347
		$display_value=$$element{description};
348
	}
349
	return $display_value;
350
}
351
sub reservestatushuman{
352
	my ($val)=@_;
353
	my %hashhuman=(
354
	1=>"1- placed",
355
	2=>"2- processed",
356
	3=>"3- pending",
357
	4=>"4- satisfied",
358
	5=>"5- cancelled",
359
	6=>"6- not a status"
360
	);
361
	$hashhuman{$val};
362
}
363
sub changeifreservestatus{
364
	my ($val)=@_;
365
	($val=~/reservestatus/
366
		?$val=qq{ case 
367
					when priority>0 then 1 
368
					when priority=0 then
369
						(case 
370
						   when found='f' then 4
371
						   when found='w' then 
372
						   (case 
373
						    when cancellationdate is null then 3
374
							else 5
375
							end )
376
						   else 2 
377
						 end )
378
				    else 6 
379
					end }
380
		:$val);
381
}
382
1;

Return to bug 5869