Bugzilla – Attachment 3306 Details for
Bug 5869
New report wizard for holds
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Initial Patch
0001-Bug-5869-Adding-a-reserve-report.patch (text/plain), 43.60 KB, created by
Chris Cormack
on 2011-03-15 23:49:26 UTC
(
hide
)
Description:
Initial Patch
Filename:
MIME Type:
Creator:
Chris Cormack
Created:
2011-03-15 23:49:26 UTC
Size:
43.60 KB
patch
obsolete
>From f17689719773a30e20f355cf4e5740d02f96c482 Mon Sep 17 00:00:00 2001 >From: Paul Poulain <paul.poulain@biblibre.com> >Date: Wed, 15 Dec 2010 00:03:38 +0100 >Subject: [PATCH] Bug 5869 : Adding a reserve report > >--- > .../prog/en/modules/reports/reports-home.tmpl | 1 + > .../prog/en/modules/reports/reserves_stats.tmpl | 549 ++++++++++++++++++++ > reports/reserves_stats.pl | 382 ++++++++++++++ > 3 files changed, 932 insertions(+), 0 deletions(-) > create mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/reports/reserves_stats.tmpl > create mode 100755 reports/reserves_stats.pl > >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/reports/reports-home.tmpl b/koha-tmpl/intranet-tmpl/prog/en/modules/reports/reports-home.tmpl >index b2d8487..7c6efae 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/reports/reports-home.tmpl >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/reports/reports-home.tmpl >@@ -34,6 +34,7 @@ > <li><a href="/cgi-bin/koha/reports/catalogue_stats.pl">Catalog</a></li> > <li><a href="/cgi-bin/koha/reports/issues_stats.pl">Circulation</a></li> > <li><a href="/cgi-bin/koha/reports/serials_stats.pl">Serials</a></li> >+ <li><a href="/cgi-bin/koha/reports/reserves_stats.pl">Reserves</a></li> > </ul></div> > > <div class="yui-u"><h2>Top Lists</h2> >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/reports/reserves_stats.tmpl b/koha-tmpl/intranet-tmpl/prog/en/modules/reports/reserves_stats.tmpl >new file mode 100644 >index 0000000..2b78133 >--- /dev/null >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/reports/reserves_stats.tmpl >@@ -0,0 +1,549 @@ >+<!-- 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" --> >diff --git a/reports/reserves_stats.pl b/reports/reserves_stats.pl >new file mode 100755 >index 0000000..93f2818 >--- /dev/null >+++ b/reports/reserves_stats.pl >@@ -0,0 +1,382 @@ >+#!/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; >-- >1.7.1 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 5869
: 3306 |
3307
|
3326
|
3327