diff --git a/htdocs/categories/class/categorie.class.php b/htdocs/categories/class/categorie.class.php
index d2e1ba7e923..ac4e5b030c1 100644
--- a/htdocs/categories/class/categorie.class.php
+++ b/htdocs/categories/class/categorie.class.php
@@ -1958,4 +1958,56 @@ class Categorie extends CommonObject
return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables, 1);
}
+
+ /**
+ * Return the addtional SQL JOIN query for filtering a list by a category
+ *
+ * @param string $type The category type (e.g Categorie::TYPE_WAREHOUSE)
+ * @param string $rowIdName The name of the row id inside the whole sql query (e.g. "e.rowid")
+ * @return string A additional SQL JOIN query
+ */
+ public static function getFilterJoinQuery($type, $rowIdName)
+ {
+ return " LEFT JOIN ".MAIN_DB_PREFIX."categorie_".$type." as cp"
+ . " ON ".$rowIdName." = cp.fk_".$type;
+ }
+
+ /**
+ * Return the addtional SQL SELECT query for filtering a list by a category
+ *
+ * @param string $type The category type (e.g Categorie::TYPE_WAREHOUSE)
+ * @param string $rowIdName The name of the row id inside the whole sql query (e.g. "e.rowid")
+ * @param Array $searchList A list with the selected categories
+ * @return string A additional SQL SELECT query
+ */
+ public static function getFilterSelectQuery($type, $rowIdName, $searchList)
+ {
+ if (empty($searchList) && !is_array($searchList))
+ {
+ return "";
+ }
+
+ foreach ($searchList as $searchCategory)
+ {
+ if (intval($searchCategory) == -2)
+ {
+ $searchCategorySqlList[] = " cp.fk_categorie IS NULL";
+ }
+ elseif (intval($searchCategory) > 0)
+ {
+ $searchCategorySqlList[] = " ".$rowIdName
+ ." IN (SELECT fk_".$type." FROM ".MAIN_DB_PREFIX."categorie_".$type
+ ." WHERE fk_categorie = ".$searchCategory.")";
+ }
+ }
+
+ if (!empty($searchCategorySqlList))
+ {
+ return " AND (".implode(' AND ', $searchCategorySqlList).")";
+ }
+ else
+ {
+ return "";
+ }
+ }
}
diff --git a/htdocs/core/class/html.formcategory.class.php b/htdocs/core/class/html.formcategory.class.php
new file mode 100644
index 00000000000..4dd8bed247b
--- /dev/null
+++ b/htdocs/core/class/html.formcategory.class.php
@@ -0,0 +1,58 @@
+
+ *
+ * This program 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 this program. If not, see .
+ */
+
+/**
+ * \file htdocs/core/class/html.formcategory.class.php
+ * \ingroup core
+ * \brief File of class to build HTML component for category filtering
+ */
+
+require_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php';
+
+class FormCategory extends Form
+{
+ /**
+ * Return a HTML filter box for a list filter view
+ *
+ * @param string $type The categorie type (e.g Categorie::TYPE_WAREHOUSE)
+ * @param Array $preSelected A list with the elements that should pre-selected
+ * @return string A HTML filter box (Note: selected results can get with GETPOST("search_category_".$type."_list"))
+ */
+ public function getFilterBox($type, $preSelected)
+ {
+ // phpcs:enable
+ global $langs;
+
+ if (empty($preSelected) || !is_array($preSelected))
+ {
+ $preSelected = array();
+ }
+
+ $htmlName = "search_category_".$type."_list";
+
+ $categoryArray = $this->select_all_categories($type, "", "", 64, 0, 1);
+ $categoryArray[-2] = "- ".$langs->trans('NotCategorized')." -";
+
+ $filter = '';
+ $filter .= '