dolibarr  16.0.5
product.php
Go to the documentation of this file.
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 
33 require '../../main.inc.php';
34 require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
35 require_once DOL_DOCUMENT_ROOT.'/core/lib/product.lib.php';
36 require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
37 require_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
43 if (!$user->admin || (empty($conf->product->enabled) && empty($conf->service->enabled))) {
45 }
46 
47 $action = GETPOST('action', 'aZ09');
48 $value = GETPOST('value', 'alpha');
49 $modulepart = GETPOST('modulepart', 'aZ09'); // Used by actions_setmoduleoptions.inc.php
50 
51 $label = GETPOST('label', 'alpha');
52 $scandir = GETPOST('scan_dir', 'alpha');
53 $type = 'product';
54 
55 // Pricing Rules
56 $select_pricing_rules = array(
57  'PRODUCT_PRICE_UNIQ'=>$langs->trans('PriceCatalogue'), // Unique price
58  'PRODUIT_MULTIPRICES'=>$langs->trans('MultiPricesAbility'), // Several prices according to a customer level
59  'PRODUIT_CUSTOMER_PRICES'=>$langs->trans('PriceByCustomer'), // Different price for each customer
60 );
61 $keyforparam = 'PRODUIT_CUSTOMER_PRICES_BY_QTY';
62 if ($conf->global->MAIN_FEATURES_LEVEL >= 1 || !empty($conf->global->$keyforparam)) {
63  $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
64 }
65 $keyforparam = 'PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES';
66 if ($conf->global->MAIN_FEATURES_LEVEL >= 2 || !empty($conf->global->$keyforparam)) {
67  $select_pricing_rules['PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES'] = $langs->trans('MultiPricesAbility').'+'.$langs->trans('PriceByQuantity').' ('.$langs->trans("VersionExperimental").')';
68 }
69 
70 // Clean param
71 if (!empty($conf->global->PRODUIT_MULTIPRICES) && empty($conf->global->PRODUIT_MULTIPRICES_LIMIT)) {
72  dolibarr_set_const($db, 'PRODUIT_MULTIPRICES_LIMIT', 5, 'chaine', 0, '', $conf->entity);
73 }
74 
75 $error = 0;
76 
77 
78 /*
79  * Actions
80  */
81 
82 $nomessageinsetmoduleoptions = 1;
83 include DOL_DOCUMENT_ROOT.'/core/actions_setmoduleoptions.inc.php';
84 
85 if ($action == 'setcodeproduct') {
86  if (dolibarr_set_const($db, "PRODUCT_CODEPRODUCT_ADDON", $value, 'chaine', 0, '', $conf->entity) > 0) {
87  header("Location: ".$_SERVER["PHP_SELF"]);
88  exit;
89  } else {
90  dol_print_error($db);
91  }
92 }
93 
94 if ($action == 'other' && GETPOST('value_PRODUIT_LIMIT_SIZE') >= 0) {
95  $res = dolibarr_set_const($db, "PRODUIT_LIMIT_SIZE", GETPOST('value_PRODUIT_LIMIT_SIZE'), 'chaine', 0, '', $conf->entity);
96  if (!($res > 0)) {
97  $error++;
98  }
99 }
100 if ($action == 'other' && GETPOST('value_PRODUIT_MULTIPRICES_LIMIT') > 0) {
101  $res = dolibarr_set_const($db, "PRODUIT_MULTIPRICES_LIMIT", GETPOST('value_PRODUIT_MULTIPRICES_LIMIT'), 'chaine', 0, '', $conf->entity);
102  if (!($res > 0)) {
103  $error++;
104  }
105 }
106 if ($action == 'other') {
107  $princingrules = GETPOST('princingrule', 'alpha');
108  foreach ($select_pricing_rules as $rule => $label) { // Loop on each possible mode
109  if ($rule == $princingrules) { // We are on selected rule, we enable it
110  if ($princingrules == 'PRODUCT_PRICE_UNIQ') { // For this case, we disable entries manually
111  $res = dolibarr_set_const($db, 'PRODUIT_MULTIPRICES', 0, 'chaine', 0, '', $conf->entity);
112  $res = dolibarr_set_const($db, 'PRODUIT_CUSTOMER_PRICES_BY_QTY', 0, 'chaine', 0, '', $conf->entity);
113  $res = dolibarr_set_const($db, 'PRODUIT_CUSTOMER_PRICES', 0, 'chaine', 0, '', $conf->entity);
114  dolibarr_set_const($db, 'PRODUCT_PRICE_UNIQ', 1, 'chaine', 0, '', $conf->entity);
115  } else {
116  $multirule = explode('&', $princingrules);
117  foreach ($multirule as $rulesselected) {
118  $res = dolibarr_set_const($db, $rulesselected, 1, 'chaine', 0, '', $conf->entity);
119  }
120  }
121  } else // We clear this mode
122  {
123  if (strpos($rule, '&') === false) {
124  $res = dolibarr_set_const($db, $rule, 0, 'chaine', 0, '', $conf->entity);
125  }
126  }
127  }
128 
129  $value = GETPOST('price_base_type', 'alpha');
130  $res = dolibarr_set_const($db, "PRODUCT_PRICE_BASE_TYPE", $value, 'chaine', 0, '', $conf->entity);
131 
132  /*$value = GETPOST('PRODUIT_SOUSPRODUITS', 'alpha');
133  $res = dolibarr_set_const($db, "PRODUIT_SOUSPRODUITS", $value, 'chaine', 0, '', $conf->entity);*/
134 
135  $value = GETPOST('activate_viewProdDescInForm', 'alpha');
136  $res = dolibarr_set_const($db, "PRODUIT_DESC_IN_FORM", $value, 'chaine', 0, '', $conf->entity);
137 
138  $value = GETPOST('activate_viewProdTextsInThirdpartyLanguage', 'alpha');
139  $res = dolibarr_set_const($db, "PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE", $value, 'chaine', 0, '', $conf->entity);
140 
141  $value = GETPOST('activate_mergePropalProductCard', 'alpha');
142  $res = dolibarr_set_const($db, "PRODUIT_PDF_MERGE_PROPAL", $value, 'chaine', 0, '', $conf->entity);
143 
144  $value = GETPOST('activate_usesearchtoselectproduct', 'alpha');
145  $res = dolibarr_set_const($db, "PRODUIT_USE_SEARCH_TO_SELECT", $value, 'chaine', 0, '', $conf->entity);
146 
147  $value = GETPOST('activate_FillProductDescAuto', 'alpha');
148  $res = dolibarr_set_const($db, "PRODUIT_AUTOFILL_DESC", $value, 'chaine', 0, '', $conf->entity);
149 
150  $value = GETPOST('PRODUIT_FOURN_TEXTS', 'alpha');
151  $res = dolibarr_set_const($db, "PRODUIT_FOURN_TEXTS", $value, 'chaine', 0, '', $conf->entity);
152 
153  $value = GETPOST('PRODUCT_USE_SUPPLIER_PACKAGING', 'alpha');
154  $res = dolibarr_set_const($db, "PRODUCT_USE_SUPPLIER_PACKAGING", $value, 'chaine', 0, '', $conf->entity);
155 }
156 
157 
158 if ($action == 'specimen') { // For products
159  $modele = GETPOST('module', 'alpha');
160 
161  $product = new Product($db);
162  $product->initAsSpecimen();
163 
164  // Search template files
165  $file = ''; $classname = ''; $filefound = 0;
166  $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
167  foreach ($dirmodels as $reldir) {
168  $file = dol_buildpath($reldir."core/modules/product/doc/pdf_".$modele.".modules.php", 0);
169  if (file_exists($file)) {
170  $filefound = 1;
171  $classname = "pdf_".$modele;
172  break;
173  }
174  }
175 
176  if ($filefound) {
177  require_once $file;
178 
179  $module = new $classname($db);
180 
181  if ($module->write_file($product, $langs, '') > 0) {
182  header("Location: ".DOL_URL_ROOT."/document.php?modulepart=product&file=SPECIMEN.pdf");
183  return;
184  } else {
185  setEventMessages($obj->error, $obj->errors, 'errors');
186  dol_syslog($obj->error, LOG_ERR);
187  }
188  } else {
189  setEventMessages($langs->trans("ErrorModuleNotFound"), null, 'errors');
190  dol_syslog($langs->trans("ErrorModuleNotFound"), LOG_ERR);
191  }
192 }
193 
194 // Activate a model
195 if ($action == 'set') {
196  $ret = addDocumentModel($value, $type, $label, $scandir);
197 }
198 
199 if ($action == 'del') {
200  $ret = delDocumentModel($value, $type);
201  if ($ret > 0) {
202  if ($conf->global->PRODUCT_ADDON_PDF == "$value") {
203  dolibarr_del_const($db, 'PRODUCT_ADDON_PDF', $conf->entity);
204  }
205  }
206 }
207 
208 // Set default model
209 if ($action == 'setdoc') {
210  if (dolibarr_set_const($db, "PRODUCT_ADDON_PDF", $value, 'chaine', 0, '', $conf->entity)) {
211  // La constante qui a ete lue en avant du nouveau set
212  // on passe donc par une variable pour avoir un affichage coherent
213  $conf->global->PRODUCT_ADDON_PDF = $value;
214  }
215 
216  // On active le modele
217  $ret = delDocumentModel($value, $type);
218  if ($ret > 0) {
219  $ret = addDocumentModel($value, $type, $label, $scandir);
220  }
221 }
222 
223 
224 if ($action == 'set') {
225  $const = "PRODUCT_SPECIAL_".strtoupper(GETPOST('spe', 'alpha'));
226  $value = GETPOST('value');
227  if (GETPOST('value', 'alpha')) {
228  $res = dolibarr_set_const($db, $const, $value, 'chaine', 0, '', $conf->entity);
229  } else {
230  $res = dolibarr_del_const($db, $const, $conf->entity);
231  }
232  if (!($res > 0)) {
233  $error++;
234  }
235 }
236 
237 // To enable a constant whithout javascript
238 if (preg_match('/set_(.+)/', $action, $reg)) {
239  $keyforvar = $reg[1];
240  if ($keyforvar) {
241  $value = 1;
242  $res = dolibarr_set_const($db, $keyforvar, $value, 'chaine', 0, '', $conf->entity);
243  }
244 }
245 
246 // To disable a constant whithout javascript
247 if (preg_match('/del_(.+)/', $action, $reg)) {
248  $keyforvar = $reg[1];
249  if ($keyforvar) {
250  $res = dolibarr_del_const($db, $keyforvar, $conf->entity);
251  }
252 }
253 
254 if ($action) {
255  if (!$error) {
256  setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
257  } else {
258  setEventMessages($langs->trans("SetupNotError"), null, 'errors');
259  }
260 }
261 
262 /*
263  * View
264  */
265 
266 $formbarcode = new FormBarCode($db);
267 
268 $title = $langs->trans('ProductServiceSetup');
269 $tab = $langs->trans("ProductsAndServices");
270 if (empty($conf->product->enabled)) {
271  $title = $langs->trans('ServiceSetup');
272  $tab = $langs->trans('Services');
273 } elseif (empty($conf->service->enabled)) {
274  $title = $langs->trans('ProductSetup');
275  $tab = $langs->trans('Products');
276 }
277 
278 llxHeader('', $title);
279 
280 $linkback = '<a href="'.DOL_URL_ROOT.'/admin/modules.php?restore_lastsearch_values=1">'.$langs->trans("BackToModuleList").'</a>';
281 print load_fiche_titre($title, $linkback, 'title_setup');
282 
284 print dol_get_fiche_head($head, 'general', $tab, -1, 'product');
285 
286 $form = new Form($db);
287 
288 // Module to manage product / services code
289 $dirproduct = array('/core/modules/product/');
290 $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
291 
292 print load_fiche_titre($langs->trans("ProductCodeChecker"), '', '');
293 
294 print '<div class="div-table-responsive-no-min">';
295 print '<table class="noborder centpercent">'."\n";
296 print '<tr class="liste_titre">'."\n";
297 print ' <td>'.$langs->trans("Name").'</td>';
298 print ' <td>'.$langs->trans("Description").'</td>';
299 print ' <td>'.$langs->trans("Example").'</td>';
300 print ' <td class="center" width="80">'.$langs->trans("Status").'</td>';
301 print ' <td class="center"></td>';
302 print "</tr>\n";
303 
304 foreach ($dirproduct as $dirroot) {
305  $dir = dol_buildpath($dirroot, 0);
306 
307  $handle = @opendir($dir);
308  if (is_resource($handle)) {
309  // Loop on each module find in opened directory
310  while (($file = readdir($handle)) !== false) {
311  if (substr($file, 0, 16) == 'mod_codeproduct_' && substr($file, -3) == 'php') {
312  $file = substr($file, 0, dol_strlen($file) - 4);
313 
314  try {
315  dol_include_once($dirroot.$file.'.php');
316  } catch (Exception $e) {
317  dol_syslog($e->getMessage(), LOG_ERR);
318  }
319 
320  $modCodeProduct = new $file;
321 
322  // Show modules according to features level
323  if ($modCodeProduct->version == 'development' && $conf->global->MAIN_FEATURES_LEVEL < 2) {
324  continue;
325  }
326  if ($modCodeProduct->version == 'experimental' && $conf->global->MAIN_FEATURES_LEVEL < 1) {
327  continue;
328  }
329 
330  print '<tr class="oddeven">'."\n";
331  print '<td width="140">'.$modCodeProduct->name.'</td>'."\n";
332  print '<td>'.$modCodeProduct->info($langs).'</td>'."\n";
333  print '<td class="nowrap"><span class="opacitymedium">'.$modCodeProduct->getExample($langs).'</span></td>'."\n";
334 
335  if (!empty($conf->global->PRODUCT_CODEPRODUCT_ADDON) && $conf->global->PRODUCT_CODEPRODUCT_ADDON == $file) {
336  print '<td class="center">'."\n";
337  print img_picto($langs->trans("Activated"), 'switch_on');
338  print "</td>\n";
339  } else {
340  $disabled = false;
341  if (!empty($conf->multicompany->enabled) && (is_object($mc) && !empty($mc->sharings['referent']) && $mc->sharings['referent'] == $conf->entity) ? false : true) {
342  }
343  print '<td class="center">';
344  if (!$disabled) {
345  print '<a class="reposition" href="'.$_SERVER['PHP_SELF'].'?action=setcodeproduct&token='.newToken().'&value='.urlencode($file).'">';
346  }
347  print img_picto($langs->trans("Disabled"), 'switch_off');
348  if (!$disabled) {
349  print '</a>';
350  }
351  print '</td>';
352  }
353 
354  print '<td class="center">';
355  $s = $modCodeProduct->getToolTip($langs, null, -1);
356  print $form->textwithpicto('', $s, 1);
357  print '</td>';
358 
359  print '</tr>';
360  }
361  }
362  closedir($handle);
363  }
364 }
365 print '</table>';
366 print '</div>';
367 
368 // Module to build doc
369 $def = array();
370 $sql = "SELECT nom";
371 $sql .= " FROM ".MAIN_DB_PREFIX."document_model";
372 $sql .= " WHERE type = '".$db->escape($type)."'";
373 $sql .= " AND entity = ".$conf->entity;
374 $resql = $db->query($sql);
375 if ($resql) {
376  $i = 0;
377  $num_rows = $db->num_rows($resql);
378  while ($i < $num_rows) {
379  $array = $db->fetch_array($resql);
380  array_push($def, $array[0]);
381  $i++;
382  }
383 } else {
384  dol_print_error($db);
385 }
386 
387 print '<br>';
388 
389 print load_fiche_titre($langs->trans("ProductDocumentTemplates"), '', '');
390 
391 print '<div class="div-table-responsive-no-min">';
392 print '<table class="noborder centpercent">';
393 print '<tr class="liste_titre">';
394 print '<td>'.$langs->trans("Name").'</td>';
395 print '<td>'.$langs->trans("Description").'</td>';
396 print '<td class="center" width="60">'.$langs->trans("Status")."</td>\n";
397 print '<td class="center" width="60">'.$langs->trans("Default")."</td>\n";
398 print '<td class="center"></td>';
399 print '<td class="center" width="80">'.$langs->trans("Preview").'</td>';
400 print "</tr>\n";
401 
402 clearstatcache();
403 
404 foreach ($dirmodels as $reldir) {
405  foreach (array('', '/doc') as $valdir) {
406  $dir = dol_buildpath($reldir."core/modules/product".$valdir);
407  if (is_dir($dir)) {
408  $handle = opendir($dir);
409  if (is_resource($handle)) {
410  while (($file = readdir($handle)) !== false) {
411  $filelist[] = $file;
412  }
413  closedir($handle);
414  arsort($filelist);
415 
416  foreach ($filelist as $file) {
417  if (preg_match('/\.modules\.php$/i', $file) && preg_match('/^(pdf_|doc_)/', $file)) {
418  if (file_exists($dir.'/'.$file)) {
419  $name = substr($file, 4, dol_strlen($file) - 16);
420  $classname = substr($file, 0, dol_strlen($file) - 12);
421 
422  require_once $dir.'/'.$file;
423  $module = new $classname($db);
424 
425  $modulequalified = 1;
426  if ($module->version == 'development' && $conf->global->MAIN_FEATURES_LEVEL < 2) {
427  $modulequalified = 0;
428  }
429  if ($module->version == 'experimental' && $conf->global->MAIN_FEATURES_LEVEL < 1) {
430  $modulequalified = 0;
431  }
432 
433  if ($modulequalified) {
434  print '<tr class="oddeven"><td width="100">';
435  print (empty($module->name) ? $name : $module->name);
436  print "</td><td>\n";
437  if (method_exists($module, 'info')) {
438  print $module->info($langs);
439  } else {
440  print $module->description;
441  }
442  print '</td>';
443 
444  // Active
445  if (in_array($name, $def)) {
446  print '<td class="center">'."\n";
447  print '<a href="'.$_SERVER["PHP_SELF"].'?action=del&token='.newToken().'&value='.urlencode($name).'">';
448  print img_picto($langs->trans("Enabled"), 'switch_on');
449  print '</a>';
450  print '</td>';
451  } else {
452  print '<td class="center">'."\n";
453  print '<a href="'.$_SERVER["PHP_SELF"].'?action=set&token='.newToken().'&value='.urlencode($name).'&scan_dir='.urlencode($module->scandir).'&label='.urlencode($module->name).'">'.img_picto($langs->trans("Disabled"), 'switch_off').'</a>';
454  print "</td>";
455  }
456 
457  // Defaut
458  print '<td class="center">';
459  if ($conf->global->PRODUCT_ADDON_PDF == $name) {
460  print img_picto($langs->trans("Default"), 'on');
461  } else {
462  print '<a href="'.$_SERVER["PHP_SELF"].'?action=setdoc&token='.newToken().'&value='.urlencode($name).'&scan_dir='.urlencode($module->scandir).'&label='.urlencode($module->name).'" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("Disabled"), 'off').'</a>';
463  }
464  print '</td>';
465 
466  // Info
467  $htmltooltip = ''.$langs->trans("Name").': '.$module->name;
468  $htmltooltip .= '<br>'.$langs->trans("Type").': '.($module->type ? $module->type : $langs->trans("Unknown"));
469  if ($module->type == 'pdf') {
470  $htmltooltip .= '<br>'.$langs->trans("Width").'/'.$langs->trans("Height").': '.$module->page_largeur.'/'.$module->page_hauteur;
471  }
472  $htmltooltip .= '<br><br><u>'.$langs->trans("FeaturesSupported").':</u>';
473  $htmltooltip .= '<br>'.$langs->trans("Logo").': '.yn($module->option_logo, 1, 1);
474  $htmltooltip .= '<br>'.$langs->trans("MultiLanguage").': '.yn($module->option_multilang, 1, 1);
475 
476 
477  print '<td class="center">';
478  print $form->textwithpicto('', $htmltooltip, 1, 0);
479  print '</td>';
480 
481  // Preview
482  print '<td class="center">';
483  if ($module->type == 'pdf') {
484  print '<a href="'.$_SERVER["PHP_SELF"].'?action=specimen&module='.$name.'">'.img_object($langs->trans("Preview"), 'contract').'</a>';
485  } else {
486  print img_object($langs->trans("PreviewNotAvailable"), 'generic');
487  }
488  print '</td>';
489 
490  print "</tr>\n";
491  }
492  }
493  }
494  }
495  }
496  }
497  }
498 }
499 
500 print '</table>';
501 print '</div>';
502 
503 print "<br>";
504 
505 /*
506  * Other conf
507  */
508 
509 print "<br>";
510 
511 
512 print '<form method="POST" action="'.$_SERVER['PHP_SELF'].'">';
513 print '<input type="hidden" name="token" value="'.newToken().'">';
514 print '<input type="hidden" name="action" value="other">';
515 print '<input type="hidden" name="page_y" value="">';
516 
517 
518 print load_fiche_titre($langs->trans("ProductOtherConf"), '', '');
519 
520 
521 print '<div class="div-table-responsive-no-min">';
522 print '<table class="noborder centpercent">';
523 print '<tr class="liste_titre">';
524 print '<td>'.$langs->trans("Parameters").'</td>'."\n";
525 print '<td class="right" width="60">'.$langs->trans("Value").'</td>'."\n";
526 print '</tr>'."\n";
527 
528 
529 // Enable kits (subproducts)
530 
531 print '<tr class="oddeven">';
532 print '<td>'.$langs->trans("AssociatedProductsAbility").'</td>';
533 print '<td class="right">';
534 print ajax_constantonoff("PRODUIT_SOUSPRODUITS", array(), $conf->entity, 0, 0, 1, 0);
535 //print $form->selectyesno("PRODUIT_SOUSPRODUITS", $conf->global->PRODUIT_SOUSPRODUITS, 1);
536 print '</td>';
537 print '</tr>';
538 
539 
540 // Enable variants
541 
542 print '<tr class="oddeven">';
543 print '<td>'.$langs->trans("VariantsAbility").'</td>';
544 print '<td class="right">';
545 //print ajax_constantonoff("PRODUIT_SOUSPRODUITS", array(), $conf->entity, 0, 0, 1, 0);
546 //print $form->selectyesno("PRODUIT_SOUSPRODUITS", $conf->global->PRODUIT_SOUSPRODUITS, 1);
547 if (empty($conf->variants->enabled)) {
548  print '<span class="opacitymedium">'.$langs->trans("ModuleMustBeEnabled", $langs->transnoentitiesnoconv("Module610Name")).'</span>';
549 } else {
550  print yn(1).' <span class="opacitymedium">('.$langs->trans("ModuleIsEnabled", $langs->transnoentitiesnoconv("Module610Name")).')</span>';
551 }
552 print '</td>';
553 print '</tr>';
554 
555 
556 // Rule for price
557 
558 print '<tr class="oddeven">';
559 if (empty($conf->multicompany->enabled)) {
560  print '<td>'.$langs->trans("PricingRule").'</td>';
561 } else {
562  print '<td>'.$form->textwithpicto($langs->trans("PricingRule"), $langs->trans("SamePriceAlsoForSharedCompanies"), 1).'</td>';
563 }
564 print '<td class="right">';
565 $current_rule = 'PRODUCT_PRICE_UNIQ';
566 if (!empty($conf->global->PRODUIT_MULTIPRICES)) {
567  $current_rule = 'PRODUIT_MULTIPRICES';
568 }
569 if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY)) {
570  $current_rule = 'PRODUIT_CUSTOMER_PRICES_BY_QTY';
571 }
572 if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES)) {
573  $current_rule = 'PRODUIT_CUSTOMER_PRICES';
574 }
575 if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES)) {
576  $current_rule = 'PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES';
577 }
578 print $form->selectarray("princingrule", $select_pricing_rules, $current_rule, 0, 0, 0, '', 1, 0, 0, '', 'maxwidth400', 1);
579 print '</td>';
580 print '</tr>';
581 
582 
583 // multiprix nombre de prix a proposer
584 if (!empty($conf->global->PRODUIT_MULTIPRICES) || !empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES)) {
585  print '<tr class="oddeven">';
586  print '<td>'.$langs->trans("MultiPricesNumPrices").'</td>';
587  print '<td class="right"><input size="3" type="text" class="flat right" name="value_PRODUIT_MULTIPRICES_LIMIT" value="'.$conf->global->PRODUIT_MULTIPRICES_LIMIT.'"></td>';
588  print '</tr>';
589 }
590 
591 // Default product price base type
592 print '<tr class="oddeven">';
593 print '<td>'.$langs->trans("DefaultPriceType").'</td>';
594 print '<td class="right">';
595 print $form->selectPriceBaseType($conf->global->PRODUCT_PRICE_BASE_TYPE, "price_base_type");
596 print '</td>';
597 print '</tr>';
598 
599 // Use conditionnement in buying
600 if ((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || !empty($conf->supplier_order->enabled) || !empty($conf->supplier_invoice->enabled)) {
601  print '<tr class="oddeven">';
602  print '<td>'.$form->textwithpicto($langs->trans("UseProductSupplierPackaging"), $langs->trans("PackagingForThisProductDesc")).'</td>';
603  print '<td align="right">';
604  print ajax_constantonoff("PRODUCT_USE_SUPPLIER_PACKAGING", array(), $conf->entity, 0, 0, 0, 0);
605  //print $form->selectyesno("activate_useProdSupplierPackaging", (!empty($conf->global->PRODUCT_USE_SUPPLIER_PACKAGING) ? $conf->global->PRODUCT_USE_SUPPLIER_PACKAGING : 0), 1);
606  print '</td>';
607  print '</tr>';
608 
609  print '<tr class="oddeven">';
610  print '<td>'.$langs->trans("UseProductFournDesc").'</td>';
611  print '<td class="right">';
612  print ajax_constantonoff("PRODUIT_FOURN_TEXTS", array(), $conf->entity, 0, 0, 0, 0);
613  //print $form->selectyesno("activate_useProdFournDesc", (!empty($conf->global->PRODUIT_FOURN_TEXTS) ? $conf->global->PRODUIT_FOURN_TEXTS : 0), 1);
614  print '</td>';
615  print '</tr>';
616 }
617 
618 print '</table>';
619 print '</div>';
620 
621 print '<div class="center">';
622 print '<input type="submit" class="button reposition" value="'.$langs->trans("Modify").'">';
623 print '</div>';
624 
625 
626 print load_fiche_titre($langs->trans("UserInterface"), '', '');
627 
628 
629 print '<div class="div-table-responsive-no-min">';
630 print '<table class="noborder centpercent">';
631 print '<tr class="liste_titre">';
632 print '<td>'.$langs->trans("Parameters").'</td>'."\n";
633 print '<td class="right" width="60">'.$langs->trans("Value").'</td>'."\n";
634 print '</tr>'."\n";
635 
636 // Use Ajax form to select a product
637 
638 print '<tr class="oddeven">';
639 print '<td>'.$form->textwithpicto($langs->trans("UseSearchToSelectProduct"), $langs->trans('UseSearchToSelectProductTooltip'), 1).'</td>';
640 if (empty($conf->use_javascript_ajax)) {
641  print '<td class="nowrap right">';
642  print $langs->trans("NotAvailableWhenAjaxDisabled");
643  print '</td>';
644 } else {
645  print '<td class="right">';
646  $arrval = array(
647  '0'=>$langs->trans("No"),
648  '1'=>$langs->trans("Yes").' ('.$langs->trans("NumberOfKeyToSearch", 1).')',
649  '2'=>$langs->trans("Yes").' ('.$langs->trans("NumberOfKeyToSearch", 2).')',
650  '3'=>$langs->trans("Yes").' ('.$langs->trans("NumberOfKeyToSearch", 3).')',
651  );
652  print $form->selectarray("activate_usesearchtoselectproduct", $arrval, $conf->global->PRODUIT_USE_SEARCH_TO_SELECT);
653  print '</td>';
654 }
655 print '</tr>';
656 
657 if (empty($conf->global->PRODUIT_USE_SEARCH_TO_SELECT)) {
658  print '<tr class="oddeven">';
659  print '<td>'.$langs->trans("NumberOfProductShowInSelect").'</td>';
660  print '<td class="right"><input size="3" type="text" class="flat" name="value_PRODUIT_LIMIT_SIZE" value="'.$conf->global->PRODUIT_LIMIT_SIZE.'"></td>';
661  print '</tr>';
662 }
663 
664 // Do Not Add Product description on add lines
665 print '<tr class="oddeven">';
666 print '<td>'.$langs->trans("OnProductSelectAddProductDesc").'</td>';
667 print '<td class="right">';
668 print '<!-- PRODUIT_AUTOFILL_DESC -->';
669 print $form->selectarray(
670  "activate_FillProductDescAuto",
671  array(0=>'DoNotAutofillButAutoConcat', 1=>'AutoFillFormFieldBeforeSubmit', 2=>'DoNotUseDescriptionOfProdut'),
672  empty($conf->global->PRODUIT_AUTOFILL_DESC) ? 0 : $conf->global->PRODUIT_AUTOFILL_DESC,
673  0,
674  0,
675  0,
676  '',
677  1,
678  0,
679  0,
680  '',
681  'minwidth100imp maxwidth400',
682  1
683 );
684 print '</td>';
685 print '</tr>';
686 
687 // Visualiser description produit dans les formulaires activation/desactivation
688 print '<tr class="oddeven">';
689 print '<td>'.$langs->trans("ViewProductDescInFormAbility").'</td>';
690 print '<td class="right">';
691 print $form->selectyesno("activate_viewProdDescInForm", $conf->global->PRODUIT_DESC_IN_FORM, 1);
692 print '</td>';
693 print '</tr>';
694 
695 // Activate propal merge produt card
696 /* Kept as hidden feature only. PRODUIT_PDF_MERGE_PROPAL can be added manually. Still did not understand how this feature works.
697 
698 print '<tr class="oddeven">';
699 print '<td>'.$langs->trans("MergePropalProductCard").'</td>';
700 print '<td class="right">';
701 print $form->selectyesno("activate_mergePropalProductCard",$conf->global->PRODUIT_PDF_MERGE_PROPAL,1);
702 print '</td>';
703 print '</tr>';
704 */
705 
706 // Use units
707 /* 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
708 
709 print '<tr class="oddeven">';
710 print '<td>'.$langs->trans("UseUnits").'</td>';
711 print '<td class="right">';
712 print $form->selectyesno("activate_units",$conf->global->PRODUCT_USE_UNITS,1);
713 print '</td>';
714 print '</tr>';
715 */
716 
717 // View product description in thirdparty language
718 if (!empty($conf->global->MAIN_MULTILANGS)) {
719  print '<tr class="oddeven">';
720  print '<td>'.$langs->trans("ViewProductDescInThirdpartyLanguageAbility").'</td>';
721  print '<td class="right">';
722  print $form->selectyesno("activate_viewProdTextsInThirdpartyLanguage", (!empty($conf->global->PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE) ? $conf->global->PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE : 0), 1);
723  print '</td>';
724  print '</tr>';
725 }
726 
727 
728 if (!empty($conf->global->PRODUCT_CANVAS_ABILITY)) {
729  // Add canvas feature
730  $dir = DOL_DOCUMENT_ROOT."/product/canvas/";
731 
732  print '<tr class="liste_titre">';
733  print '<td>'.$langs->trans("ProductSpecial").'</td>'."\n";
734  print '<td class="right">'.$langs->trans("Value").'</td>'."\n";
735  print '</tr>'."\n";
736 
737  if (is_dir($dir)) {
738  require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
739 
740  $handle = opendir($dir);
741  if (is_resource($handle)) {
742  while (($file = readdir($handle)) !== false) {
743  if (file_exists($dir.$file.'/product.'.$file.'.class.php')) {
744  $classfile = $dir.$file.'/product.'.$file.'.class.php';
745  $classname = 'Product'.ucfirst($file);
746 
747  require_once $classfile;
748  $object = new $classname();
749 
750  $module = $object->module;
751 
752  if ($conf->$module->enabled) {
753  print '<tr class="oddeven"><td>';
754 
755  print $object->description;
756 
757  print '</td><td class="right">';
758 
759  $const = "PRODUCT_SPECIAL_".strtoupper($file);
760 
761  if ($conf->global->$const) {
762  print img_picto($langs->trans("Active"), 'tick');
763  print '</td><td class="right">';
764  print '<a href="'.$_SERVER["PHP_SELF"].'?action=set&token='.newToken().'&spe='.urlencode($file).'&value=0">'.$langs->trans("Disable").'</a>';
765  } else {
766  print '&nbsp;</td><td class="right">';
767  print '<a href="'.$_SERVER["PHP_SELF"].'?action=set&token='.newToken().'&spe='.urlencode($file).'&value=1">'.$langs->trans("Activate").'</a>';
768  }
769 
770  print '</td></tr>';
771  }
772  }
773  }
774  closedir($handle);
775  }
776  } else {
777  setEventMessages($dir.' '.$langs->trans("IsNotADir"), null, 'errors');
778  }
779 }
780 
781 print '</table>';
782 print '</div>';
783 
784 print '<div class="center">';
785 print '<input type="submit" class="button reposition" value="'.$langs->trans("Modify").'">';
786 print '</div>';
787 
788 print '</form>';
789 
790 // End of page
791 llxFooter();
792 $db->close();
yn
yn($yesno, $case=1, $color=0)
Return yes or no in current language.
Definition: functions.lib.php:6491
llxFooter
llxFooter()
Empty footer.
Definition: wrapper.php:73
FormBarCode
Class to manage barcode HTML.
Definition: html.formbarcode.class.php:30
dolibarr_del_const
dolibarr_del_const($db, $name, $entity=1)
Delete a constant.
Definition: admin.lib.php:552
load_fiche_titre
load_fiche_titre($titre, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='')
Load a title with picto.
Definition: functions.lib.php:5204
GETPOST
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
Definition: functions.lib.php:484
dol_print_error
dol_print_error($db='', $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
Definition: functions.lib.php:4844
dol_include_once
if(!function_exists('dol_getprefix')) dol_include_once($relpath, $classname='')
Make an include_once using default root and alternate root if it fails.
Definition: functions.lib.php:1033
dol_buildpath
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
Definition: functions.lib.php:1062
$form
if($cancel &&! $id) if($action=='add' &&! $cancel) if($action=='delete') if($id) $form
Actions.
Definition: card.php:142
img_picto
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
Definition: functions.lib.php:3880
Exception
delDocumentModel
delDocumentModel($name, $type)
Delete document model used by doc generator.
Definition: admin.lib.php:1894
dol_syslog
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
Definition: functions.lib.php:1603
product_admin_prepare_head
product_admin_prepare_head()
Return array head with list of tabs to view object informations.
Definition: product.lib.php:275
ajax_constantonoff
ajax_constantonoff($code, $input=array(), $entity=null, $revertonoff=0, $strict=0, $forcereload=0, $marginleftonlyshort=2, $forcenoajax=0, $setzeroinsteadofdel=0, $suffix='', $mode='')
On/off button for constant.
Definition: ajax.lib.php:573
dol_get_fiche_head
dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limittoshow=0, $moretabssuffix='')
Show tabs of a record.
Definition: functions.lib.php:1822
dol_strlen
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
Definition: functions.lib.php:3747
newToken
newToken()
Return the value of token currently saved into session with name 'newtoken'.
Definition: functions.lib.php:10878
dolibarr_set_const
dolibarr_set_const($db, $name, $value, $type='chaine', $visible=0, $note='', $entity=1)
Insert a parameter (key,value) into database (delete old key then insert it again).
Definition: admin.lib.php:627
addDocumentModel
addDocumentModel($name, $type, $label='', $description='')
Add document model used by doc generator.
Definition: admin.lib.php:1863
Product
Class to manage products or services.
Definition: product.class.php:46
Form
Class to manage generation of HTML components Only common components must be here.
Definition: html.form.class.php:52
img_object
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0)
Show a picto called object_picto (generic function)
Definition: functions.lib.php:4211
$resql
if(isModEnabled('facture') &&!empty($user->rights->facture->lire)) if((isModEnabled('fournisseur') &&empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->rights->fournisseur->facture->lire)||(isModEnabled('supplier_invoice') && $user->rights->supplier_invoice->lire)) if(isModEnabled('don') &&!empty($user->rights->don->lire)) if(isModEnabled('tax') &&!empty($user->rights->tax->charges->lire)) if(isModEnabled('facture') &&isModEnabled('commande') && $user->rights->commande->lire &&empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) $resql
Social contributions to pay.
Definition: index.php:742
setEventMessages
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='')
Set event messages in dol_events session object.
Definition: functions.lib.php:8137
accessforbidden
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program Calling this function terminate execution ...
Definition: security.lib.php:933
llxHeader
if(!defined('NOREQUIRESOC')) if(!defined('NOREQUIRETRAN')) if(!defined('NOCSRFCHECK')) if(!defined('NOTOKENRENEWAL')) if(!defined('NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined('NOREQUIREAJAX')) llxHeader()
Empty header.
Definition: wrapper.php:59