diff --git a/htdocs/categories/admin/categorie.php b/htdocs/categories/admin/categorie.php index fd198e043e9..e506906808a 100644 --- a/htdocs/categories/admin/categorie.php +++ b/htdocs/categories/admin/categorie.php @@ -31,7 +31,7 @@ if (!$user->admin) accessforbidden(); // Load translation files required by the page -$langs->load("categories"); +$langs->loadLangs(array("categories","admin")); $action=GETPOST('action', 'aZ09'); diff --git a/htdocs/categories/class/categorie.class.php b/htdocs/categories/class/categorie.class.php index d5159f003e2..5db9b4be136 100644 --- a/htdocs/categories/class/categorie.class.php +++ b/htdocs/categories/class/categorie.class.php @@ -909,7 +909,7 @@ class Categorie extends CommonObject // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** - * Return direct childs of a category + * Return direct childs id of a category into an array * * @return array|int <0 KO, array ok */ @@ -947,9 +947,7 @@ class Categorie extends CommonObject protected function load_motherof() { // phpcs:enable - global $conf; - - $this->motherof=array(); + $this->motherof=array(); // Load array[child]=parent $sql = "SELECT fk_parent as id_parent, rowid as id_son"; @@ -985,12 +983,12 @@ class Categorie extends CommonObject * fulllabel = nom avec chemin complet de la categorie * fullpath = chemin complet compose des id * - * @param string $type Type of categories ('customer', 'supplier', 'contact', 'product', 'member') or (0, 1, 2, ...). - * @param int $markafterid Removed all categories including the leaf $markafterid in category tree. - * - * @return array|int Array of categories. this->cats and this->motherof are set, -1 on error + * @param string $type Type of categories ('customer', 'supplier', 'contact', 'product', 'member') or (0, 1, 2, ...). + * @param int $markafterid Removed all categories including the leaf $markafterid in category tree. + * @param int $keeponlyifinleafid Keep only of category is inside the leaf starting with this id. + * @return array|int Array of categories. this->cats and this->motherof are set, -1 on error */ - public function get_full_arbo($type, $markafterid = 0) + public function get_full_arbo($type, $markafterid = 0, $keeponlyifinleafid = 0) { // phpcs:enable global $conf, $langs; @@ -1059,6 +1057,27 @@ class Categorie extends CommonObject } } } + // Exclude leaf including $markafterid from tree + if ($keeponlyifinleafid) + { + //print "Look to discard category ".$keeponlyifinleafid."\n"; + $keyfilter1='^'.$keeponlyifinleafid.'$'; + $keyfilter2='_'.$keeponlyifinleafid.'$'; + $keyfilter3='^'.$keeponlyifinleafid.'_'; + $keyfilter4='_'.$keeponlyifinleafid.'_'; + foreach($this->cats as $key => $val) + { + if (preg_match('/'.$keyfilter1.'/', $val['fullpath']) || preg_match('/'.$keyfilter2.'/', $val['fullpath']) + || preg_match('/'.$keyfilter3.'/', $val['fullpath']) || preg_match('/'.$keyfilter4.'/', $val['fullpath'])) + { + // We keep + } + else + { + unset($this->cats[$key]); + } + } + } dol_syslog(get_class($this)."::get_full_arbo dol_sort_array", LOG_DEBUG); $this->cats=dol_sort_array($this->cats, 'fulllabel', 'asc', true, false); @@ -1070,7 +1089,8 @@ class Categorie extends CommonObject // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** - * For category id_categ and its childs available in this->cats, define property fullpath and fulllabel + * For category id_categ and its childs available in this->cats, define property fullpath and fulllabel. + * This function is a memory scan only from $this->cats and $this->motherof, no database access must be done here. * * @param int $id_categ id_categ entry to update * @param int $protection Deep counter to avoid infinite loop @@ -1174,6 +1194,19 @@ class Categorie extends CommonObject } } + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + /** + * Returns the top level categories (which are not child) + * + * @param int $type Type of category (0, 1, ...) + * @return array + */ + public function get_main_categories($type = null) + { + // phpcs:enable + return $this->get_all_categories($type, true); + } + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** * Check if no category with same label already exists for this cat's parent or root and for this cat's type @@ -1225,18 +1258,6 @@ class Categorie extends CommonObject } } - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps - /** - * Returns the top level categories (which are not girls) - * - * @param int $type Type of category (0, 1, ...) - * @return array - */ - public function get_main_categories($type = null) - { - // phpcs:enable - return $this->get_all_categories($type, true); - } // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 765bd307464..69ff39ba0dd 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -3805,7 +3805,7 @@ class Form * @param int $excludeafterid Exclude all categories after this leaf in category tree. * @param int $outputmode 0=HTML select string, 1=Array * @return string - * @see select_categories + * @see select_categories() */ public function select_all_categories($type, $selected = '', $htmlname = "parent", $maxlength = 64, $excludeafterid = 0, $outputmode = 0) { diff --git a/htdocs/core/lib/ajax.lib.php b/htdocs/core/lib/ajax.lib.php index f1a06b46262..a96e63a4f43 100644 --- a/htdocs/core/lib/ajax.lib.php +++ b/htdocs/core/lib/ajax.lib.php @@ -375,8 +375,7 @@ function ajax_combobox($htmlname, $events = array(), $minLengthToAutocomplete = { global $conf; - // select2 disabled for smartphones with standard browser. - // TODO With select2 v4, it seems ok, except that responsive style on table become crazy when scrolling at end of array) + // select2 can be disabled for smartphones if (! empty($conf->browser->layout) && $conf->browser->layout == 'phone' && ! empty($conf->global->MAIN_DISALLOW_SELECT2_WITH_SMARTPHONE)) return ''; if (! empty($conf->global->MAIN_DISABLE_AJAX_COMBOX)) return ''; diff --git a/htdocs/expedition/card.php b/htdocs/expedition/card.php index e88e435df67..05819fe91be 100644 --- a/htdocs/expedition/card.php +++ b/htdocs/expedition/card.php @@ -784,7 +784,8 @@ if (empty($reshook)) $stockLocation="entl".$detail_entrepot->line_id; $qty = "qtyl".$detail_entrepot->line_id; $warehouse = GETPOST($stockLocation, 'int'); - if (!empty($warehouse)) { + if (!empty($warehouse)) + { $line->id = $detail_entrepot->line_id; $line->entrepot_id = $warehouse; $line->qty = GETPOST($qty, 'int'); @@ -1173,7 +1174,7 @@ if ($action == 'create') print $form->textwithtooltip($text, $description, 3, '', '', $i); // Show range - print_date_range($db->jdate($line->date_start),$db->jdate($line->date_end)); + print_date_range($db->jdate($line->date_start), $db->jdate($line->date_end)); // Add description in form if (! empty($conf->global->PRODUIT_DESC_IN_FORM)) @@ -1186,18 +1187,18 @@ if ($action == 'create') else { print ""; - if ($type==1) $text = img_object($langs->trans('Service'),'service'); - else $text = img_object($langs->trans('Product'),'product'); + if ($type==1) $text = img_object($langs->trans('Service'), 'service'); + else $text = img_object($langs->trans('Product'), 'product'); if (! empty($line->label)) { $text.= ' '.$line->label.''; - print $form->textwithtooltip($text,$line->desc,3,'','',$i); + print $form->textwithtooltip($text, $line->desc, 3, '', '', $i); } else { print $text.' '.nl2br($line->desc); } // Show range - print_date_range($db->jdate($line->date_start),$db->jdate($line->date_end)); + print_date_range($db->jdate($line->date_start), $db->jdate($line->date_end)); print "\n"; } @@ -1256,7 +1257,7 @@ if ($action == 'create') // Show warehouse combo list $ent = "entl".$indiceAsked; $idl = "idl".$indiceAsked; - $tmpentrepot_id = is_numeric(GETPOST($ent,'int'))?GETPOST($ent,'int'):$warehouse_id; + $tmpentrepot_id = is_numeric(GETPOST($ent, 'int'))?GETPOST($ent, 'int'):$warehouse_id; if ($line->fk_product > 0) { print ''; @@ -1344,8 +1345,8 @@ if ($action == 'create') $detail=''; $detail.= $langs->trans("Batch").': '.$dbatch->batch; - $detail.= ' - '.$langs->trans("SellByDate").': '.dol_print_date($dbatch->sellby,"day"); - $detail.= ' - '.$langs->trans("EatByDate").': '.dol_print_date($dbatch->eatby,"day"); + $detail.= ' - '.$langs->trans("SellByDate").': '.dol_print_date($dbatch->sellby, "day"); + $detail.= ' - '.$langs->trans("EatByDate").': '.dol_print_date($dbatch->eatby, "day"); $detail.= ' - '.$langs->trans("Qty").': '.$dbatch->qty; $detail.= '
'; print $detail; diff --git a/htdocs/expedition/shipment.php b/htdocs/expedition/shipment.php index 4f58fb6dd1f..d9b2537e4ba 100644 --- a/htdocs/expedition/shipment.php +++ b/htdocs/expedition/shipment.php @@ -686,7 +686,7 @@ if ($id > 0 || ! empty($ref)) if (empty($newlang)) $newlang=$object->thirdparty->default_lang; if (! empty($newlang)) { - $outputlangs = new Translate("",$conf); + $outputlangs = new Translate("", $conf); $outputlangs->setDefaultLang($newlang); } @@ -707,10 +707,10 @@ if ($id > 0 || ! empty($ref)) $text.= ' - '.$label; $description=($conf->global->PRODUIT_DESC_IN_FORM?'':dol_htmlentitiesbr($objp->description)).'
'; $description.= $product_static->show_photos('product', $conf->product->multidir_output[$product_static->entity], 1, 1, 0, 0, 0, 80); - print $form->textwithtooltip($text,$description,3,'','',$i); + print $form->textwithtooltip($text, $description, 3, '', '', $i); // Show range - print_date_range($db->jdate($objp->date_start),$db->jdate($objp->date_end)); + print_date_range($db->jdate($objp->date_start), $db->jdate($objp->date_end)); // Add description in form if (! empty($conf->global->PRODUIT_DESC_IN_FORM)) @@ -723,18 +723,18 @@ if ($id > 0 || ! empty($ref)) else { print ""; - if ($type==1) $text = img_object($langs->trans('Service'),'service'); - else $text = img_object($langs->trans('Product'),'product'); + if ($type==1) $text = img_object($langs->trans('Service'), 'service'); + else $text = img_object($langs->trans('Product'), 'product'); if (! empty($objp->label)) { $text.= ' '.$objp->label.''; - print $form->textwithtooltip($text,$objp->description,3,'','',$i); + print $form->textwithtooltip($text, $objp->description, 3, '', '', $i); } else { print $text.' '.nl2br($objp->description); } // Show range - print_date_range($db->jdate($objp->date_start),$db->jdate($objp->date_end)); + print_date_range($db->jdate($objp->date_start), $db->jdate($objp->date_end)); print "\n"; } diff --git a/htdocs/fourn/class/fournisseur.product.class.php b/htdocs/fourn/class/fournisseur.product.class.php index 3a35105104b..9eedea68335 100644 --- a/htdocs/fourn/class/fournisseur.product.class.php +++ b/htdocs/fourn/class/fournisseur.product.class.php @@ -231,7 +231,7 @@ class ProductFournisseur extends Product * @param int $fk_barcode_type Barcode type * @return int <0 if KO, >=0 if OK */ - public function update_buyprice($qty, $buyprice, $user, $price_base_type, $fourn, $availability, $ref_fourn, $tva_tx, $charges = 0, $remise_percent = 0, $remise = 0, $newnpr = 0, $delivery_time_days = 0, $supplier_reputation = '', $localtaxes_array = array(), $newdefaultvatcode = '', $multicurrency_buyprice = 0, $multicurrency_price_base_type = 'HT', $multicurrency_tx = 1, $multicurrency_code = '', $desc_fourn = '', $barcode='', $fk_barcode_type='') + public function update_buyprice($qty, $buyprice, $user, $price_base_type, $fourn, $availability, $ref_fourn, $tva_tx, $charges = 0, $remise_percent = 0, $remise = 0, $newnpr = 0, $delivery_time_days = 0, $supplier_reputation = '', $localtaxes_array = array(), $newdefaultvatcode = '', $multicurrency_buyprice = 0, $multicurrency_price_base_type = 'HT', $multicurrency_tx = 1, $multicurrency_code = '', $desc_fourn = '', $barcode = '', $fk_barcode_type = '') { // phpcs:enable global $conf, $langs; diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index 6fc421e19a4..68eef7f5bd5 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -1860,3 +1860,5 @@ MAIN_OPTIMIZEFORTEXTBROWSERDesc=Enable this option if you are a blind person, or ThisValueCanOverwrittenOnUserLevel=This value can be overwritten by each user from its user page - tab '%s' DefaultCustomerType=Default thirdparty type for "New customer" creation form ABankAccountMustBeDefinedOnPaymentModeSetup=Note: The bank account must be defined on the module of each payment mode (Paypal, Stripe, ...) to have this feature working. +RootCategoryForProductsToSell=Root category of products to sell +RootCategoryForProductsToSellDesc=If defined, only products inside this category or childs of this category will be available in the Point Of Sale \ No newline at end of file diff --git a/htdocs/langs/en_US/categories.lang b/htdocs/langs/en_US/categories.lang index eb34e302cad..a6c3ffa01b0 100644 --- a/htdocs/langs/en_US/categories.lang +++ b/htdocs/langs/en_US/categories.lang @@ -83,7 +83,7 @@ DeleteFromCat=Remove from tags/category ExtraFieldsCategories=Complementary attributes CategoriesSetup=Tags/categories setup CategorieRecursiv=Link with parent tag/category automatically -CategorieRecursivHelp=If activated, product will also linked to parent category when adding into a subcategory +CategorieRecursivHelp=If option is on, when you add a product into a subcategory, product will also be added into the parent category. AddProductServiceIntoCategory=Add the following product/service ShowCategory=Show tag/category ByDefaultInList=By default in list diff --git a/htdocs/product/card.php b/htdocs/product/card.php index dc286faa36c..8fcc2af6634 100644 --- a/htdocs/product/card.php +++ b/htdocs/product/card.php @@ -1496,7 +1496,7 @@ else // Tags-Categories if ($conf->categorie->enabled) { - print ''.$langs->trans("Categories").''; + print ''.$langs->trans("Categories").''; $cate_arbo = $form->select_all_categories(Categorie::TYPE_PRODUCT, '', 'parent', 64, 0, 1); $c = new Categorie($db); $cats = $c->containing($object->id, Categorie::TYPE_PRODUCT); diff --git a/htdocs/product/fournisseurs.php b/htdocs/product/fournisseurs.php index 0e34c9adce6..e2d05cc7e0c 100644 --- a/htdocs/product/fournisseurs.php +++ b/htdocs/product/fournisseurs.php @@ -799,10 +799,10 @@ SCRIPT; print_liste_field_titre("NbDaysToDelivery", $_SERVER["PHP_SELF"], "pfp.delivery_time_days", "", $param, '', $sortfield, $sortorder, 'right '); print_liste_field_titre("ReputationForThisProduct", $_SERVER["PHP_SELF"], "pfp.supplier_reputation", "", $param, '', $sortfield, $sortorder, 'center '); if ($conf->barcode->enabled) { - print_liste_field_titre("BarcodeValue", $_SERVER["PHP_SELF"], "pfp.barcode", "", $param, 'align="center"', $sortfield, $sortorder); - print_liste_field_titre("BarcodeType", $_SERVER["PHP_SELF"], "pfp.fk_barcode_type", "", $param, 'align="center"', $sortfield, $sortorder); - } - print_liste_field_titre("DateModification",$_SERVER["PHP_SELF"],"pfp.tms","",$param,'align="right"',$sortfield,$sortorder); + print_liste_field_titre("BarcodeValue", $_SERVER["PHP_SELF"], "pfp.barcode", "", $param, '', $sortfield, $sortorder, 'center '); + print_liste_field_titre("BarcodeType", $_SERVER["PHP_SELF"], "pfp.fk_barcode_type", "", $param, '', $sortfield, $sortorder, 'center '); + } + print_liste_field_titre("DateModification", $_SERVER["PHP_SELF"], "pfp.tms", "", $param, '', $sortfield, $sortorder, 'right '); print_liste_field_titre(''); print "\n"; @@ -913,7 +913,7 @@ SCRIPT; print ''; print dol_print_date($productfourn->date_modification, "dayhour"); print ''; - + if (is_object($hookmanager)) { $parameters=array('id_pfp'=>$productfourn->product_fourn_price_id,'id_fourn'=>$id_fourn,'prod_id'=>$object->id); diff --git a/htdocs/takepos/admin/setup.php b/htdocs/takepos/admin/setup.php index e7d21acbc75..c00fa060493 100644 --- a/htdocs/takepos/admin/setup.php +++ b/htdocs/takepos/admin/setup.php @@ -26,6 +26,7 @@ require '../../main.inc.php'; // Load $user and permissions require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; 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'; // If socid provided by ajax company selector if (! empty($_REQUEST['CASHDESK_ID_THIRDPARTY_id'])) @@ -56,6 +57,8 @@ if (GETPOST('action', 'alpha') == 'set') $res = dolibarr_set_const($db, "CASHDESK_ID_WAREHOUSE", (GETPOST('CASHDESK_ID_WAREHOUSE', 'alpha') > 0 ? GETPOST('CASHDESK_ID_WAREHOUSE', 'alpha') : ''), 'chaine', 0, '', $conf->entity); $res = dolibarr_set_const($db, "CASHDESK_NO_DECREASE_STOCK", GETPOST('CASHDESK_NO_DECREASE_STOCK', 'alpha'), 'chaine', 0, '', $conf->entity); $res = dolibarr_set_const($db, "CASHDESK_SERVICES", GETPOST('CASHDESK_SERVICES', 'alpha'), 'chaine', 0, '', $conf->entity); + $res = dolibarr_set_const($db, "TAKEPOS_ROOT_CATEGORY_ID", GETPOST('TAKEPOS_ROOT_CATEGORY_ID', 'alpha'), 'chaine', 0, '', $conf->entity); + $res = dolibarr_set_const($db, "TAKEPOSCONNECTOR", GETPOST('TAKEPOSCONNECTOR', 'alpha'), 'chaine', 0, '', $conf->entity); $res = dolibarr_set_const($db, "TAKEPOS_BAR_RESTAURANT", GETPOST('TAKEPOS_BAR_RESTAURANT', 'alpha'), 'chaine', 0, '', $conf->entity); $res = dolibarr_set_const($db, "TAKEPOS_PRINT_SERVER", GETPOST('TAKEPOS_PRINT_SERVER', 'alpha'), 'chaine', 0, '', $conf->entity); @@ -64,7 +67,7 @@ if (GETPOST('action', 'alpha') == 'set') $res = dolibarr_set_const($db, "TAKEPOS_HEADER", GETPOST('TAKEPOS_HEADER', 'alpha'), 'chaine', 0, '', $conf->entity); $res = dolibarr_set_const($db, "TAKEPOS_FOOTER", GETPOST('TAKEPOS_FOOTER', 'alpha'), 'chaine', 0, '', $conf->entity); $res = dolibarr_set_const($db, "TAKEPOS_NUMPAD", GETPOST('TAKEPOS_NUMPAD', 'alpha'), 'chaine', 0, '', $conf->entity); - + if ($conf->global->TAKEPOS_ORDER_NOTES==1) { $extrafields = new ExtraFields($db); @@ -121,6 +124,13 @@ if (! empty($conf->service->enabled)) print "\n"; } +print ''; +print $form->textwithpicto($langs->trans("RootCategoryForProductsToSell"), $langs->trans("RootCategoryForProductsToSellDesc")); +print ''; +print $form->select_all_categories(Categorie::TYPE_PRODUCT, $conf->global->TAKEPOS_ROOT_CATEGORY_ID, 'TAKEPOS_ROOT_CATEGORY_ID', 64, 0, 0); +print ajax_combobox('TAKEPOS_ROOT_CATEGORY_ID'); +print "\n"; + // Use Takepos printing print ''; print $langs->trans("DolibarrReceiptPrinter").' ('.$langs->trans("TakeposConnectorNecesary").')'; @@ -149,7 +159,7 @@ if ($conf->global->TAKEPOS_BAR_RESTAURANT && $conf->global->TAKEPOSCONNECTOR){ print ''; print $form->selectyesno("TAKEPOS_ORDER_PRINTERS", $conf->global->TAKEPOS_ORDER_PRINTERS, 1); print ''; - + print ''; print $langs->trans("OrderNotes"); print ''; diff --git a/htdocs/takepos/css/pos.css b/htdocs/takepos/css/pos.css index fff566e6aaa..086e4e5fcb0 100644 --- a/htdocs/takepos/css/pos.css +++ b/htdocs/takepos/css/pos.css @@ -83,7 +83,7 @@ div.wrapper2{ width:12.5%; height:25%; margin:0; - padding:1px; + /* padding:1px; */ border: 0.1em solid; box-shadow: 2px 2px 1px #888; text-align: center; diff --git a/htdocs/takepos/takepos.php b/htdocs/takepos/takepos.php index bcfca236925..36b670146f9 100644 --- a/htdocs/takepos/takepos.php +++ b/htdocs/takepos/takepos.php @@ -40,6 +40,11 @@ $action = GETPOST('action', 'alpha'); $langs->loadLangs(array("bills","orders","commercial","cashdesk","receiptprinter")); +$categorie = new Categorie($db); + +$MAXCATEG = 16; +$MAXPRODUCT = 32; + /* * View @@ -61,14 +66,30 @@ top_htmlhead($head, $title, $disablejs, $disablehead, $arrayofjs, $arrayofcss);