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"];