Bug 10860: In-House Use
authorJonathan Druart <jonathan.druart@biblibre.com>
Wed, 18 Sep 2013 12:16:49 +0000 (14:16 +0200)
committerTomas Cohen Arazi <tomascohen@gmail.com>
Mon, 3 Nov 2014 13:26:19 +0000 (10:26 -0300)
This patch implements the In-House Use feature for Koha.

It adds:
- 2 new sysprefs:
  'In-House Use' to enable/disable this feature
  'In-House Use Forced' to enable/disable the feature for *all* users.
- 2 new columns issues.inhouse_use and old_issues.inhouse_use
- Datatable on the circulation history pages (readingrec) at the OPAC
  and the intranet.

A new checkbox in the Circulation tab. If checked, the issue become a
in-house use (in the statistics and issues tables).
When you check it, the due date changes to the today date.

The syspref "In-House Use Force" allows to force the in-house use to
permit the checkout even if the borrower is debarred or others problems.

In the issue table, a new string (in red) marks the issue as "in-house use".

The circulation history contains 3 tabs : "all", "checkout" and
"in-house use" (OPAC and intranet).

The cronjob script:
If AutomaticItemReturn if off, a library would like not to do a transit
operation manually. This script (to launch each night) do returns
for a specific branches.

Test plan:
1/ Execute the updatedatabase entry
2/ Enable the 'In-House Use' pref.
3/ Checkout a biblio for a patron and check the 'in-house use' checkbox.
4/ Check that the due date is the today date (with 23:59) and is not modifiable.
5/ Click on the check out button and check that the new check out
appears in the table bellow with the "(In-house use)" string.
6/ Go on the circulation history pages (readingrec and opac-readingrec)
and try the 3 tabs. In the last one, your last checkout should appear.
7/ Check in.
8/ Check readingrec pages.
9/ Choose a debarred patron and check that you cannot checkout a biblio
for him.
10/ Switch on the 'In-House Use Forced' pref
11/ You are now allowed to checkout a biblio for the debarred patron.

Signed-off-by: Chris Cormack <chris@bigballofwax.co.nz>
Signed-off-by: Tomas Cohen Arazi <tomascohen@gmail.com>
19 files changed:
C4/Circulation.pm
C4/Items.pm
C4/Stats.pm
circ/circulation.pl
installer/data/mysql/kohastructure.sql
installer/data/mysql/sysprefs.sql
installer/data/mysql/updatedatabase.pl
koha-tmpl/intranet-tmpl/prog/en/css/staff-global.css
koha-tmpl/intranet-tmpl/prog/en/includes/strings.inc
koha-tmpl/intranet-tmpl/prog/en/js/checkouts.js
koha-tmpl/intranet-tmpl/prog/en/js/pages/circulation.js
koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref
koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt
koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt
koha-tmpl/intranet-tmpl/prog/en/modules/members/readingrec.tt
koha-tmpl/opac-tmpl/bootstrap/css/datatables.css
koha-tmpl/opac-tmpl/bootstrap/en/includes/item-status.inc
koha-tmpl/opac-tmpl/bootstrap/js/datatables.js
svc/checkouts

