From 13a77bb0292d54f55654a02846015227656c9884 Mon Sep 17 00:00:00 2001
From: Blou <philippe.blouin@inlibro.com>
Date: Mon, 27 Jan 2014 13:16:05 -0500
Subject: [PATCH] Fix and rebase following mtompset's comments

http://bugs.koha-community.org/show_bug.cgi?id=10937
---
 C4/Koha.pm                                         |   50 ++++++++++++++++++++
 admin/authorised_values.pl                         |    2 +-
 admin/itemtypes.pl                                 |   14 +++++-
 installer/data/mysql/kohastructure.sql             |    2 +
 installer/data/mysql/updatedatabase.pl             |    9 ++++
 .../prog/en/modules/admin/itemtypes.tt             |   46 ++++++++++++++++++
 .../bootstrap/en/modules/opac-advsearch.tt         |    4 +-
 .../opac-tmpl/prog/en/modules/opac-advsearch.tt    |    6 ++-
 opac/opac-search.pl                                |   28 +++++++++--
 9 files changed, 150 insertions(+), 11 deletions(-)

diff --git a/C4/Koha.pm b/C4/Koha.pm
index 6f98ac6..2f2cee1 100644
--- a/C4/Koha.pm
+++ b/C4/Koha.pm
@@ -43,6 +43,7 @@ BEGIN {
 		&subfield_is_koha_internal_p
 		&GetPrinters &GetPrinter
 		&GetItemTypes &getitemtypeinfo
+		&GetItemTypesCategorized &GetItemTypesByCategory
 		&GetSupportName &GetSupportList
 		&get_itemtypeinfos_of
 		&getframeworks &getframeworkinfo
@@ -275,6 +276,55 @@ sub GetItemTypes {
     }
 }
 
