1<?php 2/* Copyright (C) 2004-2011 Laurent Destailleur <eldy@users.sourceforge.net> 3 * Copyright (C) 2006 Andre Cianfarani <acianfa@free.fr> 4 * Copyright (C) 2006-2007 Rodolphe Quiedeville <rodolphe@quiedeville.org> 5 * Copyright (C) 2007 Auguria SARL <info@auguria.org> 6 * Copyright (C) 2005-2012 Regis Houssin <regis.houssin@inodbox.com> 7 * Copyright (C) 2011-2012 Juanjo Menent <jmenent@2byte.es> 8 * Copyright (C) 2012 Christophe Battarel <christophe.battarel@altairis.fr> 9 * Copyright (C) 2012 Cedric Salvador <csalvador@gpcsolutions.fr> 10 * Copyright (C) 2016 Charlie Benke <charlie@patas-monkey.com> 11 * Copyright (C) 2016 Ferran Marcet <fmarcet@2byte.es> 12 * 13 * This program is free software; you can redistribute it and/or modify 14 * it under the terms of the GNU General Public License as published by 15 * the Free Software Foundation; either version 3 of the License, or 16 * (at your option) any later version. 17 * 18 * This program is distributed in the hope that it will be useful, 19 * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 * GNU General Public License for more details. 22 * 23 * You should have received a copy of the GNU General Public License 24 * along with this program. If not, see <https://www.gnu.org/licenses/>. 25 */ 26 27/** 28 * \file htdocs/product/admin/product.php 29 * \ingroup produit 30 * \brief Setup page of product module 31 */ 32 33require '../../main.inc.php'; 34require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; 35require_once DOL_DOCUMENT_ROOT.'/core/lib/product.lib.php'; 36require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; 37require_once DOL_DOCUMENT_ROOT.'/core/class/html.formbarcode.class.php'; 38 39// Load translation files required by the page 40$langs->loadLangs(array("admin", "products")); 41 42// Security check 43if (!$user->admin || (empty($conf->product->enabled) && empty($conf->service->enabled))) 44 accessforbidden(); 45 46$action = GETPOST('action', 'aZ09'); 47$value = GETPOST('value', 'alpha'); 48$label = GETPOST('label', 'alpha'); 49$scandir = GETPOST('scan_dir', 'alpha'); 50$type = 'product'; 51 52// Pricing Rules 53$select_pricing_rules = array( 54 'PRODUCT_PRICE_UNIQ'=>$langs->trans('PriceCatalogue'), // Unique price 55 'PRODUIT_MULTIPRICES'=>$langs->trans('MultiPricesAbility'), // Several prices according to a customer level 56 'PRODUIT_CUSTOMER_PRICES'=>$langs->trans('PriceByCustomer'), // Different price for each customer 57); 58$keyforparam = 'PRODUIT_CUSTOMER_PRICES_BY_QTY'; 59if ($conf->global->MAIN_FEATURES_LEVEL >= 1 || !empty($conf->global->$keyforparam)) $select_pricing_rules['PRODUIT_CUSTOMER_PRICES_BY_QTY'] = $langs->trans('PriceByQuantity').' ('.$langs->trans("VersionExperimental").')'; // TODO If this is enabled, price must be hidden when price by qty is enabled, also price for quantity must be used when adding product into order/propal/invoice 60$keyforparam = 'PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES'; 61if ($conf->global->MAIN_FEATURES_LEVEL >= 2 || !empty($conf->global->$keyforparam)) $select_pricing_rules['PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES'] = $langs->trans('MultiPricesAbility').'+'.$langs->trans('PriceByQuantity').' ('.$langs->trans("VersionExperimental").')'; 62 63// Clean param 64if (!empty($conf->global->PRODUIT_MULTIPRICES) && empty($conf->global->PRODUIT_MULTIPRICES_LIMIT)) { 65 dolibarr_set_const($db, 'PRODUIT_MULTIPRICES_LIMIT', 5, 'chaine', 0, '', $conf->entity); 66} 67 68$error = 0; 69 70 71/* 72 * Actions 73 */ 74 75$nomessageinsetmoduleoptions = 1; 76include DOL_DOCUMENT_ROOT.'/core/actions_setmoduleoptions.inc.php'; 77 78if ($action == 'setcodeproduct') 79{ 80 if (dolibarr_set_const($db, "PRODUCT_CODEPRODUCT_ADDON", $value, 'chaine', 0, '', $conf->entity) > 0) 81 { 82 header("Location: ".$_SERVER["PHP_SELF"]); 83 exit; 84 } else { 85 dol_print_error($db); 86 } 87} 88 89if ($action == 'other' && GETPOST('value_PRODUIT_LIMIT_SIZE') >= 0) 90{ 91 $res = dolibarr_set_const($db, "PRODUIT_LIMIT_SIZE", GETPOST('value_PRODUIT_LIMIT_SIZE'), 'chaine', 0, '', $conf->entity); 92 if (!($res > 0)) $error++; 93} 94if ($action == 'other' && GETPOST('value_PRODUIT_MULTIPRICES_LIMIT') > 0) 95{ 96 $res = dolibarr_set_const($db, "PRODUIT_MULTIPRICES_LIMIT", GETPOST('value_PRODUIT_MULTIPRICES_LIMIT'), 'chaine', 0, '', $conf->entity); 97 if (!($res > 0)) $error++; 98} 99if ($action == 'other') 100{ 101 $princingrules = GETPOST('princingrule', 'alpha'); 102 foreach ($select_pricing_rules as $rule => $label) // Loop on each possible mode 103 { 104 if ($rule == $princingrules) // We are on selected rule, we enable it 105 { 106 if ($princingrules == 'PRODUCT_PRICE_UNIQ') // For this case, we disable entries manually 107 { 108 $res = dolibarr_set_const($db, 'PRODUIT_MULTIPRICES', 0, 'chaine', 0, '', $conf->entity); 109 $res = dolibarr_set_const($db, 'PRODUIT_CUSTOMER_PRICES_BY_QTY', 0, 'chaine', 0, '', $conf->entity); 110 $res = dolibarr_set_const($db, 'PRODUIT_CUSTOMER_PRICES', 0, 'chaine', 0, '', $conf->entity); 111 dolibarr_set_const($db, 'PRODUCT_PRICE_UNIQ', 1, 'chaine', 0, '', $conf->entity); 112 } else { 113 $multirule = explode('&', $princingrules); 114 foreach ($multirule as $rulesselected) 115 { 116 $res = dolibarr_set_const($db, $rulesselected, 1, 'chaine', 0, '', $conf->entity); 117 } 118 } 119 } else // We clear this mode 120 { 121 if (strpos($rule, '&') === false) { 122 $res = dolibarr_set_const($db, $rule, 0, 'chaine', 0, '', $conf->entity); 123 } 124 } 125 } 126 127 $value = GETPOST('price_base_type', 'alpha'); 128 $res = dolibarr_set_const($db, "PRODUCT_PRICE_BASE_TYPE", $value, 'chaine', 0, '', $conf->entity); 129 130 /*$value = GETPOST('PRODUIT_SOUSPRODUITS', 'alpha'); 131 $res = dolibarr_set_const($db, "PRODUIT_SOUSPRODUITS", $value, 'chaine', 0, '', $conf->entity);*/ 132 133 $value = GETPOST('activate_viewProdDescInForm', 'alpha'); 134 $res = dolibarr_set_const($db, "PRODUIT_DESC_IN_FORM", $value, 'chaine', 0, '', $conf->entity); 135 136 $value = GETPOST('activate_viewProdTextsInThirdpartyLanguage', 'alpha'); 137 $res = dolibarr_set_const($db, "PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE", $value, 'chaine', 0, '', $conf->entity); 138 139 $value = GETPOST('activate_mergePropalProductCard', 'alpha'); 140 $res = dolibarr_set_const($db, "PRODUIT_PDF_MERGE_PROPAL", $value, 'chaine', 0, '', $conf->entity); 141 142 $value = GETPOST('activate_usesearchtoselectproduct', 'alpha'); 143 $res = dolibarr_set_const($db, "PRODUIT_USE_SEARCH_TO_SELECT", $value, 'chaine', 0, '', $conf->entity); 144 145 $value = GETPOST('activate_useProdFournDesc', 'alpha'); 146 $res = dolibarr_set_const($db, "PRODUIT_FOURN_TEXTS", $value, 'chaine', 0, '', $conf->entity); 147 148 if ($value) { 149 $sql_test = "SELECT count(desc_fourn) as cpt FROM ".MAIN_DB_PREFIX."product_fournisseur_price WHERE 1"; 150 $resql = $db->query($sql_test); 151 if (!$resql && $db->lasterrno == 'DB_ERROR_NOSUCHFIELD') // if the field does not exist, we create it 152 { 153 $sql_new = "ALTER TABLE ".MAIN_DB_PREFIX."product_fournisseur_price ADD COLUMN desc_fourn text"; 154 $resql_new = $db->query($sql_new); 155 } 156 } 157 158 $value = GETPOST('activate_useProdSupplierPackaging', 'alpha'); 159 $res = dolibarr_set_const($db, "PRODUCT_USE_SUPPLIER_PACKAGING", $value, 'chaine', 0, '', $conf->entity); 160 if ($value) { 161 $sql_test = "SELECT count(packaging) as cpt FROM ".MAIN_DB_PREFIX."product_fournisseur_price WHERE 1"; 162 $resql = $db->query($sql_test); 163 if (!$resql && $db->lasterrno == 'DB_ERROR_NOSUCHFIELD') // if the field does not exist, we create it 164 { 165 $sql_new = "ALTER TABLE ".MAIN_DB_PREFIX."product_fournisseur_price ADD COLUMN packaging double(24,8) DEFAULT 1"; 166 $resql_new = $db->query($sql_new); 167 } 168 } 169} 170 171if ($action == 'specimen') // For products 172{ 173 $modele = GETPOST('module', 'alpha'); 174 175 $product = new Product($db); 176 $product->initAsSpecimen(); 177 178 // Search template files 179 $file = ''; $classname = ''; $filefound = 0; 180 $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']); 181 foreach ($dirmodels as $reldir) 182 { 183 $file = dol_buildpath($reldir."core/modules/product/doc/pdf_".$modele.".modules.php", 0); 184 if (file_exists($file)) 185 { 186 $filefound = 1; 187 $classname = "pdf_".$modele; 188 break; 189 } 190 } 191 192 if ($filefound) 193 { 194 require_once $file; 195 196 $module = new $classname($db); 197 198 if ($module->write_file($product, $langs, '') > 0) 199 { 200 header("Location: ".DOL_URL_ROOT."/document.php?modulepart=product&file=SPECIMEN.pdf"); 201 return; 202 } else { 203 setEventMessages($obj->error, $obj->errors, 'errors'); 204 dol_syslog($obj->error, LOG_ERR); 205 } 206 } else { 207 setEventMessages($langs->trans("ErrorModuleNotFound"), null, 'errors'); 208 dol_syslog($langs->trans("ErrorModuleNotFound"), LOG_ERR); 209 } 210} 211 212// Activate a model 213if ($action == 'set') 214{ 215 $ret = addDocumentModel($value, $type, $label, $scandir); 216} 217 218if ($action == 'del') 219{ 220 $ret = delDocumentModel($value, $type); 221 if ($ret > 0) 222 { 223 if ($conf->global->PRODUCT_ADDON_PDF == "$value") dolibarr_del_const($db, 'PRODUCT_ADDON_PDF', $conf->entity); 224 } 225} 226 227// Set default model 228if ($action == 'setdoc') 229{ 230 if (dolibarr_set_const($db, "PRODUCT_ADDON_PDF", $value, 'chaine', 0, '', $conf->entity)) 231 { 232 // La constante qui a ete lue en avant du nouveau set 233 // on passe donc par une variable pour avoir un affichage coherent 234 $conf->global->PRODUCT_ADDON_PDF = $value; 235 } 236 237 // On active le modele 238 $ret = delDocumentModel($value, $type); 239 if ($ret > 0) 240 { 241 $ret = addDocumentModel($value, $type, $label, $scandir); 242 } 243} 244 245 246if ($action == 'set') 247{ 248 $const = "PRODUCT_SPECIAL_".strtoupper(GETPOST('spe', 'alpha')); 249 $value = GETPOST('value'); 250 if (GETPOST('value', 'alpha')) $res = dolibarr_set_const($db, $const, $value, 'chaine', 0, '', $conf->entity); 251 else $res = dolibarr_del_const($db, $const, $conf->entity); 252 if (!($res > 0)) $error++; 253} 254 255//if ($action == 'other') 256//{ 257// $value = GETPOST('activate_units', 'alpha'); 258// $res = dolibarr_set_const($db, "PRODUCT_USE_UNITS", $value, 'chaine', 0, '', $conf->entity); 259// if (! $res > 0) $error++; 260//} 261 262if ($action) 263{ 264 if (!$error) 265 { 266 setEventMessages($langs->trans("SetupSaved"), null, 'mesgs'); 267 } else { 268 setEventMessages($langs->trans("SetupNotError"), null, 'errors'); 269 } 270} 271 272/* 273 * View 274 */ 275 276$formbarcode = new FormBarCode($db); 277 278$title = $langs->trans('ProductServiceSetup'); 279$tab = $langs->trans("ProductsAndServices"); 280if (empty($conf->product->enabled)) 281{ 282 $title = $langs->trans('ServiceSetup'); 283 $tab = $langs->trans('Services'); 284} elseif (empty($conf->service->enabled)) 285{ 286 $title = $langs->trans('ProductSetup'); 287 $tab = $langs->trans('Products'); 288} 289 290llxHeader('', $title); 291 292$linkback = '<a href="'.DOL_URL_ROOT.'/admin/modules.php?restore_lastsearch_values=1">'.$langs->trans("BackToModuleList").'</a>'; 293print load_fiche_titre($title, $linkback, 'title_setup'); 294 295$head = product_admin_prepare_head(); 296print dol_get_fiche_head($head, 'general', $tab, -1, 'product'); 297 298$form = new Form($db); 299 300// Module to manage product / services code 301$dirproduct = array('/core/modules/product/'); 302$dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']); 303 304print load_fiche_titre($langs->trans("ProductCodeChecker"), '', ''); 305 306print '<table class="noborder centpercent">'."\n"; 307print '<tr class="liste_titre">'."\n"; 308print ' <td>'.$langs->trans("Name").'</td>'; 309print ' <td>'.$langs->trans("Description").'</td>'; 310print ' <td>'.$langs->trans("Example").'</td>'; 311print ' <td class="center" width="80">'.$langs->trans("Status").'</td>'; 312print ' <td class="center" width="60">'.$langs->trans("ShortInfo").'</td>'; 313print "</tr>\n"; 314 315foreach ($dirproduct as $dirroot) 316{ 317 $dir = dol_buildpath($dirroot, 0); 318 319 $handle = @opendir($dir); 320 if (is_resource($handle)) 321 { 322 // Loop on each module find in opened directory 323 while (($file = readdir($handle)) !== false) 324 { 325 if (substr($file, 0, 16) == 'mod_codeproduct_' && substr($file, -3) == 'php') 326 { 327 $file = substr($file, 0, dol_strlen($file) - 4); 328 329 try { 330 dol_include_once($dirroot.$file.'.php'); 331 } catch (Exception $e) 332 { 333 dol_syslog($e->getMessage(), LOG_ERR); 334 } 335 336 $modCodeProduct = new $file; 337 338 // Show modules according to features level 339 if ($modCodeProduct->version == 'development' && $conf->global->MAIN_FEATURES_LEVEL < 2) continue; 340 if ($modCodeProduct->version == 'experimental' && $conf->global->MAIN_FEATURES_LEVEL < 1) continue; 341 342 print '<tr class="oddeven">'."\n"; 343 print '<td width="140">'.$modCodeProduct->name.'</td>'."\n"; 344 print '<td>'.$modCodeProduct->info($langs).'</td>'."\n"; 345 print '<td class="nowrap">'.$modCodeProduct->getExample($langs).'</td>'."\n"; 346 347 if (!empty($conf->global->PRODUCT_CODEPRODUCT_ADDON) && $conf->global->PRODUCT_CODEPRODUCT_ADDON == $file) 348 { 349 print '<td class="center">'."\n"; 350 print img_picto($langs->trans("Activated"), 'switch_on'); 351 print "</td>\n"; 352 } else { 353 $disabled = false; 354 if (!empty($conf->multicompany->enabled) && (is_object($mc) && !empty($mc->sharings['referent']) && $mc->sharings['referent'] == $conf->entity) ? false : true); 355 print '<td class="center">'; 356 if (!$disabled) print '<a class="reposition" href="'.$_SERVER['PHP_SELF'].'?action=setcodeproduct&token='.newToken().'&value='.$file.'">'; 357 print img_picto($langs->trans("Disabled"), 'switch_off'); 358 if (!$disabled) print '</a>'; 359 print '</td>'; 360 } 361 362 print '<td class="center">'; 363 $s = $modCodeProduct->getToolTip($langs, null, -1); 364 print $form->textwithpicto('', $s, 1); 365 print '</td>'; 366 367 print '</tr>'; 368 } 369 } 370 closedir($handle); 371 } 372} 373print '</table>'; 374 375// Module to build doc 376$def = array(); 377$sql = "SELECT nom"; 378$sql .= " FROM ".MAIN_DB_PREFIX."document_model"; 379$sql .= " WHERE type = '".$db->escape($type)."'"; 380$sql .= " AND entity = ".$conf->entity; 381$resql = $db->query($sql); 382if ($resql) 383{ 384 $i = 0; 385 $num_rows = $db->num_rows($resql); 386 while ($i < $num_rows) 387 { 388 $array = $db->fetch_array($resql); 389 array_push($def, $array[0]); 390 $i++; 391 } 392} else { 393 dol_print_error($db); 394} 395 396print '<br>'; 397 398print load_fiche_titre($langs->trans("ProductDocumentTemplates"), '', ''); 399 400print '<table class="noborder centpercent">'; 401print '<tr class="liste_titre">'; 402print '<td>'.$langs->trans("Name").'</td>'; 403print '<td>'.$langs->trans("Description").'</td>'; 404print '<td class="center" width="60">'.$langs->trans("Status")."</td>\n"; 405print '<td class="center" width="60">'.$langs->trans("Default")."</td>\n"; 406print '<td class="center" width="80">'.$langs->trans("ShortInfo").'</td>'; 407print '<td class="center" width="80">'.$langs->trans("Preview").'</td>'; 408print "</tr>\n"; 409 410clearstatcache(); 411 412foreach ($dirmodels as $reldir) 413{ 414 foreach (array('', '/doc') as $valdir) 415 { 416 $dir = dol_buildpath($reldir."core/modules/product".$valdir); 417 if (is_dir($dir)) 418 { 419 $handle = opendir($dir); 420 if (is_resource($handle)) 421 { 422 while (($file = readdir($handle)) !== false) 423 { 424 $filelist[] = $file; 425 } 426 closedir($handle); 427 arsort($filelist); 428 429 foreach ($filelist as $file) 430 { 431 if (preg_match('/\.modules\.php$/i', $file) && preg_match('/^(pdf_|doc_)/', $file)) 432 { 433 if (file_exists($dir.'/'.$file)) 434 { 435 $name = substr($file, 4, dol_strlen($file) - 16); 436 $classname = substr($file, 0, dol_strlen($file) - 12); 437 438 require_once $dir.'/'.$file; 439 $module = new $classname($db); 440 441 $modulequalified = 1; 442 if ($module->version == 'development' && $conf->global->MAIN_FEATURES_LEVEL < 2) $modulequalified = 0; 443 if ($module->version == 'experimental' && $conf->global->MAIN_FEATURES_LEVEL < 1) $modulequalified = 0; 444 445 if ($modulequalified) 446 { 447 print '<tr class="oddeven"><td width="100">'; 448 print (empty($module->name) ? $name : $module->name); 449 print "</td><td>\n"; 450 if (method_exists($module, 'info')) print $module->info($langs); 451 else print $module->description; 452 print '</td>'; 453 454 // Active 455 if (in_array($name, $def)) 456 { 457 print '<td class="center">'."\n"; 458 print '<a href="'.$_SERVER["PHP_SELF"].'?action=del&value='.$name.'">'; 459 print img_picto($langs->trans("Enabled"), 'switch_on'); 460 print '</a>'; 461 print '</td>'; 462 } else { 463 print '<td class="center">'."\n"; 464 print '<a href="'.$_SERVER["PHP_SELF"].'?action=set&token='.newToken().'&value='.$name.'&scan_dir='.$module->scandir.'&label='.urlencode($module->name).'">'.img_picto($langs->trans("Disabled"), 'switch_off').'</a>'; 465 print "</td>"; 466 } 467 468 // Defaut 469 print '<td class="center">'; 470 if ($conf->global->PRODUCT_ADDON_PDF == $name) 471 { 472 print img_picto($langs->trans("Default"), 'on'); 473 } else { 474 print '<a href="'.$_SERVER["PHP_SELF"].'?action=setdoc&token='.newToken().'&value='.$name.'&scan_dir='.$module->scandir.'&label='.urlencode($module->name).'" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("Disabled"), 'off').'</a>'; 475 } 476 print '</td>'; 477 478 // Info 479 $htmltooltip = ''.$langs->trans("Name").': '.$module->name; 480 $htmltooltip .= '<br>'.$langs->trans("Type").': '.($module->type ? $module->type : $langs->trans("Unknown")); 481 if ($module->type == 'pdf') 482 { 483 $htmltooltip .= '<br>'.$langs->trans("Width").'/'.$langs->trans("Height").': '.$module->page_largeur.'/'.$module->page_hauteur; 484 } 485 $htmltooltip .= '<br><br><u>'.$langs->trans("FeaturesSupported").':</u>'; 486 $htmltooltip .= '<br>'.$langs->trans("Logo").': '.yn($module->option_logo, 1, 1); 487 $htmltooltip .= '<br>'.$langs->trans("MultiLanguage").': '.yn($module->option_multilang, 1, 1); 488 489 490 print '<td class="center">'; 491 print $form->textwithpicto('', $htmltooltip, 1, 0); 492 print '</td>'; 493 494 // Preview 495 print '<td class="center">'; 496 if ($module->type == 'pdf') 497 { 498 print '<a href="'.$_SERVER["PHP_SELF"].'?action=specimen&module='.$name.'">'.img_object($langs->trans("Preview"), 'contract').'</a>'; 499 } else { 500 print img_object($langs->trans("PreviewNotAvailable"), 'generic'); 501 } 502 print '</td>'; 503 504 print "</tr>\n"; 505 } 506 } 507 } 508 } 509 } 510 } 511 } 512} 513 514print '</table>'; 515print "<br>"; 516 517/* 518 * Other conf 519 */ 520 521print "<br>"; 522 523print load_fiche_titre($langs->trans("ProductOtherConf"), '', ''); 524 525 526print '<form method="POST" action="'.$_SERVER['PHP_SELF'].'">'; 527print '<input type="hidden" name="token" value="'.newToken().'">'; 528print '<input type="hidden" name="action" value="other">'; 529print '<input type="hidden" name="page_y" value="">'; 530 531print '<table class="noborder centpercent">'; 532print '<tr class="liste_titre">'; 533print '<td>'.$langs->trans("Parameters").'</td>'."\n"; 534print '<td class="right" width="60">'.$langs->trans("Value").'</td>'."\n"; 535print '</tr>'."\n"; 536 537 538// Enable kits (subproducts) 539 540print '<tr class="oddeven">'; 541print '<td>'.$langs->trans("AssociatedProductsAbility").'</td>'; 542print '<td class="right">'; 543print ajax_constantonoff("PRODUIT_SOUSPRODUITS", array(), $conf->entity, 0, 0, 1, 0); 544//print $form->selectyesno("PRODUIT_SOUSPRODUITS", $conf->global->PRODUIT_SOUSPRODUITS, 1); 545print '</td>'; 546print '</tr>'; 547 548 549// Enable variants 550 551print '<tr class="oddeven">'; 552print '<td>'.$langs->trans("VariantsAbility").'</td>'; 553print '<td class="right">'; 554//print ajax_constantonoff("PRODUIT_SOUSPRODUITS", array(), $conf->entity, 0, 0, 1, 0); 555//print $form->selectyesno("PRODUIT_SOUSPRODUITS", $conf->global->PRODUIT_SOUSPRODUITS, 1); 556if (empty($conf->variants->enabled)) { 557 print '<span class="opacitymedium">'.$langs->trans("ModuleMustBeEnabled", $langs->transnoentitiesnoconv("Module610Name")).'</span>'; 558} else { 559 print yn(1).' <span class="opacitymedium">('.$langs->trans("ModuleIsEnabled", $langs->transnoentitiesnoconv("Module610Name")).')</span>'; 560} 561print '</td>'; 562print '</tr>'; 563 564 565// Rule for price 566 567print '<tr class="oddeven">'; 568if (empty($conf->multicompany->enabled)) 569{ 570 print '<td>'.$langs->trans("PricingRule").'</td>'; 571} else { 572 print '<td>'.$form->textwithpicto($langs->trans("PricingRule"), $langs->trans("SamePriceAlsoForSharedCompanies"), 1).'</td>'; 573} 574print '<td class="right">'; 575$current_rule = 'PRODUCT_PRICE_UNIQ'; 576if (!empty($conf->global->PRODUIT_MULTIPRICES)) $current_rule = 'PRODUIT_MULTIPRICES'; 577if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY)) $current_rule = 'PRODUIT_CUSTOMER_PRICES_BY_QTY'; 578if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES)) $current_rule = 'PRODUIT_CUSTOMER_PRICES'; 579if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES)) $current_rule = 'PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES'; 580print $form->selectarray("princingrule", $select_pricing_rules, $current_rule); 581print '</td>'; 582print '</tr>'; 583 584 585// multiprix nombre de prix a proposer 586if (!empty($conf->global->PRODUIT_MULTIPRICES) || !empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES)) 587{ 588 print '<tr class="oddeven">'; 589 print '<td>'.$langs->trans("MultiPricesNumPrices").'</td>'; 590 print '<td class="right"><input size="3" type="text" class="flat" name="value_PRODUIT_MULTIPRICES_LIMIT" value="'.$conf->global->PRODUIT_MULTIPRICES_LIMIT.'"></td>'; 591 print '</tr>'; 592} 593 594// Default product price base type 595print '<tr class="oddeven">'; 596print '<td>'.$langs->trans("DefaultPriceType").'</td>'; 597print '<td class="right">'; 598print $form->selectPriceBaseType($conf->global->PRODUCT_PRICE_BASE_TYPE, "price_base_type"); 599print '</td>'; 600print '</tr>'; 601 602// Use Ajax form to select a product 603 604print '<tr class="oddeven">'; 605print '<td>'.$form->textwithpicto($langs->trans("UseSearchToSelectProduct"), $langs->trans('UseSearchToSelectProductTooltip'), 1).'</td>'; 606if (empty($conf->use_javascript_ajax)) 607{ 608 print '<td class="nowrap right">'; 609 print $langs->trans("NotAvailableWhenAjaxDisabled"); 610 print '</td>'; 611} else { 612 print '<td class="right">'; 613 $arrval = array( 614 '0'=>$langs->trans("No"), 615 '1'=>$langs->trans("Yes").' ('.$langs->trans("NumberOfKeyToSearch", 1).')', 616 '2'=>$langs->trans("Yes").' ('.$langs->trans("NumberOfKeyToSearch", 2).')', 617 '3'=>$langs->trans("Yes").' ('.$langs->trans("NumberOfKeyToSearch", 3).')', 618 ); 619 print $form->selectarray("activate_usesearchtoselectproduct", $arrval, $conf->global->PRODUIT_USE_SEARCH_TO_SELECT); 620 print '</td>'; 621} 622print '</tr>'; 623 624if (empty($conf->global->PRODUIT_USE_SEARCH_TO_SELECT)) 625{ 626 print '<tr class="oddeven">'; 627 print '<td>'.$langs->trans("NumberOfProductShowInSelect").'</td>'; 628 print '<td class="right"><input size="3" type="text" class="flat" name="value_PRODUIT_LIMIT_SIZE" value="'.$conf->global->PRODUIT_LIMIT_SIZE.'"></td>'; 629 print '</tr>'; 630} 631 632// Visualiser description produit dans les formulaires activation/desactivation 633print '<tr class="oddeven">'; 634print '<td>'.$langs->trans("ViewProductDescInFormAbility").'</td>'; 635print '<td class="right">'; 636print $form->selectyesno("activate_viewProdDescInForm", $conf->global->PRODUIT_DESC_IN_FORM, 1); 637print '</td>'; 638print '</tr>'; 639 640// Activate propal merge produt card 641/* Kept as hidden feature only. PRODUIT_PDF_MERGE_PROPAL can be added manually. Still did not understand how this feature works. 642 643print '<tr class="oddeven">'; 644print '<td>'.$langs->trans("MergePropalProductCard").'</td>'; 645print '<td class="right">'; 646print $form->selectyesno("activate_mergePropalProductCard",$conf->global->PRODUIT_PDF_MERGE_PROPAL,1); 647print '</td>'; 648print '</tr>'; 649*/ 650 651// Use units 652/* Kept as hidden feature only. PRODUCT_USE_UNITS is hidden for the moment. Because it seems to be a duplicated feature with already existing field to store unit of product 653 654print '<tr class="oddeven">'; 655print '<td>'.$langs->trans("UseUnits").'</td>'; 656print '<td class="right">'; 657print $form->selectyesno("activate_units",$conf->global->PRODUCT_USE_UNITS,1); 658print '</td>'; 659print '</tr>'; 660*/ 661 662// View product description in thirdparty language 663if (!empty($conf->global->MAIN_MULTILANGS)) 664{ 665 print '<tr class="oddeven">'; 666 print '<td>'.$langs->trans("ViewProductDescInThirdpartyLanguageAbility").'</td>'; 667 print '<td class="right">'; 668 print $form->selectyesno("activate_viewProdTextsInThirdpartyLanguage", (!empty($conf->global->PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE) ? $conf->global->PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE : 0), 1); 669 print '</td>'; 670 print '</tr>'; 671} 672 673if (!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) || !empty($conf->supplier_order->enabled) || !empty($conf->supplier_invoice->enabled)) 674{ 675 print '<tr class="oddeven">'; 676 print '<td>'.$langs->trans("UseProductFournDesc").'</td>'; 677 print '<td class="right">'; 678 print $form->selectyesno("activate_useProdFournDesc", (!empty($conf->global->PRODUIT_FOURN_TEXTS) ? $conf->global->PRODUIT_FOURN_TEXTS : 0), 1); 679 print '</td>'; 680 print '</tr>'; 681 682 print '<tr class="oddeven">'; 683 print '<td>'.$langs->trans("UseProductSupplierPackaging").'</td>'; 684 print '<td align="right">'; 685 print $form->selectyesno("activate_useProdSupplierPackaging", (!empty($conf->global->PRODUCT_USE_SUPPLIER_PACKAGING) ? $conf->global->PRODUCT_USE_SUPPLIER_PACKAGING : 0), 1); 686 print '</td>'; 687 print '</tr>'; 688} 689 690 691if (!empty($conf->global->PRODUCT_CANVAS_ABILITY)) 692{ 693 // Add canvas feature 694 $dir = DOL_DOCUMENT_ROOT."/product/canvas/"; 695 696 print '<tr class="liste_titre">'; 697 print '<td>'.$langs->trans("ProductSpecial").'</td>'."\n"; 698 print '<td class="right">'.$langs->trans("Value").'</td>'."\n"; 699 print '</tr>'."\n"; 700 701 if (is_dir($dir)) 702 { 703 require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; 704 705 $handle = opendir($dir); 706 if (is_resource($handle)) 707 { 708 while (($file = readdir($handle)) !== false) 709 { 710 if (file_exists($dir.$file.'/product.'.$file.'.class.php')) 711 { 712 $classfile = $dir.$file.'/product.'.$file.'.class.php'; 713 $classname = 'Product'.ucfirst($file); 714 715 require_once $classfile; 716 $object = new $classname(); 717 718 $module = $object->module; 719 720 if ($conf->$module->enabled) 721 { 722 print '<tr class="oddeven"><td>'; 723 724 print $object->description; 725 726 print '</td><td class="right">'; 727 728 $const = "PRODUCT_SPECIAL_".strtoupper($file); 729 730 if ($conf->global->$const) 731 { 732 print img_picto($langs->trans("Active"), 'tick'); 733 print '</td><td class="right">'; 734 print '<a href="'.$_SERVER["PHP_SELF"].'?action=set&token='.newToken().'&spe='.urlencode($file).'&value=0">'.$langs->trans("Disable").'</a>'; 735 } else { 736 print ' </td><td class="right">'; 737 print '<a href="'.$_SERVER["PHP_SELF"].'?action=set&token='.newToken().'&spe='.urlencode($file).'&value=1">'.$langs->trans("Activate").'</a>'; 738 } 739 740 print '</td></tr>'; 741 } 742 } 743 } 744 closedir($handle); 745 } 746 } else { 747 setEventMessages($dir.' '.$langs->trans("IsNotADir"), null, 'errors'); 748 } 749} 750 751print '</table>'; 752 753print '<div class="center">'; 754print '<input type="submit" class="button reposition" value="'.$langs->trans("Modify").'">'; 755print '</div>'; 756 757print '</form>'; 758 759// End of page 760llxFooter(); 761$db->close(); 762