dolibarr 25.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-2026 MDW <mdeweerd@users.noreply.github.com>
9 * Copyright (C) 2024-2026 Frédéric France <frederic.france@free.fr>
10 * Copyright (C) 2026 Jose Martinez <jose.martinez@pichinov.com>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 3 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program. If not, see <https://www.gnu.org/licenses/>.
24 */
25
31require '../main.inc.php';
39require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
40require_once DOL_DOCUMENT_ROOT.'/core/lib/stock.lib.php';
41require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php';
42
43// Load translation files required by the page
44$langs->loadLangs(array("admin", "stocks"));
45
46// Security check
47if (!$user->admin) {
49}
50
51$action = GETPOST('action', 'aZ09');
52$value = GETPOST('value', 'alpha');
53$modulepart = GETPOST('modulepart', 'aZ09'); // Used by actions_setmoduleoptions.inc.php
54$label = GETPOST('label', 'alpha');
55$scandir = GETPOST('scan_dir', 'alpha');
56$type = 'stock';
57$page_y = GETPOST('page_y');
58
59
60/*
61 * Action
62 */
63
64$error = 0;
65
66include DOL_DOCUMENT_ROOT.'/core/actions_setmoduleoptions.inc.php';
67
68$reg = array();
69
70if ($action == 'update' || preg_match('/set_([a-z0-9_\-]+)/i', $action, $reg)) {
71 if ($action == 'update') {
72 $arrayofcode = array(
73 'STOCK_CALCULATE_ON_BILL', 'STOCK_CALCULATE_ON_VALIDATE_ORDER', 'STOCK_CALCULATE_ON_SHIPMENT', 'STOCK_CALCULATE_ON_SHIPMENT_CLOSE',
74 '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',
75 'STOCK_DISALLOW_NEGATIVE_TRANSFER', 'STOCK_MUST_BE_ENOUGH_FOR_INVOICE', 'STOCK_MUST_BE_ENOUGH_FOR_ORDER', 'STOCK_MUST_BE_ENOUGH_FOR_SHIPMENT',
76 'STOCK_USE_REAL_STOCK_BY_DEFAULT_FOR_REPLENISHMENT'
77 );
78 } else {
79 $arrayofcode = array($reg[1]);
80 }
81
82 $result = 1;
83 foreach ($arrayofcode as $code) {
84 $value = 1;
85 if (GETPOSTISSET($code)) { // For the case of nojs=1
86 $value = GETPOST($code);
87 }
88
89 if ($value == 1) {
90 if (in_array($code, array('STOCK_CALCULATE_ON_BILL', 'STOCK_CALCULATE_ON_VALIDATE_ORDER', 'STOCK_CALCULATE_ON_SHIPMENT', 'STOCK_CALCULATE_ON_SHIPMENT_CLOSE'))) {
91 dolibarr_del_const($db, 'STOCK_CALCULATE_ON_BILL', $conf->entity);
92 dolibarr_del_const($db, 'STOCK_CALCULATE_ON_VALIDATE_ORDER', $conf->entity);
93 dolibarr_del_const($db, 'STOCK_CALCULATE_ON_SHIPMENT', $conf->entity);
94 dolibarr_del_const($db, 'STOCK_CALCULATE_ON_SHIPMENT_CLOSE', $conf->entity);
95 }
96 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'))) {
97 dolibarr_del_const($db, 'STOCK_CALCULATE_ON_SUPPLIER_BILL', $conf->entity);
98 dolibarr_del_const($db, 'STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER', $conf->entity);
99 dolibarr_del_const($db, 'STOCK_CALCULATE_ON_RECEPTION', $conf->entity);
100 dolibarr_del_const($db, 'STOCK_CALCULATE_ON_RECEPTION_CLOSE', $conf->entity);
101 dolibarr_del_const($db, 'STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER', $conf->entity);
102 }
103 }
104
105 // If constant is for a unique choice, delete other choices
106 $result = dolibarr_set_const($db, $code, $value, 'chaine', 0, '', $conf->entity);
107 }
108
109 if ($result) {
110 header("Location: ".$_SERVER["PHP_SELF"].($page_y ? '?page_y='.$page_y : ''));
111 exit;
112 } else {
113 dol_print_error($db);
114 }
115}
116
117if ($action == 'update' || preg_match('/del_([a-z0-9_\-]+)/i', $action, $reg)) {
118 if ($action == 'update') {
119 $arrayofcode = array(
120 'STOCK_CALCULATE_ON_BILL', 'STOCK_CALCULATE_ON_VALIDATE_ORDER', 'STOCK_CALCULATE_ON_SHIPMENT', 'STOCK_CALCULATE_ON_SHIPMENT_CLOSE',
121 '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',
122 );
123 } else {
124 $arrayofcode = array($reg[1]);
125 }
126
127 $result = 1;
128 foreach ($arrayofcode as $code) {
129 $result = dolibarr_del_const($db, $code, $conf->entity);
130 }
131 if ($result > 0) {
132 header("Location: ".$_SERVER["PHP_SELF"].($page_y ? '?page_y='.$page_y : ''));
133 exit;
134 } else {
135 dol_print_error($db);
136 }
137}
138
139if ($action == 'warehouse') {
140 $value = GETPOST('default_warehouse', 'alpha');
141 $res = dolibarr_set_const($db, "MAIN_DEFAULT_WAREHOUSE", $value, 'chaine', 0, '', $conf->entity);
142 if ($value == -1 || empty($value) && getDolGlobalString('MAIN_DEFAULT_WAREHOUSE')) {
143 $res = dolibarr_del_const($db, "MAIN_DEFAULT_WAREHOUSE", $conf->entity);
144 }
145 if (!($res > 0)) {
146 $error++;
147 }
148
149 if (GETPOSTISSET('STOCK_VIRTUAL_HORIZON_IN_DAYS')) {
150 $value = GETPOST('STOCK_VIRTUAL_HORIZON_IN_DAYS', 'alphanohtml');
151 if ($value === '') { // An empty field disables the horizon. A 0 is a valid value, so it must be kept.
152 $res = dolibarr_del_const($db, "STOCK_VIRTUAL_HORIZON_IN_DAYS", $conf->entity);
153 } else {
154 $res = dolibarr_set_const($db, "STOCK_VIRTUAL_HORIZON_IN_DAYS", max(0, (int) $value), 'chaine', 0, '', $conf->entity);
155 }
156 }
157 if (!($res > 0)) {
158 $error++;
159 }
160}
161
162if ($action == 'specimen') {
163 $modele = GETPOST('module', 'alpha');
164
165 $object = new Entrepot($db);
166 $object->initAsSpecimen();
167
168 // Search template files
169 $file = '';
170 $classname = '';
171 $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
172 foreach ($dirmodels as $reldir) {
173 $file = dol_buildpath($reldir."core/modules/stock/doc/pdf_".$modele.".modules.php", 0);
174 if (file_exists($file)) {
175 $classname = "pdf_".$modele;
176 break;
177 }
178 }
179
180 if ($classname !== '') {
181 require_once $file;
182
183 $module = new $classname($db);
184 '@phan-var-force ModelePDFStock $module';
185
186 if ($module->write_file($object, $langs) > 0) {
187 header("Location: ".DOL_URL_ROOT."/document.php?modulepart=stock&file=SPECIMEN.pdf");
188 return;
189 } else {
190 setEventMessages($module->error, null, 'errors');
191 dol_syslog($module->error, LOG_ERR);
192 }
193 } else {
194 setEventMessages($langs->trans("ErrorModuleNotFound"), null, 'errors');
195 dol_syslog($langs->trans("ErrorModuleNotFound"), LOG_ERR);
196 }
197} elseif ($action == 'set') {
198 // Activate a model
199 $ret = addDocumentModel($value, $type, $label, $scandir);
200} elseif ($action == 'del') {
201 $ret = delDocumentModel($value, $type);
202 if ($ret > 0) {
203 if (getDolGlobalString('STOCK_ADDON_PDF') == "$value") {
204 dolibarr_del_const($db, 'STOCK_ADDON_PDF', $conf->entity);
205 }
206 }
207} elseif ($action == 'setdoc') {
208 // Set default model
209 if (dolibarr_set_const($db, "STOCK_ADDON_PDF", $value, 'chaine', 0, '', $conf->entity)) {
210 // The constant that was read before the new set
211 // We therefore requires a variable to have a coherent view
212 $conf->global->STOCK_ADDON_PDF = $value;
213 }
214
215 // On active le modele
216 $ret = delDocumentModel($value, $type);
217 if ($ret > 0) {
218 $ret = addDocumentModel($value, $type, $label, $scandir);
219 }
220}
221
222
223/*
224 * View
225 */
226
227$form = new Form($db);
228$dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
229
230llxHeader('', $langs->trans("StockSetup"), '', '', 0, 0, '', '', '', 'mod-admin page-stock');
231
232$linkback = '<a href="'.dolBuildUrl(DOL_URL_ROOT.'/admin/modules.php', ['restore_lastsearch_values' => 1]).'">'.img_picto($langs->trans("BackToModuleList"), 'back', 'class="pictofixedwidth"').'<span class="hideonsmartphone">'.$langs->trans("BackToModuleList").'</span></a>';
233
234print load_fiche_titre($langs->trans("StockSetup"), $linkback, 'title_setup');
235
237
238print dol_get_fiche_head($head, 'general', $langs->trans("StockSetup"), -1, 'stock');
239
240$form = new Form($db);
241$formproduct = new FormProduct($db);
242
243
244$disableStockCalculateOn = array();
245if (getDolGlobalInt('PRODUIT_SOUSPRODUITS')) {
246 // If option virtual stock is enabled, we disable some mode for inc/dec stock change
247 // Why this ? As i don't see why, i comment this code by a hidden option
248 if (getDolGlobalString('PRODUIT_RESTRICT_STOCK_INCDEC_IF_SUBPRODUCTS_ENABLED')) {
249 $disableStockCalculateOn[] = 'BILL';
250 $disableStockCalculateOn[] = 'VALIDATE_ORDER';
251 // STOCK_CALCULATE_ON_SHIPMENT is ok so not disable
252 // STOCK_CALCULATE_ON_SHIPMENT_CLOSE is ok so not disabled
253
254 $disableStockCalculateOn[] = 'SUPPLIER_BILL';
255 $disableStockCalculateOn[] = 'SUPPLIER_VALIDATE_ORDER';
256
257 print info_admin($langs->trans('WhenProductVirtualOnOptionAreForced'));
258 }
259}
260if (isModEnabled('productbatch')) {
261 // If module lot/serial enabled, we disable some mode for inc/dec stock change
262 $langs->load("productbatch");
263 $disableStockCalculateOn[] = 'BILL';
264 $disableStockCalculateOn[] = 'VALIDATE_ORDER';
265 // STOCK_CALCULATE_ON_SHIPMENT is ok so not disable
266 // STOCK_CALCULATE_ON_SHIPMENT_CLOSE is ok so not disabled
267
268 $disableStockCalculateOn[] = 'SUPPLIER_BILL';
269 $disableStockCalculateOn[] = 'SUPPLIER_VALIDATE_ORDER';
270
271 $descmode = ""; $incmode = "";
272 /* $descmode = $langs->trans('DeStockOnShipmentOnClosing');
273 if (!isModEnabled('reception')) {
274 // STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER
275 $incmode = $langs->trans('ReStockOnDispatchOrder');
276 } else {
277 // STOCK_CALCULATE_ON_RECEPTION_CLOSE
278 $incmode = $langs->trans('StockOnReceptionOnClosing');
279 } */
280 print info_admin($langs->transnoentitiesnoconv("WhenProductBatchModuleOnOptionAreForced", $descmode, $incmode));
281}
282
283
284print info_admin($langs->trans("IfYouUsePointOfSaleCheckModule"));
285print '<br>';
286
287
288print '<form method="POST" action="'.$_SERVER['PHP_SELF'].'" spellcheck="false">';
289print '<input type="hidden" name="token" value="'.newToken().'">';
290print '<input type="hidden" name="action" value="update">';
291print '<input type="hidden" name="page_y" value="">';
292
293// Title rule for stock decrease
294print '<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
295print '<table class="noborder centpercent">';
296print '<tr class="liste_titre">';
297print "<td>".$langs->trans("RuleForStockManagementDecrease")."</td>\n";
298print '<td class="right">'.$langs->trans("Status").'</td>'."\n";
299print '</tr>'."\n";
300
301$found = 0;
302
303print '<!-- STOCK_CALCULATE_ON_BILL -->';
304print '<tr class="oddeven">';
305print '<td>'.$langs->trans("DeStockOnBill").'</td>';
306print '<td class="right">';
307if (isModEnabled('invoice')) {
308 if ($conf->use_javascript_ajax) {
309 if (in_array('BILL', $disableStockCalculateOn)) {
310 print img_picto($langs->trans("Disabled"), 'off', 'class="opacitymedium"');
311 } else {
312 print ajax_constantonoff('STOCK_CALCULATE_ON_BILL', array(), null, 0, 0, 0, 2, 1, 0, '', '', 'reposition');
313 }
314 } else {
315 $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
316 print $form->selectarray("STOCK_CALCULATE_ON_BILL", $arrval, getDolGlobalString('STOCK_CALCULATE_ON_BILL'));
317 }
318} else {
319 print '<span class="opacitymedium">'.$langs->trans("ModuleMustBeEnabledFirst", $langs->transnoentitiesnoconv("Module30Name")).'</span>';
320}
321print "</td>\n</tr>\n";
322$found++;
323
324
325print '<!-- STOCK_CALCULATE_ON_VALIDATE_ORDER -->';
326print '<tr class="oddeven">';
327print '<td>'.$langs->trans("DeStockOnValidateOrder").'</td>';
328print '<td class="right">';
329if (isModEnabled('order')) {
330 if ($conf->use_javascript_ajax) {
331 if (in_array('VALIDATE_ORDER', $disableStockCalculateOn)) {
332 print img_picto($langs->trans("Disabled"), 'off', 'class="opacitymedium"');
333 } else {
334 print ajax_constantonoff('STOCK_CALCULATE_ON_VALIDATE_ORDER', array(), null, 0, 0, 0, 2, 1, 0, '', '', 'reposition');
335 }
336 } else {
337 $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
338 print $form->selectarray("STOCK_CALCULATE_ON_VALIDATE_ORDER", $arrval, getDolGlobalString('STOCK_CALCULATE_ON_VALIDATE_ORDER'));
339 }
340} else {
341 print '<span class="opacitymedium">'.$langs->trans("ModuleMustBeEnabledFirst", $langs->transnoentitiesnoconv("Module25Name")).'</span>';
342}
343print "</td>\n</tr>\n";
344$found++;
345
346//if (isModEnabled('shipping'))
347//{
348
349print '<!-- STOCK_CALCULATE_ON_SHIPMENT -->';
350print '<tr class="oddeven">';
351print '<td>'.$langs->trans("DeStockOnShipment").'</td>';
352print '<td class="right">';
353if (isModEnabled("shipping")) {
354 if ($conf->use_javascript_ajax) {
355 if (in_array('SHIPMENT', $disableStockCalculateOn)) {
356 print img_picto($langs->trans("Disabled"), 'off', 'class="opacitymedium"');
357 } else {
358 print ajax_constantonoff('STOCK_CALCULATE_ON_SHIPMENT', array(), null, 0, 0, 0, 2, 1, 0, '', '', 'reposition');
359 }
360 } else {
361 $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
362 print $form->selectarray("STOCK_CALCULATE_ON_SHIPMENT", $arrval, getDolGlobalString('STOCK_CALCULATE_ON_SHIPMENT'));
363 }
364} else {
365 print '<span class="opacitymedium">'.$langs->trans("ModuleMustBeEnabledFirst", $langs->transnoentitiesnoconv("Module80Name")).'</span>';
366}
367print "</td>\n</tr>\n";
368$found++;
369
370print '<!-- STOCK_CALCULATE_ON_SHIPMENT_CLOSE -->';
371print '<tr class="oddeven">';
372print '<td>'.$langs->trans("DeStockOnShipmentOnClosing").'</td>';
373print '<td class="right">';
374if (isModEnabled("shipping")) {
375 if ($conf->use_javascript_ajax) {
376 if (in_array('SHIPMENT_CLOSE', $disableStockCalculateOn)) {
377 print img_picto($langs->trans("Disabled"), 'off', 'class="opacitymedium"');
378 } else {
379 print ajax_constantonoff('STOCK_CALCULATE_ON_SHIPMENT_CLOSE', array(), null, 0, 0, 0, 2, 1, 0, '', '', 'reposition');
380 }
381 } else {
382 $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
383 print $form->selectarray("STOCK_CALCULATE_ON_SHIPMENT_CLOSE", $arrval, getDolGlobalString('STOCK_CALCULATE_ON_SHIPMENT_CLOSE'));
384 }
385} else {
386 print '<span class="opacitymedium">'.$langs->trans("ModuleMustBeEnabledFirst", $langs->transnoentitiesnoconv("Module80Name")).'</span>';
387}
388print "</td>\n</tr>\n";
389$found++;
390
391print '</table>';
392print '</div>';
393
394
395print '<br>';
396
397
398// Title rule for stock increase
399print '<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
400print '<table class="noborder centpercent">';
401print '<tr class="liste_titre">';
402print "<td>".$langs->trans("RuleForStockManagementIncrease")."</td>\n";
403print '<td class="right">'.$langs->trans("Status").'</td>'."\n";
404print '</tr>'."\n";
405
406$found = 0;
407
408print '<!-- STOCK_CALCULATE_ON_SUPPLIER_BILL -->';
409print '<tr class="oddeven">';
410print '<td>'.$langs->trans("ReStockOnBill").'</td>';
411print '<td class="right">';
412if (isModEnabled("supplier_order") || isModEnabled("supplier_invoice")) {
413 if ($conf->use_javascript_ajax) {
414 if (in_array('SUPPLIER_BILL', $disableStockCalculateOn)) {
415 print img_picto($langs->trans("Disabled"), 'off', 'class="opacitymedium"');
416 } else {
417 print ajax_constantonoff('STOCK_CALCULATE_ON_SUPPLIER_BILL', array(), null, 0, 0, 0, 2, 1, 0, '', '', 'reposition');
418 }
419 } else {
420 $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
421 print $form->selectarray("STOCK_CALCULATE_ON_SUPPLIER_BILL", $arrval, getDolGlobalString('STOCK_CALCULATE_ON_SUPPLIER_BILL'));
422 }
423} else {
424 print '<span class="opacitymedium">'.$langs->trans("ModuleMustBeEnabledFirst", $langs->transnoentitiesnoconv("Module40Name")).'</span>';
425}
426print "</td>\n</tr>\n";
427$found++;
428
429
430print '<!-- STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER -->';
431print '<tr class="oddeven">';
432print '<td>'.$langs->trans("ReStockOnValidateOrder").'</td>';
433print '<td class="right">';
434if (isModEnabled("supplier_order") || isModEnabled("supplier_invoice")) {
435 if ($conf->use_javascript_ajax) {
436 if (in_array('SUPPLIER_VALIDATE_ORDER', $disableStockCalculateOn)) {
437 print img_picto($langs->trans("Disabled"), 'off', 'class="opacitymedium"');
438 } else {
439 print ajax_constantonoff('STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER', array(), null, 0, 0, 0, 2, 1, 0, '', '', 'reposition');
440 }
441 } else {
442 $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
443 print $form->selectarray("STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER", $arrval, getDolGlobalString('STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER'));
444 }
445} else {
446 print '<span class="opacitymedium">'.$langs->trans("ModuleMustBeEnabledFirst", $langs->transnoentitiesnoconv("Module40Name")).'</span>';
447}
448print "</td>\n</tr>\n";
449$found++;
450
451if (isModEnabled("reception")) {
452 print '<!-- STOCK_CALCULATE_ON_RECEPTION -->';
453 print '<tr class="oddeven">';
454 print '<td>'.$langs->trans("StockOnReception").'</td>';
455 print '<td class="right">';
456
457 if ($conf->use_javascript_ajax) {
458 if (in_array('RECEPTION', $disableStockCalculateOn)) {
459 print img_picto($langs->trans("Disabled"), 'off', 'class="opacitymedium"');
460 } else {
461 print ajax_constantonoff('STOCK_CALCULATE_ON_RECEPTION', array(), null, 0, 0, 0, 2, 1, 0, '', '', 'reposition');
462 }
463 } else {
464 $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
465 print $form->selectarray("STOCK_CALCULATE_ON_RECEPTION", $arrval, getDolGlobalString('STOCK_CALCULATE_ON_RECEPTION'));
466 }
467
468 print "</td>\n</tr>\n";
469 $found++;
470
471 print '<!-- STOCK_CALCULATE_ON_RECEPTION_CLOSE -->';
472 print '<tr class="oddeven">';
473 print '<td>'.$langs->trans("StockOnReceptionOnClosing").'</td>';
474 print '<td class="right">';
475
476 if ($conf->use_javascript_ajax) {
477 if (in_array('RECEPTION_CLOSE', $disableStockCalculateOn)) {
478 print img_picto($langs->trans("Disabled"), 'off', 'class="opacitymedium"');
479 } else {
480 print ajax_constantonoff('STOCK_CALCULATE_ON_RECEPTION_CLOSE', array(), null, 0, 0, 0, 2, 1, 0, '', '', 'reposition');
481 }
482 } else {
483 $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
484 print $form->selectarray("STOCK_CALCULATE_ON_RECEPTION_CLOSE", $arrval, getDolGlobalString('STOCK_CALCULATE_ON_RECEPTION_CLOSE'));
485 }
486 print "</td>\n</tr>\n";
487 $found++;
488} else {
489 // When module Reception is not enabled, option to increase real stocks on manual dispatching into warehouse, after purchase order receipt of goods
490 print '<!-- STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER -->';
491 print '<tr class="oddeven">';
492 print '<td>'.$langs->trans("ReStockOnDispatchOrder").'</td>';
493 print '<td class="right">';
494 if (isModEnabled("supplier_order")) {
495 if ($conf->use_javascript_ajax) {
496 if (in_array('SUPPLIER_DISPATCH_ORDER', $disableStockCalculateOn)) {
497 print img_picto($langs->trans("Disabled"), 'off', 'class="opacitymedium"');
498 } else {
499 print ajax_constantonoff('STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER', array(), null, 0, 0, 0, 2, 1, 0, '', '', 'reposition');
500 }
501 } else {
502 $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
503 print $form->selectarray("STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER", $arrval, getDolGlobalString('STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER'));
504 }
505 } else {
506 print '<span class="opacitymedium">'.$langs->trans("ModuleMustBeEnabledFirst", $langs->transnoentitiesnoconv("Module40Name")).'</span>';
507 }
508 print "</td>\n</tr>\n";
509 $found++;
510}
511
512print '</table>';
513print '</div>';
514
515print '<br>';
516
517print '<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
518print '<table class="noborder centpercent">';
519print '<tr class="liste_titre">';
520print "<td>".$langs->trans("RuleForStockAvailability")."</td>\n";
521print '<td class="right">'.$langs->trans("Status").'</td>'."\n";
522print '</tr>'."\n";
523
524
525print '<tr class="oddeven">';
526print '<td>'.$langs->trans("WarehouseAllowNegativeTransfer").'</td>';
527print '<td class="right">';
528if ($conf->use_javascript_ajax) {
529 print ajax_constantonoff('STOCK_DISALLOW_NEGATIVE_TRANSFER', array(), null, 1);
530} else {
531 $arrval = array('1' => $langs->trans("No"), '0' => $langs->trans("Yes"));
532 print $form->selectarray("STOCK_DISALLOW_NEGATIVE_TRANSFER", $arrval, getDolGlobalInt('STOCK_DISALLOW_NEGATIVE_TRANSFER'));
533}
534print "</td>\n";
535print "</tr>\n";
536
537// Option to force stock to be enough before adding a line into document
538if (isModEnabled('invoice')) {
539 print '<tr class="oddeven">';
540 print '<td>'.$langs->trans("StockMustBeEnoughForInvoice").'</td>';
541 print '<td class="right">';
542 if ($conf->use_javascript_ajax) {
543 print ajax_constantonoff('STOCK_MUST_BE_ENOUGH_FOR_INVOICE');
544 } else {
545 $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
546 print $form->selectarray("STOCK_MUST_BE_ENOUGH_FOR_INVOICE", $arrval, getDolGlobalString('STOCK_MUST_BE_ENOUGH_FOR_INVOICE'));
547 }
548 print "</td>\n";
549 print "</tr>\n";
550}
551
552if (isModEnabled('order')) {
553 print '<tr class="oddeven">';
554 print '<td>'.$langs->trans("StockMustBeEnoughForOrder").'</td>';
555 print '<td class="right">';
556 if ($conf->use_javascript_ajax) {
557 print ajax_constantonoff('STOCK_MUST_BE_ENOUGH_FOR_ORDER');
558 } else {
559 $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
560 print $form->selectarray("STOCK_MUST_BE_ENOUGH_FOR_ORDER", $arrval, getDolGlobalString('STOCK_MUST_BE_ENOUGH_FOR_ORDER'));
561 }
562 print "</td>\n";
563 print "</tr>\n";
564}
565
566if (isModEnabled("shipping")) {
567 print '<tr class="oddeven">';
568 print '<td>'.$langs->trans("StockMustBeEnoughForShipment").'</td>';
569 print '<td class="right">';
570 if ($conf->use_javascript_ajax) {
571 print ajax_constantonoff('STOCK_MUST_BE_ENOUGH_FOR_SHIPMENT');
572 } else {
573 $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
574 print $form->selectarray("STOCK_MUST_BE_ENOUGH_FOR_SHIPMENT", $arrval, getDolGlobalString('STOCK_MUST_BE_ENOUGH_FOR_SHIPMENT'));
575 }
576 print "</td>\n";
577 print "</tr>\n";
578}
579print '</table>';
580print '</div>';
581
582print '<br>';
583
584$virtualdiffersfromphysical = 0;
585if (getDolGlobalString('STOCK_CALCULATE_ON_SHIPMENT')
586 || getDolGlobalString('STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER')
587 || getDolGlobalString('STOCK_CALCULATE_ON_SHIPMENT_CLOSE')
588 || getDolGlobalString('STOCK_CALCULATE_ON_RECEPTION')
589 || getDolGlobalString('STOCK_CALCULATE_ON_RECEPTION_CLOSE')
590 || isModEnabled('mrp')) {
591 $virtualdiffersfromphysical = 1; // According to increase/decrease stock options, virtual and physical stock may differs.
592}
593
594if ($virtualdiffersfromphysical) {
595 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
596 print '<table class="noborder centpercent">';
597 print '<tr class="liste_titre">';
598 print "<td>".$langs->trans("RuleForStockReplenishment")." ".img_help(1, $langs->trans("VirtualDiffersFromPhysical"))."</td>\n";
599 print '<td class="right">'.$langs->trans("Status").'</td>'."\n";
600 print '</tr>'."\n";
601
602 print '<tr class="oddeven">';
603 print '<td>';
604 print $form->textwithpicto($langs->trans("UseRealStockByDefault"), $langs->trans("ReplenishmentCalculation"));
605 print '</td>';
606 print '<td class="right">';
607 if ($conf->use_javascript_ajax) {
608 print ajax_constantonoff('STOCK_USE_REAL_STOCK_BY_DEFAULT_FOR_REPLENISHMENT');
609 } else {
610 $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
611 print $form->selectarray("STOCK_USE_REAL_STOCK_BY_DEFAULT_FOR_REPLENISHMENT", $arrval, getDolGlobalString('STOCK_USE_REAL_STOCK_BY_DEFAULT_FOR_REPLENISHMENT'));
612 }
613 print "</td>\n";
614 print "</tr>\n";
615 print '</table>';
616 print '</div>';
617
618 print '<br>';
619}
620
621if (empty($conf->use_javascript_ajax)) {
622 print '<center>';
623 print '<input type="submit" class="button button-edit" value="'.$langs->trans("Save").'">';
624 print '<center>';
625 print '<br>';
626}
627
628print '</form>';
629
630
631/*
632 * Document templates generators
633 */
634
635printDocumentModelList($type, 'stock', 'STOCK_ADDON_PDF', $langs->trans("WarehouseModelModules"), array(
636 'Logo' => 'option_logo',
637 'MultiLanguage' => 'option_multilang',
638));
639
640
641// Other
642
643print '<form method="POST" action="'.$_SERVER['PHP_SELF'].'" spellcheck="false">';
644print '<input type="hidden" name="token" value="'.newToken().'">';
645print '<input type="hidden" name="action" value="warehouse">';
646print '<input type="hidden" name="page_y" value="">';
647
648print load_fiche_titre($langs->trans("Other"), '', '');
649
650print '<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
651print '<table class="noborder centpercent">';
652
653print '<tr class="liste_titre">';
654print "<td>".$langs->trans("Parameter")."</td>\n";
655print '<td class="right"></td>'."\n";
656print '</tr>'."\n";
657
658print '<tr class="oddeven">';
659print '<td>'.$langs->trans("MainDefaultWarehouse").'</td>';
660print '<td class="right">';
661print $formproduct->selectWarehouses(getDolGlobalInt('MAIN_DEFAULT_WAREHOUSE', -1), 'default_warehouse', '', 1, 0, 0, '', 0, 0, array(), 'left reposition');
662print '<input type="submit" class="button button-edit smallpaddingimp" value="'.$langs->trans("Modify").'">';
663print "</td>";
664print "</tr>\n";
665
666// The horizon setup stays hidden by default until the feature is applied by every virtual stock
667// consumer (see review): it only shows up on experimental installs (MAIN_FEATURES_LEVEL >= 2) or
668// when the constant is already set (via Home - Setup - Other), so it can be inspected and cleared.
669// The save handler above is GETPOSTISSET-guarded, so hiding the field cannot wipe the value.
670if (getDolGlobalInt('MAIN_FEATURES_LEVEL') >= 2 || getDolGlobalString('STOCK_VIRTUAL_HORIZON_IN_DAYS') !== '') {
671 print '<tr class="oddeven">';
672 print '<td>'.$form->textwithpicto($langs->trans("VirtualStockHorizon"), $langs->trans("VirtualStockHorizonHelp")).'</td>';
673 print '<td class="right">';
674 print '<input type="number" min="0" step="1" class="width50 right" name="STOCK_VIRTUAL_HORIZON_IN_DAYS" value="'.dol_escape_htmltag(getDolGlobalString('STOCK_VIRTUAL_HORIZON_IN_DAYS')).'"> '.$langs->trans("days").' ';
675 print '<input type="submit" class="button button-edit smallpaddingimp" value="'.$langs->trans("Modify").'">';
676 print "</td>";
677 print "</tr>\n";
678
679 if (getDolGlobalString('STOCK_VIRTUAL_HORIZON_IN_DAYS') !== '') {
680 print '<tr class="oddeven">';
681 print '<td>'.$form->textwithpicto($langs->trans("VirtualStockHorizonKeepUndatedOrders"), $langs->trans("VirtualStockHorizonKeepUndatedOrdersHelp")).'</td>';
682 print '<td class="right">';
683 if ($conf->use_javascript_ajax) {
684 print ajax_constantonoff('STOCK_VIRTUAL_HORIZON_INCLUDE_UNDATED_ORDERS');
685 } else {
686 $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
687 print $form->selectarray("STOCK_VIRTUAL_HORIZON_INCLUDE_UNDATED_ORDERS", $arrval, getDolGlobalString('STOCK_VIRTUAL_HORIZON_INCLUDE_UNDATED_ORDERS'));
688 }
689 print "</td>\n";
690 print "</tr>\n";
691 }
692}
693
694print '<tr class="oddeven">';
695print '<td>'.$langs->trans("UserDefaultWarehouse").'</td>';
696print '<td class="right">';
697if ($conf->use_javascript_ajax) {
698 print ajax_constantonoff('MAIN_DEFAULT_WAREHOUSE_USER', array(), null, 0, 0, 1);
699} else {
700 $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
701 print $form->selectarray("MAIN_DEFAULT_WAREHOUSE_USER", $arrval, getDolGlobalString('MAIN_DEFAULT_WAREHOUSE_USER'));
702}
703print "</td>\n";
704print "</tr>\n";
705
706if (getDolGlobalString('MAIN_DEFAULT_WAREHOUSE_USER')) {
707 print '<tr class="oddeven">';
708 print '<td>'.$langs->trans("UserWarehouseAutoCreate").'</td>';
709 print '<td class="right">';
710 if ($conf->use_javascript_ajax) {
711 print ajax_constantonoff('STOCK_USERSTOCK_AUTOCREATE');
712 } else {
713 $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
714 print $form->selectarray("STOCK_USERSTOCK_AUTOCREATE", $arrval, getDolGlobalString('STOCK_USERSTOCK_AUTOCREATE'));
715 }
716 print "</td>\n";
717 print "</tr>\n";
718}
719
720print '<tr class="oddeven">';
721print '<td>'.$langs->trans("WarehouseAskWarehouseOnThirparty").'</td>';
722print '<td class="right">';
723if ($conf->use_javascript_ajax) {
724 print ajax_constantonoff('SOCIETE_ASK_FOR_WAREHOUSE');
725} else {
726 $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
727 print $form->selectarray("SOCIETE_ASK_FOR_WAREHOUSE", $arrval, getDolGlobalString('SOCIETE_ASK_FOR_WAREHOUSE'));
728}
729print "</td>";
730print "</tr>\n";
731
732print '<tr class="oddeven">';
733print '<td>'.$langs->trans("WarehouseAskWarehouseDuringPropal").'</td>';
734print '<td class="right">';
735if ($conf->use_javascript_ajax) {
736 print ajax_constantonoff('WAREHOUSE_ASK_WAREHOUSE_DURING_PROPAL');
737} else {
738 $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
739 print $form->selectarray("WAREHOUSE_ASK_WAREHOUSE_DURING_PROPAL", $arrval, getDolGlobalString('WAREHOUSE_ASK_WAREHOUSE_DURING_PROPAL'));
740}
741print "</td>";
742print "</tr>\n";
743
744print '<tr class="oddeven">';
745print '<td>'.$langs->trans("WarehouseAskWarehouseDuringOrder").'</td>';
746print '<td class="right">';
747if ($conf->use_javascript_ajax) {
748 print ajax_constantonoff('WAREHOUSE_ASK_WAREHOUSE_DURING_ORDER');
749} else {
750 $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
751 print $form->selectarray("WAREHOUSE_ASK_WAREHOUSE_DURING_ORDER", $arrval, getDolGlobalString('WAREHOUSE_ASK_WAREHOUSE_DURING_ORDER'));
752}
753print '</td>';
754print "</tr>\n";
755
756/*
757print '<tr class="oddeven">';
758print '<td>'.$langs->trans("WarehouseAskWarehouseDuringProject").'</td>';
759print '<td class="right">';
760if ($conf->use_javascript_ajax) {
761 print ajax_constantonoff('WAREHOUSE_ASK_WAREHOUSE_DURING_PROJECT');
762} else {
763 $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
764 print $form->selectarray("WAREHOUSE_ASK_WAREHOUSE_DURING_PROJECT", $arrval, getDolGlobalString('WAREHOUSE_ASK_WAREHOUSE_DURING_PROJECT'));
765}
766print '</td>';
767print "</tr>\n";
768*/
769
770print '<tr class="oddeven">';
771print '<td>';
772print $form->textwithpicto($langs->trans("StockSupportServices"), $langs->trans("StockSupportServicesDesc"));
773print '</td>';
774print '<td class="right">';
775if ($conf->use_javascript_ajax) {
776 print ajax_constantonoff('STOCK_SUPPORTS_SERVICES');
777} else {
778 $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
779 print $form->selectarray("STOCK_SUPPORTS_SERVICES", $arrval, getDolGlobalString('STOCK_SUPPORTS_SERVICES'));
780}
781print "</td>\n";
782print "</tr>\n";
783
784// Add option to allow a "Limit for warning" and a "Desired stock" per warehouse.
785print '<tr class="oddeven">';
786print '<td>'.$langs->trans("AllowAddLimitStockByWarehouse").'</td>';
787print '<td class="right">';
788if ($conf->use_javascript_ajax) {
789 print ajax_constantonoff('STOCK_ALLOW_ADD_LIMIT_STOCK_BY_WAREHOUSE');
790} else {
791 $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
792 print $form->selectarray("STOCK_ALLOW_ADD_LIMIT_STOCK_BY_WAREHOUSE", $arrval, getDolGlobalString('STOCK_ALLOW_ADD_LIMIT_STOCK_BY_WAREHOUSE'));
793}
794print "</td>\n";
795print "</tr>\n";
796
797print '<tr class="oddeven">';
798print '<td>'.$langs->trans("AlwaysShowFullArbo").'</td>';
799print '<td class="right">';
800if ($conf->use_javascript_ajax) {
801 print ajax_constantonoff('STOCK_ALWAYS_SHOW_FULL_ARBO');
802} else {
803 $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
804 print $form->selectarray("STOCK_ALWAYS_SHOW_FULL_ARBO", $arrval, getDolGlobalString('STOCK_ALWAYS_SHOW_FULL_ARBO'));
805}
806print "</td>\n";
807print "</tr>\n";
808
809print '</table>';
810print '</div>';
811
812print '</form>';
813
814// End of page
815llxFooter();
816$db->close();
if(! $sortfield) if(! $sortorder) $object
Definition account.php:100
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.
llxFooter($comment='', $zone='private', $disabledoutputofmessages=0)
Empty footer.
Definition wrapper.php:91
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:73
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 ...
if(! $sortfield) if(! $sortorder) $module
Definition list.php:193
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $conf
The main.inc.php has been included so the following variable are now defined:
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0, $nodefault=0)
Return value of a param into GET or POST supervariable.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
GETPOSTISSET($paramname)
Return true if we are in a context of submitting the parameter $paramname from a POST of a form.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
isModEnabled($module)
Is Dolibarr module enabled.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limittoshow=0, $moretabssuffix='', $dragdropfile=0, $morecssdiv='')
Show tabs of a record.
Definition html.lib.php:540
load_fiche_titre($title, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='', $morecssonpicto='widthpictotitle')
Load a title with picto.
info_admin($text, $infoonimgalt=0, $nodiv=0, $admin='1', $morecss='hideonsmartphone', $textfordropdown='', $picto='', $textonpictotooltip='', $cssfordropdown='info_admin')
Show information in HTML for admin users or standard users.
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