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&amp;token='.newToken().'&amp;value='.$name.'&amp;scan_dir='.$module->scandir.'&amp;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&amp;token='.newToken().'&amp;value='.$name.'&amp;scan_dir='.$module->scandir.'&amp;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&amp;token='.newToken().'&amp;spe='.urlencode($file).'&amp;value=0">'.$langs->trans("Disable").'</a>';
735						} else {
736							print '&nbsp;</td><td class="right">';
737							print '<a href="'.$_SERVER["PHP_SELF"].'?action=set&amp;token='.newToken().'&amp;spe='.urlencode($file).'&amp;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