--- /dev/null
+<!-- TMPL_INCLUDE NAME="doc-head-open.inc" -->
+<title>Koha › Reports › Checkout statistics <!-- TMPL_IF NAME="do_it" -->› Results<!-- /TMPL_IF --></title>
+<!-- TMPL_INCLUDE NAME="doc-head-close.inc" -->
+<!-- TMPL_INCLUDE NAME="calendar.inc" -->
+<style type="text/css">
+ .sql {display:none;}
+</style>
+</head>
+<body>
+<!-- TMPL_INCLUDE NAME="header.inc" -->
+<!-- TMPL_INCLUDE NAME="cat-search.inc" -->
+
+<div id="breadcrumbs"><a href="/cgi-bin/koha/mainpage.pl">Home</a> › <a href="/cgi-bin/koha/reports/reports-home.pl">Reports</a> <!-- TMPL_IF NAME="do_it" -->› <a href="/cgi-bin/koha/reports/reserves_stats.pl">Reserves statistics</a> › Results <!-- TMPL_ELSE -->› Reserves statistics<!-- /TMPL_IF --></div>
+
+<div id="doc3" class="yui-t2">
+
+ <div id="bd">
+ <div id="yui-main">
+ <div class="yui-b">
+
+<!-- TMPL_IF NAME="do_it" -->
+ <!-- TMPL_IF NAME="mainloop" -->
+ <h1>Reserves statistics</h1>
+ <!-- TMPL_IF NAME="loopfilter" -->
+ <p>Filtered on</p>
+ <ul>
+ <!-- TMPL_LOOP NAME="loopfilter" -->
+ <!-- TMPL_IF NAME="err" --><li class="error">Error:
+ <!-- TMPL_ELSIF NAME="sql" --><li class="sql">
+ <!-- TMPL_ELSE --><li>
+ <!--/TMPL_IF -->
+ <!-- TMPL_VAR NAME="crit"--> <!-- TMPL_VAR NAME="filter"-->
+ </li>
+ <!-- /TMPL_LOOP -->
+ </ul>
+ <!-- /TMPL_IF -->
+
+ <!-- TMPL_LOOP NAME="mainloop" -->
+
+ <table>
+ <tr>
+ <th><!-- TMPL_VAR name="line" --> / <!-- TMPL_VAR name="column" --></th>
+ <!-- TMPL_LOOP NAME="loopcol" -->
+ <th><!-- TMPL_VAR ESCAPE="HTML" NAME="coltitle_display" --></th>
+ <!-- /TMPL_LOOP -->
+ <th>TOTAL</th>
+ </tr>
+ <!-- TMPL_LOOP NAME="looprow" -->
+ <tr<!-- TMPL_UNLESS NAME="__odd__" --> class="highlight"<!-- /TMPL_UNLESS -->>
+ <td><!-- TMPL_VAR ESCAPE="HTML" NAME="rowtitle_display" DEFAULT="UNKNOWN VALUE" --></td>
+ <!-- TMPL_LOOP NAME="loopcell" -->
+ <td align="center">
+ <!--TMPL_IF Name="url_complement"--><a href="reserves_stats.pl?output=<!--TMPL_VAR Name=output-->&<!--TMPL_VAR Name="url_complement"-->"><!-- TMPL_VAR NAME="value" DEFAULT=" " --></a><!--TMPL_ELSE--><!-- TMPL_VAR NAME="value" DEFAULT=" " --><!--/TMPL_IF-->
+ </td>
+ <!-- /TMPL_LOOP -->
+ <td align="center"><!-- TMPL_VAR NAME="totalrow" --></td>
+ </tr>
+ <!-- /TMPL_LOOP -->
+ <tr>
+ <th>TOTAL</th>
+ <!-- TMPL_LOOP NAME="loopfooter" -->
+ <th><!-- TMPL_VAR NAME="totalcol" --></th>
+ <!-- /TMPL_LOOP -->
+ <th><!-- TMPL_VAR NAME="total" --></th>
+ </tr>
+ </table>
+ <!-- /TMPL_LOOP -->
+ <!-- /TMPL_IF -->
+<!-- TMPL_ELSE -->
+
+ <form method="post" action="/cgi-bin/koha/reports/reserves_stats.pl">
+ <fieldset class="rows">
+ <legend>Reserve statistics</legend><table>
+ <thead>
+ <tr>
+ <th>Title</th>
+ <th>Row</th>
+ <th>Column</th>
+ <th>Filter</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr >
+ <td>Reserve status </td>
+ <td><input type="radio" name="Line" value="reservestatus" /></td>
+ <td><input type="radio" name="Column" value="reservestatus" checked="checked" /></td>
+ <td>
+ <input type="checkbox" name="filter_reservestatus_or_1" value="1">Asked</input>
+ <input type="checkbox" name="filter_reservestatus_or_2" value="2"> Processing</input>
+ <input type="checkbox" name="filter_reservestatus_or_3" value="3">Waiting</input>
+ <input type="checkbox" name="filter_reservestatus_or_4" value="4">Satisfied</input>
+ <input type="checkbox" name="filter_reservestatus_or_5" value="5">cancelled</input>
+ </td>
+ </tr>
+ <tr class="highlight">
+ <td>reserve date</td>
+ <td><input type="radio" name="Line" value="reservedate" /></td>
+ <td><input type="radio" name="Column" value="reservedate" /></td>
+ <td><label for="reservedate_begin">From</label> <input type="text" size="10" id="filter_reservedate_begin" name="filter_reservedate_begin" />
+ <img src="<!-- TMPL_VAR Name="themelang" -->/lib/calendar/cal.gif" alt="Show Calendar" border="0" id="openreservedateFrom" style="cursor: pointer;" />
+ <script type="text/javascript">
+ //<![CDATA[
+ function validate1(date) {
+ var day = date.getDate();
+ var month = date.getMonth() + 1;
+ var year = date.getFullYear();
+ var weekDay = date.getDay();
+ var dayMonth = month + '-' + day;
+ var dateString = year + '-' + month + '-' + day;
+ var dateTo = document.getElementById('filter_reservedate_end').value.split("-");
+ var limitDate = new Date(dateTo[0], (dateTo[1] - 1), dateTo[2]);
+ if (date > limitDate) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+ Calendar.setup({
+ inputField : "filter_reservedate_begin",
+ ifFormat : "<!-- TMPL_VAR NAME="DHTMLcalendar_dateformat" -->",
+ button : "openreservedateFrom",
+ disableFunc : validate1,
+ dateStatusFunc : validate1
+ });
+ //]]>
+ </script>
+ <label for="filter_reservedate_end">To</label> <input size="10" id="filter_reservedate_end" name="filter_reservedate_end" value="" type="text" />
+ <img src="<!-- TMPL_VAR Name="themelang" -->/lib/calendar/cal.gif" alt="Show Calendar" id="openreservedateTo" style="cursor: pointer;" border="0" />
+ <script type="text/javascript">
+ //<![CDATA[
+ function validate2(date) {
+ var day = date.getDate();
+ var month = date.getMonth() + 1;
+ var year = date.getFullYear();
+ var weekDay = date.getDay();
+ var dayMonth = month + '-' + day;
+ var dateString = year + '-' + month + '-' + day;
+ var dateFrom = document.getElementById('filter_reservedate_begin').value.split("-");
+ var limitDate = new Date(dateFrom[0], (dateFrom[1] - 1), dateFrom[2]);
+ if (limitDate > date) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+ Calendar.setup({
+ inputField : "filter_reservedate_end",
+ ifFormat : "<!-- TMPL_VAR NAME="DHTMLcalendar_dateformat" -->",
+ button : "openreservedateTo",
+ disableFunc : validate2,
+ dateStatusFunc : validate2
+ });
+ //]]>
+ </script>
+ </td>
+ </tr>
+ <tr>
+ <td>notification date</td>
+ <td><input type="radio" name="Line" value="notificationdate" /></td>
+ <td><input type="radio" name="Column" value="notificationdate" /></td>
+ <td><label for="filter_notificationdate_begin">From</label> <input type="text" size="10" id="filter_notificationdate_begin" name="filter_notificationdate_begin" />
+ <img src="<!-- TMPL_VAR Name="themelang" -->/lib/calendar/cal.gif" alt="Show Calendar" border="0" id="opennotificationdateFrom" style="cursor: pointer;" />
+ <script type="text/javascript">
+ //<![CDATA[
+ function validate1(date) {
+ var day = date.getDate();
+ var month = date.getMonth() + 1;
+ var year = date.getFullYear();
+ var weekDay = date.getDay();
+ var dayMonth = month + '-' + day;
+ var dateString = year + '-' + month + '-' + day;
+ var dateTo = document.getElementById('filter_notificationdate_end').value.split("-");
+ var limitDate = new Date(dateTo[0], (dateTo[1] - 1), dateTo[2]);
+ if (date > limitDate) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+ Calendar.setup({
+ inputField : "filter_notificationdate_begin",
+ ifFormat : "<!-- TMPL_VAR NAME="DHTMLcalendar_dateformat" -->",
+ button : "opennotificationdateFrom",
+ disableFunc : validate1,
+ dateStatusFunc : validate1
+ });
+ //]]>
+ </script>
+ <label for="filter_notificationdate_end">To</label> <input size="10" id="filter_notificationdate_end" name="filter_notificationdate_end" value="" type="text" />
+ <img src="<!-- TMPL_VAR Name="themelang" -->/lib/calendar/cal.gif" alt="Show Calendar" id="opennotificationdateTo" style="cursor: pointer;" border="0" />
+ <script type="text/javascript">
+ //<![CDATA[
+ function validate2(date) {
+ var day = date.getDate();
+ var month = date.getMonth() + 1;
+ var year = date.getFullYear();
+ var weekDay = date.getDay();
+ var dayMonth = month + '-' + day;
+ var dateString = year + '-' + month + '-' + day;
+ var dateFrom = document.getElementById('filter_notificationdate_begin').value.split("-");
+ var limitDate = new Date(dateFrom[0], (dateFrom[1] - 1), dateFrom[2]);
+ if (limitDate > date) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+ Calendar.setup({
+ inputField : "filter_notificationdate_end",
+ ifFormat : "<!-- TMPL_VAR NAME="DHTMLcalendar_dateformat" -->",
+ button : "opennotificationdateTo",
+ disableFunc : validate2,
+ dateStatusFunc : validate2
+ });
+ //]]>
+ </script>
+ </td>
+ </tr>
+ <tr>
+ <td>Reminder date</td>
+ <td><input type="radio" name="Line" value="reminderdate" /></td>
+ <td><input type="radio" name="Column" value="reminderdate" /></td>
+ <td><label for="filter_reminderdate_begin">From</label> <input type="text" size="10" id="filter_reminderdate_begin" name="Filter" />
+ <img src="<!-- TMPL_VAR Name="themelang" -->/lib/calendar/cal.gif" alt="Show Calendar" border="0" id="openreminderdateFrom" style="cursor: pointer;" />
+ <script type="text/javascript">
+ //<![CDATA[
+ function validate1(date) {
+ var day = date.getDate();
+ var month = date.getMonth() + 1;
+ var year = date.getFullYear();
+ var weekDay = date.getDay();
+ var dayMonth = month + '-' + day;
+ var dateString = year + '-' + month + '-' + day;
+ var dateTo = document.getElementById('filter_reminderdate_end').value.split("-");
+ var limitDate = new Date(dateTo[0], (dateTo[1] - 1), dateTo[2]);
+ if (date > limitDate) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+ Calendar.setup({
+ inputField : "filter_reminderdate_begin",
+ ifFormat : "<!-- TMPL_VAR NAME="DHTMLcalendar_dateformat" -->",
+ button : "openreminderdateFrom",
+ disableFunc : validate1,
+ dateStatusFunc : validate1
+ });
+ //]]>
+ </script>
+ <label for="filter_reminderdate_end">To</label> <input size="10" id="filter_reminderdate_end" name="filter_reminderdate_end" value="" type="text" />
+ <img src="<!-- TMPL_VAR Name="themelang" -->/lib/calendar/cal.gif" alt="Show Calendar" id="openreminderdateTo" style="cursor: pointer;" border="0" />
+ <script type="text/javascript">
+ //<![CDATA[
+ function validate2(date) {
+ var day = date.getDate();
+ var month = date.getMonth() + 1;
+ var year = date.getFullYear();
+ var weekDay = date.getDay();
+ var dayMonth = month + '-' + day;
+ var dateString = year + '-' + month + '-' + day;
+ var dateFrom = document.getElementById('filter_reminderdate_begin').value.split("-");
+ var limitDate = new Date(dateFrom[0], (dateFrom[1] - 1), dateFrom[2]);
+ if (limitDate > date) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+ Calendar.setup({
+ inputField : "filter_reminderdate_end",
+ ifFormat : "<!-- TMPL_VAR NAME="DHTMLcalendar_dateformat" -->",
+ button : "openreminderdateTo",
+ disableFunc : validate2,
+ dateStatusFunc : validate2
+ });
+ //]]>
+ </script>
+ </td>
+ </tr>
+ <tr>
+ <td>Waiting date</td>
+ <td><input type="radio" name="Line" value="waitingdate" /></td>
+ <td><input type="radio" name="Column" value="waitingdate" /></td>
+ <td><label for="filter_waitingdate_begin">From</label> <input type="text" size="10" id="filter_waitingdate_begin" name="filter_waitingdate_begin" />
+ <img src="<!-- TMPL_VAR Name="themelang" -->/lib/calendar/cal.gif" alt="Show Calendar" border="0" id="openwaitingdateFrom" style="cursor: pointer;" />
+ <script type="text/javascript">
+ //<![CDATA[
+ function validate1(date) {
+ var day = date.getDate();
+ var month = date.getMonth() + 1;
+ var year = date.getFullYear();
+ var weekDay = date.getDay();
+ var dayMonth = month + '-' + day;
+ var dateString = year + '-' + month + '-' + day;
+ var dateTo = document.getElementById('filter_waitingdate_end').value.split("-");
+ var limitDate = new Date(dateTo[0], (dateTo[1] - 1), dateTo[2]);
+ if (date > limitDate) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+ Calendar.setup({
+ inputField : "filter_waitingdate_begin",
+ ifFormat : "<!-- TMPL_VAR NAME="DHTMLcalendar_dateformat" -->",
+ button : "openwaitingdateFrom",
+ disableFunc : validate1,
+ dateStatusFunc : validate1
+ });
+ //]]>
+ </script>
+ <label for="filter_waitingdate_end">To</label> <input size="10" id="filter_waitingdate_end" name="filter_waitingdate_end" value="" type="text" />
+ <img src="<!-- TMPL_VAR Name="themelang" -->/lib/calendar/cal.gif" alt="Show Calendar" id="openwaitingdateTo" style="cursor: pointer;" border="0" />
+ <script type="text/javascript">
+ //<![CDATA[
+ function validate2(date) {
+ var day = date.getDate();
+ var month = date.getMonth() + 1;
+ var year = date.getFullYear();
+ var weekDay = date.getDay();
+ var dayMonth = month + '-' + day;
+ var dateString = year + '-' + month + '-' + day;
+ var dateFrom = document.getElementById('filter_waitingdate_begin').value.split("-");
+ var limitDate = new Date(dateFrom[0], (dateFrom[1] - 1), dateFrom[2]);
+ if (limitDate > date) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+ Calendar.setup({
+ inputField : "filter_waitingdate_end",
+ ifFormat : "<!-- TMPL_VAR NAME="DHTMLcalendar_dateformat" -->",
+ button : "openwaitingdateTo",
+ disableFunc : validate2,
+ dateStatusFunc : validate2
+ });
+ //]]>
+ </script>
+ </td>
+ </tr>
+ <tr>
+ <td>cancellation date</td>
+ <td><input type="radio" name="Line" value="cancellationdate" /></td>
+ <td><input type="radio" name="Column" value="cancellationdate" /></td>
+ <td><label for="filter_cancellationdate_begin">From</label> <input type="text" size="10" id="filter_cancellationdate_begin" name="filter_cancellationdate_begin" />
+ <img src="<!-- TMPL_VAR Name="themelang" -->/lib/calendar/cal.gif" alt="Show Calendar" border="0" id="opencancellationdateFrom" style="cursor: pointer;" />
+ <script type="text/javascript">
+ //<![CDATA[
+ function validate1(date) {
+ var day = date.getDate();
+ var month = date.getMonth() + 1;
+ var year = date.getFullYear();
+ var weekDay = date.getDay();
+ var dayMonth = month + '-' + day;
+ var dateString = year + '-' + month + '-' + day;
+ var dateTo = document.getElementById('filter_cancellationdate_end').value.split("-");
+ var limitDate = new Date(dateTo[0], (dateTo[1] - 1), dateTo[2]);
+ if (date > limitDate) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+ Calendar.setup({
+ inputField : "filter_cancellationdate_begin",
+ ifFormat : "<!-- TMPL_VAR NAME="DHTMLcalendar_dateformat" -->",
+ button : "opencancellationdateFrom",
+ disableFunc : validate1,
+ dateStatusFunc : validate1
+ });
+ //]]>
+ </script>
+ <label for="filter_cancellationdate_end">To</label> <input size="10" id="filter_cancellationdate_end" name="filter_cancellationdate_end" value="" type="text" />
+ <img src="<!-- TMPL_VAR Name="themelang" -->/lib/calendar/cal.gif" alt="Show Calendar" id="opencancellationdateTo" style="cursor: pointer;" border="0" />
+ <script type="text/javascript">
+ //<![CDATA[
+ function validate2(date) {
+ var day = date.getDate();
+ var month = date.getMonth() + 1;
+ var year = date.getFullYear();
+ var weekDay = date.getDay();
+ var dayMonth = month + '-' + day;
+ var dateString = year + '-' + month + '-' + day;
+ var dateFrom = document.getElementById('filter_cancellationdate_begin').value.split("-");
+ var limitDate = new Date(dateFrom[0], (dateFrom[1] - 1), dateFrom[2]);
+ if (limitDate > date) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+ Calendar.setup({
+ inputField : "filter_cancellationdate_end",
+ ifFormat : "<!-- TMPL_VAR NAME="DHTMLcalendar_dateformat" -->",
+ button : "opencancellationdateTo",
+ disableFunc : validate2,
+ dateStatusFunc : validate2
+ });
+ //]]>
+ </script>
+ </td>
+ </tr>
+ <tr>
+ <td>Patron Category</td>
+ <td><input type="radio" name="Line" value="borrowers.categorycode" /></td>
+ <td><input type="radio" name="Column" value="borrowers.categorycode" /></td>
+ <td><select name="filter_categorycode" id="borcat">
+ <option value=""> </option>
+ <!-- TMPL_LOOP NAME="categoryloop" -->
+ <!-- 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 -->
+ <!-- /TMPL_LOOP -->
+ </select>
+ </td>
+ </tr>
+ <tr class="highlight">
+ <td>Item Type</td>
+ <td><input type="radio" name="Line" value="items.itype" /></td>
+ <td><input type="radio" name="Column" value="items.itype" /></td>
+ <td><select name="filter_items.itype" id="itype">
+ <option value=""> </option>
+ <!-- TMPL_LOOP NAME="itypeloop" -->
+ <!-- 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 -->
+ <!-- /TMPL_LOOP -->
+ </select>
+ </td>
+ </tr>
+ <tr>
+ <td>Pickup Library</td>
+ <td><input type="radio" name="Line" value="reserves.branchcode" checked="checked" /></td>
+ <td><input type="radio" name="Column" value="reserves.branchcode" /></td>
+ <td><select name="filter_reserves.branchcode" id="resbranchcode">
+ <option value=""> </option>
+ <!-- TMPL_LOOP NAME="branchloop" -->
+<!-- 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 -->
+ <!-- /TMPL_LOOP -->
+ </select>
+ </td>
+ </tr>
+ <tr class="highlight">
+ <td>Holding Library</td>
+ <td><input type="radio" name="Line" value="holdingbranch" /></td>
+ <td><input type="radio" name="Column" value="holdingbranch" /></td>
+ <td><select name="filter_holdingbranch" id="holdingbranch">
+ <option value=""> </option>
+ <!-- TMPL_LOOP NAME="branchloop" -->
+<!-- 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 -->
+ <!-- /TMPL_LOOP -->
+ </select>
+ </td>
+ </tr>
+ <tr>
+ <td>Home Library</td>
+ <td><input type="radio" name="Line" value="homebranch" /></td>
+ <td><input type="radio" name="Column" value="homebranch" /></td>
+ <td><select name="filter_homebranch" id="homebranch">
+ <option value=""> </option>
+ <!-- TMPL_LOOP NAME="branchloop" -->
+<!-- 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 -->
+ <!-- /TMPL_LOOP -->
+ </select>
+ </td>
+ </tr>
+ <tr class="highlight">
+ <td>Collection</td>
+ <td><input type="radio" name="Line" value="items.ccode" /></td>
+ <td><input type="radio" name="Column" value="items.ccode" /></td>
+ <td><select name="filter_items.ccode" id="ccode">
+ <option value=""> </option>
+ <!-- TMPL_LOOP NAME="ccodeloop" -->
+ <!-- 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 -->
+ <!-- /TMPL_LOOP -->
+ </select>
+ </td>
+ </tr>
+ <tr>
+ <td>Shelving Location</td>
+ <td><input type="radio" name="Line" value="items.location" /></td>
+ <td><input type="radio" name="Column" value="items.location" /></td>
+ <td><select name="filter_items.location" id="location">
+ <option value=""> </option>
+ <!-- TMPL_LOOP NAME="locationloop" -->
+ <!-- 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 -->
+ <!-- /TMPL_LOOP -->
+ </select>
+ </td>
+ </tr>
+ <tr class="highlight">
+ <td>Item Call Number</td>
+ <td></td>
+ <td></td>
+ <td>From <input type="text" name="filter_itemcallnumber" size="10" /> (inclusive) to <input type="text" name="fiter_itemcallnumber" size="10" /> (exclusive) </td>
+ </tr>
+ <!-- TMPL_IF Name="hassort1" -->
+ <tr><td>Patron sort1</td>
+ <td><input type="radio" name="Line" value="borrowers.sort1" /></td>
+ <td><input type="radio" name="Column" value="borrowers.sort1" /></td>
+ <td><select name="filter_borrowers.sort1" id="sort1">
+ <option value=""> </option>
+ <!-- TMPL_LOOP NAME="Bsort1" -->
+ <!-- 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 -->
+ <!-- /TMPL_LOOP -->
+ </select>
+ </td>
+ </tr>
+ <!-- /TMPL_IF -->
+ <!-- TMPL_IF Name="hassort2" -->
+ <tr class="highlight"><td>Patron sort2</td>
+ <td><input type="radio" name="Line" value="borrowers.sort2" /></td>
+ <td><input type="radio" name="Column" value="borrowers.sort2" /></td>
+ <td><select name="filter_borrowers.sort2" id="sort2">
+ <option value=""> </option>
+ <!-- TMPL_LOOP NAME="Bsort2" -->
+ <!-- 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 -->
+ <!-- /TMPL_LOOP -->
+ </select>
+ </td>
+ </tr>
+ <!-- /TMPL_IF -->
+ </tbody>
+ </table><br /></fieldset>
+
+<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>
+ <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>
+
+ <fieldset class="rows">
+ <legend>Output</legend>
+<ol><li><label for="outputscreen">To screen into the browser: </label><input type="radio" checked="checked" name="output" id="outputscreen" value="screen" /> </li>
+<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
+ </label><!-- TMPL_VAR NAME="CGIextChoice" -->
+ <!-- TMPL_VAR NAME="CGIsepChoice" --></li></ol>
+ </fieldset>
+
+ <fieldset class="action">
+ <input type="submit" value="Submit" />
+ <input type="hidden" name="report_name" value="<!--TMPL_VAR NAME="report_name" -->" />
+ <input type="hidden" name="do_it" value="1" />
+ </fieldset>
+ </form>
+<!-- /TMPL_IF -->
+
+</div>
+</div>
+<div class="yui-b">
+<!-- TMPL_INCLUDE NAME="reports-menu.inc" -->
+</div>
+</div>
+<!-- TMPL_INCLUDE NAME="intranet-bottom.inc" -->
--- /dev/null
+#!/usr/bin/perl
+
+
+# Copyright 2000-2002 Katipo Communications
+#
+# This file is part of Koha.
+#
+# Koha is free software; you can redistribute it and/or modify it under the
+# terms of the GNU General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at your option) any later
+# version.
+#
+# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along with
+# Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+# Suite 330, Boston, MA 02111-1307 USA
+
+use strict;
+
+use CGI;
+
+use C4::Auth;
+use C4::Debug;
+use C4::Context;
+use C4::Branch; # GetBranches
+use C4::Koha;
+use C4::Output;
+use C4::Reports;
+use C4::Members;
+use C4::Dates qw/format_date format_date_in_iso/;
+use C4::Category;
+use List::MoreUtils qw/any/;
+use YAML;
+
+=head1 NAME
+
+plugin that shows circulation stats
+
+=head1 DESCRIPTION
+
+=over 2
+
+=cut
+
+# my $debug = 1; # override for now.
+my $input = new CGI;
+my $fullreportname = "reports/reserves_stats.tmpl";
+my $do_it = $input->param('do_it');
+my $line = $input->param("Line");
+my $column = $input->param("Column");
+my $podsp = $input->param("DisplayBy");
+my $type = $input->param("PeriodTypeSel");
+my $daysel = $input->param("PeriodDaySel");
+my $monthsel = $input->param("PeriodMonthSel");
+my $calc = $input->param("Cellvalue");
+my $output = $input->param("output");
+my $basename = $input->param("basename");
+my $mime = $input->param("MIME");
+my $hash_params = $input->Vars;
+my $filter_hashref;
+foreach my $filter (grep {$_ =~/^filter/} keys %$hash_params){
+ my $filterstring=$filter;
+ $filterstring=~s/^filter_//g;
+ $$filter_hashref{$filterstring}=$$hash_params{$filter} if (defined $$hash_params{$filter} && $$hash_params{$filter} ne "");
+}
+my ($template, $borrowernumber, $cookie) = get_template_and_user({
+ template_name => $fullreportname,
+ query => $input,
+ type => "intranet",
+ authnotrequired => 0,
+ flagsrequired => {reports => '*'},
+ debug => 0,
+});
+our $sep = $input->param("sep");
+$sep = "\t" if ($sep eq 'tabulation');
+$template->param(do_it => $do_it,
+ DHTMLcalendar_dateformat => C4::Dates->DHTMLcalendar(),
+);
+
+my $itemtypes = GetItemTypes();
+my $categoryloop = GetBorrowercategoryList;
+
+my $ccodes = GetKohaAuthorisedValues("items.ccode");
+my $locations = GetKohaAuthorisedValues("items.location");
+my $authvalue = GetKohaAuthorisedValues("items.authvalue");
+
+my $Bsort1 = GetAuthorisedValues("Bsort1");
+my $Bsort2 = GetAuthorisedValues("Bsort2");
+my ($hassort1,$hassort2);
+$hassort1=1 if $Bsort1;
+$hassort2=1 if $Bsort2;
+
+
+if ($do_it) {
+# Displaying results
+ my $results = calculate($line, $column, $calc, $filter_hashref);
+ if ($output eq "screen"){
+# Printing results to screen
+ $template->param(mainloop => $results);
+ output_html_with_http_headers $input, $cookie, $template->output;
+ } else {
+# Printing to a csv file
+ print $input->header(-type => 'application/vnd.sun.xml.calc',
+ -encoding => 'utf-8',
+ -attachment=>"$basename.csv",
+ -filename=>"$basename.csv" );
+ my $cols = @$results[0]->{loopcol};
+ my $lines = @$results[0]->{looprow};
+# header top-right
+ print @$results[0]->{line} ."/". @$results[0]->{column} .$sep;
+# Other header
+ foreach my $col ( @$cols ) {
+ print $col->{coltitle}.$sep;
+ }
+ print "Total\n";
+# Table
+ foreach my $line ( @$lines ) {
+ my $x = $line->{loopcell};
+ print $line->{rowtitle}.$sep;
+ print map {$_->{value}.$sep} @$x;
+ print $line->{totalrow}, "\n";
+ }
+# footer
+ print "TOTAL";
+ $cols = @$results[0]->{loopfooter};
+ print map {$sep.$_->{totalcol}} @$cols;
+ print $sep.@$results[0]->{total};
+ }
+ exit(1); # exit either way after $do_it
+}
+
+my $dbh = C4::Context->dbh;
+my @values;
+my %labels;
+my %select;
+
+# create itemtype arrayref for <select>.
+my @itemtypeloop;
+for my $itype ( sort {$itemtypes->{$a}->{description} cmp $itemtypes->{$b}->{description}} keys(%$itemtypes)) {
+ push @itemtypeloop, { code => $itype , description => $itemtypes->{$itype}->{description} } ;
+}
+
+ # location list
+my @locations;
+foreach (sort keys %$locations) {
+ push @locations, { code => $_, description => "$_ - " . $locations->{$_} };
+}
+
+my @ccodes;
+foreach (sort {$ccodes->{$a} cmp $ccodes->{$b}} keys %$ccodes) {
+ push @ccodes, { code => $_, description => $ccodes->{$_} };
+}
+
+# various
+my @mime = (C4::Context->preference("MIME"));
+
+my $CGIextChoice=CGI::scrolling_list(
+ -name => 'MIME',
+ -id => 'MIME',
+ -values => \@mime,
+ -size => 1,
+ -multiple => 0 );
+
+my $CGIsepChoice=GetDelimiterChoices;
+
+$template->param(
+ categoryloop => $categoryloop,
+ itemtypeloop => \@itemtypeloop,
+ ccodeloop => \@ccodes,
+ branchloop => GetBranchesLoop(C4::Context->userenv->{'branch'}),
+ hassort1=> $hassort1,
+ hassort2=> $hassort2,
+ Bsort1 => $Bsort1,
+ Bsort2 => $Bsort2,
+ CGIextChoice => $CGIextChoice,
+ CGIsepChoice => $CGIsepChoice,
+);
+output_html_with_http_headers $input, $cookie, $template->output;
+
+sub calculate {
+ my ($linefield, $colfield, $process, $filters_hashref) = @_;
+ my @loopfooter;
+ my @loopcol;
+ my @loopline;
+ my @looprow;
+ my %globalline;
+ my $grantotal =0;
+# extract parameters
+ my $dbh = C4::Context->dbh;
+
+# Filters
+# Checking filters
+#
+ my @loopfilter;
+ foreach my $filter (keys %$filters_hashref){
+ $$filters_hashref{$filter} =~s/\*/%/;
+ $$filters_hashref{$filter} = format_date_in_iso($$filters_hashref{$_}) if ($_=~/date/);
+ }
+ #display
+ @loopfilter= map{{ crit=>$_ ,filter=>($_=~/date/?
+ format_date($$filters_hashref{$_})
+ :$$filters_hashref{$_}
+ )
+ }
+ } sort keys %$filters_hashref;
+
+
+
+
+ my $linesql=changeifreservestatus($linefield);
+ my $colsql=changeifreservestatus($colfield);
+ #Initialization of cell values.....
+
+ # preparing calculation
+ my $strcalc = "(SELECT $linesql line, $colsql col, ";
+ $strcalc .= ($process == 1) ? " COUNT(*) calculation" :
+ ($process == 2) ? "(COUNT(DISTINCT reserves.borrowernumber)) calculation" :
+ ($process == 3) ? "(COUNT(DISTINCT reserves.itemnumber)) calculation" :
+ ($process == 4) ? "(COUNT(DISTINCT reserves.biblionumber)) calculation" : '*';
+ $strcalc .= "
+ FROM reserves
+ LEFT JOIN borrowers USING (borrowernumber)
+ ";
+ $strcalc .= "LEFT JOIN biblio ON reserves.biblionumber=biblio.biblionumber "
+ if ($linefield =~ /^biblio\./ or $colfield =~ /^biblio\./ or any {$_=~/biblio/}keys %$filters_hashref);
+ $strcalc .= "LEFT JOIN items ON reserves.itemnumber=items.itemnumber "
+ if ($linefield =~ /^items\./ or $colfield =~ /^items\./ or any {$_=~/items/}keys %$filters_hashref);
+
+ my @sqlparams;
+ my @sqlorparams;
+ my @sqlor;
+ my @sqlwhere;
+ ($debug) and print STDERR Dump($filters_hashref);
+ foreach my $filter (keys %$filters_hashref){
+ my $string;
+ my $stringfield=$filter;
+ $stringfield=~s/\_[a-z_]+$//;
+ warn $stringfield;
+ if ($filter=~/ /){
+ $string=$stringfield;
+ }
+ elsif ($filter=~/_or/){
+ push @sqlor, qq{( }.changeifreservestatus($filter)." = ? ) ";
+ push @sqlorparams, $$filters_hashref{$filter};
+ }
+ elsif ($filter=~/_end$/){
+ $string = " $stringfield <= ? ";
+ }
+ elsif ($filter=~/_begin$/){
+ $string = " $stringfield >= ? ";
+ }
+ else {
+ $string = " $stringfield LIKE ? ";
+ }
+ if ($string){
+ push @sqlwhere, $string;
+ push @sqlparams, $$filters_hashref{$filter};
+ }
+ }
+
+ $strcalc .= " WHERE ".join(" AND ",@sqlwhere) if (@sqlwhere);
+ $strcalc .= " AND (".join(" OR ",@sqlor).")" if (@sqlor);
+ $strcalc .= " GROUP BY line, col )";
+ my $strcalc_old=$strcalc;
+ $strcalc_old=~s/reserves/old_reserves/g;
+ $strcalc.=qq{ UNION $strcalc_old ORDER BY line, col};
+ ($debug) and print STDERR $strcalc;
+ my $dbcalc = $dbh->prepare($strcalc);
+ push @loopfilter, {crit=>'SQL =', sql=>1, filter=>$strcalc};
+ @sqlparams=(@sqlparams,@sqlorparams);
+ $dbcalc->execute(@sqlparams,@sqlparams);
+ my ($emptycol,$emptyrow);
+ my $data = $dbcalc->fetchall_hashref([qw(line col)]);
+ my @loopline;
+ my %cols_hash;
+ foreach my $row (keys %$data){
+ push @loopline, $row;
+ foreach my $col (keys %{$$data{$row}}){
+ $$data{$row}{totalrow}+=$$data{$row}{$col}{calculation};
+ $grantotal+=$$data{$row}{$col}{calculation};
+ $cols_hash{$col}=1 ;
+ }
+ }
+ my $urlbase="do_it=1&".join("&",map{"filter_$_=$$filters_hashref{$_}"} keys %$filters_hashref);
+ foreach my $row (sort @loopline) {
+ my @loopcell;
+ #@loopcol ensures the order for columns is common with column titles
+ # and the number matches the number of columns
+ foreach my $col (sort keys %cols_hash) {
+ push @loopcell, {value =>( $$data{$row}{$col}{calculation} or ""),
+ # url_complement=>($urlbase=~/&$/?$urlbase."&":$urlbase)."filter_$linefield=$row&filter_$colfield=$col"
+ }
+ }
+ push @looprow, {
+ 'rowtitle_display' => display_value($linefield,$row),
+ 'rowtitle' => $row,
+ 'loopcell' => \@loopcell,
+ 'totalrow' => $$data{$row}{totalrow}
+ };
+ }
+ for my $col ( sort keys %cols_hash ) {
+ my $total = 0;
+ foreach my $row (@loopline) {
+ $total += $$data{$row}{$col}{calculation};
+ $debug and warn "value added ".$$data{$row}{$col}{calculation}. "for line ".$row;
+ }
+ push @loopfooter, {'totalcol' => $total};
+ push @loopcol, {'coltitle' => $col,
+ coltitle_display=>display_value($colfield,$col)};
+ }
+
+ # the header of the table
+ $globalline{loopfilter}=\@loopfilter;
+ # the core of the table
+ $globalline{looprow} = \@looprow;
+ $globalline{loopcol} = \@loopcol;
+ # # the foot (totals by borrower type)
+ $globalline{loopfooter} = \@loopfooter;
+ $globalline{total} = $grantotal;
+ $globalline{line} = $linefield;
+ $globalline{column} = $colfield;
+ return [(\%globalline)];
+}
+
+sub null_to_zzempty ($) {
+ my $string = shift;
+ defined($string) or return 'zzEMPTY';
+ ($string eq "NULL") and return 'zzEMPTY';
+ return $string; # else return the valid value
+}
+sub display_value{
+ my ($crit,$value)=@_;
+ my $display_value =
+ ($crit =~ /ccode/ ) ? $ccodes->{$value} :
+ ($crit =~ /location/) ? $locations->{$value} :
+ ($crit =~ /itemtype/) ? $itemtypes->{$value}->{description} :
+ ($crit =~ /branch/) ? GetBranchName($value):
+ ($crit =~ /reservestatus/) ? reservestatushuman($value):
+ $value; # default fallback
+ if ($crit =~ /(sort1|sort2)/) {
+ $display_value=GetAuthorisedValues("B$_",$value);
+ } elsif ($crit =~ /category/) {
+ my $element=any{$value eq $_->{categorycode}} @$categoryloop;
+ $display_value=$$element{description};
+ }
+ return $display_value;
+}
+sub reservestatushuman{
+ my ($val)=@_;
+ my %hashhuman=(
+ 1=>"1- placed",
+ 2=>"2- processed",
+ 3=>"3- pending",
+ 4=>"4- satisfied",
+ 5=>"5- cancelled",
+ 6=>"6- not a status"
+ );
+ $hashhuman{$val};
+}
+sub changeifreservestatus{
+ my ($val)=@_;
+ ($val=~/reservestatus/
+ ?$val=qq{ case
+ when priority>0 then 1
+ when priority=0 then
+ (case
+ when found='f' then 4
+ when found='w' then
+ (case
+ when cancellationdate is null then 3
+ else 5
+ end )
+ else 2
+ end )
+ else 6
+ end }
+ :$val);
+}
+1;