dolibarr  20.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 
30 require '../main.inc.php';
31 require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
32 require_once DOL_DOCUMENT_ROOT.'/core/lib/stock.lib.php';
33 require_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
39 if (!$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  */
54 include DOL_DOCUMENT_ROOT.'/core/actions_setmoduleoptions.inc.php';
55 
56 $reg = array();
57 
58 if (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 
84 if (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 
94 if ($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 
105 if ($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 CommonDocGenerator $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 
173 llxHeader('', $langs->trans("StockSetup"));
174 
175 $linkback = '<a href="'.DOL_URL_ROOT.'/admin/modules.php?restore_lastsearch_values=1">'.$langs->trans("BackToModuleList").'</a>';
176 print load_fiche_titre($langs->trans("StockSetup"), $linkback, 'title_setup');
177 
178 $head = stock_admin_prepare_head();
179 
180 print 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 = '';
188 if (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 
206 print info_admin($langs->trans("IfYouUsePointOfSaleCheckModule"));
207 print '<br>';
208 
209 
210 print '<form method="POST" action="'.$_SERVER['PHP_SELF'].'">';
211 print '<input type="hidden" name="token" value="'.newToken().'">';
212 print '<input type="hidden" name="action" value="warehouse">';
213 
214 // Title rule for stock decrease
215 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
216 print '<table class="noborder centpercent">';
217 print '<tr class="liste_titre">';
218 print "<td>".$langs->trans("RuleForStockManagementDecrease")."</td>\n";
219 print '<td class="right">'.$langs->trans("Status").'</td>'."\n";
220 print '</tr>'."\n";
221 
222 $found = 0;
223 
224 print '<!-- STOCK_CALCULATE_ON_BILL -->';
225 print '<tr class="oddeven">';
226 print '<td>'.$langs->trans("DeStockOnBill").'</td>';
227 print '<td class="right">';
228 if (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 }
242 print "</td>\n</tr>\n";
243 $found++;
244 
245 
246 print '<!-- STOCK_CALCULATE_ON_VALIDATE_ORDER -->';
247 print '<tr class="oddeven">';
248 print '<td>'.$langs->trans("DeStockOnValidateOrder").'</td>';
249 print '<td class="right">';
250 if (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, '', '', '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 }
264 print "</td>\n</tr>\n";
265 $found++;
266 
267 //if (isModEnabled('expedition'))
268 //{
269 
270 print '<!-- STOCK_CALCULATE_ON_SHIPMENT -->';
271 print '<tr class="oddeven">';
272 print '<td>'.$langs->trans("DeStockOnShipment").'</td>';
273 print '<td class="right">';
274 if (isModEnabled("shipping")) {
275  if ($conf->use_javascript_ajax) {
276  print ajax_constantonoff('STOCK_CALCULATE_ON_SHIPMENT', array(), null, 0, 0, 0, 2, 1, '', '', '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 }
284 print "</td>\n</tr>\n";
285 $found++;
286 
287 print '<!-- STOCK_CALCULATE_ON_SHIPMENT_CLOSE -->';
288 print '<tr class="oddeven">';
289 print '<td>'.$langs->trans("DeStockOnShipmentOnClosing").'</td>';
290 print '<td class="right">';
291 if (isModEnabled("shipping")) {
292  if ($conf->use_javascript_ajax) {
293  print ajax_constantonoff('STOCK_CALCULATE_ON_SHIPMENT_CLOSE', array(), null, 0, 0, 0, 2, 1, '', '', '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 }
301 print "</td>\n</tr>\n";
302 $found++;
303 
304 print '</table>';
305 print '</div>';
306 
307 print '<br>';
308 
309 
310 // Title rule for stock increase
311 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
312 print '<table class="noborder centpercent">';
313 print '<tr class="liste_titre">';
314 print "<td>".$langs->trans("RuleForStockManagementIncrease")."</td>\n";
315 print '<td class="right">'.$langs->trans("Status").'</td>'."\n";
316 print '</tr>'."\n";
317 
318 $found = 0;
319 
320 print '<!-- STOCK_CALCULATE_ON_SUPPLIER_BILL -->';
321 print '<tr class="oddeven">';
322 print '<td>'.$langs->trans("ReStockOnBill").'</td>';
323 print '<td class="right">';
324 if (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, '', '', '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 }
338 print "</td>\n</tr>\n";
339 $found++;
340 
341 
342 print '<!-- STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER -->';
343 print '<tr class="oddeven">';
344 print '<td>'.$langs->trans("ReStockOnValidateOrder").'</td>';
345 print '<td class="right">';
346 if (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, '', '', '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 }
360 print "</td>\n</tr>\n";
361 $found++;
362 
363 if (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, '', '', '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, '', '', '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, '', '', '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 
411 print '</table>';
412 print '</div>';
413 
414 print '<br>';
415 
416 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
417 print '<table class="noborder centpercent">';
418 print '<tr class="liste_titre">';
419 print "<td>".$langs->trans("RuleForStockAvailability")."</td>\n";
420 print '<td class="right">'.$langs->trans("Status").'</td>'."\n";
421 print '</tr>'."\n";
422 
423 
424 print '<tr class="oddeven">';
425 print '<td>'.$langs->trans("WarehouseAllowNegativeTransfer").'</td>';
426 print '<td class="right">';
427 if ($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 }
433 print "</td>\n";
434 print "</tr>\n";
435 
436 // Option to force stock to be enough before adding a line into document
437 if (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 
451 if (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 
465 if (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 }
478 print '</table>';
479 print '</div>';
480 
481 print '<br>';
482 
483 $virtualdiffersfromphysical = 0;
484 if (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 
493 if ($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('help', $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 
520 print '<form>';
521 
522 
523 print '<form method="POST" action="'.$_SERVER['PHP_SELF'].'">';
524 print '<input type="hidden" name="token" value="'.newToken().'">';
525 print '<input type="hidden" name="action" value="warehouse">';
526 
527 
528 /*
529  * Document templates generators
530  */
531 
532 print 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);
541 if ($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 
556 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
557 print '<table class="noborder centpercent">'."\n";
558 print '<tr class="liste_titre">'."\n";
559 print '<td>'.$langs->trans("Name").'</td>';
560 print '<td>'.$langs->trans("Description").'</td>';
561 print '<td class="center" width="60">'.$langs->trans("Status")."</td>\n";
562 print '<td class="center" width="60">'.$langs->trans("Default")."</td>\n";
563 print '<td class="center" width="38">'.$langs->trans("ShortInfo").'</td>';
564 print '<td class="center" width="38">'.$langs->trans("Preview").'</td>';
565 print "</tr>\n";
566 
567 clearstatcache();
568 
569 foreach ($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);
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 
671 print '</table>';
672 print '</div>';
673 
674 print '</form>';
675 
676 
677 // Other
678 
679 print '<form method="POST" action="'.$_SERVER['PHP_SELF'].'">';
680 print '<input type="hidden" name="token" value="'.newToken().'">';
681 print '<input type="hidden" name="action" value="warehouse">';
682 
683 print load_fiche_titre($langs->trans("Other"), '', '');
684 
685 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
686 print '<table class="noborder centpercent">';
687 
688 print '<tr class="liste_titre">';
689 print "<td>".$langs->trans("Parameter")."</td>\n";
690 print '<td class="right">'.$langs->trans("Value").'</td>'."\n";
691 print '</tr>'."\n";
692 
693 print '<tr class="oddeven">';
694 print '<td>'.$langs->trans("MainDefaultWarehouse").'</td>';
695 print '<td class="right">';
696 print $formproduct->selectWarehouses(getDolGlobalString('MAIN_DEFAULT_WAREHOUSE') ? $conf->global->MAIN_DEFAULT_WAREHOUSE : -1, 'default_warehouse', '', 1, 0, 0, '', 0, 0, array(), 'left reposition');
697 print '<input type="submit" class="button button-edit smallpaddingimp" value="'.$langs->trans("Modify").'">';
698 print "</td>";
699 print "</tr>\n";
700 
701 print '<tr class="oddeven">';
702 print '<td>'.$langs->trans("UserDefaultWarehouse").'</td>';
703 print '<td class="right">';
704 if ($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 }
710 print "</td>\n";
711 print "</tr>\n";
712 
713 if (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 
727 print '<tr class="oddeven">';
728 print '<td>'.$langs->trans("WarehouseAskWarehouseOnThirparty").'</td>';
729 print '<td class="right">';
730 if ($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 }
736 print "</td>";
737 print "</tr>\n";
738 
739 print '<tr class="oddeven">';
740 print '<td>'.$langs->trans("WarehouseAskWarehouseDuringPropal").'</td>';
741 print '<td class="right">';
742 if ($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 }
748 print "</td>";
749 print "</tr>\n";
750 
751 print '<tr class="oddeven">';
752 print '<td>'.$langs->trans("WarehouseAskWarehouseDuringOrder").'</td>';
753 print '<td class="right">';
754 if ($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 }
760 print '</td>';
761 print "</tr>\n";
762 
763 /*
764 print '<tr class="oddeven">';
765 print '<td>'.$langs->trans("WarehouseAskWarehouseDuringProject").'</td>';
766 print '<td class="right">';
767 if ($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 }
773 print '</td>';
774 print "</tr>\n";
775 */
776 
777 print '<tr class="oddeven">';
778 print '<td>';
779 print $form->textwithpicto($langs->trans("StockSupportServices"), $langs->trans("StockSupportServicesDesc"));
780 print '</td>';
781 print '<td class="right">';
782 if ($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 }
788 print "</td>\n";
789 print "</tr>\n";
790 
791 // Add option to allow a "Limit for warning" and a "Desired stock" per warehouse.
792 print '<tr class="oddeven">';
793 print '<td>'.$langs->trans("AllowAddLimitStockByWarehouse").'</td>';
794 print '<td class="right">';
795 if ($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 }
801 print "</td>\n";
802 print "</tr>\n";
803 
804 print '<tr class="oddeven">';
805 print '<td>'.$langs->trans("AlwaysShowFullArbo").'</td>';
806 print '<td class="right">';
807 if ($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 }
813 print "</td>\n";
814 print "</tr>\n";
815 
816 /* Disabled. Would be better to be managed with a user cookie
817 if (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 
832 print '</table>';
833 print '</div>';
834 
835 print '</form>';
836 
837 // End of page
838 llxFooter();
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.
Definition: admin.lib.php:1939
dolibarr_set_const($db, $name, $value, $type='chaine', $visible=0, $note='', $entity=1)
Insert a parameter (key,value) into database (delete old key then insert it again).
Definition: admin.lib.php:655
dolibarr_del_const($db, $name, $entity=1)
Delete a constant.
Definition: admin.lib.php:579
delDocumentModel($name, $type)
Delete document model used by doc generator.
Definition: admin.lib.php:1970
ajax_constantonoff($code, $input=array(), $entity=null, $revertonoff=0, $strict=0, $forcereload=0, $marginleftonlyshort=2, $forcenoajax=0, $setzeroinsteadofdel=0, $suffix='', $mode='', $morecss='inline-block')
On/off button for constant.
Definition: ajax.lib.php:646
if(!defined('NOREQUIRESOC')) if(!defined('NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined('NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined('NOREQUIREAJAX')) llxHeader()
Empty header.
Definition: wrapper.php:56
llxFooter()
Empty footer.
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 ...
if(isModEnabled('invoice') && $user->hasRight('facture', 'lire')) if((isModEnabled('fournisseur') &&!getDolGlobalString('MAIN_USE_NEW_SUPPLIERMOD') && $user->hasRight("fournisseur", "facture", "lire"))||(isModEnabled('supplier_invoice') && $user->hasRight("supplier_invoice", "lire"))) if(isModEnabled('don') && $user->hasRight('don', 'lire')) if(isModEnabled('tax') && $user->hasRight('tax', 'charges', 'lire')) if(isModEnabled('invoice') &&isModEnabled('order') && $user->hasRight("commande", "lire") &&!getDolGlobalString('WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER')) $sql
Social contributions to pay.
Definition: index.php:744
if($cancel &&! $id) if($action=='add' &&! $cancel) if($action=='delete') if($id) $form
Actions.
Definition: card.php:143
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0)
Show a picto called object_picto (generic function)
load_fiche_titre($titre, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='')
Load a title with picto.
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)
yn($yesno, $case=1, $color=0)
Return yes or no in current language.
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'.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
info_admin($text, $infoonimgalt=0, $nodiv=0, $admin='1', $morecss='hideonsmartphone', $textfordropdown='')
Show information in HTML for admin users or standard users.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0)
Set event messages in dol_events session object.
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 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.
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:91