dolibarr 21.0.0-beta
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
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
58
59/*
60 * Action
61 */
62$error = 0;
63
64include DOL_DOCUMENT_ROOT.'/core/actions_setmoduleoptions.inc.php';
65
66$reg = array();
67
68if (preg_match('/set_([a-z0-9_\-]+)/i', $action, $reg)) {
69 $code = $reg[1];
70
71 // If constant is for a unique choice, delete other choices
72 if (in_array($code, array('STOCK_CALCULATE_ON_BILL', 'STOCK_CALCULATE_ON_VALIDATE_ORDER', 'STOCK_CALCULATE_ON_SHIPMENT', 'STOCK_CALCULATE_ON_SHIPMENT_CLOSE'))) {
73 dolibarr_del_const($db, 'STOCK_CALCULATE_ON_BILL', $conf->entity);
74 dolibarr_del_const($db, 'STOCK_CALCULATE_ON_VALIDATE_ORDER', $conf->entity);
75 dolibarr_del_const($db, 'STOCK_CALCULATE_ON_SHIPMENT', $conf->entity);
76 dolibarr_del_const($db, 'STOCK_CALCULATE_ON_SHIPMENT_CLOSE', $conf->entity);
77 }
78 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'))) {
79 dolibarr_del_const($db, 'STOCK_CALCULATE_ON_SUPPLIER_BILL', $conf->entity);
80 dolibarr_del_const($db, 'STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER', $conf->entity);
81 dolibarr_del_const($db, 'STOCK_CALCULATE_ON_RECEPTION', $conf->entity);
82 dolibarr_del_const($db, 'STOCK_CALCULATE_ON_RECEPTION_CLOSE', $conf->entity);
83 dolibarr_del_const($db, 'STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER', $conf->entity);
84 }
85
86 if (dolibarr_set_const($db, $code, 1, 'chaine', 0, '', $conf->entity) > 0) {
87 header("Location: ".$_SERVER["PHP_SELF"]);
88 exit;
89 } else {
90 dol_print_error($db);
91 }
92}
93
94if (preg_match('/del_([a-z0-9_\-]+)/i', $action, $reg)) {
95 $code = $reg[1];
96 if (dolibarr_del_const($db, $code, $conf->entity) > 0) {
97 header("Location: ".$_SERVER["PHP_SELF"]);
98 exit;
99 } else {
100 dol_print_error($db);
101 }
102}
103
104if ($action == 'warehouse') {
105 $value = GETPOST('default_warehouse', 'alpha');
106 $res = dolibarr_set_const($db, "MAIN_DEFAULT_WAREHOUSE", $value, 'chaine', 0, '', $conf->entity);
107 if ($value == -1 || empty($value) && getDolGlobalString('MAIN_DEFAULT_WAREHOUSE')) {
108 $res = dolibarr_del_const($db, "MAIN_DEFAULT_WAREHOUSE", $conf->entity);
109 }
110 if (!($res > 0)) {
111 $error++;
112 }
113}
114
115if ($action == 'specimen') {
116 $modele = GETPOST('module', 'alpha');
117
118 $object = new Entrepot($db);
119 $object->initAsSpecimen();
120
121 // Search template files
122 $file = '';
123 $classname = '';
124 $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
125 foreach ($dirmodels as $reldir) {
126 $file = dol_buildpath($reldir."core/modules/stock/doc/pdf_".$modele.".modules.php", 0);
127 if (file_exists($file)) {
128 $classname = "pdf_".$modele;
129 break;
130 }
131 }
132
133 if ($classname !== '') {
134 require_once $file;
135
136 $module = new $classname($db);
137 '@phan-var-force ModelePDFStock $module';
138
139 if ($module->write_file($object, $langs) > 0) {
140 header("Location: ".DOL_URL_ROOT."/document.php?modulepart=stock&file=SPECIMEN.pdf");
141 return;
142 } else {
143 setEventMessages($module->error, null, 'errors');
144 dol_syslog($module->error, LOG_ERR);
145 }
146 } else {
147 setEventMessages($langs->trans("ErrorModuleNotFound"), null, 'errors');
148 dol_syslog($langs->trans("ErrorModuleNotFound"), LOG_ERR);
149 }
150} elseif ($action == 'set') {
151 // Activate a model
152 $ret = addDocumentModel($value, $type, $label, $scandir);
153} elseif ($action == 'del') {
154 $ret = delDocumentModel($value, $type);
155 if ($ret > 0) {
156 if (getDolGlobalString('STOCK_ADDON_PDF') == "$value") {
157 dolibarr_del_const($db, 'STOCK_ADDON_PDF', $conf->entity);
158 }
159 }
160} elseif ($action == 'setdoc') {
161 // Set default model
162 if (dolibarr_set_const($db, "STOCK_ADDON_PDF", $value, 'chaine', 0, '', $conf->entity)) {
163 // The constant that was read before the new set
164 // We therefore requires a variable to have a coherent view
165 $conf->global->STOCK_ADDON_PDF = $value;
166 }
167
168 // On active le modele
169 $ret = delDocumentModel($value, $type);
170 if ($ret > 0) {
171 $ret = addDocumentModel($value, $type, $label, $scandir);
172 }
173}
174
175
176/*
177 * View
178 */
179
180$form = new Form($db);
181$dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
182
183llxHeader('', $langs->trans("StockSetup"), '', '', 0, 0, '', '', '', 'mod-admin page-stock');
184
185$linkback = '<a href="'.DOL_URL_ROOT.'/admin/modules.php?restore_lastsearch_values=1">'.$langs->trans("BackToModuleList").'</a>';
186print load_fiche_titre($langs->trans("StockSetup"), $linkback, 'title_setup');
187
189
190print dol_get_fiche_head($head, 'general', $langs->trans("StockSetup"), -1, 'stock');
191
192$form = new Form($db);
193$formproduct = new FormProduct($db);
194
195
196
197$disabled = '';
198if (isModEnabled('productbatch')) {
199 // If module lot/serial enabled, we force the inc/dec mode to STOCK_CALCULATE_ON_SHIPMENT_CLOSE and STOCK_CALCULATE_ON_RECEPTION_CLOSE
200 $langs->load("productbatch");
201 $disabled = ' disabled';
202
203 // STOCK_CALCULATE_ON_SHIPMENT_CLOSE
204 $descmode = $langs->trans('DeStockOnShipmentOnClosing');
205 if (!isModEnabled('reception')) {
206 // STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER
207 $incmode = $langs->trans('ReStockOnDispatchOrder');
208 } else {
209 // STOCK_CALCULATE_ON_RECEPTION_CLOSE
210 $incmode = $langs->trans('StockOnReceptionOnClosing');
211 }
212 print info_admin($langs->transnoentitiesnoconv("WhenProductBatchModuleOnOptionAreForced", $descmode, $incmode));
213}
214
215
216print info_admin($langs->trans("IfYouUsePointOfSaleCheckModule"));
217print '<br>';
218
219
220print '<form method="POST" action="'.$_SERVER['PHP_SELF'].'">';
221print '<input type="hidden" name="token" value="'.newToken().'">';
222print '<input type="hidden" name="action" value="warehouse">';
223
224// Title rule for stock decrease
225print '<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
226print '<table class="noborder centpercent">';
227print '<tr class="liste_titre">';
228print "<td>".$langs->trans("RuleForStockManagementDecrease")."</td>\n";
229print '<td class="right">'.$langs->trans("Status").'</td>'."\n";
230print '</tr>'."\n";
231
232$found = 0;
233
234print '<!-- STOCK_CALCULATE_ON_BILL -->';
235print '<tr class="oddeven">';
236print '<td>'.$langs->trans("DeStockOnBill").'</td>';
237print '<td class="right">';
238if (isModEnabled('invoice')) {
239 if ($conf->use_javascript_ajax) {
240 if ($disabled) {
241 print img_picto($langs->trans("Disabled"), 'off', 'class="opacitymedium"');
242 } else {
243 print ajax_constantonoff('STOCK_CALCULATE_ON_BILL', array(), null, 0, 0, 0, 2, 1, 0, '', '', 'reposition');
244 }
245 } else {
246 $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
247 print $form->selectarray("STOCK_CALCULATE_ON_BILL", $arrval, $conf->global->STOCK_CALCULATE_ON_BILL);
248 }
249} else {
250 print '<span class="opacitymedium">'.$langs->trans("ModuleMustBeEnabledFirst", $langs->transnoentitiesnoconv("Module30Name")).'</span>';
251}
252print "</td>\n</tr>\n";
253$found++;
254
255
256print '<!-- STOCK_CALCULATE_ON_VALIDATE_ORDER -->';
257print '<tr class="oddeven">';
258print '<td>'.$langs->trans("DeStockOnValidateOrder").'</td>';
259print '<td class="right">';
260if (isModEnabled('order')) {
261 if ($conf->use_javascript_ajax) {
262 if ($disabled) {
263 print img_picto($langs->trans("Disabled"), 'off', 'class="opacitymedium"');
264 } else {
265 print ajax_constantonoff('STOCK_CALCULATE_ON_VALIDATE_ORDER', array(), null, 0, 0, 0, 2, 1, 0, '', 'reposition');
266 }
267 } else {
268 $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
269 print $form->selectarray("STOCK_CALCULATE_ON_VALIDATE_ORDER", $arrval, $conf->global->STOCK_CALCULATE_ON_VALIDATE_ORDER);
270 }
271} else {
272 print '<span class="opacitymedium">'.$langs->trans("ModuleMustBeEnabledFirst", $langs->transnoentitiesnoconv("Module25Name")).'</span>';
273}
274print "</td>\n</tr>\n";
275$found++;
276
277//if (isModEnabled('shipping'))
278//{
279
280print '<!-- STOCK_CALCULATE_ON_SHIPMENT -->';
281print '<tr class="oddeven">';
282print '<td>'.$langs->trans("DeStockOnShipment").'</td>';
283print '<td class="right">';
284if (isModEnabled("shipping")) {
285 if ($conf->use_javascript_ajax) {
286 print ajax_constantonoff('STOCK_CALCULATE_ON_SHIPMENT', array(), null, 0, 0, 0, 2, 1, 0, '', 'reposition');
287 } else {
288 $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
289 print $form->selectarray("STOCK_CALCULATE_ON_SHIPMENT", $arrval, $conf->global->STOCK_CALCULATE_ON_SHIPMENT);
290 }
291} else {
292 print '<span class="opacitymedium">'.$langs->trans("ModuleMustBeEnabledFirst", $langs->transnoentitiesnoconv("Module80Name")).'</span>';
293}
294print "</td>\n</tr>\n";
295$found++;
296
297print '<!-- STOCK_CALCULATE_ON_SHIPMENT_CLOSE -->';
298print '<tr class="oddeven">';
299print '<td>'.$langs->trans("DeStockOnShipmentOnClosing").'</td>';
300print '<td class="right">';
301if (isModEnabled("shipping")) {
302 if ($conf->use_javascript_ajax) {
303 print ajax_constantonoff('STOCK_CALCULATE_ON_SHIPMENT_CLOSE', array(), null, 0, 0, 0, 2, 1, 0, '', 'reposition');
304 } else {
305 $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
306 print $form->selectarray("STOCK_CALCULATE_ON_SHIPMENT_CLOSE", $arrval, getDolGlobalString('STOCK_CALCULATE_ON_SHIPMENT_CLOSE'));
307 }
308} else {
309 print '<span class="opacitymedium">'.$langs->trans("ModuleMustBeEnabledFirst", $langs->transnoentitiesnoconv("Module80Name")).'</span>';
310}
311print "</td>\n</tr>\n";
312$found++;
313
314print '</table>';
315print '</div>';
316
317print '<br>';
318
319
320// Title rule for stock increase
321print '<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
322print '<table class="noborder centpercent">';
323print '<tr class="liste_titre">';
324print "<td>".$langs->trans("RuleForStockManagementIncrease")."</td>\n";
325print '<td class="right">'.$langs->trans("Status").'</td>'."\n";
326print '</tr>'."\n";
327
328$found = 0;
329
330print '<!-- STOCK_CALCULATE_ON_SUPPLIER_BILL -->';
331print '<tr class="oddeven">';
332print '<td>'.$langs->trans("ReStockOnBill").'</td>';
333print '<td class="right">';
334if (isModEnabled("supplier_order") || isModEnabled("supplier_invoice")) {
335 if ($conf->use_javascript_ajax) {
336 if ($disabled) {
337 print img_picto($langs->trans("Disabled"), 'off', 'class="opacitymedium"');
338 } else {
339 print ajax_constantonoff('STOCK_CALCULATE_ON_SUPPLIER_BILL', array(), null, 0, 0, 0, 2, 1, 0, '', 'reposition');
340 }
341 } else {
342 $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
343 print $form->selectarray("STOCK_CALCULATE_ON_SUPPLIER_BILL", $arrval, $conf->global->STOCK_CALCULATE_ON_SUPPLIER_BILL);
344 }
345} else {
346 print '<span class="opacitymedium">'.$langs->trans("ModuleMustBeEnabledFirst", $langs->transnoentitiesnoconv("Module40Name")).'</span>';
347}
348print "</td>\n</tr>\n";
349$found++;
350
351
352print '<!-- STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER -->';
353print '<tr class="oddeven">';
354print '<td>'.$langs->trans("ReStockOnValidateOrder").'</td>';
355print '<td class="right">';
356if (isModEnabled("supplier_order") || isModEnabled("supplier_invoice")) {
357 if ($conf->use_javascript_ajax) {
358 if ($disabled) {
359 print img_picto($langs->trans("Disabled"), 'off', 'class="opacitymedium"');
360 } else {
361 print ajax_constantonoff('STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER', array(), null, 0, 0, 0, 2, 1, 0, '', 'reposition');
362 }
363 } else {
364 $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
365 print $form->selectarray("STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER", $arrval, $conf->global->STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER);
366 }
367} else {
368 print '<span class="opacitymedium">'.$langs->trans("ModuleMustBeEnabledFirst", $langs->transnoentitiesnoconv("Module40Name")).'</span>';
369}
370print "</td>\n</tr>\n";
371$found++;
372
373if (isModEnabled("reception")) {
374 print '<!-- STOCK_CALCULATE_ON_RECEPTION_CLOSE -->';
375 print '<tr class="oddeven">';
376 print '<td>'.$langs->trans("StockOnReception").'</td>';
377 print '<td class="right">';
378
379 if ($conf->use_javascript_ajax) {
380 print ajax_constantonoff('STOCK_CALCULATE_ON_RECEPTION', array(), null, 0, 0, 0, 2, 1, 0, '', 'reposition');
381 } else {
382 $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
383 print $form->selectarray("STOCK_CALCULATE_ON_RECEPTION", $arrval, $conf->global->STOCK_CALCULATE_ON_RECEPTION);
384 }
385
386 print "</td>\n</tr>\n";
387 $found++;
388
389
390 print '<tr class="oddeven">';
391 print '<td>'.$langs->trans("StockOnReceptionOnClosing").'</td>';
392 print '<td class="right">';
393
394 if ($conf->use_javascript_ajax) {
395 print ajax_constantonoff('STOCK_CALCULATE_ON_RECEPTION_CLOSE', array(), null, 0, 0, 0, 2, 1, 0, '', 'reposition');
396 } else {
397 $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
398 print $form->selectarray("STOCK_CALCULATE_ON_RECEPTION_CLOSE", $arrval, $conf->global->STOCK_CALCULATE_ON_RECEPTION_CLOSE);
399 }
400 print "</td>\n</tr>\n";
401 $found++;
402} else {
403 print '<!-- STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER -->';
404 print '<tr class="oddeven">';
405 print '<td>'.$langs->trans("ReStockOnDispatchOrder").'</td>';
406 print '<td class="right">';
407 if (isModEnabled("supplier_order")) {
408 if ($conf->use_javascript_ajax) {
409 print ajax_constantonoff('STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER', array(), null, 0, 0, 0, 2, 1, 0, '', 'reposition');
410 } else {
411 $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
412 print $form->selectarray("STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER", $arrval, $conf->global->STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER);
413 }
414 } else {
415 print '<span class="opacitymedium">'.$langs->trans("ModuleMustBeEnabledFirst", $langs->transnoentitiesnoconv("Module40Name")).'</span>';
416 }
417 print "</td>\n</tr>\n";
418 $found++;
419}
420
421print '</table>';
422print '</div>';
423
424print '<br>';
425
426print '<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
427print '<table class="noborder centpercent">';
428print '<tr class="liste_titre">';
429print "<td>".$langs->trans("RuleForStockAvailability")."</td>\n";
430print '<td class="right">'.$langs->trans("Status").'</td>'."\n";
431print '</tr>'."\n";
432
433
434print '<tr class="oddeven">';
435print '<td>'.$langs->trans("WarehouseAllowNegativeTransfer").'</td>';
436print '<td class="right">';
437if ($conf->use_javascript_ajax) {
438 print ajax_constantonoff('STOCK_ALLOW_NEGATIVE_TRANSFER');
439} else {
440 $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
441 print $form->selectarray("STOCK_ALLOW_NEGATIVE_TRANSFER", $arrval, $conf->global->STOCK_ALLOW_NEGATIVE_TRANSFER);
442}
443print "</td>\n";
444print "</tr>\n";
445
446// Option to force stock to be enough before adding a line into document
447if (isModEnabled('invoice')) {
448 print '<tr class="oddeven">';
449 print '<td>'.$langs->trans("StockMustBeEnoughForInvoice").'</td>';
450 print '<td class="right">';
451 if ($conf->use_javascript_ajax) {
452 print ajax_constantonoff('STOCK_MUST_BE_ENOUGH_FOR_INVOICE');
453 } else {
454 $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
455 print $form->selectarray("STOCK_MUST_BE_ENOUGH_FOR_INVOICE", $arrval, $conf->global->STOCK_MUST_BE_ENOUGH_FOR_INVOICE);
456 }
457 print "</td>\n";
458 print "</tr>\n";
459}
460
461if (isModEnabled('order')) {
462 print '<tr class="oddeven">';
463 print '<td>'.$langs->trans("StockMustBeEnoughForOrder").'</td>';
464 print '<td class="right">';
465 if ($conf->use_javascript_ajax) {
466 print ajax_constantonoff('STOCK_MUST_BE_ENOUGH_FOR_ORDER');
467 } else {
468 $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
469 print $form->selectarray("STOCK_MUST_BE_ENOUGH_FOR_ORDER", $arrval, $conf->global->STOCK_MUST_BE_ENOUGH_FOR_ORDER);
470 }
471 print "</td>\n";
472 print "</tr>\n";
473}
474
475if (isModEnabled("shipping")) {
476 print '<tr class="oddeven">';
477 print '<td>'.$langs->trans("StockMustBeEnoughForShipment").'</td>';
478 print '<td class="right">';
479 if ($conf->use_javascript_ajax) {
480 print ajax_constantonoff('STOCK_MUST_BE_ENOUGH_FOR_SHIPMENT');
481 } else {
482 $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
483 print $form->selectarray("STOCK_MUST_BE_ENOUGH_FOR_SHIPMENT", $arrval, $conf->global->STOCK_MUST_BE_ENOUGH_FOR_SHIPMENT);
484 }
485 print "</td>\n";
486 print "</tr>\n";
487}
488print '</table>';
489print '</div>';
490
491print '<br>';
492
493$virtualdiffersfromphysical = 0;
494if (getDolGlobalString('STOCK_CALCULATE_ON_SHIPMENT')
495 || getDolGlobalString('STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER')
496 || getDolGlobalString('STOCK_CALCULATE_ON_SHIPMENT_CLOSE')
497 || getDolGlobalString('STOCK_CALCULATE_ON_RECEPTION')
498 || getDolGlobalString('STOCK_CALCULATE_ON_RECEPTION_CLOSE')
499 || isModEnabled('mrp')) {
500 $virtualdiffersfromphysical = 1; // According to increase/decrease stock options, virtual and physical stock may differs.
501}
502
503if ($virtualdiffersfromphysical) {
504 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
505 print '<table class="noborder centpercent">';
506 print '<tr class="liste_titre">';
507 print "<td>".$langs->trans("RuleForStockReplenishment")." ".img_help(1, $langs->trans("VirtualDiffersFromPhysical"))."</td>\n";
508 print '<td class="right">'.$langs->trans("Status").'</td>'."\n";
509 print '</tr>'."\n";
510
511 print '<tr class="oddeven">';
512 print '<td>';
513 print $form->textwithpicto($langs->trans("UseRealStockByDefault"), $langs->trans("ReplenishmentCalculation"));
514 print '</td>';
515 print '<td class="right">';
516 if ($conf->use_javascript_ajax) {
517 print ajax_constantonoff('STOCK_USE_REAL_STOCK_BY_DEFAULT_FOR_REPLENISHMENT');
518 } else {
519 $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
520 print $form->selectarray("STOCK_USE_REAL_STOCK_BY_DEFAULT_FOR_REPLENISHMENT", $arrval, $conf->global->STOCK_USE_REAL_STOCK_BY_DEFAULT_FOR_REPLENISHMENT);
521 }
522 print "</td>\n";
523 print "</tr>\n";
524 print '</table>';
525 print '</div>';
526
527 print '<br>';
528}
529
530print '<form>';
531
532
533print '<form method="POST" action="'.$_SERVER['PHP_SELF'].'">';
534print '<input type="hidden" name="token" value="'.newToken().'">';
535print '<input type="hidden" name="action" value="warehouse">';
536
537
538/*
539 * Document templates generators
540 */
541
542print load_fiche_titre($langs->trans("WarehouseModelModules"), '', '');
543
544// Load array def with activated templates
545$def = array();
546$sql = "SELECT nom";
547$sql .= " FROM ".MAIN_DB_PREFIX."document_model";
548$sql .= " WHERE type = '".$db->escape($type)."'";
549$sql .= " AND entity = ".$conf->entity;
550$resql = $db->query($sql);
551if ($resql) {
552 $i = 0;
553 $num_rows = $db->num_rows($resql);
554 while ($i < $num_rows) {
555 $array = $db->fetch_array($resql);
556 if (is_array($array)) {
557 array_push($def, $array[0]);
558 }
559 $i++;
560 }
561} else {
562 dol_print_error($db);
563}
564
565
566print '<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
567print '<table class="noborder centpercent">'."\n";
568print '<tr class="liste_titre">'."\n";
569print '<td>'.$langs->trans("Name").'</td>';
570print '<td>'.$langs->trans("Description").'</td>';
571print '<td class="center" width="60">'.$langs->trans("Status")."</td>\n";
572print '<td class="center" width="60">'.$langs->trans("Default")."</td>\n";
573print '<td class="center" width="38">'.$langs->trans("ShortInfo").'</td>';
574print '<td class="center" width="38">'.$langs->trans("Preview").'</td>';
575print "</tr>\n";
576
577clearstatcache();
578
579foreach ($dirmodels as $reldir) {
580 foreach (array('', '/doc') as $valdir) {
581 $realpath = $reldir."core/modules/stock".$valdir;
582 $dir = dol_buildpath($realpath);
583
584 if (is_dir($dir)) {
585 $handle = opendir($dir);
586 if (is_resource($handle)) {
587 $filelist = array();
588 while (($file = readdir($handle)) !== false) {
589 $filelist[] = $file;
590 }
591 closedir($handle);
592 arsort($filelist);
593
594 foreach ($filelist as $file) {
595 if (preg_match('/\.modules\.php$/i', $file) && preg_match('/^(pdf_|doc_)/', $file)) {
596 if (file_exists($dir.'/'.$file)) {
597 $name = substr($file, 4, dol_strlen($file) - 16);
598 $classname = substr($file, 0, dol_strlen($file) - 12);
599
600 require_once $dir.'/'.$file;
601 $module = new $classname($db);
602 '@phan-var-force ModelePDFStock $module';
603
604 $modulequalified = 1;
605 if ($module->version == 'development' && getDolGlobalInt('MAIN_FEATURES_LEVEL') < 2) {
606 $modulequalified = 0;
607 }
608 if ($module->version == 'experimental' && getDolGlobalInt('MAIN_FEATURES_LEVEL') < 1) {
609 $modulequalified = 0;
610 }
611
612 if ($modulequalified) {
613 print '<tr class="oddeven"><td width="100">';
614 print(empty($module->name) ? $name : $module->name);
615 print "</td><td>\n";
616 if (method_exists($module, 'info')) {
617 print $module->info($langs); // @phan-suppress-current-line PhanUndeclaredMethod
618 } else {
619 print $module->description;
620 }
621 print '</td>';
622
623 // Active
624 if (in_array($name, $def)) {
625 print '<td class="center">'."\n";
626 print '<a class="reposition" href="'.$_SERVER["PHP_SELF"].'?action=del&token='.newToken().'&value='.urlencode($name).'">';
627 print img_picto($langs->trans("Enabled"), 'switch_on');
628 print '</a>';
629 print '</td>';
630 } else {
631 print '<td class="center">'."\n";
632 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>';
633 print "</td>";
634 }
635
636 // Default
637 print '<td class="center">';
638 if (getDolGlobalString('STOCK_ADDON_PDF') == $name) {
639 print img_picto($langs->trans("Default"), 'on');
640 } else {
641 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>';
642 }
643 print '</td>';
644
645 // Info
646 $htmltooltip = ''.$langs->trans("Name").': '.$module->name;
647 $htmltooltip .= '<br>'.$langs->trans("Type").': '.($module->type ? $module->type : $langs->trans("Unknown"));
648 if ($module->type == 'pdf') {
649 $htmltooltip .= '<br>'.$langs->trans("Width").'/'.$langs->trans("Height").': '.$module->page_largeur.'/'.$module->page_hauteur;
650 }
651 $htmltooltip .= '<br>'.$langs->trans("Path").': '.preg_replace('/^\//', '', $realpath).'/'.$file;
652
653 $htmltooltip .= '<br><br><u>'.$langs->trans("FeaturesSupported").':</u>';
654 $htmltooltip .= '<br>'.$langs->trans("Logo").': '.yn($module->option_logo, 1, 1);
655 $htmltooltip .= '<br>'.$langs->trans("MultiLanguage").': '.yn($module->option_multilang, 1, 1);
656
657
658 print '<td class="center">';
659 print $form->textwithpicto('', $htmltooltip, 1, 0);
660 print '</td>';
661
662 // Preview
663 print '<td class="center">';
664 if ($module->type == 'pdf') {
665 print '<a href="'.$_SERVER["PHP_SELF"].'?action=specimen&module='.$name.'">'.img_object($langs->trans("Preview"), 'pdf').'</a>';
666 } else {
667 print img_object($langs->trans("PreviewNotAvailable"), 'generic');
668 }
669 print '</td>';
670
671 print "</tr>\n";
672 }
673 }
674 }
675 }
676 }
677 }
678 }
679}
680
681print '</table>';
682print '</div>';
683
684print '</form>';
685
686
687// Other
688
689print '<form method="POST" action="'.$_SERVER['PHP_SELF'].'">';
690print '<input type="hidden" name="token" value="'.newToken().'">';
691print '<input type="hidden" name="action" value="warehouse">';
692
693print load_fiche_titre($langs->trans("Other"), '', '');
694
695print '<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
696print '<table class="noborder centpercent">';
697
698print '<tr class="liste_titre">';
699print "<td>".$langs->trans("Parameter")."</td>\n";
700print '<td class="right">'.$langs->trans("Value").'</td>'."\n";
701print '</tr>'."\n";
702
703print '<tr class="oddeven">';
704print '<td>'.$langs->trans("MainDefaultWarehouse").'</td>';
705print '<td class="right">';
706print $formproduct->selectWarehouses(getDolGlobalString('MAIN_DEFAULT_WAREHOUSE') ? $conf->global->MAIN_DEFAULT_WAREHOUSE : -1, 'default_warehouse', '', 1, 0, 0, '', 0, 0, array(), 'left reposition');
707print '<input type="submit" class="button button-edit smallpaddingimp" value="'.$langs->trans("Modify").'">';
708print "</td>";
709print "</tr>\n";
710
711print '<tr class="oddeven">';
712print '<td>'.$langs->trans("UserDefaultWarehouse").'</td>';
713print '<td class="right">';
714if ($conf->use_javascript_ajax) {
715 print ajax_constantonoff('MAIN_DEFAULT_WAREHOUSE_USER', array(), null, 0, 0, 1);
716} else {
717 $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
718 print $form->selectarray("MAIN_DEFAULT_WAREHOUSE_USER", $arrval, $conf->global->MAIN_DEFAULT_WAREHOUSE_USER);
719}
720print "</td>\n";
721print "</tr>\n";
722
723if (getDolGlobalString('MAIN_DEFAULT_WAREHOUSE_USER')) {
724 print '<tr class="oddeven">';
725 print '<td>'.$langs->trans("UserWarehouseAutoCreate").'</td>';
726 print '<td class="right">';
727 if ($conf->use_javascript_ajax) {
728 print ajax_constantonoff('STOCK_USERSTOCK_AUTOCREATE');
729 } else {
730 $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
731 print $form->selectarray("STOCK_USERSTOCK_AUTOCREATE", $arrval, $conf->global->STOCK_USERSTOCK_AUTOCREATE);
732 }
733 print "</td>\n";
734 print "</tr>\n";
735}
736
737print '<tr class="oddeven">';
738print '<td>'.$langs->trans("WarehouseAskWarehouseOnThirparty").'</td>';
739print '<td class="right">';
740if ($conf->use_javascript_ajax) {
741 print ajax_constantonoff('SOCIETE_ASK_FOR_WAREHOUSE');
742} else {
743 $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
744 print $form->selectarray("SOCIETE_ASK_FOR_WAREHOUSE", $arrval, $conf->global->SOCIETE_ASK_FOR_WAREHOUSE);
745}
746print "</td>";
747print "</tr>\n";
748
749print '<tr class="oddeven">';
750print '<td>'.$langs->trans("WarehouseAskWarehouseDuringPropal").'</td>';
751print '<td class="right">';
752if ($conf->use_javascript_ajax) {
753 print ajax_constantonoff('WAREHOUSE_ASK_WAREHOUSE_DURING_PROPAL');
754} else {
755 $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
756 print $form->selectarray("WAREHOUSE_ASK_WAREHOUSE_DURING_PROPAL", $arrval, $conf->global->WAREHOUSE_ASK_WAREHOUSE_DURING_PROPAL);
757}
758print "</td>";
759print "</tr>\n";
760
761print '<tr class="oddeven">';
762print '<td>'.$langs->trans("WarehouseAskWarehouseDuringOrder").'</td>';
763print '<td class="right">';
764if ($conf->use_javascript_ajax) {
765 print ajax_constantonoff('WAREHOUSE_ASK_WAREHOUSE_DURING_ORDER');
766} else {
767 $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
768 print $form->selectarray("WAREHOUSE_ASK_WAREHOUSE_DURING_ORDER", $arrval, $conf->global->WAREHOUSE_ASK_WAREHOUSE_DURING_ORDER);
769}
770print '</td>';
771print "</tr>\n";
772
773/*
774print '<tr class="oddeven">';
775print '<td>'.$langs->trans("WarehouseAskWarehouseDuringProject").'</td>';
776print '<td class="right">';
777if ($conf->use_javascript_ajax) {
778 print ajax_constantonoff('WAREHOUSE_ASK_WAREHOUSE_DURING_PROJECT');
779} else {
780 $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
781 print $form->selectarray("WAREHOUSE_ASK_WAREHOUSE_DURING_PROJECT", $arrval, $conf->global->WAREHOUSE_ASK_WAREHOUSE_DURING_PROJECT);
782}
783print '</td>';
784print "</tr>\n";
785*/
786
787print '<tr class="oddeven">';
788print '<td>';
789print $form->textwithpicto($langs->trans("StockSupportServices"), $langs->trans("StockSupportServicesDesc"));
790print '</td>';
791print '<td class="right">';
792if ($conf->use_javascript_ajax) {
793 print ajax_constantonoff('STOCK_SUPPORTS_SERVICES');
794} else {
795 $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
796 print $form->selectarray("STOCK_SUPPORTS_SERVICES", $arrval, getDolGlobalString('STOCK_SUPPORTS_SERVICES'));
797}
798print "</td>\n";
799print "</tr>\n";
800
801// Add option to allow a "Limit for warning" and a "Desired stock" per warehouse.
802print '<tr class="oddeven">';
803print '<td>'.$langs->trans("AllowAddLimitStockByWarehouse").'</td>';
804print '<td class="right">';
805if ($conf->use_javascript_ajax) {
806 print ajax_constantonoff('STOCK_ALLOW_ADD_LIMIT_STOCK_BY_WAREHOUSE');
807} else {
808 $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
809 print $form->selectarray("STOCK_ALLOW_ADD_LIMIT_STOCK_BY_WAREHOUSE", $arrval, $conf->global->STOCK_ALLOW_ADD_LIMIT_STOCK_BY_WAREHOUSE);
810}
811print "</td>\n";
812print "</tr>\n";
813
814print '<tr class="oddeven">';
815print '<td>'.$langs->trans("AlwaysShowFullArbo").'</td>';
816print '<td class="right">';
817if ($conf->use_javascript_ajax) {
818 print ajax_constantonoff('STOCK_ALWAYS_SHOW_FULL_ARBO');
819} else {
820 $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
821 print $form->selectarray("STOCK_ALWAYS_SHOW_FULL_ARBO", $arrval, $conf->global->STOCK_ALWAYS_SHOW_FULL_ARBO);
822}
823print "</td>\n";
824print "</tr>\n";
825
826/* Disabled. Would be better to be managed with a user cookie
827if (isModEnabled('productbatch')) {
828 print '<tr class="oddeven">';
829 print '<td>' . $langs->trans("ShowAllBatchByDefault") . '</td>';
830 print '<td class="right">';
831 if ($conf->use_javascript_ajax) {
832 print ajax_constantonoff('STOCK_SHOW_ALL_BATCH_BY_DEFAULT');
833 } else {
834 $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
835 print $form->selectarray("STOCK_SHOW_ALL_BATCH_BY_DEFAULT", $arrval, $conf->global->STOCK_SHOW_ALL_BATCH_BY_DEFAULT);
836 }
837 print "</td>\n";
838 print "</tr>\n";
839}
840*/
841
842print '</table>';
843print '</div>';
844
845print '</form>';
846
847// End of page
848llxFooter();
849$db->close();
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:66
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:71
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.
global $conf
The following vars must be defined: $type2label $form $conf, $lang, The following vars may also be de...
Definition member.php:79
$conf db name
Only used if Module[ID]Name translation string is not found.
Definition repair.php:152
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