index 76b6652..5caa929 100644 (file)
@@ -1188,9 +1188,13 @@ AddIssue does the following things :
 =cut
 
 sub AddIssue {
-    my ( $borrower, $barcode, $datedue, $cancelreserve, $issuedate, $sipmode, $auto_renew ) = @_;
+    my ( $borrower, $barcode, $datedue, $cancelreserve, $issuedate, $sipmode, $params ) = @_;
+    my $inhouse_use = $params->{inhouse_use};
+    my $auto_renew = $params->{auto_renew};
     my $dbh = C4::Context->dbh;
-       my $barcodecheck=CheckValidBarcode($barcode);
+    my $barcodecheck=CheckValidBarcode($barcode);
+    $inhouse_use = ( $inhouse_use ? 1 : 0 );
+
     if ($datedue && ref $datedue ne 'DateTime') {
         $datedue = dt_from_string($datedue);
     }
@@ -1264,8 +1268,8 @@ sub AddIssue {
         my $sth =
           $dbh->prepare(
                 "INSERT INTO issues
-                    (borrowernumber, itemnumber,issuedate, date_due, branchcode, auto_renew)
-                VALUES (?,?,?,?,?,?)"
+                    (borrowernumber, itemnumber,issuedate, date_due, branchcode, inhouse_use, auto_renew)
+                VALUES (?,?,?,?,?,?,?)"
           );
         unless ($datedue) {
             my $itype = ( C4::Context->preference('item-level_itypes') ) ? $biblio->{'itype'} : $biblio->{'itemtype'};
@@ -1273,12 +1277,14 @@ sub AddIssue {
 
         }
         $datedue->truncate( to => 'minute');
+
         $sth->execute(
             $borrower->{'borrowernumber'},      # borrowernumber
             $item->{'itemnumber'},              # itemnumber
             $issuedate->strftime('%Y-%m-%d %H:%M:00'), # issuedate
             $datedue->strftime('%Y-%m-%d %H:%M:00'),   # date_due
             C4::Context->userenv->{'branch'},   # branchcode
+            $inhouse_use,
             $auto_renew ? 1 : 0                 # automatic renewal
         );
         if ( C4::Context->preference('ReturnToShelvingCart') ) { ## ReturnToShelvingCart is on, anything issued should be taken off the cart.
@@ -1320,7 +1326,7 @@ sub AddIssue {
         # Record the fact that this book was issued.
         &UpdateStats({
                       branch => C4::Context->userenv->{'branch'},
-                      type => 'issue',
+                      type => ( $inhouse_use ? 'inhouse_use' : 'issue' ),
                       amount => $charge,
                       other => ($sipmode ? "SIP-$sipmode" : ''),
                       itemnumber => $item->{'itemnumber'},
index c23b272..6085960 100644 (file)
@@ -1299,6 +1299,10 @@ sub GetItemsInfo {
            holding.branchname,
            holding.opac_info as holding_branch_opac_info,
            home.opac_info as home_branch_opac_info
+    ";
+    $query .= ", issues.inhouse_use"
+        if C4::Context->preference("In-House Use");
+    $query .= "
      FROM items
      LEFT JOIN branches AS holding ON items.holdingbranch = holding.branchcode
      LEFT JOIN branches AS home ON items.homebranch=home.branchcode
@@ -1306,6 +1310,8 @@ sub GetItemsInfo {
      LEFT JOIN biblioitems ON biblioitems.biblioitemnumber = items.biblioitemnumber
      LEFT JOIN itemtypes   ON   itemtypes.itemtype         = "
      . (C4::Context->preference('item-level_itypes') ? 'items.itype' : 'biblioitems.itemtype');
+    $query .= " LEFT JOIN issues ON issues.itemnumber = items.itemnumber"
+        if C4::Context->preference("In-House Use");
     $query .= " WHERE items.biblionumber = ? ORDER BY home.branchname, items.enumchron, LPAD( items.copynumber, 8, '0' ), items.dateaccessioned DESC" ;
     my $sth = $dbh->prepare($query);
     $sth->execute($biblionumber);
index a1098ae..250c48c 100644 (file)
@@ -87,7 +87,7 @@ sub UpdateStats {
     return () if ! defined $params;
 # change these arrays if new types of transaction or new parameters are allowed
     my @allowed_keys = qw (type branch amount other itemnumber itemtype borrowernumber accountno ccode);
-    my @allowed_circulation_types = qw (renew issue localuse return);
+    my @allowed_circulation_types = qw (renew issue localuse return inhouse_use);
     my @allowed_accounts_types = qw (writeoff payment);
     my @circulation_mandatory_keys = qw (type branch borrowernumber itemnumber ccode itemtype);
     my @accounts_mandatory_keys = qw (type branch borrowernumber amount);
index c920787..e617a36 100755 (executable)
@@ -25,6 +25,8 @@
 use strict;
 use warnings;
 use CGI;
+use DateTime;
+use DateTime::Duration;
 use C4::Output;
 use C4::Print;
 use C4::Auth qw/:DEFAULT get_session haspermission/;
@@ -334,13 +336,15 @@ if ($barcode) {
         }
     }
 
-    delete $question->{'DEBT'} if ($debt_confirmed);
-    foreach my $impossible ( keys %$error ) {
-        $template->param(
-            $impossible => $$error{$impossible},
-            IMPOSSIBLE  => 1
-        );
-        $blocker = 1;
+    unless( $query->param('inhouse_use') and C4::Context->preference("In-House Use Force") ) {
+        delete $question->{'DEBT'} if ($debt_confirmed);
+        foreach my $impossible ( keys %$error ) {
+            $template->param(
+                $impossible => $$error{$impossible},
+                IMPOSSIBLE  => 1
+            );
+            $blocker = 1;
+        }
     }
     if( !$blocker || $force_allow_issue ){
         my $confirm_required = 0;
@@ -356,13 +360,15 @@ if ($barcode) {
                     $needsconfirmation => $$question{$needsconfirmation},
                     getTitleMessageIteminfo => $getmessageiteminfo->{'title'},
                     getBarcodeMessageIteminfo => $getmessageiteminfo->{'barcode'},
-                    NEEDSCONFIRMATION  => 1
+                    NEEDSCONFIRMATION  => 1,
+                    inhouse_use => $query->param('inhouse_use'),
                 );
                 $confirm_required = 1;
             }
         }
         unless($confirm_required) {
-            AddIssue( $borrower, $barcode, $datedue, $cancelreserve, undef, undef, $session->param('auto_renew') );
+            my $inhouse_use = $query->param('inhouse_use');
+            AddIssue( $borrower, $barcode, $datedue, $cancelreserve, undef, undef, { inhouse_use => $inhouse_use, auto_renew => $session->param('auto_renew') } );
             $session->clear('auto_renew');
             $inprocess = 1;
         }
@@ -594,6 +600,9 @@ $template->param(
     export_with_csv_profile   => C4::Context->preference("ExportWithCsvProfile"),
     canned_bor_notes_loop     => $canned_notes,
     debarments                => GetDebarments({ borrowernumber => $borrowernumber }),
+    todaysdate                => dt_from_string()->set(hour => 23)->set(minute => 59),
+    inhouse_use_feature       => C4::Context->preference("In-House Use"),
+    inhouse_use_forced        => C4::Context->preference("In-House Use Force"),
 );
 
 output_html_with_http_headers $query, $cookie, $template->output;
index b135e21..5df2dea 100644 (file)
@@ -1128,6 +1128,7 @@ CREATE TABLE `issues` ( -- information related to check outs or issues
   `auto_renew` BOOLEAN default FALSE, -- automatic renewal
   `timestamp` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP, -- the date and time this record was last touched
   `issuedate` datetime default NULL, -- date the item was checked out or issued
+  `inhouse_use` int(1) NOT NULL default 0, -- in house use flag
   KEY `issuesborridx` (`borrowernumber`),
   KEY `itemnumber_idx` (`itemnumber`),
   KEY `branchcode_idx` (`branchcode`),
@@ -1601,6 +1602,7 @@ CREATE TABLE `old_issues` ( -- lists items that were checked out and have been r
   `auto_renew` BOOLEAN default FALSE, -- automatic renewal
   `timestamp` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP, -- the date and time this record was last touched
   `issuedate` datetime default NULL, -- date the item was checked out or issued
+  `inhouse_use` int(1) NOT NULL default 0, -- in house use flag
   KEY `old_issuesborridx` (`borrowernumber`),
   KEY `old_issuesitemidx` (`itemnumber`),
   KEY `branchcode_idx` (`branchcode`),
index efd12fd..fb55827 100644 (file)
@@ -147,6 +147,8 @@ INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, `
 ('ImageLimit','5','','Limit images stored in the database by the Patron Card image manager to this number.','Integer'),
 ('IncludeSeeFromInSearches','0','','Include see-from references in searches.','YesNo'),
 ('IndependentBranches','0',NULL,'If ON, increases security between libraries','YesNo'),
+('In-House use','0','','Enable/Disable the in-house use feature','YesNo'),
+('In-House use Force','0','','Enable/Disable the in-house for all cases (Even if a user is debarred, etc.)','YesNo'),
 ('InProcessingToShelvingCart','0','','If set, when any item with a location code of PROC is \'checked in\', it\'s location code will be changed to CART.','YesNo'),
 ('INTRAdidyoumean',NULL,NULL,'Did you mean? configuration for the Intranet. Do not change, as this is controlled by /cgi-bin/koha/admin/didyoumean.pl.','Free'),
 ('IntranetBiblioDefaultView','normal','normal|marc|isbd|labeled_marc','Choose the default detail view in the staff interface; choose between normal, labeled_marc, marc or isbd','Choice'),
index 7e54990..e42237a 100755 (executable)
@@ -8949,6 +8949,28 @@ if ( CheckVersion($DBversion) ) {
         ADD COLUMN cancellationreason TEXT DEFAULT NULL AFTER datecancellationprinted
     ");
     print "Upgrade to $DBversion done (Bug 7162: Add aqorders.cancellationreason)\n";
+    SetVersion ($DBversion);
+}
+
+$DBversion = "3.17.00.XXX";
+if ( C4::Context->preference("Version") < TransformToNum($DBversion) ) {
+    $dbh->do(q{
+        INSERT IGNORE INTO systempreferences
+            (variable,value,explanation,options,type)
+            VALUES('In-House use','0','Enable/Disable the in-house use feature','','YesNo');
+    });
+    $dbh->do(q{
+        INSERT IGNORE INTO systempreferences
+            (variable,value,explanation,options,type)
+            VALUES('In-House use Force','0','Enable/Disable the in-house for all cases (Even if a user is debarred, etc.)','','YesNo');
+    });
+    $dbh->do(q{
+        ALTER TABLE issues ADD COLUMN inhouse_use INT(1) NOT NULL DEFAULT 0 AFTER issuedate;
+    });
+    $dbh->do(q{
+        ALTER TABLE old_issues ADD COLUMN inhouse_use INT(1) NOT NULL DEFAULT 0 AFTER issuedate;
+    });
+    print "Upgrade to $DBversion done (Bug 10860: Add new system preference In-House use + fields [old_]issues.inhouse_use)\n";
     SetVersion($DBversion);
 }
 
index 0f67416..a256db3 100644 (file)
@@ -2714,3 +2714,17 @@ span.browse-button {
 #i18nMenu .dropdown-menu a:focus {
     color : #FFF;
 }
+
+.inhouse_use-select {
+    font-size : 85%;
+    font-weight: normal;
+    padding-top : .3em;
+}
+#circ_circulation_issue .inhouse_use-select label,
+.inhouse_use-select label {
+    font-size : inherit;
+    font-weight: normal;
+}
+span.inhouse_use {
+    color: red;
+}
index fd6ee49..eb75ac1 100644 (file)
@@ -26,5 +26,6 @@
     var NOT_TRANSFERRED_YET = _("Item hasn't been transferred yet from %s");
     var NO = _("No");
     var YES = _("Yes");
+    var INHOUSE_USE = _("In-house use");
 //]]>
 </script>
index 749a3f7..4c0ba36 100644 (file)
@@ -215,6 +215,11 @@ $(document).ready(function() {
                             title += " - <span class='" + span_class + "'>" + oObj.itemnotes + "</span>"
                         }
 
+                        var inhouse_use = '';
+                        if ( oObj.inhouse_use == 1 ) {
+                            inhouse_use += " <span class='inhouse_use'>(" + INHOUSE_USE + ")</span>";
+                        }
+
                         title += " "
                               + "<a href='/cgi-bin/koha/catalogue/moredetail.pl?biblionumber="
                               + oObj.biblionumber
@@ -224,7 +229,8 @@ $(document).ready(function() {
                               + oObj.itemnumber
                               + "'>"
                               + oObj.barcode
-                              + "</a>";
+                              + "</a>"
+                              + inhouse_use;
 
                         return title;
                     }
@@ -305,7 +311,7 @@ $(document).ready(function() {
                                 +  "<input type='checkbox' class='renew' id='renew_" + oObj.itemnumber + "' name='renew' value='" + oObj.itemnumber +"'/>"
                                 +  "</span>";
 
-                        if ( oObj.renewals_remaining ) {
+                        if ( oObj.renewals_remaining && inhouse_use == 0 ) {
                             content += "<span class='renewals'>("
                                     + RENEWALS_REMAINING.format( oObj.renewals_remaining, oObj.renewals_allowed )
                                     + ")</span>";
@@ -313,7 +319,6 @@ $(document).ready(function() {
 
                         content += "</span>";
 
-
                         return content;
                     }
                 },
@@ -437,6 +442,11 @@ $(document).ready(function() {
                                 title += " - <span class='" + span_class + "'>" + oObj.itemnotes + "</span>"
                             }
 
+                            var inhouse_use = '';
+                            if ( oObj.inhouse_use == 1 ) {
+                                inhouse_use += " <span class='inhouse_use'>("+INHOUSE_USE+")</span>";
+                            }
+
                             title += " "
                                   + "<a href='/cgi-bin/koha/catalogue/moredetail.pl?biblionumber="
                                   + oObj.biblionumber
@@ -446,7 +456,8 @@ $(document).ready(function() {
                                   + oObj.itemnumber
                                   + "'>"
                                   + oObj.barcode
-                                  + "</a>";
+                                  + "</a>"
+                                  + inhouse_use;
 
                             return title;
                         }
index aa3fd43..e6ac3e8 100644 (file)
@@ -46,6 +46,10 @@ $(document).ready(function() {
         return false;
     });
 
+    toggle_inhouse_use();
+    $("#inhouse_use").click(function(){
+        toggle_inhouse_use();
+    });
 });
 
 function export_checkouts(format) {
index 2190004..07c86c5 100644 (file)
@@ -383,6 +383,18 @@ Circulation:
             - This is a list of value pairs. When an item is checked in, if the not for loan value on the left matches the items not for loan value
             - "it will be updated to the right-hand value. E.g. '-1: 0' will cause an item that was set to 'Ordered' to now be available for loan."
             - Each pair of values should be on a separate line.
+        -
+            - pref: In-House use
+              choices:
+                  yes: Enable
+                  no: Disable
+            - the in-house use feature.
+        -
+            - pref: In-House use Force
+              choices:
+                  yes: Enable
+                  no: Disable
+            - the in-house for all cases (Even if a user is debarred, etc.).
     Holds Policy:
         -
             - pref: AllowHoldPolicyOverride
index e10d95f..68f2bcd 100644 (file)
@@ -586,9 +586,17 @@ function verify_images() {
                     <td class="status">
 
                         [% IF ( item.datedue ) %]
+                          [% IF inhouse_use %]
+                            <span>Currently in local use
+                          [% ELSE %]
                             <span class="datedue">Checked out
+                          [% END %]
                                 [% UNLESS ( item.NOTSAMEBRANCH ) %]
+                                  [% IF inhouse_use %]
+                                    by <a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% item.borrowernumber %]">
+                                  [% ELSE %]
                                     to <a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% item.borrowernumber %]">
+                                  [% END %]
                                         [% IF ( item.hidepatronname ) %]
                                             [% item.cardnumber %]
                                         [% ELSE %]
index ca492ef..b506241 100644 (file)
@@ -55,6 +55,21 @@ $(document).ready(function() {
         });
     [% END %]
 });
+
+// In-house use
+function toggle_inhouse_use(){
+    if ( $("#inhouse_use").attr('checked') ) {
+        $("#duedatespec").val("[% todaysdate | $KohaDates with_hours => 1%]")
+        $("#duedatespec").datetimepicker('destroy');
+    } else {
+        $("#duedatespec").datetimepicker({
+            onClose: function(dateText, inst) { $("#barcode").focus(); },
+            hour: 23,
+            minute: 59
+        });
+    }
+}
+
 //]]>
 </script>
 </head>
@@ -289,6 +304,7 @@ $(document).ready(function() {
     [% ELSE %]
     <input type="submit" class="approve" value="Yes, check out (Y)" accesskey="y" />
     [% END %]
+    <input type="hidden" name="inhouse_use" value="[% inhouse_use %]" />
 </form>
 [% END %]
 
@@ -483,7 +499,7 @@ No patron matched <span class="ex">[% message %]</span>
 
 [% IF ( borrowernumber ) %]
 <div class="yui-g">
-[% UNLESS ( noissues ) %]
+[% IF !noissues || inhouse_use_forced %]
 [% IF ( flagged ) %]
 <div class="yui-u first">
 [% ELSE %]
@@ -532,6 +548,18 @@ No patron matched <span class="ex">[% message %]</span>
 [% END %]
           <button class="btn btn-small action" id="cleardate" name="cleardate" onclick="this.checked = false; this.form.duedatespec.value = ''; this.form.stickyduedate.checked = false; this.form.barcode.focus(); return false;" >Clear</button>
 </div>[% END %]
+
+      [% IF inhouse_use_feature %]
+        <div class="inhouse_use-select">
+          [% IF noissues %]
+            <input type="checkbox" id="inhouse_use" name="inhouse_use_forced" checked="checked" disabled="disabled" /> <label for="inhouse_use">In-house use</label>
+            <input type="hidden" name="inhouse_use" checked="checked" value="1" />
+          [% ELSE %]
+            <input type="checkbox" id="inhouse_use" name="inhouse_use" /> <label for="inhouse_use">In-house use</label>
+          [% END %]
+        </div>
+      [% END %]
+
           <input type="hidden" name="borrowernumber" id="borrowernumber" value="[% borrowernumber %]" />
           <input type="hidden" name="branch" value="[% branch %]" />
           <input type="hidden" name="printer" value="[% printer %]" />
@@ -546,18 +574,23 @@ No patron matched <span class="ex">[% message %]</span>
 
 [% IF ( noissues ) %]<div>[% ELSE %]<div class="yui-u">[% END %]
 
-    [% IF ( flagged ) %]
-               [% IF ( noissues ) %]
-               <h4>Checking out to [% INCLUDE 'patron-title.inc' %]</h4>
-        <div id="circmessages" class="circmessage warning">
-               [% ELSE %]
+    [% IF flagged %]
+      [% IF NOT noissues || ( noissues && inhouse_use_forced ) %]
         <div id="circmessages" class="circmessage attention">
-               [% END %]
-
-               <h3>[% IF ( noissues ) %]
-                       Cannot check out!
-               [% ELSE %]Attention:[% END %]</h3>
-
+      [% ELSE %]
+        <h4>Checking out to [% INCLUDE 'patron-title.inc' %]</h4>
+        <div id="circmessages" class="circmessage warning">
+      [% END %]
+      <h3>
+        [% IF noissues %]
+          Cannot check out!
+          [% IF inhouse_use_forced %]
+            <span style="color:red;">Only in-house use is allowed</span>
+          [% END %]
+        [% ELSE %]
+          Attention:
+        [% END %]
+      </h3>
 
                <ul>
 
index 5460ea0..8cd23ef 100644 (file)
@@ -8,7 +8,7 @@
 //<![CDATA[
 
  $(document).ready(function() {
-    $("#table_readingrec").dataTable($.extend(true, {}, dataTablesDefaults, {
+    var table = $("#table_readingrec").dataTable($.extend(true, {}, dataTablesDefaults, {
         "sPaginationType": "four_button",
         "aaSorting": [],
         "aoColumnDefs": [
             { "sType": "title-string", "aTargets" : [ "title-string" ] }
         ]
     }));
+    var tabs = $("#tabs").tabs({
+        select: function(e, ui) {
+            var id = $(ui.tab).attr("id");
+            if ( id == "tab_checkout" ) {
+                table.fnFilter("checkout", 0);
+            } else if ( id == "tab_inhouse_use" ) {
+                table.fnFilter("inhouse_use", 0);
+            } else { // all
+                table.fnFilter('', 0);
+            }
+        }
+    });
  });
 //]]>
 </script>
 <form action="/cgi-bin/koha/members/readingrec.pl" method="get"><input type="hidden" name="borrowernumber" id="borrowernumber" value="[% borrowernumber %]" /></form>
 
 
-<table id="table_readingrec">
-<thead>
-    <tr>
-    <th class="title-string">Date</th>
-    <th class="anti-the">Title</th>
-       <th>Author</th>
-    <th>Call no.</th>
-       <th>Barcode</th>
-    <th>Number of renewals</th>
-    <th class="title-string">Checked out on</th>
-       <th>Checked out from</th>
-    <th class="title-string">Date due</th>
-    <th class="title-string">Return date</th>
-    </tr>
-</thead>
-<tbody>
-[% FOREACH issue IN loop_reading %]
-    [% IF  issue.returndate  %]<tr>[% ELSE %]<tr class="onissue">[% END %]
-        <td>
+<div id="tabs" class="toptabs">
+  <ul>
+    <li><a href="#readingrec" id="tab_all">All</a></li>
+    <li><a href="#readingrec" id="tab_checkout">Checkouts</a></li>
+    <li><a href="#readingrec" id="tab_inhouse_use">In-house use</a></li>
+  </ul>
+  <div id="readingrec" style="overflow:hidden">
+    <table id="table_readingrec">
+      <thead>
+        <th style="display:none;">Type</th>
+        <th class="title-string">Date</th>
+        <th class="anti-the">Title</th>
+        <th>Author</th>
+        <th>Call no.</th>
+        <th>Barcode</th>
+        <th>Number of renewals</th>
+        <th class="title-string">Checked out on</th>
+        <th>Checked out from</th>
+        <th class="title-string">Date due</th>
+        <th class="title-string">Return date</th>
+      </thead>
+      <tbody>
+      [% FOREACH issue IN loop_reading %]
+        [% IF  issue.returndate  %]<tr>[% ELSE %]<tr class="onissue">[% END %]
+          <td style="display:none;">
+            [% IF issue.inhouse_use %]
+              inhouse_use
+            [% ELSE %]
+              checkout
+            [% END %]
+          </td>
+          <td>
             <span title="[% issue.issuestimestamp %]">[% issue.issuestimestamp | $KohaDates %]</span>
-        </td>
-        <td><a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=[% issue.biblionumber %]">[% issue.title |html %]</a></td>
+          </td>
+          <td><a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=[% issue.biblionumber %]">[% issue.title |html %]</a></td>
 
-        <td>[% issue.author %]</td>
+          <td>[% issue.author %]</td>
 
-        <td>
+          <td>
             [% IF issue.classification %]
                 [% issue.classification %]
             [% ELSE %]
                 [% issue.itemcallnumber %]
             [% END %]
-       </td>
-
-        <td>[% issue.barcode %]</td>
+          </td>
 
-            <td>
-        [% issue.renewals %]</td>
-            <td>
-                <span title="[% issue.issuedate %]">[% issue.issuedate | $KohaDates %]</span></td>
-            <td>
-        [% issue.issuingbranch %]</td>
-                       <td>[% IF issue.date_due %]
-                    <span title="[% issue.date_due %]">[% issue.date_due | $KohaDates %]</span>
-                [% ELSE %]
-                    <span title="0000-00-00"></span>
-                [% END %]
-            </td>
-            <td>
-                [% IF  issue.returndate %]
-                    <span title="[% issue.returndate %]">[% issue.returndate | $KohaDates %]</span>
-                [% ELSE %]
-                    <span title="Checked Out"><small>Checked out</small></span>
-                [% END %]
-            </td>
-</tr>
-[% END %]
-</tbody>
-</table>
+          <td>[% issue.barcode %]</td>
+          <td>[% issue.renewals %]</td>
+          <td>
+            <span title="[% issue.issuedate %]">[% issue.issuedate | $KohaDates %]</span></td>
+          </td>
+          <td>[% issue.issuedate | $KohaDates %]</td>
+          <td>[% issue.issuingbranch %]</td>
+          <td>
+            [% IF issue.date_due %]
+                <span title="[% issue.date_due %]">[% issue.date_due | $KohaDates %]</span>
+            [% ELSE %]
+                <span title="0000-00-00"></span>
+            [% END %]
+          </td>
+          <td>
+            [% IF  issue.returndate %]
+              <span title="[% issue.returndate %]">[% issue.returndate | $KohaDates %]</span>
+            [% ELSE %]
+              <span title="Checked Out"><small>Checked Out</small></span>
+            [% END %]
+          </td>
+        </tr>
+      [% END %]
+      </tbody>
+    </table>
+  </div>
+</div>
 [% END %]
 </div>
 </div>
index e7b11bd..5669543 100644 (file)
@@ -3,23 +3,23 @@ input.search_init {
 }
 .sorting_asc {
     padding-right: 19px;
-    background: url("../../img/asc.gif") no-repeat scroll right center #EEEEEE;
+    background: url("../../images/asc.gif") no-repeat scroll right center #EEEEEE;
 }
 .sorting_desc {
     padding-right: 19px;
-    background: url("../../img/desc.gif") no-repeat scroll right center #EEEEEE;
+    background: url("../../images/desc.gif") no-repeat scroll right center #EEEEEE;
 }
 .sorting {
     padding-right: 19px;
-    background: url("../../img/ascdesc.gif") no-repeat scroll right center #EEEEEE;
+    background: url("../../images/ascdesc.gif") no-repeat scroll right center #EEEEEE;
 }
 .sorting_asc_disabled {
     padding-right: 19px;
-    background: url("../../img/datatables/sort_asc_disabled.png") no-repeat scroll right center #EEEEEE;
+    background: url("../../images/datatables/sort_asc_disabled.png") no-repeat scroll right center #EEEEEE;
 }
 .sorting_desc_disabled {
     padding-right: 19px;
-    background: url("../../img/datatables/sort_desc_disabled.png") no-repeat scroll right center #EEEEEE;
+    background: url("../../images/datatables/sort_desc_disabled.png") no-repeat scroll right center #EEEEEE;
 }
 .sorting_disabled {
     padding-right: 19px;
@@ -64,12 +64,11 @@ div.dataTables_filter {
 }
 div.dataTables_paginate {
     background-color : #F4F4F4;
-    font-size: 110%;
     padding : 0;
 }
 
-.paging_full_numbers span.paginate_button,
-.paging_full_numbers span.paginate_active {
+.paging_full_numbers a.paginate_button,
+.paging_full_numbers a.paginate_active {
     border-right : 1px solid #AAA;
     border-left : 1px solid #FFF;
     display : block;
@@ -79,48 +78,48 @@ div.dataTables_paginate {
     cursor: pointer;
 }
 
-.paging_full_numbers span.paginate_button {
+.paging_full_numbers a.paginate_button {
     color : #0000CC;
 }
-.paging_full_numbers span.paginate_button.first {
-    background-image : url('../../img/first.png');
+.paging_full_numbers a.paginate_button.first {
+    background-image : url('../../images/first.png');
     background-repeat: no-repeat;
-    background-position : 2px center;
+    background-position : 1% center;
     padding-left : 2em;
 }
-.paging_full_numbers span.paginate_button.previous {
-    background-image : url('../../img/prev.png');
+.paging_full_numbers a.paginate_button.previous {
+    background-image : url('../../images/prev.png');
     background-repeat: no-repeat;
-    background-position : 2px center;
+    background-position : 1% center;
     padding-left : 2em;
 }
-.paging_full_numbers span.paginate_button.next {
-    background-image : url('../../img/next.png');
+.paging_full_numbers a.paginate_button.next {
+    background-image : url('../../images/next.png');
     background-repeat: no-repeat;
-    background-position : right center;
+    background-position : 96% center;
     padding-right : 2em;
 }
-.paging_full_numbers span.paginate_button.last {
-    background-image : url('../../img/last.png');
+.paging_full_numbers a.paginate_button.last {
+    background-image : url('../../images/last.png');
     background-repeat: no-repeat;
-    background-position : right center;
+    background-position : 96% center;
     border-right : 1px solid #686868;
     padding-right : 2em;
 }
-div.bottom.pager .paging_full_numbers span.paginate_button.last {
+div.bottom.pager .paging_full_numbers a.paginate_button.last {
     border-right-width : 0;
 }
-.paging_full_numbers span.paginate_active {
+.paging_full_numbers a.paginate_active {
     background-color : #FFFFEA;
     color : #000;
     font-weight: bold;
 }
 
-.paging_full_numbers span.paginate_button:hover {
+.paging_full_numbers a.paginate_button:hover {
     background-color: #FFC;
 }
 
-.paging_full_numbers span.paginate_button.paginate_button_disabled {
+.paging_full_numbers a.paginate_button.paginate_button_disabled {
     color : #666;
 }
 
@@ -131,7 +130,7 @@ div.dataTables_paginate.paging_four_button {
     background-color : transparent;
     border-right : 1px solid #686868;
     border-left : 1px solid #FFF;
-    line-height : 1.8em;
+    line-height : 2.5em;
 }
 .paginate_disabled_first,
 .paginate_enabled_first,
@@ -141,55 +140,67 @@ div.dataTables_paginate.paging_four_button {
 .paginate_enabled_next,
 .paginate_disabled_last,
 .paginate_enabled_last {
-    float: left;
-    height: 16px;
-    margin: .5em;
-    width: 16px;
+    cursor: pointer;
+    *cursor: hand;
+    padding: .1em 0;
+}
+
+.paginate_disabled_previous,
+.paginate_enabled_previous,
+.paginate_disabled_next,
+.paginate_enabled_next {
+    color: #111 !important;
+}
+
+.paginate_disabled_previous,
+.paginate_enabled_previous {
+    padding-left: 23px;
 }
+.paginate_disabled_next,
+.paginate_enabled_next,
+.paginate_disabled_last,
+.paginate_enabled_last {
+    padding-right: 23px;
+    margin-left: 10px;
+    margin-right : .3em;
+}
+
+.paging_four_button .paginate_disabled_first,
+.paging_four_button .paginate_disabled_previous,
+.paging_four_button .paginate_enabled_first,
+.paging_four_button .paginate_enabled_previous  {
+    margin-left : .3em;
+}
+
 .paginate_disabled_first {
-    background-image: url("../../img/first-disabled.png");
+    background: transparent url("../../images/first-disabled.png") no-repeat 3px top;
 }
 .paginate_enabled_first {
-    background-image: url("../../img/first.png");
+    background: transparent url("../../images/first.png") no-repeat 3px top;
     cursor: pointer;
 }
 .paginate_disabled_previous {
-    background-image: url("../../img/prev-disabled.png");
+    background: transparent url("../../images/prev-disabled.png") no-repeat 3px top;
 }
 .paginate_enabled_previous {
-    background-image: url("../../img/prev.png");
+    background: transparent url("../../images/prev.png") no-repeat 3px top;
     cursor: pointer;
 }
 .paginate_disabled_next {
-    background-image: url("../../img/next-disabled.png");
+    background: transparent url("../../images/next-disabled.png") no-repeat right top;
 }
 .paginate_enabled_next {
-    background-image: url("../../img/next.png");
+    background: transparent url("../../images/next.png") no-repeat right top;
     cursor: pointer;
 }
 .paginate_disabled_last {
-    background-image: url("../../img/last-disabled.png");
+    background: transparent url("../../images/last-disabled.png") no-repeat right top;
 }
 .paginate_enabled_last {
-    background-image: url("../../img/last.png");
+    background: transparent url("../../images/last.png") no-repeat right top;
     cursor: pointer;
 }
 
-
-/*
-table.display {
-    width: 100%;
-}
-table.display thead th {
-    border-bottom: 1px solid black;
-    cursor: pointer;
-    font-weight: bold;
-    padding: 3px 18px 3px 10px;
-}
-.dataTables_wrapper {
-    clear: both;
-    position: relative;
-}
 .dataTables_processing {
     background-color: white;
     border: 1px solid #DDDDDD;
@@ -205,61 +216,44 @@ table.display thead th {
     top: 50%;
     width: 250px;
 }
-.dataTables_info {
-    float: left;
-    width: 60%;
-}
-.dataTables_paginate {
-    float: right;
-    text-align: right;
-    width: 44px;
-}
-.paging_full_numbers {
-    height: 22px;
-    line-height: 22px;
-    width: 400px;
-}
-.paging_full_numbers span.paginate_button,
-     .paging_full_numbers span.paginate_active {
-    border: 1px solid #aaa;
-    -webkit-border-radius: 5px;
-    -moz-border-radius: 5px;
-    padding: 2px 5px;
-    margin: 0 3px;
-    cursor: pointer;
-    *cursor: hand;
-}
 
-.paging_full_numbers span.paginate_button {
-    background-color: #ddd;
+tr.odd.selected td {
+    background-color: #D3D3D3;
 }
 
-.paging_full_numbers span.paginate_button:hover {
-    background-color: #ccc;
+tr.even.selected td {
+    background-color: #D3D3D3;
 }
 
-.paging_full_numbers span.paginate_active {
-    background-color: #99B3FF;
-}
-.paginate_disabled_previous, .paginate_enabled_previous, .paginate_disabled_next, .paginate_enabled_next {
-    float: left;
-    height: 19px;
-    margin-left: 3px;
-    width: 19px;
+/* ColumnFilter */
+span.filter_column > input.text_filter {
+    font-size: 80%;
+    width: 100%;
 }
-.paginate_disabled_previous {
-    background-image: url("../../img/datatables/back_disabled.jpg");
+
+div.pager {
+    background-color : #E8E8E8;
+    border : 1px solid #BCBCBC;
+    -moz-border-radius : 5px;
+    border-radius : 5px;
+    display : inline-block;
+    font-size : 85%;
+    padding : .3em .5em .3em .5em;
+    margin : .4em 0;
 }
-.paginate_enabled_previous {
-    background-image: url("../../img/datatables/back_enabled.jpg");
+div.pager img {
+    vertical-align : middle;
 }
-.paginate_disabled_next {
-    background-image: url("../../img/datatables/forward_disabled.jpg");
+
+div.pager img.last {
+    padding-right: 5px;
 }
-.paginate_enabled_next {
-    background-image: url("../../img/datatables/forward_enabled.jpg");
+div.pager input.pagedisplay {
+    border : 0;
+    background-color : transparent;
+    font-weight: bold;
+    text-align : center;
 }
-.spacer {
-    clear: both;
-    height: 20px;
+div.pager p {
+    margin: 0;
 }
index 16599de..faa38b1 100644 (file)
@@ -19,11 +19,19 @@ not use an API to fetch items that populates item.datedue.
         [% END %]
     [% END %]
 [% ELSIF ( item.datedue || issue.date_due ) %]
+  [% IF inhouse_use %]
+    [% IF ( OPACShowCheckoutName ) %]
+        Currently in local use by [% item.cardnumber %] [% item.firstname %] [% item.surname %]
+    [% ELSE %]
+        Currently in local use
+    [% END %]
+  [% ELSE %]
     [% IF ( OPACShowCheckoutName ) %]
         Checked out to [% item.cardnumber %] [% item.firstname %] [% item.surname %]
     [% ELSE %]
         Checked out
     [% END %]
+  [% END %]
 [% ELSIF ( item.transfertwhen ) %]
     In transit from [% item.transfertfrom %]
     to [% item.transfertto %] since [% item.transfertwhen %]
index 3c4ffdf..5f0892d 100644 (file)
@@ -97,4 +97,4 @@ jQuery.extend( jQuery.fn.dataTableExt.oSort, {
         }
     });
 
-}());
\ No newline at end of file
+}());
index 11f0895..9e56f64 100755 (executable)
@@ -63,6 +63,8 @@ my $sql = '
         date_due < now() as date_due_overdue,
         issues.timestamp,
 
+        inhouse_use,
+
         biblionumber,
         biblio.title,
         author,
@@ -152,6 +154,7 @@ while ( my $c = $sth->fetchrow_hashref() ) {
         date_due            => $c->{date_due},
         date_due_overdue    => $c->{date_due_overdue} ? JSON::true : JSON::false,
         timestamp           => $c->{timestamp},
+        inhouse_use         => $c->{inhouse_use},
         renewals_count      => $renewals_count,
         renewals_allowed    => $renewals_allowed,
         renewals_remaining  => $renewals_remaining,