dolibarr 21.0.0-alpha
stock.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2006 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3 * Copyright (C) 2008-2010 Laurent Destailleur <eldy@users.sourceforge.net>
4 * Copyright (C) 2005-2009 Regis Houssin <regis.houssin@inodbox.com>
5 * Copyright (C) 2012-2013 Juanjo Menent <jmenent@2byte.es>
6 * Copyright (C) 2013-2018 Philippe Grand <philippe.grand@atoo-net.com>
7 * Copyright (C) 2013 Florian Henry <florian.henry@open-concept.pro>
8 * Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
9 * Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 3 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program. If not, see <https://www.gnu.org/licenses/>.
23 */
24
30require '../main.inc.php';
31require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
32require_once DOL_DOCUMENT_ROOT.'/core/lib/stock.lib.php';
33require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php';
34
35// Load translation files required by the page
36$langs->loadLangs(array("admin", "stocks"));
37
38// Security check
39if (!$user->admin) {
41}
42
43$action = GETPOST('action', 'aZ09');
44$value = GETPOST('value', 'alpha');
45$modulepart = GETPOST('modulepart', 'aZ09'); // Used by actions_setmoduleoptions.inc.php
46$label = GETPOST('label', 'alpha');
47$scandir = GETPOST('scan_dir', 'alpha');
48$type = 'stock';
49
50
51/*
52 * Action
53 */
54include DOL_DOCUMENT_ROOT.'/core/actions_setmoduleoptions.inc.php';
55
56$reg = array();
57
58if (preg_match('/set_([a-z0-9_\-]+)/i', $action, $reg)) {
59 $code = $reg[1];
60
61 // If constant is for a unique choice, delete other choices
62 if (in_array($code, array('STOCK_CALCULATE_ON_BILL', 'STOCK_CALCULATE_ON_VALIDATE_ORDER', 'STOCK_CALCULATE_ON_SHIPMENT', 'STOCK_CALCULATE_ON_SHIPMENT_CLOSE'))) {
63 dolibarr_del_const($db, 'STOCK_CALCULATE_ON_BILL', $conf->entity);
64 dolibarr_del_const($db, 'STOCK_CALCULATE_ON_VALIDATE_ORDER', $conf->entity);
65 dolibarr_del_const($db, 'STOCK_CALCULATE_ON_SHIPMENT', $conf->entity);
66 dolibarr_del_const($db, 'STOCK_CALCULATE_ON_SHIPMENT_CLOSE', $conf->entity);
67 }
68 if (in_array($code, array('STOCK_CALCULATE_ON_SUPPLIER_BILL', 'STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER', 'STOCK_CALCULATE_ON_RECEPTION', 'STOCK_CALCULATE_ON_RECEPTION_CLOSE', 'STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER'))) {
69 dolibarr_del_const($db, 'STOCK_CALCULATE_ON_SUPPLIER_BILL', $conf->entity);
70 dolibarr_del_const($db, 'STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER', $conf->entity);
71 dolibarr_del_const($db, 'STOCK_CALCULATE_ON_RECEPTION', $conf->entity);
72 dolibarr_del_const($db, 'STOCK_CALCULATE_ON_RECEPTION_CLOSE', $conf->entity);
73 dolibarr_del_const($db, 'STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER', $conf->entity);
74 }
75
76 if (dolibarr_set_const($db, $code, 1, 'chaine', 0, '', $conf->entity) > 0) {
77 header("Location: ".$_SERVER["PHP_SELF"]);
78 exit;
79 } else {
80 dol_print_error($db);
81 }
82}
83
84if (preg_match('/del_([a-z0-9_\-]+)/i', $action, $reg)) {
85 $code = $reg[1];
86 if (dolibarr_del_const($db, $code, $conf->entity) > 0) {
87 header("Location: ".$_SERVER["PHP_SELF"]);
88 exit;
89 } else {
90 dol_print_error($db);
91 }
92}
93
94if ($action == 'warehouse') {
95 $value = GETPOST('default_warehouse', 'alpha');
96 $res = dolibarr_set_const($db, "MAIN_DEFAULT_WAREHOUSE", $value, 'chaine', 0, '', $conf->entity);
97 if ($value == -1 || empty($value) && getDolGlobalString('MAIN_DEFAULT_WAREHOUSE')) {
98 $res = dolibarr_del_const($db, "MAIN_DEFAULT_WAREHOUSE", $conf->entity);
99 }
100 if (!($res > 0)) {
101 $error++;
102 }
103}
104
105if ($action == 'specimen') {
106 $modele = GETPOST('module', 'alpha');
107
108 $object = new Entrepot($db);
109 $object->initAsSpecimen();
110
111 // Search template files
112 $file = '';
113 $classname = '';
114 $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
115 foreach ($dirmodels as $reldir) {
116 $file = dol_buildpath($reldir."core/modules/stock/doc/pdf_".$modele.".modules.php", 0);
117 if (file_exists($file)) {
118 $classname = "pdf_".$modele;
119 break;
120 }
121 }
122
123 if ($classname !== '') {
124 require_once $file;
125
126 $module = new $classname($db);
127 '@phan-var-force ModelePDFStock $module';
128
129 if ($module->write_file($object, $langs) > 0) {
130 header("Location: ".DOL_URL_ROOT."/document.php?modulepart=stock&file=SPECIMEN.pdf");
131 return;
132 } else {
133 setEventMessages($module->error, null, 'errors');
134 dol_syslog($module->error, LOG_ERR);
135 }
136 } else {
137 setEventMessages($langs->trans("ErrorModuleNotFound"), null, 'errors');
138 dol_syslog($langs->trans("ErrorModuleNotFound"), LOG_ERR);
139 }
140} elseif ($action == 'set') {
141 // Activate a model
142 $ret = addDocumentModel($value, $type, $label, $scandir);
143} elseif ($action == 'del') {
144 $ret = delDocumentModel($value, $type);
145 if ($ret > 0) {
146 if (getDolGlobalString('STOCK_ADDON_PDF') == "$value") {
147 dolibarr_del_const($db, 'STOCK_ADDON_PDF', $conf->entity);
148 }
149 }
150} elseif ($action == 'setdoc') {
151 // Set default model
152 if (dolibarr_set_const($db, "STOCK_ADDON_PDF", $value, 'chaine', 0, '', $conf->entity)) {
153 // The constant that was read before the new set
154 // We therefore requires a variable to have a coherent view
155 $conf->global->STOCK_ADDON_PDF = $value;
156 }
157
158 // On active le modele
159 $ret = delDocumentModel($value, $type);
160 if ($ret > 0) {
161 $ret = addDocumentModel($value, $type, $label, $scandir);
162 }
163}
164
165
166/*
167 * View
168 */
169
170$form = new Form($db);
171$dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
172
173llxHeader('', $langs->trans("StockSetup"), '', '', 0, 0, '', '', '', 'mod-admin page-stock');
174
175$linkback = '<a href="'.DOL_URL_ROOT.'/admin/modules.php?restore_lastsearch_values=1">'.$langs->trans("BackToModuleList").'</a>';
176print load_fiche_titre($langs->trans("StockSetup"), $linkback, 'title_setup');
177
179
180print dol_get_fiche_head($head, 'general', $langs->trans("StockSetup"), -1, 'stock');
181
182$form = new Form($db);
183$formproduct = new FormProduct($db);
184
185
186
187$disabled = '';
188if (isModEnabled('productbatch')) {
189 // If module lot/serial enabled, we force the inc/dec mode to STOCK_CALCULATE_ON_SHIPMENT_CLOSE and STOCK_CALCULATE_ON_RECEPTION_CLOSE
190 $langs->load("productbatch");
191 $disabled = ' disabled';
192
193 // STOCK_CALCULATE_ON_SHIPMENT_CLOSE
194 $descmode = $langs->trans('DeStockOnShipmentOnClosing');
195 if (!isModEnabled('reception')) {
196 // STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER
197 $incmode = $langs->trans('ReStockOnDispatchOrder');
198 } else {
199 // STOCK_CALCULATE_ON_RECEPTION_CLOSE
200 $incmode = $langs->trans('StockOnReceptionOnClosing');
201 }
202 print info_admin($langs->transnoentitiesnoconv("WhenProductBatchModuleOnOptionAreForced", $descmode, $incmode));
203}
204
205
206print info_admin($langs->trans("IfYouUsePointOfSaleCheckModule"));
207print '<br>';
208
209
210print '<form method="POST" action="'.$_SERVER['PHP_SELF'].'">';
211print '<input type="hidden" name="token" value="'.newToken().'">';
212print '<input type="hidden" name="action" value="warehouse">';
213
214// Title rule for stock decrease
215print '<div class="div-table-responsive-no-min">'; // You can use div-table-responsive-no-min if you don't need reserved height for your table
216print '<table class="noborder centpercent">';
217print '<tr class="liste_titre">';
218print "<td>".$langs->trans("RuleForStockManagementDecrease")."</td>\n";
219print '<td class="right">'.$langs->trans("Status").'</td>'."\n";
220print '</tr>'."\n";
221
222$found = 0;
223
224print '<!-- STOCK_CALCULATE_ON_BILL -->';
225print '<tr class="oddeven">';
226print '<td>'.$langs->trans("DeStockOnBill").'</td>';
227print '<td class="right">';
228if (isModEnabled('invoice')) {
229 if ($conf->use_javascript_ajax) {
230 if ($disabled) {
231 print img_picto($langs->trans("Disabled"), 'off', 'class="opacitymedium"');
232 } else {
233 print ajax_constantonoff('STOCK_CALCULATE_ON_BILL', array(), null, 0, 0, 0, 2, 1, 0, '', '', 'reposition');
234 }
235 } else {
236 $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
237 print $form->selectarray("STOCK_CALCULATE_ON_BILL", $arrval, $conf->global->STOCK_CALCULATE_ON_BILL);
238 }
239} else {
240 print '<span class="opacitymedium">'.$langs->trans("ModuleMustBeEnabledFirst", $langs->transnoentitiesnoconv("Module30Name")).'</span>';
241}
242print "</td>\n</tr>\n";
243$found++;
244
245
246print '<!-- STOCK_CALCULATE_ON_VALIDATE_ORDER -->';
247print '<tr class="oddeven">';
248print '<td>'.$langs->trans("DeStockOnValidateOrder").'</td>';
249print '<td class="right">';
250if (isModEnabled('order')) {
251 if ($conf->use_javascript_ajax) {
252 if ($disabled) {
253 print img_picto($langs->trans("Disabled"), 'off', 'class="opacitymedium"');
254 } else {
255 print ajax_constantonoff('STOCK_CALCULATE_ON_VALIDATE_ORDER', array(), null, 0, 0, 0, 2, 1, 0, '', 'reposition');
256 }
257 } else {
258 $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
259 print $form->selectarray("STOCK_CALCULATE_ON_VALIDATE_ORDER", $arrval, $conf->global->STOCK_CALCULATE_ON_VALIDATE_ORDER);
260 }
261} else {
262 print '<span class="opacitymedium">'.$langs->trans("ModuleMustBeEnabledFirst", $langs->transnoentitiesnoconv("Module25Name")).'</span>';
263}
264print "</td>\n</tr>\n";
265$found++;
266
267//if (isModEnabled('shipping'))
268//{
269
270print '<!-- STOCK_CALCULATE_ON_SHIPMENT -->';
271print '<tr class="oddeven">';
272print '<td>'.$langs->trans("DeStockOnShipment").'</td>';
273print '<td class="right">';
274if (isModEnabled("shipping")) {
275 if ($conf->use_javascript_ajax) {
276 print ajax_constantonoff('STOCK_CALCULATE_ON_SHIPMENT', array(), null, 0, 0, 0, 2, 1, 0, '', 'reposition');
277 } else {
278 $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
279 print $form->selectarray("STOCK_CALCULATE_ON_SHIPMENT", $arrval, $conf->global->STOCK_CALCULATE_ON_SHIPMENT);
280 }
281} else {
282 print '<span class="opacitymedium">'.$langs->trans("ModuleMustBeEnabledFirst", $langs->transnoentitiesnoconv("Module80Name")).'</span>';
283}
284print "</td>\n</tr>\n";
285$found++;
286
287print '<!-- STOCK_CALCULATE_ON_SHIPMENT_CLOSE -->';
288print '<tr class="oddeven">';
289print '<td>'.$langs->trans("DeStockOnShipmentOnClosing").'</td>';
290print '<td class="right">';
291if (isModEnabled("shipping")) {
292 if ($conf->use_javascript_ajax) {
293 print ajax_constantonoff('STOCK_CALCULATE_ON_SHIPMENT_CLOSE', array(), null, 0, 0, 0, 2, 1, 0, '', 'reposition');
294 } else {
295 $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
296 print $form->selectarray("STOCK_CALCULATE_ON_SHIPMENT_CLOSE", $arrval, getDolGlobalString('STOCK_CALCULATE_ON_SHIPMENT_CLOSE'));
297 }
298} else {
299 print '<span class="opacitymedium">'.$langs->trans("ModuleMustBeEnabledFirst", $langs->transnoentitiesnoconv("Module80Name")).'</span>';
300}
301print "</td>\n</tr>\n";
302$found++;
303
304print '</table>';
305print '</div>';
306
307print '<br>';
308
309
310// Title rule for stock increase
311print '<div class="div-table-responsive-no-min">'; // You can use div-table-responsive-no-min if you don't need reserved height for your table
312print '<table class="noborder centpercent">';
313print '<tr class="liste_titre">';
314print "<td>".$langs->trans("RuleForStockManagementIncrease")."</td>\n";
315print '<td class="right">'.$langs->trans("Status").'</td>'."\n";
316print '</tr>'."\n";
317
318$found = 0;
319
320print '<!-- STOCK_CALCULATE_ON_SUPPLIER_BILL -->';
321print '<tr class="oddeven">';
322print '<td>'.$langs->trans("ReStockOnBill").'</td>';
323print '<td class="right">';
324if (isModEnabled("supplier_order") || isModEnabled("supplier_invoice")) {
325 if ($conf->use_javascript_ajax) {
326 if ($disabled) {
327 print img_picto($langs->trans("Disabled"), 'off', 'class="opacitymedium"');
328 } else {
329 print ajax_constantonoff('STOCK_CALCULATE_ON_SUPPLIER_BILL', array(), null, 0, 0, 0, 2, 1, 0, '', 'reposition');
330 }
331 } else {
332 $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
333 print $form->selectarray("STOCK_CALCULATE_ON_SUPPLIER_BILL", $arrval, $conf->global->STOCK_CALCULATE_ON_SUPPLIER_BILL);
334 }
335} else {
336 print '<span class="opacitymedium">'.$langs->trans("ModuleMustBeEnabledFirst", $langs->transnoentitiesnoconv("Module40Name")).'</span>';
337}
338print "</td>\n</tr>\n";
339$found++;
340
341
342print '<!-- STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER -->';
343print '<tr class="oddeven">';
344print '<td>'.$langs->trans("ReStockOnValidateOrder").'</td>';
345print '<td class="right">';
346if (isModEnabled("supplier_order") || isModEnabled("supplier_invoice")) {
347 if ($conf->use_javascript_ajax) {
348 if ($disabled) {
349 print img_picto($langs->trans("Disabled"), 'off', 'class="opacitymedium"');
350 } else {
351 print ajax_constantonoff('STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER', array(), null, 0, 0, 0, 2, 1, 0, '', 'reposition');
352 }
353 } else {
354 $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
355 print $form->selectarray("STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER", $arrval, $conf->global->STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER);
356 }
357} else {
358 print '<span class="opacitymedium">'.$langs->trans("ModuleMustBeEnabledFirst", $langs->transnoentitiesnoconv("Module40Name")).'</span>';
359}
360print "</td>\n</tr>\n";
361$found++;
362
363if (isModEnabled("reception")) {
364 print '<!-- STOCK_CALCULATE_ON_RECEPTION_CLOSE -->';
365 print '<tr class="oddeven">';
366 print '<td>'.$langs->trans("StockOnReception").'</td>';
367 print '<td class="right">';
368
369 if ($conf->use_javascript_ajax) {
370 print ajax_constantonoff('STOCK_CALCULATE_ON_RECEPTION', array(), null, 0, 0, 0, 2, 1, 0, '', 'reposition');
371 } else {
372 $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
373 print $form->selectarray("STOCK_CALCULATE_ON_RECEPTION", $arrval, $conf->global->STOCK_CALCULATE_ON_RECEPTION);
374 }
375
376 print "</td>\n</tr>\n";
377 $found++;
378
379
380 print '<tr class="oddeven">';
381 print '<td>'.$langs->trans("StockOnReceptionOnClosing").'</td>';
382 print '<td class="right">';
383
384 if ($conf->use_javascript_ajax) {
385 print ajax_constantonoff('STOCK_CALCULATE_ON_RECEPTION_CLOSE', array(), null, 0, 0, 0, 2, 1, 0, '', 'reposition');
386 } else {
387 $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
388 print $form->selectarray("STOCK_CALCULATE_ON_RECEPTION_CLOSE", $arrval, $conf->global->STOCK_CALCULATE_ON_RECEPTION_CLOSE);
389 }
390 print "</td>\n</tr>\n";
391 $found++;
392} else {
393 print '<!-- STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER -->';
394 print '<tr class="oddeven">';
395 print '<td>'.$langs->trans("ReStockOnDispatchOrder").'</td>';
396 print '<td class="right">';
397 if (isModEnabled("supplier_order")) {
398 if ($conf->use_javascript_ajax) {
399 print ajax_constantonoff('STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER', array(), null, 0, 0, 0, 2, 1, 0, '', 'reposition');
400 } else {
401 $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
402 print $form->selectarray("STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER", $arrval, $conf->global->STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER);
403 }
404 } else {
405 print '<span class="opacitymedium">'.$langs->trans("ModuleMustBeEnabledFirst", $langs->transnoentitiesnoconv("Module40Name")).'</span>';
406 }
407 print "</td>\n</tr>\n";
408 $found++;
409}
410
411print '</table>';
412print '</div>';
413
414print '<br>';
415
416print '<div class="div-table-responsive-no-min">'; // You can use div-table-responsive-no-min if you don't need reserved height for your table
417print '<table class="noborder centpercent">';
418print '<tr class="liste_titre">';
419print "<td>".$langs->trans("RuleForStockAvailability")."</td>\n";
420print '<td class="right">'.$langs->trans("Status").'</td>'."\n";
421print '</tr>'."\n";
422
423
424print '<tr class="oddeven">';
425print '<td>'.$langs->trans("WarehouseAllowNegativeTransfer").'</td>';
426print '<td class="right">';
427if ($conf->use_javascript_ajax) {
428 print ajax_constantonoff('STOCK_ALLOW_NEGATIVE_TRANSFER');
429} else {
430 $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
431 print $form->selectarray("STOCK_ALLOW_NEGATIVE_TRANSFER", $arrval, $conf->global->STOCK_ALLOW_NEGATIVE_TRANSFER);
432}
433print "</td>\n";
434print "</tr>\n";
435
436// Option to force stock to be enough before adding a line into document
437if (isModEnabled('invoice')) {
438 print '<tr class="oddeven">';
439 print '<td>'.$langs->trans("StockMustBeEnoughForInvoice").'</td>';
440 print '<td class="right">';
441 if ($conf->use_javascript_ajax) {
442 print ajax_constantonoff('STOCK_MUST_BE_ENOUGH_FOR_INVOICE');
443 } else {
444 $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
445 print $form->selectarray("STOCK_MUST_BE_ENOUGH_FOR_INVOICE", $arrval, $conf->global->STOCK_MUST_BE_ENOUGH_FOR_INVOICE);
446 }
447 print "</td>\n";
448 print "</tr>\n";
449}
450
451if (isModEnabled('order')) {
452 print '<tr class="oddeven">';
453 print '<td>'.$langs->trans("StockMustBeEnoughForOrder").'</td>';
454 print '<td class="right">';
455 if ($conf->use_javascript_ajax) {
456 print ajax_constantonoff('STOCK_MUST_BE_ENOUGH_FOR_ORDER');
457 } else {
458 $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
459 print $form->selectarray("STOCK_MUST_BE_ENOUGH_FOR_ORDER", $arrval, $conf->global->STOCK_MUST_BE_ENOUGH_FOR_ORDER);
460 }
461 print "</td>\n";
462 print "</tr>\n";
463}
464
465if (isModEnabled("shipping")) {
466 print '<tr class="oddeven">';
467 print '<td>'.$langs->trans("StockMustBeEnoughForShipment").'</td>';
468 print '<td class="right">';
469 if ($conf->use_javascript_ajax) {
470 print ajax_constantonoff('STOCK_MUST_BE_ENOUGH_FOR_SHIPMENT');
471 } else {
472 $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
473 print $form->selectarray("STOCK_MUST_BE_ENOUGH_FOR_SHIPMENT", $arrval, $conf->global->STOCK_MUST_BE_ENOUGH_FOR_SHIPMENT);
474 }
475 print "</td>\n";
476 print "</tr>\n";
477}
478print '</table>';
479print '</div>';
480
481print '<br>';
482
483$virtualdiffersfromphysical = 0;
484if (getDolGlobalString('STOCK_CALCULATE_ON_SHIPMENT')
485 || getDolGlobalString('STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER')
486 || getDolGlobalString('STOCK_CALCULATE_ON_SHIPMENT_CLOSE')
487 || getDolGlobalString('STOCK_CALCULATE_ON_RECEPTION')
488 || getDolGlobalString('STOCK_CALCULATE_ON_RECEPTION_CLOSE')
489 || isModEnabled('mrp')) {
490 $virtualdiffersfromphysical = 1; // According to increase/decrease stock options, virtual and physical stock may differs.
491}
492
493if ($virtualdiffersfromphysical) {
494 print '<div class="div-table-responsive-no-min">'; // You can use div-table-responsive-no-min if you don't need reserved height for your table
495 print '<table class="noborder centpercent">';
496 print '<tr class="liste_titre">';
497 print "<td>".$langs->trans("RuleForStockReplenishment")." ".img_help(1, $langs->trans("VirtualDiffersFromPhysical"))."</td>\n";
498 print '<td class="right">'.$langs->trans("Status").'</td>'."\n";
499 print '</tr>'."\n";
500
501 print '<tr class="oddeven">';
502 print '<td>';
503 print $form->textwithpicto($langs->trans("UseRealStockByDefault"), $langs->trans("ReplenishmentCalculation"));
504 print '</td>';
505 print '<td class="right">';
506 if ($conf->use_javascript_ajax) {
507 print ajax_constantonoff('STOCK_USE_REAL_STOCK_BY_DEFAULT_FOR_REPLENISHMENT');
508 } else {
509 $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
510 print $form->selectarray("STOCK_USE_REAL_STOCK_BY_DEFAULT_FOR_REPLENISHMENT", $arrval, $conf->global->STOCK_USE_REAL_STOCK_BY_DEFAULT_FOR_REPLENISHMENT);
511 }
512 print "</td>\n";
513 print "</tr>\n";
514 print '</table>';
515 print '</div>';
516
517 print '<br>';
518}
519
520print '<form>';
521
522
523print '<form method="POST" action="'.$_SERVER['PHP_SELF'].'">';
524print '<input type="hidden" name="token" value="'.newToken().'">';
525print '<input type="hidden" name="action" value="warehouse">';
526
527
528/*
529 * Document templates generators
530 */
531
532print load_fiche_titre($langs->trans("WarehouseModelModules"), '', '');
533
534// Load array def with activated templates
535$def = array();
536$sql = "SELECT nom";
537$sql .= " FROM ".MAIN_DB_PREFIX."document_model";
538$sql .= " WHERE type = '".$db->escape($type)."'";
539$sql .= " AND entity = ".$conf->entity;
540$resql = $db->query($sql);
541if ($resql) {
542 $i = 0;
543 $num_rows = $db->num_rows($resql);
544 while ($i < $num_rows) {
545 $array = $db->fetch_array($resql);
546 if (is_array($array)) {
547 array_push($def, $array[0]);
548 }
549 $i++;
550 }
551} else {
552 dol_print_error($db);
553}
554
555
556print '<div class="div-table-responsive-no-min">'; // You can use div-table-responsive-no-min if you don't need reserved height for your table
557print '<table class="noborder centpercent">'."\n";
558print '<tr class="liste_titre">'."\n";
559print '<td>'.$langs->trans("Name").'</td>';
560print '<td>'.$langs->trans("Description").'</td>';
561print '<td class="center" width="60">'.$langs->trans("Status")."</td>\n";
562print '<td class="center" width="60">'.$langs->trans("Default")."</td>\n";
563print '<td class="center" width="38">'.$langs->trans("ShortInfo").'</td>';
564print '<td class="center" width="38">'.$langs->trans("Preview").'</td>';
565print "</tr>\n";
566
567clearstatcache();
568
569foreach ($dirmodels as $reldir) {
570 foreach (array('', '/doc') as $valdir) {
571 $realpath = $reldir."core/modules/stock".$valdir;
572 $dir = dol_buildpath($realpath);
573
574 if (is_dir($dir)) {
575 $handle = opendir($dir);
576 if (is_resource($handle)) {
577 $filelist = array();
578 while (($file = readdir($handle)) !== false) {
579 $filelist[] = $file;
580 }
581 closedir($handle);
582 arsort($filelist);
583
584 foreach ($filelist as $file) {
585 if (preg_match('/\.modules\.php$/i', $file) && preg_match('/^(pdf_|doc_)/', $file)) {
586 if (file_exists($dir.'/'.$file)) {
587 $name = substr($file, 4, dol_strlen($file) - 16);
588 $classname = substr($file, 0, dol_strlen($file) - 12);
589
590 require_once $dir.'/'.$file;
591 $module = new $classname($db);
592 '@phan-var-force ModelePDFStock $module';
593
594 $modulequalified = 1;
595 if ($module->version == 'development' && getDolGlobalInt('MAIN_FEATURES_LEVEL') < 2) {
596 $modulequalified = 0;
597 }
598 if ($module->version == 'experimental' && getDolGlobalInt('MAIN_FEATURES_LEVEL') < 1) {
599 $modulequalified = 0;
600 }
601
602 if ($modulequalified) {
603 print '<tr class="oddeven"><td width="100">';
604 print(empty($module->name) ? $name : $module->name);
605 print "</td><td>\n";
606 if (method_exists($module, 'info')) {
607 print $module->info($langs); // @phan-suppress-current-line PhanUndeclaredMethod
608 } else {
609 print $module->description;
610 }
611 print '</td>';
612
613 // Active
614 if (in_array($name, $def)) {
615 print '<td class="center">'."\n";
616 print '<a class="reposition" href="'.$_SERVER["PHP_SELF"].'?action=del&token='.newToken().'&value='.urlencode($name).'">';
617 print img_picto($langs->trans("Enabled"), 'switch_on');
618 print '</a>';
619 print '</td>';
620 } else {
621 print '<td class="center">'."\n";
622 print '<a class="reposition" 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>';
623 print "</td>";
624 }
625
626 // Default
627 print '<td class="center">';
628 if (getDolGlobalString('STOCK_ADDON_PDF') == $name) {
629 print img_picto($langs->trans("Default"), 'on');
630 } else {
631 print '<a class="reposition" 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>';
632 }
633 print '</td>';
634
635 // Info
636 $htmltooltip = ''.$langs->trans("Name").': '.$module->name;
637 $htmltooltip .= '<br>'.$langs->trans("Type").': '.($module->type ? $module->type : $langs->trans("Unknown"));
638 if ($module->type == 'pdf') {
639 $htmltooltip .= '<br>'.$langs->trans("Width").'/'.$langs->trans("Height").': '.$module->page_largeur.'/'.$module->page_hauteur;
640 }
641 $htmltooltip .= '<br>'.$langs->trans("Path").': '.preg_replace('/^\//', '', $realpath).'/'.$file;
642
643 $htmltooltip .= '<br><br><u>'.$langs->trans("FeaturesSupported").':</u>';
644 $htmltooltip .= '<br>'.$langs->trans("Logo").': '.yn($module->option_logo, 1, 1);
645 $htmltooltip .= '<br>'.$langs->trans("MultiLanguage").': '.yn($module->option_multilang, 1, 1);
646
647
648 print '<td class="center">';
649 print $form->textwithpicto('', $htmltooltip, 1, 0);
650 print '</td>';
651
652 // Preview
653 print '<td class="center">';
654 if ($module->type == 'pdf') {
655 print '<a href="'.$_SERVER["PHP_SELF"].'?action=specimen&module='.$name.'">'.img_object($langs->trans("Preview"), 'pdf').'</a>';
656 } else {
657 print img_object($langs->trans("PreviewNotAvailable"), 'generic');
658 }
659 print '</td>';
660
661 print "</tr>\n";
662 }
663 }
664 }
665 }
666 }
667 }
668 }
669}
670
671print '</table>';
672print '</div>';
673
674print '</form>';
675
676
677// Other
678
679print '<form method="POST" action="'.$_SERVER['PHP_SELF'].'">';
680print '<input type="hidden" name="token" value="'.newToken().'">';
681print '<input type="hidden" name="action" value="warehouse">';
682
683print load_fiche_titre($langs->trans("Other"), '', '');
684
685print '<div class="div-table-responsive-no-min">'; // You can use div-table-responsive-no-min if you don't need reserved height for your table
686print '<table class="noborder centpercent">';
687
688print '<tr class="liste_titre">';
689print "<td>".$langs->trans("Parameter")."</td>\n";
690print '<td class="right">'.$langs->trans("Value").'</td>'."\n";
691print '</tr>'."\n";
692
693print '<tr class="oddeven">';
694print '<td>'.$langs->trans("MainDefaultWarehouse").'</td>';
695print '<td class="right">';
696print $formproduct->selectWarehouses(getDolGlobalString('MAIN_DEFAULT_WAREHOUSE') ? $conf->global->MAIN_DEFAULT_WAREHOUSE : -1, 'default_warehouse', '', 1, 0, 0, '', 0, 0, array(), 'left reposition');
697print '<input type="submit" class="button button-edit smallpaddingimp" value="'.$langs->trans("Modify").'">';
698print "</td>";
699print "</tr>\n";
700
701print '<tr class="oddeven">';
702print '<td>'.$langs->trans("UserDefaultWarehouse").'</td>';
703print '<td class="right">';
704if ($conf->use_javascript_ajax) {
705 print ajax_constantonoff('MAIN_DEFAULT_WAREHOUSE_USER', array(), null, 0, 0, 1);
706} else {
707 $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
708 print $form->selectarray("MAIN_DEFAULT_WAREHOUSE_USER", $arrval, $conf->global->MAIN_DEFAULT_WAREHOUSE_USER);
709}
710print "</td>\n";
711print "</tr>\n";
712
713if (getDolGlobalString('MAIN_DEFAULT_WAREHOUSE_USER')) {
714 print '<tr class="oddeven">';
715 print '<td>'.$langs->trans("UserWarehouseAutoCreate").'</td>';
716 print '<td class="right">';
717 if ($conf->use_javascript_ajax) {
718 print ajax_constantonoff('STOCK_USERSTOCK_AUTOCREATE');
719 } else {
720 $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
721 print $form->selectarray("STOCK_USERSTOCK_AUTOCREATE", $arrval, $conf->global->STOCK_USERSTOCK_AUTOCREATE);
722 }
723 print "</td>\n";
724 print "</tr>\n";
725}
726
727print '<tr class="oddeven">';
728print '<td>'.$langs->trans("WarehouseAskWarehouseOnThirparty").'</td>';
729print '<td class="right">';
730if ($conf->use_javascript_ajax) {
731 print ajax_constantonoff('SOCIETE_ASK_FOR_WAREHOUSE');
732} else {
733 $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
734 print $form->selectarray("SOCIETE_ASK_FOR_WAREHOUSE", $arrval, $conf->global->SOCIETE_ASK_FOR_WAREHOUSE);
735}
736print "</td>";
737print "</tr>\n";
738
739print '<tr class="oddeven">';
740print '<td>'.$langs->trans("WarehouseAskWarehouseDuringPropal").'</td>';
741print '<td class="right">';
742if ($conf->use_javascript_ajax) {
743 print ajax_constantonoff('WAREHOUSE_ASK_WAREHOUSE_DURING_PROPAL');
744} else {
745 $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
746 print $form->selectarray("WAREHOUSE_ASK_WAREHOUSE_DURING_PROPAL", $arrval, $conf->global->WAREHOUSE_ASK_WAREHOUSE_DURING_PROPAL);
747}
748print "</td>";
749print "</tr>\n";
750
751print '<tr class="oddeven">';
752print '<td>'.$langs->trans("WarehouseAskWarehouseDuringOrder").'</td>';
753print '<td class="right">';
754if ($conf->use_javascript_ajax) {
755 print ajax_constantonoff('WAREHOUSE_ASK_WAREHOUSE_DURING_ORDER');
756} else {
757 $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
758 print $form->selectarray("WAREHOUSE_ASK_WAREHOUSE_DURING_ORDER", $arrval, $conf->global->WAREHOUSE_ASK_WAREHOUSE_DURING_ORDER);
759}
760print '</td>';
761print "</tr>\n";
762
763/*
764print '<tr class="oddeven">';
765print '<td>'.$langs->trans("WarehouseAskWarehouseDuringProject").'</td>';
766print '<td class="right">';
767if ($conf->use_javascript_ajax) {
768 print ajax_constantonoff('WAREHOUSE_ASK_WAREHOUSE_DURING_PROJECT');
769} else {
770 $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
771 print $form->selectarray("WAREHOUSE_ASK_WAREHOUSE_DURING_PROJECT", $arrval, $conf->global->WAREHOUSE_ASK_WAREHOUSE_DURING_PROJECT);
772}
773print '</td>';
774print "</tr>\n";
775*/
776
777print '<tr class="oddeven">';
778print '<td>';
779print $form->textwithpicto($langs->trans("StockSupportServices"), $langs->trans("StockSupportServicesDesc"));
780print '</td>';
781print '<td class="right">';
782if ($conf->use_javascript_ajax) {
783 print ajax_constantonoff('STOCK_SUPPORTS_SERVICES');
784} else {
785 $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
786 print $form->selectarray("STOCK_SUPPORTS_SERVICES", $arrval, getDolGlobalString('STOCK_SUPPORTS_SERVICES'));
787}
788print "</td>\n";
789print "</tr>\n";
790
791// Add option to allow a "Limit for warning" and a "Desired stock" per warehouse.
792print '<tr class="oddeven">';
793print '<td>'.$langs->trans("AllowAddLimitStockByWarehouse").'</td>';
794print '<td class="right">';
795if ($conf->use_javascript_ajax) {
796 print ajax_constantonoff('STOCK_ALLOW_ADD_LIMIT_STOCK_BY_WAREHOUSE');
797} else {
798 $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
799 print $form->selectarray("STOCK_ALLOW_ADD_LIMIT_STOCK_BY_WAREHOUSE", $arrval, $conf->global->STOCK_ALLOW_ADD_LIMIT_STOCK_BY_WAREHOUSE);
800}
801print "</td>\n";
802print "</tr>\n";
803
804print '<tr class="oddeven">';
805print '<td>'.$langs->trans("AlwaysShowFullArbo").'</td>';
806print '<td class="right">';
807if ($conf->use_javascript_ajax) {
808 print ajax_constantonoff('STOCK_ALWAYS_SHOW_FULL_ARBO');
809} else {
810 $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
811 print $form->selectarray("STOCK_ALWAYS_SHOW_FULL_ARBO", $arrval, $conf->global->STOCK_ALWAYS_SHOW_FULL_ARBO);
812}
813print "</td>\n";
814print "</tr>\n";
815
816/* Disabled. Would be better to be managed with a user cookie
817if (isModEnabled('productbatch')) {
818 print '<tr class="oddeven">';
819 print '<td>' . $langs->trans("ShowAllBatchByDefault") . '</td>';
820 print '<td class="right">';
821 if ($conf->use_javascript_ajax) {
822 print ajax_constantonoff('STOCK_SHOW_ALL_BATCH_BY_DEFAULT');
823 } else {
824 $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
825 print $form->selectarray("STOCK_SHOW_ALL_BATCH_BY_DEFAULT", $arrval, $conf->global->STOCK_SHOW_ALL_BATCH_BY_DEFAULT);
826 }
827 print "</td>\n";
828 print "</tr>\n";
829}
830*/
831
832print '</table>';
833print '</div>';
834
835print '</form>';
836
837// End of page
838llxFooter();
839$db->close();
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:58
addDocumentModel($name, $type, $label='', $description='')
Add document model used by doc generator.
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).
dolibarr_del_const($db, $name, $entity=1)
Delete a constant.
delDocumentModel($name, $type)
Delete document model used by doc generator.
if(!defined('NOREQUIRESOC')) if(!defined( 'NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined( 'NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined( 'NOREQUIREAJAX')) llxHeader($head='', $title='', $help_url='', $target='', $disablejs=0, $disablehead=0, $arrayofjs='', $arrayofcss='', $morequerystring='', $morecssonbody='', $replacemainareaby='', $disablenofollow=0, $disablenoindex=0)
Empty header.
Definition wrapper.php:70
Class to manage warehouses.
Class to manage generation of HTML components Only common components must be here.
Class with static methods for building HTML components related to products Only components common to ...
llxFooter()
Footer empty.
Definition document.php:107
load_fiche_titre($title, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='')
Load a title with picto.
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0)
Show a picto called object_picto (generic function)
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0, $attop=0)
Set event messages in dol_events session object.
img_help($usehelpcursor=1, $usealttitle=1)
Show help logo with cursor "?".
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limittoshow=0, $moretabssuffix='', $dragdropfile=0)
Show tabs of a record.
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
newToken()
Return the value of token currently saved into session with name 'newtoken'.
yn($yesno, $format=1, $color=0)
Return yes or no in current language.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
info_admin($text, $infoonimgalt=0, $nodiv=0, $admin='1', $morecss='hideonsmartphone', $textfordropdown='', $picto='')
Show information in HTML for admin users or standard users.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
$conf db name
Only used if Module[ID]Name translation string is not found.
Definition repair.php:140
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.
stock_admin_prepare_head()
Return array head with list of tabs to view object information.
Definition stock.lib.php:92