32require
'../../main.inc.php';
33require_once DOL_DOCUMENT_ROOT .
'/product/class/product.class.php';
34require_once DOL_DOCUMENT_ROOT .
'/core/class/html.formother.class.php';
35require_once DOL_DOCUMENT_ROOT .
'/core/class/html.form.class.php';
36require_once DOL_DOCUMENT_ROOT .
'/fourn/class/fournisseur.commande.class.php';
37require_once DOL_DOCUMENT_ROOT .
'/product/class/html.formproduct.class.php';
38require_once
'./lib/replenishment.lib.php';
41$langs->loadLangs(array(
'products',
'stocks',
'orders'));
45 $socid = $user->socid;
50$hookmanager->initHooks(array(
'stockreplenishlist'));
54$action =
GETPOST(
'action',
'aZ09');
55$search_ref =
GETPOST(
'search_ref',
'alpha');
56$search_label =
GETPOST(
'search_label',
'alpha');
57$sall = trim((
GETPOST(
'search_all',
'alphanohtml') !=
'') ?
GETPOST(
'search_all',
'alphanohtml') :
GETPOST(
'sall',
'alphanohtml'));
60$salert =
GETPOST(
'salert',
'alpha');
61$includeproductswithoutdesiredqty =
GETPOST(
'includeproductswithoutdesiredqty',
'alpha');
62$mode =
GETPOST(
'mode',
'alpha');
63$draftorder =
GETPOST(
'draftorder',
'alpha');
71$resWar = $db->query(
"SELECT rowid FROM " . MAIN_DB_PREFIX .
"entrepot WHERE entity IN (" . $db->sanitize(
getEntity(
'stock')) .
")");
72$listofqualifiedwarehousesid =
"";
74while ($tmpobj = $db->fetch_object($resWar)) {
75 if (!empty($listofqualifiedwarehousesid)) {
76 $listofqualifiedwarehousesid .=
",";
78 $listofqualifiedwarehousesid .= $tmpobj->rowid;
79 $lastWarehouseID = $tmpobj->rowid;
84if ($count == 1 && (empty($fk_entrepot) || $fk_entrepot <= 0) &&
getDolGlobalString(
'MULTICOMPANY_PRODUCT_SHARING_ENABLED')) {
85 $fk_entrepot = $lastWarehouseID;
90$sortfield =
GETPOST(
'sortfield',
'aZ09comma');
91$sortorder =
GETPOST(
'sortorder',
'aZ09comma');
93if (empty($page) || $page == -1) {
97$offset = $limit * $page;
100 $sortfield =
'p.ref';
108$virtualdiffersfromphysical = 0;
114 || isModEnabled(
'mrp')) {
115 $virtualdiffersfromphysical = 1;
118if ($virtualdiffersfromphysical) {
119 $usevirtualstock = !
getDolGlobalString(
'STOCK_USE_REAL_STOCK_BY_DEFAULT_FOR_REPLENISHMENT') ? 1 : 0;
121 $usevirtualstock = 0;
123if ($mode ==
'physical') {
124 $usevirtualstock = 0;
126if ($mode ==
'virtual') {
127 $usevirtualstock = 1;
130$parameters = array();
131$reshook = $hookmanager->executeHooks(
'doActions', $parameters,
$object, $action);
141if (
GETPOST(
'button_removefilter_x',
'alpha') ||
GETPOST(
'button_removefilter.x',
'alpha') ||
GETPOST(
'button_removefilter',
'alpha')) {
146 $includeproductswithoutdesiredqty =
'';
150if ($draftorder ==
'on') {
151 $draftchecked =
"checked";
155if ($action ==
'order' &&
GETPOST(
'valid')) {
159 unset($_POST[
'linecount']);
160 if ($linecount > 0) {
163 $suppliers = array();
164 require_once DOL_DOCUMENT_ROOT .
'/fourn/class/fournisseur.product.class.php';
166 for ($i = 0; $i < $linecount; $i++) {
173 $idprod = $productsupplier->get_buyprice($supplierpriceid, $qty);
174 $res = $productsupplier->fetch($idprod);
175 if ($res && $idprod > 0) {
180 $line->fk_product = $idprod;
185 $productsupplier->getMultiLangs();
189 if (!empty($productsupplier->desc_supplier) &&
getDolGlobalString(
'PRODUIT_FOURN_TEXTS')) {
190 $desc = $productsupplier->desc_supplier;
192 $desc = $productsupplier->description;
200 if (isModEnabled(
'multicurrency') && !empty($productsupplier->fourn_multicurrency_code) && $productsupplier->fourn_multicurrency_code != $conf->currency) {
201 $line->multicurrency_code = $productsupplier->fourn_multicurrency_code;
202 $line->fk_multicurrency = $productsupplier->fourn_multicurrency_id;
203 $line->multicurrency_subprice = $productsupplier->fourn_multicurrency_unitprice;
206 $line->tva_tx = $productsupplier->vatrate_supplier;
207 $line->subprice = $productsupplier->fourn_pu;
208 $line->total_ht = $productsupplier->fourn_pu * $qty;
209 $tva = $line->tva_tx / 100;
210 $line->total_tva = $line->total_ht * $tva;
211 $line->total_ttc = $line->total_ht + $line->total_tva;
212 $line->remise_percent = $productsupplier->remise_percent;
213 $line->ref_fourn = $productsupplier->ref_supplier;
214 $line->type = $productsupplier->type;
215 $line->fk_unit = $productsupplier->fk_unit;
216 $suppliers[$productsupplier->fourn_socid][
'lines'][] = $line;
218 } elseif ($idprod == -1) {
221 $error = $db->lasterror();
225 unset($_POST[
'fourn' . $i]);
234 $suppliersid = array_keys($suppliers);
235 foreach ($suppliers as $supplier) {
239 $sql =
"SELECT rowid FROM " . MAIN_DB_PREFIX .
"commande_fournisseur";
240 $sql .=
" WHERE fk_soc = " . ((int) $suppliersid[$i]);
241 $sql .=
" AND source = " . ((int) $order::SOURCE_ID_REPLENISHMENT) .
" AND fk_statut = " . ((int) $order::STATUS_DRAFT);
242 $sql .=
" AND entity IN (" .
getEntity(
'commande_fournisseur') .
")";
243 $sql .=
" ORDER BY date_creation DESC";
244 $resql = $db->query($sql);
245 if ($resql && $db->num_rows($resql) > 0) {
246 $obj = $db->fetch_object($resql);
248 $order->fetch($obj->rowid);
249 $order->fetch_thirdparty();
251 foreach ($supplier[
'lines'] as $line) {
252 if (empty($line->remise_percent)) {
253 $line->remise_percent = $order->thirdparty->remise_supplier_percent;
255 $result = $order->addline(
265 $line->remise_percent,
275 $line->multicurrency_subprice ?? 0
280 $msg = $langs->trans(
'OrderFail') .
" : ";
281 $msg .= $order->error;
288 $order->socid = $suppliersid[$i];
289 $order->fetch_thirdparty();
290 $order->multicurrency_code = $order->thirdparty->multicurrency_code;
293 $order->source = $order::SOURCE_ID_REPLENISHMENT;
295 foreach ($supplier[
'lines'] as $line) {
296 if (empty($line->remise_percent)) {
297 $line->remise_percent = $order->thirdparty->remise_supplier_percent;
299 $order->lines[] = $line;
301 $order->cond_reglement_id = $order->thirdparty->cond_reglement_supplier_id;
302 $order->mode_reglement_id = $order->thirdparty->mode_reglement_supplier_id;
304 $id = $order->create($user);
307 $msg = $langs->trans(
'OrderFail') .
" : ";
308 $msg .= $order->error;
316 setEventMessages($langs->trans(
'ErrorOrdersNotCreatedQtyTooLow'),
null,
'warnings');
323 header(
'Location: replenishorders.php');
330 setEventMessages($langs->trans(
'SelectProductWithNotNullQty'),
null,
'warnings');
339$form =
new Form($db);
343$title = $langs->trans(
'MissingStocks');
345if (
getDolGlobalString(
'STOCK_ALLOW_ADD_LIMIT_STOCK_BY_WAREHOUSE') && $fk_entrepot > 0) {
346 $sqldesiredtock = $db->ifsql(
"pse.desiredstock IS NULL",
"p.desiredstock",
"pse.desiredstock");
347 $sqlalertstock = $db->ifsql(
"pse.seuil_stock_alerte IS NULL",
"p.seuil_stock_alerte",
"pse.seuil_stock_alerte");
349 $sqldesiredtock =
'p.desiredstock';
350 $sqlalertstock =
'p.seuil_stock_alerte';
353$sql =
'SELECT p.rowid, p.ref, p.label, p.description, p.price,';
354$sql .=
' p.price_ttc, p.price_base_type, p.fk_product_type,';
355$sql .=
' p.tms as datem, p.duration, p.tobuy,';
356$sql .=
' p.desiredstock, p.seuil_stock_alerte,';
357if (
getDolGlobalString(
'STOCK_ALLOW_ADD_LIMIT_STOCK_BY_WAREHOUSE') && $fk_entrepot > 0) {
358 $sql .=
' pse.desiredstock as desiredstockpse, pse.seuil_stock_alerte as seuil_stock_alertepse,';
360$sql .=
" " . $sqldesiredtock .
" as desiredstockcombined, " . $sqlalertstock .
" as seuil_stock_alertecombined,";
361$sql .=
' s.fk_product,';
362$sql .=
" SUM(".$db->ifsql(
"s.reel IS NULL",
"0",
"s.reel").
') as stock_physique';
363if (
getDolGlobalString(
'STOCK_ALLOW_ADD_LIMIT_STOCK_BY_WAREHOUSE') && $fk_entrepot > 0) {
364 $sql .=
", SUM(".$db->ifsql(
"s.reel IS NULL OR s.fk_entrepot <> ".((
int) $fk_entrepot),
"0",
"s.reel").
') as stock_real_warehouse';
368$parameters = array();
369$reshook = $hookmanager->executeHooks(
'printFieldListSelect', $parameters);
370$sql .= $hookmanager->resPrint;
372$list_warehouse = (empty($listofqualifiedwarehousesid) ?
'0' : $listofqualifiedwarehousesid);
374$sql .=
' FROM ' . MAIN_DB_PREFIX .
'product as p';
375$sql .=
' LEFT JOIN ' . MAIN_DB_PREFIX .
'product_stock as s ON p.rowid = s.fk_product';
376$sql .=
' AND s.fk_entrepot IN (' . $db->sanitize($list_warehouse) .
')';
378$list_warehouse_selected = ($fk_entrepot < 0 || empty($fk_entrepot)) ? $list_warehouse : $fk_entrepot;
379$sql .=
' AND s.fk_entrepot IN (' . $db->sanitize($list_warehouse_selected) .
')';
383if (
getDolGlobalString(
'STOCK_ALLOW_ADD_LIMIT_STOCK_BY_WAREHOUSE') && $fk_entrepot > 0) {
384 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'product_warehouse_properties AS pse ON (p.rowid = pse.fk_product AND pse.fk_entrepot = '.((int) $fk_entrepot).
')';
387$parameters = array();
388$reshook = $hookmanager->executeHooks(
'printFieldListJoin', $parameters);
389$sql .= $hookmanager->resPrint;
391$sql .=
' WHERE p.entity IN (' .
getEntity(
'product') .
')';
393 $sql .=
natural_search(array(
'p.ref',
'p.label',
'p.description',
'p.note'), $sall);
398 $sql .=
' AND p.fk_product_type = 1';
400 $sql .=
' AND p.fk_product_type <> 1';
409$sql .=
' AND p.tobuy = 1';
410if (isModEnabled(
'variants') && !
getDolGlobalString(
'VARIANT_ALLOW_STOCK_MOVEMENT_ON_VARIANT_PARENT')) {
411 $sql .=
' AND p.rowid NOT IN (SELECT pac.fk_product_parent FROM '.MAIN_DB_PREFIX.
'product_attribute_combination as pac WHERE pac.entity IN ('.
getEntity(
'product').
'))';
413if ($fk_supplier > 0) {
414 $sql .=
' AND EXISTS (SELECT pfp.rowid FROM ' . MAIN_DB_PREFIX .
'product_fournisseur_price as pfp WHERE pfp.fk_product = p.rowid AND pfp.fk_soc = ' . ((int) $fk_supplier) .
' AND pfp.entity IN (' .
getEntity(
'product_fournisseur_price') .
'))';
417$parameters = array();
418$reshook = $hookmanager->executeHooks(
'printFieldListWhere', $parameters);
419$sql .= $hookmanager->resPrint;
421$sql .=
' GROUP BY p.rowid, p.ref, p.label, p.description, p.price';
422$sql .=
', p.price_ttc, p.price_base_type,p.fk_product_type, p.tms';
423$sql .=
', p.duration, p.tobuy';
424$sql .=
', p.desiredstock';
425$sql .=
', p.seuil_stock_alerte';
426if (
getDolGlobalString(
'STOCK_ALLOW_ADD_LIMIT_STOCK_BY_WAREHOUSE') && $fk_entrepot > 0) {
427 $sql .=
', pse.desiredstock';
428 $sql .=
', pse.seuil_stock_alerte';
430$sql .=
', s.fk_product';
432if ($usevirtualstock) {
433 if (isModEnabled(
'order')) {
434 $sqlCommandesCli =
"(SELECT ".$db->ifsql(
"SUM(cd1.qty) IS NULL",
"0",
"SUM(cd1.qty)").
" as qty";
435 $sqlCommandesCli .=
" FROM ".MAIN_DB_PREFIX.
"commandedet as cd1, ".MAIN_DB_PREFIX.
"commande as c1";
436 $sqlCommandesCli .=
" WHERE c1.rowid = cd1.fk_commande AND c1.entity IN (".getEntity(
getDolGlobalString(
'STOCK_CALCULATE_VIRTUAL_STOCK_TRANSVERSE_MODE') ?
'stock' :
'commande').
")";
437 $sqlCommandesCli .=
" AND cd1.fk_product = p.rowid";
438 $sqlCommandesCli .=
" AND c1.fk_statut IN (1,2))";
440 $sqlCommandesCli =
'0';
443 if (isModEnabled(
"shipping")) {
444 $sqlExpeditionsCli =
"(SELECT ".$db->ifsql(
"SUM(ed2.qty) IS NULL",
"0",
"SUM(ed2.qty)").
" as qty";
445 $sqlExpeditionsCli .=
" FROM ".MAIN_DB_PREFIX.
"expedition as e2,";
446 $sqlExpeditionsCli .=
" ".MAIN_DB_PREFIX.
"expeditiondet as ed2,";
447 $sqlExpeditionsCli .=
" ".MAIN_DB_PREFIX.
"commande as c2,";
448 $sqlExpeditionsCli .=
" ".MAIN_DB_PREFIX.
"commandedet as cd2";
449 $sqlExpeditionsCli .=
" WHERE ed2.fk_expedition = e2.rowid AND cd2.rowid = ed2.fk_elementdet AND e2.entity IN (".getEntity(
getDolGlobalString(
'STOCK_CALCULATE_VIRTUAL_STOCK_TRANSVERSE_MODE') ?
'stock' :
'expedition').
")";
450 $sqlExpeditionsCli .=
" AND cd2.fk_commande = c2.rowid";
451 $sqlExpeditionsCli .=
" AND c2.fk_statut IN (1,2)";
452 $sqlExpeditionsCli .=
" AND cd2.fk_product = p.rowid";
453 $sqlExpeditionsCli .=
" AND e2.fk_statut IN (1,2))";
455 $sqlExpeditionsCli =
'0';
458 if (isModEnabled(
"supplier_order")) {
459 $sqlCommandesFourn =
"(SELECT " . $db->ifsql(
"SUM(cd3.qty) IS NULL",
"0",
"SUM(cd3.qty)") .
" as qty";
460 $sqlCommandesFourn .=
" FROM " . MAIN_DB_PREFIX .
"commande_fournisseurdet as cd3,";
461 $sqlCommandesFourn .=
" " . MAIN_DB_PREFIX .
"commande_fournisseur as c3";
462 $sqlCommandesFourn .=
" WHERE c3.rowid = cd3.fk_commande";
463 $sqlCommandesFourn .=
" AND c3.entity IN (".getEntity(
getDolGlobalString(
'STOCK_CALCULATE_VIRTUAL_STOCK_TRANSVERSE_MODE') ?
'stock' :
'supplier_order').
")";
464 $sqlCommandesFourn .=
" AND cd3.fk_product = p.rowid";
465 $sqlCommandesFourn .=
" AND c3.fk_statut IN (3,4))";
467 $sqlReceptionFourn =
"(SELECT ".$db->ifsql(
"SUM(fd4.qty) IS NULL",
"0",
"SUM(fd4.qty)").
" as qty";
468 $sqlReceptionFourn .=
" FROM ".MAIN_DB_PREFIX.
"commande_fournisseur as cf4,";
469 $sqlReceptionFourn .=
" ".MAIN_DB_PREFIX.
"receptiondet_batch as fd4";
470 $sqlReceptionFourn .=
" WHERE fd4.fk_element = cf4.rowid AND cf4.entity IN (".getEntity(
getDolGlobalString(
'STOCK_CALCULATE_VIRTUAL_STOCK_TRANSVERSE_MODE') ?
'stock' :
'supplier_order').
")";
471 $sqlReceptionFourn .=
" AND fd4.fk_product = p.rowid";
472 $sqlReceptionFourn .=
" AND cf4.fk_statut IN (3,4))";
474 $sqlCommandesFourn =
'0';
475 $sqlReceptionFourn =
'0';
478 if (isModEnabled(
'mrp')) {
479 $sqlProductionToConsume =
"(SELECT GREATEST(0, ".$db->ifsql(
"SUM(".$db->ifsql(
"mp5.role = 'toconsume'",
'mp5.qty',
'- mp5.qty').
") IS NULL",
"0",
"SUM(".$db->ifsql(
"mp5.role = 'toconsume'",
'mp5.qty',
'- mp5.qty').
")").
") as qty";
480 $sqlProductionToConsume .=
" FROM ".MAIN_DB_PREFIX.
"mrp_mo as mm5,";
481 $sqlProductionToConsume .=
" ".MAIN_DB_PREFIX.
"mrp_production as mp5";
482 $sqlProductionToConsume .=
" WHERE mm5.rowid = mp5.fk_mo AND mm5.entity IN (".getEntity(
getDolGlobalString(
'STOCK_CALCULATE_VIRTUAL_STOCK_TRANSVERSE_MODE') ?
'stock' :
'mo').
")";
483 $sqlProductionToConsume .=
" AND mp5.fk_product = p.rowid";
484 $sqlProductionToConsume .=
" AND mp5.role IN ('toconsume', 'consumed')";
485 $sqlProductionToConsume .=
" AND mm5.status IN (1,2))";
487 $sqlProductionToProduce =
"(SELECT GREATEST(0, ".$db->ifsql(
"SUM(".$db->ifsql(
"mp5.role = 'toproduce'",
'mp5.qty',
'- mp5.qty').
") IS NULL",
"0",
"SUM(".$db->ifsql(
"mp5.role = 'toproduce'",
'mp5.qty',
'- mp5.qty').
")").
") as qty";
488 $sqlProductionToProduce .=
" FROM ".MAIN_DB_PREFIX.
"mrp_mo as mm5,";
489 $sqlProductionToProduce .=
" ".MAIN_DB_PREFIX.
"mrp_production as mp5";
490 $sqlProductionToProduce .=
" WHERE mm5.rowid = mp5.fk_mo AND mm5.entity IN (".getEntity(
getDolGlobalString(
'STOCK_CALCULATE_VIRTUAL_STOCK_TRANSVERSE_MODE') ?
'stock' :
'mo').
")";
491 $sqlProductionToProduce .=
" AND mp5.fk_product = p.rowid";
492 $sqlProductionToProduce .=
" AND mp5.role IN ('toproduce', 'produced')";
493 $sqlProductionToProduce .=
" AND mm5.status IN (1,2))";
495 $sqlProductionToConsume =
'0';
496 $sqlProductionToProduce =
'0';
500 $sql .=
" (" . $sqldesiredtock .
" >= 0 AND (" . $sqldesiredtock .
" > SUM(" . $db->ifsql(
"s.reel IS NULL",
"0",
"s.reel") .
')';
501 $sql .=
" - (" . $sqlCommandesCli .
" - " . $sqlExpeditionsCli .
") + (" . $sqlCommandesFourn .
" - " . $sqlReceptionFourn .
") + (" . $sqlProductionToProduce .
" - " . $sqlProductionToConsume .
")))";
503 if ($includeproductswithoutdesiredqty ==
'on') {
504 $sql .=
" ((" . $sqlalertstock .
" >= 0 OR " . $sqlalertstock .
" IS NULL) AND (" . $db->ifsql($sqlalertstock .
" IS NULL",
"0", $sqlalertstock) .
" > SUM(" . $db->ifsql(
"s.reel IS NULL",
"0",
"s.reel") .
")";
506 $sql .=
" (" . $sqlalertstock .
" >= 0 AND (" . $sqlalertstock .
" > SUM(" . $db->ifsql(
"s.reel IS NULL",
"0",
"s.reel") .
')';
508 $sql .=
" - (" . $sqlCommandesCli .
" - " . $sqlExpeditionsCli .
") + (" . $sqlCommandesFourn .
" - " . $sqlReceptionFourn .
") + (" . $sqlProductionToProduce .
" - " . $sqlProductionToConsume .
")))";
510 if (
getDolGlobalString(
'STOCK_ALLOW_ADD_LIMIT_STOCK_BY_WAREHOUSE') && $fk_entrepot > 0) {
512 $sql .=
" pse.desiredstock > 0)";
515 if ($salert ==
'on') {
517 if ($includeproductswithoutdesiredqty ==
'on') {
518 $sql .=
"(" . $sqlalertstock .
" >= 0 OR " . $sqlalertstock .
" IS NULL) AND (" . $db->ifsql($sqlalertstock .
" IS NULL",
"0", $sqlalertstock) .
" > SUM(" . $db->ifsql(
"s.reel IS NULL",
"0",
"s.reel") .
")";
520 $sql .= $sqlalertstock .
" >= 0 AND (" . $sqlalertstock .
" > SUM(" . $db->ifsql(
"s.reel IS NULL",
"0",
"s.reel") .
")";
522 $sql .=
" - (" . $sqlCommandesCli .
" - " . $sqlExpeditionsCli .
") + (" . $sqlCommandesFourn .
" - " . $sqlReceptionFourn .
") + (" . $sqlProductionToProduce .
" - " . $sqlProductionToConsume .
"))";
524 $alertchecked =
'checked';
528 $sql .=
"(" . $sqldesiredtock .
" >= 0 AND (" . $sqldesiredtock .
" > SUM(" . $db->ifsql(
"s.reel IS NULL",
"0",
"s.reel") .
")))";
530 if ($includeproductswithoutdesiredqty ==
'on') {
531 $sql .=
" ((" . $sqlalertstock .
" >= 0 OR " . $sqlalertstock .
" IS NULL) AND (" . $db->ifsql($sqlalertstock .
" IS NULL",
"0", $sqlalertstock) .
" > SUM(" . $db->ifsql(
"s.reel IS NULL",
"0",
"s.reel") .
')))';
533 $sql .=
" (" . $sqlalertstock .
" >= 0 AND (" . $sqlalertstock .
" > SUM(" . $db->ifsql(
"s.reel IS NULL",
"0",
"s.reel") .
')))';
536 if (
getDolGlobalString(
'STOCK_ALLOW_ADD_LIMIT_STOCK_BY_WAREHOUSE') && $fk_entrepot > 0) {
538 $sql .=
" pse.desiredstock > 0)";
541 if ($salert ==
'on') {
543 if ($includeproductswithoutdesiredqty ==
'on') {
544 $sql .=
" (" . $sqlalertstock .
" >= 0 OR " . $sqlalertstock .
" IS NULL) AND (" . $db->ifsql($sqlalertstock .
" IS NULL",
"0", $sqlalertstock) .
" > SUM(" . $db->ifsql(
"s.reel IS NULL",
"0",
"s.reel") .
"))";
546 $sql .=
" " . $sqlalertstock .
" >= 0 AND (" . $sqlalertstock .
" > SUM(" . $db->ifsql(
"s.reel IS NULL",
"0",
"s.reel") .
'))';
549 $alertchecked =
'checked';
553$includeproductswithoutdesiredqtychecked =
'';
554if ($includeproductswithoutdesiredqty ==
'on') {
555 $includeproductswithoutdesiredqtychecked =
'checked';
558$nbtotalofrecords =
'';
560 $result = $db->query($sql);
561 $nbtotalofrecords = $db->num_rows($result);
562 if (($page * $limit) > $nbtotalofrecords) {
568$sql .= $db->order($sortfield, $sortorder);
569$sql .= $db->plimit($limit + 1, $offset);
572$resql = $db->query($sql);
578$num = $db->num_rows($resql);
581$helpurl =
'EN:Module_Stocks_En|FR:Module_Stock|';
582$helpurl .=
'ES:Módulo_Stocks';
584llxHeader(
'', $title, $helpurl,
'', 0, 0,
'',
'',
'',
'mod-product page-stock_replenish');
588$head[0][0] = DOL_URL_ROOT .
'/product/stock/replenish.php';
590$head[0][2] =
'replenish';
592$head[1][0] = DOL_URL_ROOT .
'/product/stock/replenishorders.php';
593$head[1][1] = $langs->trans(
"ReplenishmentOrders");
594$head[1][2] =
'replenishorders';
601print
'<span class="opacitymedium">' . $langs->trans(
"ReplenishmentStatusDesc") .
'</span>' .
"\n";
605if (empty($fk_entrepot) &&
getDolGlobalString(
'STOCK_ALLOW_ADD_LIMIT_STOCK_BY_WAREHOUSE')) {
606 print
'<span class="opacitymedium">'.$langs->trans(
"ReplenishmentStatusDescPerWarehouse").
'</span>'.
"\n";
609if ($usevirtualstock == 1) {
610 print $langs->trans(
"CurentSelectionMode") .
': ';
611 print
'<span class="a-mesure">' . $langs->trans(
"UseVirtualStock") .
'</span>';
612 print
' <a class="a-mesure-disabled" href="' . $_SERVER[
"PHP_SELF"] .
'?mode=physical' . ($fk_supplier > 0 ?
'&fk_supplier=' . $fk_supplier :
'') . ($fk_entrepot > 0 ?
'&fk_entrepot=' . $fk_entrepot :
'') .
'">' . $langs->trans(
"UsePhysicalStock") .
'</a>';
615if ($usevirtualstock == 0) {
616 print $langs->trans(
"CurentSelectionMode") .
': ';
617 print
'<a class="a-mesure-disabled" href="' . $_SERVER[
"PHP_SELF"] .
'?mode=virtual' . ($fk_supplier > 0 ?
'&fk_supplier=' . $fk_supplier :
'') . ($fk_entrepot > 0 ?
'&fk_entrepot=' . $fk_entrepot :
'') .
'">' . $langs->trans(
"UseVirtualStock") .
'</a>';
618 print
' <span class="a-mesure">' . $langs->trans(
"UsePhysicalStock") .
'</span>';
623print
'<form name="formFilterWarehouse" method="POST" action="' . $_SERVER[
"PHP_SELF"] .
'">';
624print
'<input type="hidden" name="token" value="' .
newToken() .
'">';
625print
'<input type="hidden" name="action" value="filter">';
626print
'<input type="hidden" name="search_ref" value="' . $search_ref .
'">';
627print
'<input type="hidden" name="search_label" value="' . $search_label .
'">';
628print
'<input type="hidden" name="salert" value="' . $salert .
'">';
629print
'<input type="hidden" name="includeproductswithoutdesiredqty" value="' . $includeproductswithoutdesiredqty .
'">';
630print
'<input type="hidden" name="draftorder" value="' . $draftorder .
'">';
631print
'<input type="hidden" name="mode" value="' . $mode .
'">';
632if ($limit > 0 && $limit != $conf->liste_limit) {
633 print
'<input type="hidden" name="limit" value="' . $limit .
'">';
636 print
'<div class="inline-block valignmiddle" style="padding-right: 20px;">';
637 print $langs->trans(
'Warehouse') .
' ' . $formproduct->selectWarehouses($fk_entrepot,
'fk_entrepot',
'', 1);
640print
'<div class="inline-block valignmiddle" style="padding-right: 20px;">';
641$filter =
'(fournisseur:=:1)';
642print $langs->trans(
'Supplier') .
' ' . $form->select_company($fk_supplier,
'fk_supplier', $filter, 1);
645$parameters = array();
646$reshook = $hookmanager->executeHooks(
'printFieldPreListTitle', $parameters);
647if (empty($reshook)) {
648 print $hookmanager->resPrint;
651print
'<div class="inline-block valignmiddle">';
652print
'<input type="submit" class="button smallpaddingimp" name="valid" value="' . $langs->trans(
'ToFilter') .
'">';
657print
'<form action="' . $_SERVER[
"PHP_SELF"] .
'" method="POST" name="formulaire">';
658print
'<input type="hidden" name="token" value="' .
newToken() .
'">';
659print
'<input type="hidden" name="fk_supplier" value="' . $fk_supplier .
'">';
660print
'<input type="hidden" name="fk_entrepot" value="' . $fk_entrepot .
'">';
661print
'<input type="hidden" name="sortfield" value="' . $sortfield .
'">';
662print
'<input type="hidden" name="sortorder" value="' . $sortorder .
'">';
663print
'<input type="hidden" name="type" value="' . $type .
'">';
664print
'<input type="hidden" name="linecount" value="' . $num .
'">';
665print
'<input type="hidden" name="action" value="order">';
666print
'<input type="hidden" name="mode" value="' . $mode .
'">';
669if ($search_ref || $search_label || $sall || $salert || $draftorder ||
GETPOST(
'search',
'alpha')) {
670 $filters =
'&search_ref=' . urlencode($search_ref) .
'&search_label=' . urlencode($search_label);
671 $filters .=
'&sall=' . urlencode($sall);
672 $filters .=
'&salert=' . urlencode($salert);
673 $filters .=
'&draftorder=' . urlencode($draftorder);
674 $filters .=
'&mode=' . urlencode($mode);
675 if ($fk_supplier > 0) {
676 $filters .=
'&fk_supplier='.urlencode((
string) ($fk_supplier));
678 if ($fk_entrepot > 0) {
679 $filters .=
'&fk_entrepot='.urlencode((
string) ($fk_entrepot));
682 $filters =
'&search_ref='.urlencode($search_ref).
'&search_label='.urlencode($search_label);
683 $filters .=
'&fourn_id='.urlencode((
string) ($fourn_id));
684 $filters .= (isset($type) ?
'&type='.urlencode((
string) ($type)) :
'');
685 $filters .=
'&salert='.urlencode($salert);
686 $filters .=
'&draftorder='.urlencode($draftorder);
687 $filters .=
'&mode='.urlencode($mode);
688 if ($fk_supplier > 0) {
689 $filters .=
'&fk_supplier='.urlencode((
string) ($fk_supplier));
691 if ($fk_entrepot > 0) {
692 $filters .=
'&fk_entrepot='.urlencode((
string) ($fk_entrepot));
695if ($limit > 0 && $limit != $conf->liste_limit) {
696 $filters .=
'&limit=' . ((int) $limit);
698if (!empty($includeproductswithoutdesiredqty)) {
699 $filters .=
'&includeproductswithoutdesiredqty='.urlencode($includeproductswithoutdesiredqty);
701if (!empty($salert)) {
702 $filters .=
'&salert='.urlencode($salert);
705$param = (isset($type) ?
'&type='.urlencode((
string) ($type)) :
'');
706$param .=
'&fourn_id='.urlencode((
string) ($fourn_id)).
'&search_label='.urlencode((
string) ($search_label)).
'&includeproductswithoutdesiredqty='.urlencode((
string) ($includeproductswithoutdesiredqty)).
'&salert='.urlencode((
string) ($salert)).
'&draftorder='.urlencode((
string) ($draftorder));
707$param .=
'&search_ref='.urlencode($search_ref);
708$param .=
'&mode='.urlencode($mode);
709$param .=
'&fk_supplier='.urlencode((
string) ($fk_supplier));
710$param .=
'&fk_entrepot='.urlencode((
string) ($fk_entrepot));
711if (!empty($includeproductswithoutdesiredqty)) {
712 $param .=
'&includeproductswithoutdesiredqty='.urlencode($includeproductswithoutdesiredqty);
714if (!empty($salert)) {
715 $param .=
'&salert='.urlencode($salert);
718$stocklabel = $langs->trans(
'Stock');
719$stocklabelbis = $langs->trans(
'Stock');
721if ($usevirtualstock == 1) {
722 $stocklabel = $langs->trans(
'VirtualStock');
723 $stocktooltip = $langs->trans(
"VirtualStockDesc");
725if ($usevirtualstock == 0) {
726 $stocklabel = $langs->trans(
'PhysicalStock');
728if (
getDolGlobalString(
'STOCK_ALLOW_ADD_LIMIT_STOCK_BY_WAREHOUSE') && $fk_entrepot > 0) {
729 $stocklabelbis = $stocklabel.
' (Selected warehouse)';
730 $stocklabel .=
' ('.$langs->trans(
"AllWarehouses").
')';
732$texte = $langs->trans(
'Replenishment');
770print
'<div class="div-table-responsive-no-min">';
771print
'<table class="liste centpercent">';
774print
'<tr class="liste_titre_filter">';
775print
'<td class="liste_titre"> </td>';
776print
'<td class="liste_titre"><input class="flat" type="text" name="search_ref" size="8" value="' .
dol_escape_htmltag($search_ref) .
'"></td>';
777print
'<td class="liste_titre"><input class="flat" type="text" name="search_label" size="8" value="' .
dol_escape_htmltag($search_label) .
'"></td>';
778if (isModEnabled(
"service") && $type == 1) {
779 print
'<td class="liste_titre"> </td>';
781print
'<td class="liste_titre right">' . $form->textwithpicto($langs->trans(
'IncludeEmptyDesiredStock'), $langs->trans(
'IncludeProductWithUndefinedAlerts')) .
' <input type="checkbox" id="includeproductswithoutdesiredqty" name="includeproductswithoutdesiredqty" ' . (!empty($includeproductswithoutdesiredqtychecked) ? $includeproductswithoutdesiredqtychecked :
'') .
'></td>';
782print
'<td class="liste_titre right"></td>';
783print
'<td class="liste_titre right">'.$langs->trans(
'AlertOnly').
' <input type="checkbox" id="salert" name="salert" '.(!empty($alertchecked) ? $alertchecked :
'').
'></td>';
784if (
getDolGlobalString(
'STOCK_ALLOW_ADD_LIMIT_STOCK_BY_WAREHOUSE') && $fk_entrepot > 0) {
785 print
'<td class="liste_titre"> </td>';
787print
'<td class="liste_titre right">';
789 print $langs->trans(
'IncludeAlsoDraftOrders').
' <input type="checkbox" id="draftorder" name="draftorder" '.(!empty($draftchecked) ? $draftchecked :
'').
'>';
792print
'<td class="liste_titre"> </td>';
794$parameters = array(
'param' => $param,
'sortfield' => $sortfield,
'sortorder' => $sortorder);
795$reshook = $hookmanager->executeHooks(
'printFieldListOption', $parameters);
796print $hookmanager->resPrint;
798print
'<td class="liste_titre maxwidthsearch right">';
799$searchpicto = $form->showFilterAndCheckAddButtons(0);
805print
'<tr class="liste_titre">';
809if (isModEnabled(
"service") && $type == 1) {
810 print_liste_field_titre(
'Duration', $_SERVER[
"PHP_SELF"],
'p.duration', $param,
'',
'', $sortfield, $sortorder,
'center ');
812print_liste_field_titre(
'DesiredStock', $_SERVER[
"PHP_SELF"],
'p.desiredstock', $param,
'',
'', $sortfield, $sortorder,
'right ');
813print_liste_field_titre(
'StockLimitShort', $_SERVER[
"PHP_SELF"],
'p.seuil_stock_alerte', $param,
'',
'', $sortfield, $sortorder,
'right ');
814print_liste_field_titre($stocklabel, $_SERVER[
"PHP_SELF"],
'stock_physique', $param,
'',
'', $sortfield, $sortorder,
'right ', $stocktooltip);
815if (
getDolGlobalString(
'STOCK_ALLOW_ADD_LIMIT_STOCK_BY_WAREHOUSE') && $fk_entrepot > 0) {
816 print_liste_field_titre($stocklabelbis, $_SERVER[
"PHP_SELF"],
'stock_real_warehouse', $param,
'',
'', $sortfield, $sortorder,
'right ');
819print_liste_field_titre(
'StockToBuy', $_SERVER[
"PHP_SELF"],
'', $param,
'',
'', $sortfield, $sortorder,
'right ');
820print_liste_field_titre(
'SupplierRef', $_SERVER[
"PHP_SELF"],
'', $param,
'',
'', $sortfield, $sortorder,
'right ');
823$parameters = array(
'param' => $param,
'sortfield' => $sortfield,
'sortorder' => $sortorder);
824$reshook = $hookmanager->executeHooks(
'printFieldListTitle', $parameters);
825print $hookmanager->resPrint;
829while ($i < ($limit ? min($num, $limit) : $num)) {
830 $objp = $db->fetch_object($resql);
833 $result = $prod->fetch($objp->rowid);
839 $prod->load_stock(
'warehouseopen, warehouseinternal'.(!$usevirtualstock ?
', novirtual' :
''), $draftchecked);
843 $sql =
'SELECT label,description';
844 $sql .=
' FROM ' . MAIN_DB_PREFIX .
'product_lang';
845 $sql .=
' WHERE fk_product = ' . ((int) $objp->rowid);
846 $sql .=
" AND lang = '" . $db->escape($langs->getDefaultLang()) .
"'";
849 $resqlm = $db->query($sql);
851 $objtp = $db->fetch_object($resqlm);
852 if (!empty($objtp->description)) {
853 $objp->description = $objtp->description;
855 if (!empty($objtp->label)) {
856 $objp->label = $objtp->label;
862 if ($usevirtualstock) {
864 $stock = $prod->stock_theorique;
867 $stockwarehouse = $prod->stock_warehouse[$fk_entrepot]->virtual;
870 $stock = $prod->stock_reel;
871 if (
getDolGlobalString(
'STOCK_ALLOW_ADD_LIMIT_STOCK_BY_WAREHOUSE') && $fk_entrepot > 0) {
872 $stockwarehouse = $prod->stock_warehouse[$fk_entrepot]->real;
877 if (isset($draftchecked)) {
878 $result = $prod->load_stats_commande_fournisseur(0,
'0,1,2,3,4');
879 } elseif (!$usevirtualstock) {
880 $result = $prod->load_stats_commande_fournisseur(0,
'1,2,3,4');
883 if (!$usevirtualstock) {
884 $result = $prod->load_stats_reception(0,
'4');
889 $ordered = $prod->stats_commande_fournisseur[
'qty'] - $prod->stats_reception[
'qty'];
891 $desiredstock = $objp->desiredstock;
892 $alertstock = $objp->seuil_stock_alerte;
893 $desiredstockwarehouse = (!empty($objp->desiredstockpse) ? $objp->desiredstockpse : 0);
894 $alertstockwarehouse = (!empty($objp->seuil_stock_alertepse) ? $objp->seuil_stock_alertepse : 0);
897 if ($alertstock && ($stock < $alertstock)) {
898 $warning =
img_warning($langs->trans(
'StockTooLow')) .
' ';
900 $warningwarehouse =
'';
901 if ($alertstockwarehouse && ($stockwarehouse < $alertstockwarehouse)) {
902 $warningwarehouse =
img_warning($langs->trans(
'StockTooLow')) .
' ';
908 if (empty($usevirtualstock)) {
909 $stocktobuy = max(max($desiredstock, $alertstock) - $stock - $ordered, 0);
911 $stocktobuy = max(max($desiredstock, $alertstock) - $stock, 0);
913 if (empty($usevirtualstock)) {
914 $stocktobuywarehouse = max(max($desiredstockwarehouse, $alertstockwarehouse) - $stockwarehouse - $ordered, 0);
916 $stocktobuywarehouse = max(max($desiredstockwarehouse, $alertstockwarehouse) - $stockwarehouse, 0);
921 $stockforcompare = ($usevirtualstock ? $stock : $stock + $ordered);
929 $picto =
img_picto($langs->trans(
"NoPendingReceptionOnSupplierOrder"),
'help');
932 print
'<tr class="oddeven">';
935 print
'<td><input type="checkbox" class="check" name="choose' . $i .
'"></td>';
937 print
'<td class="nowrap">' . $prod->getNomUrl(1,
'stock') .
'</td>';
939 print
'<td class="tdoverflowmax200" title="' .
dol_escape_htmltag($objp->label) .
'">';
941 print
'<input type="hidden" name="desc' . $i .
'" value="' .
dol_escape_htmltag($objp->description) .
'">';
944 if (isModEnabled(
"service") && $type == 1) {
946 if (preg_match(
'/([0-9]+)y/i', $objp->duration, $regs)) {
947 $duration = $regs[1] .
' ' . $langs->trans(
'DurationYear');
948 } elseif (preg_match(
'/([0-9]+)m/i', $objp->duration, $regs)) {
949 $duration = $regs[1] .
' ' . $langs->trans(
'DurationMonth');
950 } elseif (preg_match(
'/([0-9]+)d/i', $objp->duration, $regs)) {
951 $duration = $regs[1] .
' ' . $langs->trans(
'DurationDay');
953 $duration = $objp->duration;
955 print
'<td class="center">' . $duration .
'</td>';
959 print
'<td class="right">'.((getDolGlobalString(
'STOCK_ALLOW_ADD_LIMIT_STOCK_BY_WAREHOUSE') && $fk_entrepot > 0) > 0 ? $desiredstockwarehouse : $desiredstock).
'</td>';
962 print
'<td class="right">'.((getDolGlobalString(
'STOCK_ALLOW_ADD_LIMIT_STOCK_BY_WAREHOUSE') && $fk_entrepot > 0) > 0 ? $alertstockwarehouse : $alertstock).
'</td>';
965 print
'<td class="right">' . $warning . $stock;
966 print
'<!-- stock returned by main sql is ' . $objp->stock_physique .
' -->';
970 if (
getDolGlobalString(
'STOCK_ALLOW_ADD_LIMIT_STOCK_BY_WAREHOUSE') && $fk_entrepot > 0) {
971 print
'<td class="right">'.$warningwarehouse.$stockwarehouse.
'</td>';
975 print
'<td class="right"><a href="replenishorders.php?search_product=' . $prod->id .
'">' . $ordered .
'</a> ' . $picto .
'</td>';
978 $tobuy = ((
getDolGlobalString(
'STOCK_ALLOW_ADD_LIMIT_STOCK_BY_WAREHOUSE') && $fk_entrepot > 0) > 0 ? $stocktobuywarehouse : $stocktobuy);
979 print
'<td class="right"><input type="text" size="4" name="tobuy'.$i.
'" value="'.$tobuy.
'"></td>';
982 print
'<td class="right">';
983 print $form->select_product_fourn_price($prod->id,
'fourn' . $i, $fk_supplier);
987 $parameters = array(
'objp' => $objp,
'i' => $i,
'tobuy' => $tobuy);
988 $reshook = $hookmanager->executeHooks(
'printFieldListValue', $parameters);
989 print $hookmanager->resPrint;
998 if (isModEnabled(
"service") && $type == 1) {
1001 if (
getDolGlobalString(
'STOCK_ALLOW_ADD_LIMIT_STOCK_BY_WAREHOUSE') && $fk_entrepot > 0) {
1004 print
'<tr><td colspan="' . $colspan .
'">';
1005 print
'<span class="opacitymedium">';
1006 print $langs->trans(
"None");
1011$parameters = array(
'sql' => $sql);
1012$reshook = $hookmanager->executeHooks(
'printFieldListFooter', $parameters);
1013print $hookmanager->resPrint;
1023$value = $langs->trans(
"CreateOrders");
1024print
'<div class="center"><input type="submit" class="button" name="valid" value="' . $value .
'"></div>';
1032<script type="text/javascript">
1033function toggle(source)
1035 checkboxes = document.getElementsByClassName("check");
1036 for (var i=0; i < checkboxes.length;i++) {
1037 if (!checkboxes[i].disabled) {
1038 checkboxes[i].checked = source.checked;
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
if(!defined('NOREQUIRESOC')) if(!defined( 'NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined( 'NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined( 'NOREQUIREAJAX')) llxHeader()
Empty header.
Class to manage predefined suppliers products.
Class to manage line orders.
Class to manage predefined suppliers products.
Class to manage products or services.
load_fiche_titre($title, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='')
Load a title with picto.
img_warning($titlealt='default', $moreatt='', $morecss='pictowarning')
Show warning logo.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
GETPOSTINT($paramname, $method=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
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_get_fiche_end($notab=0)
Return tab footer of a card.
natural_search($fields, $value, $mode=0, $nofirstand=0)
Generate natural SQL search string for a criteria (this criteria can be tested on one or several fiel...
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'.
print_liste_field_titre($name, $file="", $field="", $begin="", $moreparam="", $moreattrib="", $sortfield="", $sortorder="", $prefix="", $tooltip="", $forcenowrapcolumntitle=0)
Show title line of an array.
print_barre_liste($title, $page, $file, $options='', $sortfield='', $sortorder='', $morehtmlcenter='', $num=-1, $totalnboflines='', $picto='generic', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limit=-1, $hideselectlimit=0, $hidenavigation=0, $pagenavastextinput=0, $morehtmlrightbeforearrow='')
Print a title with navigation controls for pagination.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0)
Set event messages in dol_events session object.
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.
getEntity($element, $shared=1, $currentobject=null)
Get list of entity id to use.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
Returns text escaped for inclusion in HTML alt or title or value tags, or into values of HTML input f...
restrictedArea(User $user, $features, $object=0, $tableandshare='', $feature2='', $dbt_keyfield='fk_soc', $dbt_select='rowid', $isdraft=0, $mode=0)
Check permissions of a user to show a page and an object.