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);
|