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 .= '
';
+ $filter .= $langs->trans('Categories').": ";
+ $filter .= Form::multiselectarray($htmlName, $categoryArray, $preSelected, 0, 0, "minwidth300");
+ $filter .= "
";
+
+ return $filter;
+ }
+}
diff --git a/htdocs/langs/en_US/cashdesk.lang b/htdocs/langs/en_US/cashdesk.lang
index 28e87394089..7ddbc71f3e9 100644
--- a/htdocs/langs/en_US/cashdesk.lang
+++ b/htdocs/langs/en_US/cashdesk.lang
@@ -89,4 +89,5 @@ Browser=Browser
BrowserMethodDescription=Simple and easy receipt printing. Only a few parameters to configure the receipt. Print via browser.
TakeposConnectorMethodDescription=External module with extra features. Posibility to print from de cloud.
PrintMethod=Print method
-ReceiptPrinterMethodDescription=Powerful method with a lot of parameters. Full customizable with templates. Cannot print from the cloud.
\ No newline at end of file
+ReceiptPrinterMethodDescription=Powerful method with a lot of parameters. Full customizable with templates. Cannot print from the cloud.
+ByTerminal=By terminal
diff --git a/htdocs/product/stock/list.php b/htdocs/product/stock/list.php
index 491f0979409..8f8ca7ad283 100644
--- a/htdocs/product/stock/list.php
+++ b/htdocs/product/stock/list.php
@@ -3,6 +3,7 @@
* Copyright (C) 2004-2016 Laurent Destailleur
* Copyright (C) 2005-2014 Regis Houssin
* Copyright (C) 2015 Juanjo Menent
+ * Copyright (C) 2020 Tobias Sekan
*
* 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
@@ -26,6 +27,12 @@
require '../../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/product/stock/class/entrepot.class.php';
+require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcategory.class.php';
+
+if (!empty($conf->categorie->enabled))
+{
+ require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
+}
// Load translation files required by the page
$langs->loadLangs(array("stocks", "other"));
@@ -45,6 +52,11 @@ $search_ref = GETPOST("sref", "alpha") ?GETPOST("sref", "alpha") : GETPOST("sear
$search_label = GETPOST("snom", "alpha") ?GETPOST("snom", "alpha") : GETPOST("search_label", "alpha");
$search_status = GETPOST("search_status", "int");
+if (!empty($conf->categorie->enabled))
+{
+ $search_category_list = GETPOST("search_category_".Categorie::TYPE_WAREHOUSE."_list", "array");
+}
+
// Load variable for pagination
$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
$sortfield = GETPOST('sortfield', 'alpha');
@@ -137,6 +149,7 @@ if (empty($reshook))
$search_status = "";
$toselect = '';
$search_array_options = array();
+ $search_category_list = array();
}
if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')
|| GETPOST('button_search_x', 'alpha') || GETPOST('button_search.x', 'alpha') || GETPOST('button_search', 'alpha'))
@@ -158,7 +171,7 @@ if (empty($reshook))
* View
*/
-$form = new Form($db);
+$form = new FormCategory($db);
$warehouse = new Entrepot($db);
$now = dol_now();
@@ -183,10 +196,22 @@ $reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters, $obje
$sql .= $hookmanager->resPrint;
$sql = preg_replace('/,\s*$/', '', $sql);
$sql .= " FROM ".MAIN_DB_PREFIX.$object->table_element." as e";
+
+if (!empty($conf->categorie->enabled))
+{
+ $sql .= Categorie::getFilterJoinQuery(Categorie::TYPE_WAREHOUSE, "e.rowid");
+}
+
if (is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) $sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$object->table_element."_extrafields as ef on (e.rowid = ef.fk_object)";
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product_stock as ps ON e.rowid = ps.fk_entrepot";
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product as p ON ps.fk_product = p.rowid";
$sql .= " WHERE e.entity IN (".getEntity('stock').")";
+
+if (!empty($conf->categorie->enabled))
+{
+ $sql .= Categorie::getFilterSelectQuery(Categorie::TYPE_WAREHOUSE, "e.rowid", $search_category_list);
+}
+
if ($search_ref) $sql .= natural_search("e.ref", $search_ref); // ref
if ($search_label) $sql .= natural_search("e.lieu", $search_label); // label
if ($search_status != '' && $search_status >= 0) $sql .= " AND e.statut = ".$search_status;
@@ -313,6 +338,12 @@ if ($search_all)
}
$moreforfilter = '';
+
+if (!empty($conf->categorie->enabled))
+{
+ $moreforfilter .= $form->getFilterBox(Categorie::TYPE_WAREHOUSE, $search_category_list);
+}
+
/*$moreforfilter.='';
$moreforfilter.= $langs->trans('MyFilter') . ': ';
$moreforfilter.= '
';*/
diff --git a/htdocs/takepos/admin/setup.php b/htdocs/takepos/admin/setup.php
index 5b6fe25af44..eef9497e9db 100644
--- a/htdocs/takepos/admin/setup.php
+++ b/htdocs/takepos/admin/setup.php
@@ -28,6 +28,7 @@ require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php';
require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
require_once DOL_DOCUMENT_ROOT."/core/lib/takepos.lib.php";
+require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
// If socid provided by ajax company selector
if (!empty($_REQUEST['CASHDESK_ID_THIRDPARTY_id']))
@@ -79,7 +80,7 @@ if (GETPOST('action', 'alpha') == 'set')
$res = dolibarr_set_const($db, "TAKEPOS_NUM_TERMINALS", GETPOST('TAKEPOS_NUM_TERMINALS', 'alpha'), 'chaine', 0, '', $conf->entity);
$res = dolibarr_set_const($db, "TAKEPOS_DIRECT_PAYMENT", GETPOST('TAKEPOS_DIRECT_PAYMENT', 'int'), 'int', 0, '', $conf->entity);
$res = dolibarr_set_const($db, "TAKEPOS_CUSTOM_RECEIPT", GETPOST('TAKEPOS_CUSTOM_RECEIPT', 'int'), 'int', 0, '', $conf->entity);
- //$res = dolibarr_set_const($db, "TAKEPOS_HEAD_BAR", GETPOST('TAKEPOS_HEAD_BAR', 'int'), 'int', 0, '', $conf->entity);
+ $res = dolibarr_set_const($db, "TAKEPOS_ADDON", GETPOST('TAKEPOS_ADDON', 'alpha'), 'int', 0, '', $conf->entity);
$res = dolibarr_set_const($db, "TAKEPOS_EMAIL_TEMPLATE_INVOICE", GETPOST('TAKEPOS_EMAIL_TEMPLATE_INVOICE', 'alpha'), 'chaine', 0, '', $conf->entity);
if (!empty($conf->global->TAKEPOS_ENABLE_SUMUP)) {
$res = dolibarr_set_const($db, "TAKEPOS_SUMUP_AFFILIATE", GETPOST('TAKEPOS_SUMUP_AFFILIATE', 'alpha'), 'chaine', 0, '', $conf->entity);
@@ -241,6 +242,63 @@ if (is_array($formmail->lines_model)) {
print $form->selectarray('TAKEPOS_EMAIL_TEMPLATE_INVOICE', $arrayofmessagename, $conf->global->TAKEPOS_EMAIL_TEMPLATE_INVOICE, 'None', 1, 0, '', 0, 0, 0, '', '', 1);
print "\n";
+// Numbering module
+print '';
+print $langs->trans("BillsNumberingModule");
+print ' ';
+$array = array(0=>$langs->trans("Default"), "terminal"=>$langs->trans("ByTerminal"));
+$dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
+foreach ($dirmodels as $reldir)
+{
+ $dir = dol_buildpath($reldir."core/modules/facture/");
+ if (is_dir($dir))
+ {
+ $handle = opendir($dir);
+ if (is_resource($handle))
+ {
+ while (($file = readdir($handle)) !== false)
+ {
+ if (!is_dir($dir.$file) || (substr($file, 0, 1) <> '.' && substr($file, 0, 3) <> 'CVS'))
+ {
+ $filebis = $file;
+ $classname = preg_replace('/\.php$/', '', $file);
+ // For compatibility
+ if (!is_file($dir.$filebis))
+ {
+ $filebis = $file."/".$file.".modules.php";
+ $classname = "mod_facture_".$file;
+ }
+ // Check if there is a filter on country
+ preg_match('/\-(.*)_(.*)$/', $classname, $reg);
+ if (!empty($reg[2]) && $reg[2] != strtoupper($mysoc->country_code)) continue;
+
+ $classname = preg_replace('/\-.*$/', '', $classname);
+ if (!class_exists($classname) && is_readable($dir.$filebis) && (preg_match('/mod_/', $filebis) || preg_match('/mod_/', $classname)) && substr($filebis, dol_strlen($filebis) - 3, 3) == 'php')
+ {
+ // Charging the numbering class
+ require_once $dir.$filebis;
+
+ $module = new $classname($db);
+
+ // Show modules according to features level
+ if ($module->version == 'development' && $conf->global->MAIN_FEATURES_LEVEL < 2) continue;
+ if ($module->version == 'experimental' && $conf->global->MAIN_FEATURES_LEVEL < 1) continue;
+
+ if ($module->isEnabled())
+ {
+ $array[preg_replace('/\-.*$/', '', preg_replace('/\.php$/', '', $file))]=preg_replace('/\-.*$/', '', preg_replace('/mod_facture_/', '', preg_replace('/\.php$/', '', $file)));
+ }
+ }
+ }
+ }
+ closedir($handle);
+ }
+ }
+}
+
+print $form->selectarray('TAKEPOS_ADDON', $array, (empty($conf->global->TAKEPOS_ADDON) ? '0' : $conf->global->TAKEPOS_ADDON), 0);
+print " \n";
+
print '';
print '';
diff --git a/htdocs/takepos/admin/terminal.php b/htdocs/takepos/admin/terminal.php
index 1107f9101c7..08ca05bb109 100644
--- a/htdocs/takepos/admin/terminal.php
+++ b/htdocs/takepos/admin/terminal.php
@@ -90,6 +90,8 @@ if (GETPOST('action', 'alpha') == 'set')
$res = dolibarr_set_const($db, 'CASHDESK_READER_KEYCODE_FOR_ENTER'.$terminaltouse, (GETPOST('CASHDESK_READER_KEYCODE_FOR_ENTER'.$terminaltouse, 'int') > 0 ? GETPOST('CASHDESK_READER_KEYCODE_FOR_ENTER'.$terminaltouse, 'int') : ''), 'chaine', 0, '', $conf->entity);
+ $res = dolibarr_set_const($db, "TAKEPOS_ADDON".$terminaltouse, GETPOST('TAKEPOS_ADDON'.$terminaltouse, 'alpha'), 'chaine', 0, '', $conf->entity);
+
dol_syslog("admin/cashdesk: level ".GETPOST('level', 'alpha'));
if (!$res > 0) $error++;
@@ -251,6 +253,66 @@ print '';
print ' ';
print ' ';
+// Numbering module
+if ($conf->global->TAKEPOS_ADDON=="terminal"){
+ print '';
+ print $langs->trans("BillsNumberingModule");
+ print ' ';
+ $array = array(0=>$langs->trans("Default"));
+ $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
+ foreach ($dirmodels as $reldir)
+ {
+ $dir = dol_buildpath($reldir."core/modules/facture/");
+ if (is_dir($dir))
+ {
+ $handle = opendir($dir);
+ if (is_resource($handle))
+ {
+ while (($file = readdir($handle)) !== false)
+ {
+ if (!is_dir($dir.$file) || (substr($file, 0, 1) <> '.' && substr($file, 0, 3) <> 'CVS'))
+ {
+ $filebis = $file;
+ $classname = preg_replace('/\.php$/', '', $file);
+ // For compatibility
+ if (!is_file($dir.$filebis))
+ {
+ $filebis = $file."/".$file.".modules.php";
+ $classname = "mod_facture_".$file;
+ }
+ // Check if there is a filter on country
+ preg_match('/\-(.*)_(.*)$/', $classname, $reg);
+ if (!empty($reg[2]) && $reg[2] != strtoupper($mysoc->country_code)) continue;
+
+ $classname = preg_replace('/\-.*$/', '', $classname);
+ if (!class_exists($classname) && is_readable($dir.$filebis) && (preg_match('/mod_/', $filebis) || preg_match('/mod_/', $classname)) && substr($filebis, dol_strlen($filebis) - 3, 3) == 'php')
+ {
+ // Charging the numbering class
+ require_once $dir.$filebis;
+
+ $module = new $classname($db);
+
+ // Show modules according to features level
+ if ($module->version == 'development' && $conf->global->MAIN_FEATURES_LEVEL < 2) continue;
+ if ($module->version == 'experimental' && $conf->global->MAIN_FEATURES_LEVEL < 1) continue;
+
+ if ($module->isEnabled())
+ {
+ $array[preg_replace('/\-.*$/', '', preg_replace('/\.php$/', '', $file))]=preg_replace('/\-.*$/', '', preg_replace('/mod_facture_/', '', preg_replace('/\.php$/', '', $file)));
+ }
+ }
+ }
+ }
+ closedir($handle);
+ }
+ }
+ }
+ print $form->selectarray('TAKEPOS_ADDON'.$terminaltouse, $array, (empty($conf->global->{'TAKEPOS_ADDON'.$terminaltouse}) ? '0' : $conf->global->{'TAKEPOS_ADDON'.$terminaltouse}), 0);
+ print " \n";
+ print '';
+ print '';
+}
+
print '';
print '';
diff --git a/htdocs/takepos/invoice.php b/htdocs/takepos/invoice.php
index fc4ae6ee23e..e4ad387e1cc 100644
--- a/htdocs/takepos/invoice.php
+++ b/htdocs/takepos/invoice.php
@@ -171,7 +171,8 @@ if ($action == 'valid' && $user->rights->facture->creer)
$sav_FACTURE_ADDON='';
if (! empty($conf->global->TAKEPOS_ADDON)) {
$sav_FACTURE_ADDON = $conf->global->FACTURE_ADDON;
- $conf->global->FACTURE_ADDON = $conf->global->TAKEPOS_ADDON;
+ if ($conf->global->TAKEPOS_ADDON=="terminal") $conf->global->FACTURE_ADDON = $conf->global->{'TAKEPOS_ADDON'.$_SESSION["takeposterminal"]};
+ else $conf->global->FACTURE_ADDON = $conf->global->TAKEPOS_ADDON;
}
$constantforkey = 'CASHDESK_NO_DECREASE_STOCK'.$_SESSION["takeposterminal"];