+=head2 GetItemTypesCategorized
+
+Returns item types but grouped by category if available.
+The categories must be part of Authorized Values (DOCTYPECAT)
+
+=cut
+
+sub GetItemTypesCategorized {
+    my $dbh   = C4::Context->dbh;
+    my $query = qq|
+        SELECT itemtype, description, imageurl, hideinopac, 0 as 'iscat' FROM itemtypes WHERE ISNULL(searchcategory) or length(searchcategory) = 0
+        UNION
+        SELECT DISTINCT searchcategory AS `itemtype`, authorised_values.lib_opac AS description, authorised_values.imageurl AS imageurl, hideinopac, 1 as 'iscat'
+            FROM itemtypes
+	    LEFT JOIN authorised_values ON searchcategory = authorised_value WHERE searchcategory > ''
+        |;
+    my $sth = $dbh->prepare($query);
+    $sth->execute;
+
+    my %itemtypes;
+    while ( my $IT = $sth->fetchrow_hashref ) {
+        $itemtypes{ $IT->{'itemtype'} } = $IT;
+    }
+
+    return ( \%itemtypes );
+}
+
+=head2 GetItemTypesByCategory
+
+    $category = category filter
+
+Returns the itemtypes that are grouped into the category.
+
+=cut
+
+sub GetItemTypesByCategory {
+    my ($category) = @_;
+    my $count = 0;
+    my @results;
+    my $dbh = C4::Context->dbh;
+    my $sth = $dbh->prepare("SELECT itemtype FROM itemtypes WHERE searchcategory=?");
+    $sth->execute($category);
+
+    while ( my $data = $sth->fetchrow ) {
+        push ( @results, $data );
+    }
+    return @results;
+}
+
 sub get_itemtypeinfos_of {
     my @itemtypes = @_;
 
diff --git a/admin/authorised_values.pl b/admin/authorised_values.pl
index 332f09a..47847f9 100755
--- a/admin/authorised_values.pl
+++ b/admin/authorised_values.pl
@@ -247,7 +247,7 @@ sub default_form {
     }
 
     # push koha system categories
-    foreach (qw(Asort1 Asort2 Bsort1 Bsort2 SUGGEST DAMAGED LOST REPORT_GROUP REPORT_SUBGROUP DEPARTMENT TERM SUGGEST_STATUS)) {
+    foreach (qw(Asort1 Asort2 Bsort1 Bsort2 SUGGEST DAMAGED LOST REPORT_GROUP REPORT_SUBGROUP DEPARTMENT TERM SUGGEST_STATUS DOCTYPECAT)) {
         push @category_list, $_ unless $categories{$_};
     }
 
diff --git a/admin/itemtypes.pl b/admin/itemtypes.pl
index 87af801..c8ec47c 100755
--- a/admin/itemtypes.pl
+++ b/admin/itemtypes.pl
@@ -112,6 +112,8 @@ if ( $op eq 'add_form' ) {
         $remote_image = $data->{imageurl};
     }
 
+    my $searchcategory = GetAuthorisedValues("DOCTYPECAT", $data->{'searchcategory'});
+
     $template->param(
         itemtype        => $itemtype,
         description     => $data->{'description'},
@@ -125,6 +127,8 @@ if ( $op eq 'add_form' ) {
         imagesets       => $imagesets,
         remote_image    => $remote_image,
         sip_media_type  => $data->{sip_media_type},
+        hideinopac      => $data->{'hideinopac'},
+        searchcategory  => $searchcategory,
     );
 
     # END $OP eq ADD_FORM
@@ -150,6 +154,8 @@ elsif ( $op eq 'add_validate' ) {
                  , checkinmsg = ?
                  , checkinmsgtype = ?
                  , sip_media_type = ?
+                 , hideinopac = ?
+                 , searchcategory = ?
             WHERE itemtype = ?
         ';
         $sth = $dbh->prepare($query2);
@@ -168,15 +174,17 @@ elsif ( $op eq 'add_validate' ) {
             $input->param('checkinmsg'),
             $input->param('checkinmsgtype'),
             $sip_media_type,
+            $input->param('hideinopac') ? 1 : 0,
+            $input->param('searchcategory'),
             $input->param('itemtype')
         );
     }
     else {    # add a new itemtype & not modif an old
         my $query = "
             INSERT INTO itemtypes
-                (itemtype,description,rentalcharge, notforloan, imageurl, summary, checkinmsg, checkinmsgtype, sip_media_type)
+                (itemtype,description,rentalcharge, notforloan, imageurl, summary, checkinmsg, checkinmsgtype, sip_media_type, hideinopac, searchcategory)
             VALUES
-                (?,?,?,?,?,?,?,?,?);
+                (?,?,?,?,?,?,?,?,?,?,?);
             ";
         my $sth = $dbh->prepare($query);
 		my $image = $input->param('image');
@@ -192,6 +200,8 @@ elsif ( $op eq 'add_validate' ) {
             $input->param('checkinmsg'),
             $input->param('checkinmsgtype'),
             $sip_media_type,
+            $input->param('hideinopac') ? 1 : 0,
+            $input->param('searchcategory'),
         );
     }
 
diff --git a/installer/data/mysql/kohastructure.sql b/installer/data/mysql/kohastructure.sql
index b46dc6a..0f08f4c 100644
--- a/installer/data/mysql/kohastructure.sql
+++ b/installer/data/mysql/kohastructure.sql
@@ -1247,6 +1247,8 @@ CREATE TABLE `itemtypes` ( -- defines the item types
   checkinmsg VARCHAR(255), -- message that is displayed when an item with the given item type is checked in
   checkinmsgtype CHAR(16) DEFAULT 'message' NOT NULL, -- type (CSS class) for the checkinmsg, can be "alert" or "message"
   sip_media_type VARCHAR(3) DEFAULT NULL, -- SIP2 protocol media type for this itemtype
+  hideinopac tinyint(1) NOT NULL DEFAULT 0, -- Hide the item type from the search options in OPAC
+  searchcategory varchar(20) default NULL, -- Group this item type with others with the same value on OPAC search options
   PRIMARY KEY  (`itemtype`),
   UNIQUE KEY `itemtype` (`itemtype`)
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
diff --git a/installer/data/mysql/updatedatabase.pl b/installer/data/mysql/updatedatabase.pl
index 01472d7..c4ad278 100755
--- a/installer/data/mysql/updatedatabase.pl
+++ b/installer/data/mysql/updatedatabase.pl
@@ -8551,6 +8551,15 @@ if (CheckVersion($DBversion)) {
     SetVersion($DBversion);
 }
 
+$DBversion = "3.15.00.XXX";
+if ( CheckVersion($DBversion) ) {
+    $dbh->do(q{
+        ALTER TABLE itemtypes
+            ADD hideinopac TINYINT(1) NOT NULL DEFAULT 0,
+            ADD searchcategory VARCHAR(20) DEFAULT NULL;
+    });
+}
+
 =head1 FUNCTIONS
 
 =head2 TableExists($table)
diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/itemtypes.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/itemtypes.tt
index 522420b..2467902 100644
--- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/itemtypes.tt
+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/itemtypes.tt
@@ -109,6 +109,39 @@ Item types administration
   [% END %]
       <li>
           <label for="description" class="required">Description: </label><input type="text" id="description" name="description" size="48" value="[% description |html %]" required="required" /> <span class="required">Required</span></li>
+      [% IF ( itemtype ) %]
+      <li>
+          <span class="label">Search category</span>
+          <select id="searchcategory" name="searchcategory">
+          <option value="">None</option>
+                [% FOREACH cat IN searchcategory %]
+                    [% IF ( cat.selected ) %]
+                        <option value="[% cat.authorised_value %]" selected="selected">
+                            [% cat.lib %]
+                        </option>
+                    [% ELSE %]
+                        <option value="[% cat.authorised_value %]" >
+                            [% cat.lib %]
+                        </option>
+                    [% END %]
+                [% END %]
+          </select>
+          (Options are defined as the authorized values for the DOCTYPECAT category)
+      </li>
+      [% ELSE %]
+      <li>
+          <span class="label">Search category</span>
+          <select id="searchcategory" name="searchcategory">
+          <option value="" />
+              [% FOREACH cat IN searchcategory %]
+                  <option value="[% cat.authorised_value %]" >
+                      [% cat.lib %]
+                  </option>
+              [% END %]
+          </select>
+      </li>
+      [% END %]
+
      [% IF ( noItemTypeImages ) %]
 	 <li><span class="label">Image: </span>Item type images are disabled. To enable them, turn off the <a href="/cgi-bin/koha/admin/preferences.pl?op=search&amp;searchfield=noItemTypeImages">noItemTypeImages system preference</a></li></ol>
 	 [% ELSE %]</ol>
@@ -164,6 +197,15 @@ Item types administration
 [% END %]
 <ol>
       <li>
+          <label for="hideinopac">Hide in OPAC: </label>
+          [% IF ( hideinopac ) %]
+              <input type="checkbox" id="hideinopac" name="hideinopac" checked="checked" value="1" />
+          [% ELSE %]
+              <input type="checkbox" id="hideinopac" name="hideinopac" value="1" />
+          [% END %]
+          (if checked, items of this type will be hidden as filters in OPAC's advanced search)
+      </li>
+      <li>
           <label for="notforloan">Not for loan: </label>   [% IF ( notforloan ) %]
                 <input type="checkbox" id="notforloan" name="notforloan" checked="checked" value="1" />
             [% ELSE %]
@@ -260,7 +302,9 @@ Item types administration
     [% UNLESS ( noItemTypeImages ) %]<th>Image</th>[% END %]
     <th>Code</th>
     <th>Description</th>
+    <th>Search category</th>
     <th>Not for loan</th>
+    <th>Hide in OPAC</th>
     <th>Charge</th>
     <th>Checkin message</th>
     <th>Actions</th>
@@ -278,7 +322,9 @@ Item types administration
       </a>
     </td>
     <td>[% loo.description %]</td>
+    <td>[% loo.searchcategory %]</td>
     <td>[% IF ( loo.notforloan ) %]Yes[% ELSE %]&nbsp;[% END %]</td>
+    <td>[% IF ( loo.hideinopac ) %]Yes[% ELSE %]&nbsp;[% END %]</td>
     <td>
     [% UNLESS ( loo.notforloan ) %]
       [% loo.rentalcharge %]
diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-advsearch.tt b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-advsearch.tt
index d9b2d4b..f4f9fe0 100644
--- a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-advsearch.tt
+++ b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-advsearch.tt
@@ -141,9 +141,11 @@
                                     <legend>Limit to any of the following:</legend>
                                     <div class="row-fluid">
                                         [% FOREACH itemtypeloo IN advsearchloo.code_loop %]
-                                            <div class="span3"><input type="checkbox" id="[% itemtypeloo.ccl FILTER remove(',') %]-[% itemtypeloo.number %]" name="limit" value="mc-[% itemtypeloo.ccl %]:[% itemtypeloo.code %]"/><label for="[% itemtypeloo.ccl FILTER remove(',') %]-[% itemtypeloo.number %]">[% UNLESS ( noItemTypeImages ) %][% IF ( itemtypeloo.imageurl ) %]<img src="[% itemtypeloo.imageurl %]" alt="[% itemtypeloo.description %]" />[% END %]&nbsp;[% END %]
+                                            [% IF ((!itemtypeloo.searchcategory) AND (itemtypeloo.cat == 0)) OR (itemtypeloo.cat == 1) %]
+                                            <div class="span3"><input type="checkbox" id="[% itemtypeloo.ccl FILTER remove(',') %]-[% itemtypeloo.number %]" name="[% IF ( itemtypeloo.cat == 1 ) %]searchcat[% ELSE %]limit[% END %]" value="[% IF ( itemtypeloo.cat == 1 ) %][% itemtypeloo.code %][% ELSE %]mc-[% itemtypeloo.ccl %]:[% itemtypeloo.code %][% END %]"/><label for="[% itemtypeloo.ccl FILTER remove(',') %]-[% itemtypeloo.number %]">[% UNLESS ( noItemTypeImages ) %][% IF ( itemtypeloo.imageurl ) %]<img border="0" src="[% itemtypeloo.imageurl %]" alt="[% itemtypeloo.description %]" />[% END %]&nbsp;[% END %]
                                             [% itemtypeloo.description %]</label></div>
                                             [% IF ( loop.last ) %]</div>[% ELSE %][% UNLESS ( loop.count % 4 ) %]</div><div class="row-fluid">[% END %][% END %]
+                                            [% END %]
                                         [% END %]
                                 </fieldset>
                             </div> <!-- / #advsearch-[% advsearchloo.advanced_search_type %] -->
diff --git a/koha-tmpl/opac-tmpl/prog/en/modules/opac-advsearch.tt b/koha-tmpl/opac-tmpl/prog/en/modules/opac-advsearch.tt
index 04ab78c..8bf2dc0 100644
--- a/koha-tmpl/opac-tmpl/prog/en/modules/opac-advsearch.tt
+++ b/koha-tmpl/opac-tmpl/prog/en/modules/opac-advsearch.tt
@@ -187,8 +187,10 @@
     <table>
         <tr>
     [% FOREACH itemtypeloo IN advsearchloo.code_loop %]
-        <td><input type="checkbox" id="[% itemtypeloo.ccl FILTER remove(',') %]-[% itemtypeloo.number %]" name="limit" value="mc-[% itemtypeloo.ccl %]:[% itemtypeloo.code %]"/><label for="[% itemtypeloo.ccl FILTER remove(',') %]-[% itemtypeloo.number %]">[% UNLESS ( noItemTypeImages ) %][% IF ( itemtypeloo.imageurl ) %]<img border="0" src="[% itemtypeloo.imageurl %]" alt="[% itemtypeloo.description %]" />[% END %]&nbsp;[% END %]
-        [% itemtypeloo.description %]</label></td>
+            [% IF ((!itemtypeloo.searchcategory) AND (itemtypeloo.cat == 0)) OR (itemtypeloo.cat == 1) %]
+                <td><input type="checkbox" id="[% itemtypeloo.ccl FILTER remove(',') %]-[% itemtypeloo.number %]" name="[% IF ( itemtypeloo.cat == 1 ) %]searchcat[% ELSE %]limit[% END %]" value="[% IF ( itemtypeloo.cat == 1 ) %][% itemtypeloo.code %][% ELSE %]mc-[% itemtypeloo.ccl %]:[% itemtypeloo.code %][% END %]"/><label for="[% itemtypeloo.ccl FILTER remove(',') %]-[% itemtypeloo.number %]">[% UNLESS ( noItemTypeImages ) %][% IF ( itemtypeloo.imageurl ) %]<img border="0" src="[% itemtypeloo.imageurl %]" alt="[% itemtypeloo.description %]" />[% END %]&nbsp;[% END %]
+                [% itemtypeloo.description %]</label></td>
+            [% END %]
         [% IF ( loop.last ) %]</tr>[% ELSE %][% UNLESS ( loop.count % 5 ) %]</tr><tr>[% END %][% END %]
     [% END %]
     </table>
diff --git a/opac/opac-search.pl b/opac/opac-search.pl
index 990cbd0..94b70db 100755
--- a/opac/opac-search.pl
+++ b/opac/opac-search.pl
@@ -95,17 +95,17 @@ my ($template,$borrowernumber,$cookie);
 my $template_name;
 my $template_type = 'basic';
 my @params = $cgi->param("limit");
-
+my @searchCategories = $cgi->param('searchcat');
 
 my $format = $cgi->param("format") || '';
 my $build_grouped_results = C4::Context->preference('OPACGroupResults');
 if ($format =~ /(rss|atom|opensearchdescription)/) {
     $template_name = 'opac-opensearch.tmpl';
 }
-elsif (@params && $build_grouped_results) {
+elsif ((@params || @searchCategories) && $build_grouped_results) {
     $template_name = 'opac-results-grouped.tmpl';
 }
-elsif ((@params>=1) || ($cgi->param("q")) || ($cgi->param('multibranchlimit')) || ($cgi->param('limit-yr')) ) {
+elsif (((@params>=1) || (@searchCategories>=1)) || ($cgi->param("q")) || ($cgi->param('multibranchlimit')) || ($cgi->param('limit-yr')) ) {
     $template_name = 'opac-results.tmpl';
 }
 else {
@@ -205,7 +205,7 @@ my $languages_limit_loop = getLanguages($lang, 1);
 $template->param(search_languages_loop => $languages_limit_loop,);
 
 # load the Type stuff
-my $itemtypes = GetItemTypes;
+my $itemtypes = GetItemTypesCategorized;
 # the index parameter is different for item-level itemtypes
 my $itype_or_itemtype = (C4::Context->preference("item-level_itypes"))?'itype':'itemtype';
 my @advancedsearchesloop;
@@ -223,8 +223,13 @@ foreach my $advanced_srch_type (@advanced_search_types) {
                 code => $thisitemtype,
                 description => $itemtypes->{$thisitemtype}->{'description'},
                 imageurl=> getitemtypeimagelocation( 'opac', $itemtypes->{$thisitemtype}->{'imageurl'} ),
+                cat => $itemtypes->{$thisitemtype}->{'iscat'},
+                hideinopac => $itemtypes->{$thisitemtype}->{'hideinopac'},
+                searchcategory => $itemtypes->{$thisitemtype}->{'searchcategory'},
             );
-	    push @itypesloop, \%row;
+        if ( !$itemtypes->{$thisitemtype}->{'hideinopac'} ) {
+	        push @itypesloop, \%row;
+        }
 	}
         my %search_code = (  advanced_search_type => $advanced_srch_type,
                              code_loop => \@itypesloop );
@@ -239,6 +244,7 @@ foreach my $advanced_srch_type (@advanced_search_types) {
 				ccl => $advanced_srch_type,
                 code => $thisitemtype->{authorised_value},
                 description => $thisitemtype->{'lib_opac'} || $thisitemtype->{'lib'},
+                searchcategory => $itemtypes->{$thisitemtype}->{'searchcategory'},
                 imageurl => getitemtypeimagelocation( 'opac', $thisitemtype->{'imageurl'} ),
                 );
 		push @authvalueloop, \%row;
@@ -406,6 +412,18 @@ my @limits = $cgi->param('limit');
 my @nolimits = $cgi->param('nolimit');
 my %is_nolimit = map { $_ => 1 } @nolimits;
 @limits = grep { not $is_nolimit{$_} } @limits;
+
+if (@searchCategories > 0) {
+	my @tabcat;
+    foreach my $typecategory (@searchCategories) {
+        push (@tabcat, GetItemTypesByCategory($typecategory));
+    }
+
+    foreach my $itemtypeInCategory (@tabcat) {
+        push (@limits, "mc-$itype_or_itemtype,phr:".$itemtypeInCategory);
+    }
+}
+
 @limits = map { uri_unescape($_) } @limits;
 
 if($params->{'multibranchlimit'}) {
-- 
1.7.9.5