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'));
59$tobuy =
GETPOST(
'tobuy',
'int');
60$salert =
GETPOST(
'salert',
'alpha');
61$includeproductswithoutdesiredqty =
GETPOST(
'includeproductswithoutdesiredqty',
'alpha');
62$mode =
GETPOST(
'mode',
'alpha');
63$draftorder =
GETPOST(
'draftorder',
'alpha');
66$fourn_id =
GETPOST(
'fourn_id',
'int');
67$fk_supplier =
GETPOST(
'fk_supplier',
'int');
68$fk_entrepot =
GETPOST(
'fk_entrepot',
'int');
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) && !empty($conf->global->MULTICOMPANY_PRODUCT_SHARING_ENABLED)) {
85 $fk_entrepot = $lastWarehouseID;
90$sortfield =
GETPOST(
'sortfield',
'aZ09comma');
91$sortorder =
GETPOST(
'sortorder',
'aZ09comma');
92$page = GETPOSTISSET(
'pageplusone') ? (
GETPOST(
'pageplusone') - 1) :
GETPOST(
"page",
'int');
93if (empty($page) || $page == -1) {
96$limit =
GETPOST(
'limit',
'int') ?
GETPOST(
'limit',
'int') : $conf->liste_limit;
97$offset = $limit * $page;
100 $sortfield =
'p.ref';
108$virtualdiffersfromphysical = 0;
109if (!empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT)
110 || !empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER)
111 || !empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT_CLOSE)
112 || !empty($conf->global->STOCK_CALCULATE_ON_RECEPTION)
113 || !empty($conf->global->STOCK_CALCULATE_ON_RECEPTION_CLOSE)
114 || isModEnabled(
'mrp')) {
115 $virtualdiffersfromphysical = 1;
118if ($virtualdiffersfromphysical) {
119 $usevirtualstock = empty($conf->global->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')) {
156 $linecount =
GETPOST(
'linecount',
'int');
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++) {
167 if (
GETPOST(
'choose' . $i,
'alpha') ===
'on' &&
GETPOST(
'fourn' . $i,
'int') > 0) {
170 $supplierpriceid =
GETPOST(
'fourn' . $i,
'int');
172 $qty =
GETPOST(
'tobuy' . $i,
'int');
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) && !empty($conf->global->PRODUIT_FOURN_TEXTS)) {
190 $desc = $productsupplier->desc_supplier;
192 $desc = $productsupplier->description;
199 $line->tva_tx = $productsupplier->vatrate_supplier;
200 $tva = $line->tva_tx / 100;
203 if (isModEnabled(
'multicurrency') && !empty($productsupplier->fourn_multicurrency_code) && $productsupplier->fourn_multicurrency_code != $conf->currency) {
204 $line->multicurrency_code = $productsupplier->fourn_multicurrency_code;
205 $line->fk_multicurrency = $productsupplier->fourn_multicurrency_id;
206 $line->multicurrency_subprice = $productsupplier->fourn_multicurrency_unitprice;
207 $line->multicurrency_total_ht = $line->multicurrency_subprice * $qty;
208 $line->multicurrency_total_tva = $line->multicurrency_total_ht * $tva;
209 $line->multicurrency_total_ttc = $line->multicurrency_total_ht + $line->multicurrency_total_tva;
211 $line->subprice = $productsupplier->fourn_pu;
212 $line->total_ht = $productsupplier->fourn_pu * $qty;
213 $line->total_tva = $line->total_ht * $tva;
214 $line->total_ttc = $line->total_ht + $line->total_tva;
215 $line->remise_percent = $productsupplier->remise_percent;
216 $line->ref_fourn = $productsupplier->ref_supplier;
217 $line->type = $productsupplier->type;
218 $line->fk_unit = $productsupplier->fk_unit;
219 $suppliers[$productsupplier->fourn_socid][
'lines'][] = $line;
221 } elseif ($idprod == -1) {
224 $error = $db->lasterror();
228 unset($_POST[
'fourn' . $i]);
237 $suppliersid = array_keys($suppliers);
238 foreach ($suppliers as $supplier) {
242 $sql =
"SELECT rowid FROM " . MAIN_DB_PREFIX .
"commande_fournisseur";
243 $sql .=
" WHERE fk_soc = " . ((int) $suppliersid[$i]);
244 $sql .=
" AND source = " . ((int) $order::SOURCE_ID_REPLENISHMENT) .
" AND fk_statut = " . ((int) $order::STATUS_DRAFT);
245 $sql .=
" AND entity IN (" .
getEntity(
'commande_fournisseur') .
")";
246 $sql .=
" ORDER BY date_creation DESC";
247 $resql = $db->query($sql);
248 if ($resql && $db->num_rows($resql) > 0) {
249 $obj = $db->fetch_object($resql);
251 $order->fetch($obj->rowid);
252 $order->fetch_thirdparty();
254 foreach ($supplier[
'lines'] as $line) {
255 if (empty($line->remise_percent)) {
256 $line->remise_percent = $order->thirdparty->remise_supplier_percent;
258 $result = $order->addline(
268 $line->remise_percent,
278 $line->multicurrency_subprice ?? 0
283 $msg = $langs->trans(
'OrderFail') .
" : ";
284 $msg .= $order->error;
291 $order->socid = $suppliersid[$i];
292 $order->fetch_thirdparty();
293 $order->multicurrency_code = $order->thirdparty->multicurrency_code;
296 $order->source = $order::SOURCE_ID_REPLENISHMENT;
298 foreach ($supplier[
'lines'] as $line) {
299 if (empty($line->remise_percent)) {
300 $line->remise_percent = $order->thirdparty->remise_supplier_percent;
302 $order->lines[] = $line;
304 $order->cond_reglement_id = $order->thirdparty->cond_reglement_supplier_id;
305 $order->mode_reglement_id = $order->thirdparty->mode_reglement_supplier_id;
307 $id = $order->create($user);
310 $msg = $langs->trans(
'OrderFail') .
" : ";
311 $msg .= $order->error;
319 setEventMessages($langs->trans(
'ErrorOrdersNotCreatedQtyTooLow'),
null,
'warnings');
326 header(
'Location: replenishorders.php');
333 setEventMessages($langs->trans(
'SelectProductWithNotNullQty'),
null,
'warnings');
342$form =
new Form($db);
346$title = $langs->trans(
'MissingStocks');
348if (!empty($conf->global->STOCK_ALLOW_ADD_LIMIT_STOCK_BY_WAREHOUSE) && $fk_entrepot > 0) {
349 $sqldesiredtock = $db->ifsql(
"pse.desiredstock IS NULL",
"p.desiredstock",
"pse.desiredstock");
350 $sqlalertstock = $db->ifsql(
"pse.seuil_stock_alerte IS NULL",
"p.seuil_stock_alerte",
"pse.seuil_stock_alerte");
352 $sqldesiredtock =
'p.desiredstock';
353 $sqlalertstock =
'p.seuil_stock_alerte';
356$sql =
'SELECT p.rowid, p.ref, p.label, p.description, p.price,';
357$sql .=
' p.price_ttc, p.price_base_type, p.fk_product_type,';
358$sql .=
' p.tms as datem, p.duration, p.tobuy,';
359$sql .=
' p.desiredstock, p.seuil_stock_alerte,';
360if (!empty($conf->global->STOCK_ALLOW_ADD_LIMIT_STOCK_BY_WAREHOUSE) && $fk_entrepot > 0) {
361 $sql .=
' pse.desiredstock as desiredstockpse, pse.seuil_stock_alerte as seuil_stock_alertepse,';
363$sql .=
" " . $sqldesiredtock .
" as desiredstockcombined, " . $sqlalertstock .
" as seuil_stock_alertecombined,";
364$sql .=
' s.fk_product,';
365$sql .=
" SUM(" . $db->ifsql(
"s.reel IS NULL",
"0",
"s.reel") .
') as stock_physique';
366if (!empty($conf->global->STOCK_ALLOW_ADD_LIMIT_STOCK_BY_WAREHOUSE) && $fk_entrepot > 0) {
367 $sql .=
", SUM(" . $db->ifsql(
"s.reel IS NULL OR s.fk_entrepot <> " . $fk_entrepot,
"0",
"s.reel") .
') as stock_real_warehouse';
371$parameters = array();
372$reshook = $hookmanager->executeHooks(
'printFieldListSelect', $parameters);
373$sql .= $hookmanager->resPrint;
375$list_warehouse = (empty($listofqualifiedwarehousesid) ?
'0' : $listofqualifiedwarehousesid);
377$sql .=
' FROM ' . MAIN_DB_PREFIX .
'product as p';
378$sql .=
' LEFT JOIN ' . MAIN_DB_PREFIX .
'product_stock as s ON p.rowid = s.fk_product';
379$sql .=
' AND s.fk_entrepot IN (' . $db->sanitize($list_warehouse) .
')';
381$list_warehouse_selected = ($fk_entrepot < 0 || empty($fk_entrepot)) ? $list_warehouse : $fk_entrepot;
382$sql .=
' AND s.fk_entrepot IN (' . $db->sanitize($list_warehouse_selected) .
')';
386if (!empty($conf->global->STOCK_ALLOW_ADD_LIMIT_STOCK_BY_WAREHOUSE) && $fk_entrepot > 0) {
387 $sql .=
' LEFT JOIN ' . MAIN_DB_PREFIX .
'product_warehouse_properties AS pse ON (p.rowid = pse.fk_product AND pse.fk_entrepot = ' . ((int) $fk_entrepot) .
')';
390$parameters = array();
391$reshook = $hookmanager->executeHooks(
'printFieldListJoin', $parameters);
392$sql .= $hookmanager->resPrint;
394$sql .=
' WHERE p.entity IN (' .
getEntity(
'product') .
')';
396 $sql .=
natural_search(array(
'p.ref',
'p.label',
'p.description',
'p.note'), $sall);
401 $sql .=
' AND p.fk_product_type = 1';
403 $sql .=
' AND p.fk_product_type <> 1';
412$sql .=
' AND p.tobuy = 1';
413if (isModEnabled(
'variants') && !
getDolGlobalString(
'VARIANT_ALLOW_STOCK_MOVEMENT_ON_VARIANT_PARENT')) {
414 $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') .
'))';
416if ($fk_supplier > 0) {
417 $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') .
'))';
420$parameters = array();
421$reshook = $hookmanager->executeHooks(
'printFieldListWhere', $parameters);
422$sql .= $hookmanager->resPrint;
424$sql .=
' GROUP BY p.rowid, p.ref, p.label, p.description, p.price';
425$sql .=
', p.price_ttc, p.price_base_type,p.fk_product_type, p.tms';
426$sql .=
', p.duration, p.tobuy';
427$sql .=
', p.desiredstock';
428$sql .=
', p.seuil_stock_alerte';
429if (!empty($conf->global->STOCK_ALLOW_ADD_LIMIT_STOCK_BY_WAREHOUSE) && $fk_entrepot > 0) {
430 $sql .=
', pse.desiredstock';
431 $sql .=
', pse.seuil_stock_alerte';
433$sql .=
', s.fk_product';
435if ($usevirtualstock) {
436 if (isModEnabled(
'commande')) {
437 $sqlCommandesCli =
"(SELECT " . $db->ifsql(
"SUM(cd1.qty) IS NULL",
"0",
"SUM(cd1.qty)") .
" as qty";
438 $sqlCommandesCli .=
" FROM " . MAIN_DB_PREFIX .
"commandedet as cd1, " . MAIN_DB_PREFIX .
"commande as c1";
439 $sqlCommandesCli .=
" WHERE c1.rowid = cd1.fk_commande AND c1.entity IN (" .
getEntity(!empty($conf->global->STOCK_CALCULATE_VIRTUAL_STOCK_TRANSVERSE_MODE) ?
'stock' :
'commande') .
")";
440 $sqlCommandesCli .=
" AND cd1.fk_product = p.rowid";
441 $sqlCommandesCli .=
" AND c1.fk_statut IN (1,2))";
443 $sqlCommandesCli =
'0';
446 if (isModEnabled(
"expedition")) {
447 $sqlExpeditionsCli =
"(SELECT " . $db->ifsql(
"SUM(ed2.qty) IS NULL",
"0",
"SUM(ed2.qty)") .
" as qty";
448 $sqlExpeditionsCli .=
" FROM " . MAIN_DB_PREFIX .
"expedition as e2,";
449 $sqlExpeditionsCli .=
" " . MAIN_DB_PREFIX .
"expeditiondet as ed2,";
450 $sqlExpeditionsCli .=
" " . MAIN_DB_PREFIX .
"commande as c2,";
451 $sqlExpeditionsCli .=
" " . MAIN_DB_PREFIX .
"commandedet as cd2";
452 $sqlExpeditionsCli .=
" WHERE ed2.fk_expedition = e2.rowid AND cd2.rowid = ed2.fk_origin_line AND e2.entity IN (" .
getEntity(!empty($conf->global->STOCK_CALCULATE_VIRTUAL_STOCK_TRANSVERSE_MODE) ?
'stock' :
'expedition') .
")";
453 $sqlExpeditionsCli .=
" AND cd2.fk_commande = c2.rowid";
454 $sqlExpeditionsCli .=
" AND c2.fk_statut IN (1,2)";
455 $sqlExpeditionsCli .=
" AND cd2.fk_product = p.rowid";
456 $sqlExpeditionsCli .=
" AND e2.fk_statut IN (1,2))";
458 $sqlExpeditionsCli =
'0';
461 if (isModEnabled(
"supplier_order")) {
462 $sqlCommandesFourn =
"(SELECT " . $db->ifsql(
"SUM(cd3.qty) IS NULL",
"0",
"SUM(cd3.qty)") .
" as qty";
463 $sqlCommandesFourn .=
" FROM " . MAIN_DB_PREFIX .
"commande_fournisseurdet as cd3,";
464 $sqlCommandesFourn .=
" " . MAIN_DB_PREFIX .
"commande_fournisseur as c3";
465 $sqlCommandesFourn .=
" WHERE c3.rowid = cd3.fk_commande";
466 $sqlCommandesFourn .=
" AND c3.entity IN (" .
getEntity(!empty($conf->global->STOCK_CALCULATE_VIRTUAL_STOCK_TRANSVERSE_MODE) ?
'stock' :
'supplier_order') .
")";
467 $sqlCommandesFourn .=
" AND cd3.fk_product = p.rowid";
468 $sqlCommandesFourn .=
" AND c3.fk_statut IN (3,4))";
470 $sqlReceptionFourn =
"(SELECT " . $db->ifsql(
"SUM(fd4.qty) IS NULL",
"0",
"SUM(fd4.qty)") .
" as qty";
471 $sqlReceptionFourn .=
" FROM " . MAIN_DB_PREFIX .
"commande_fournisseur as cf4,";
472 $sqlReceptionFourn .=
" " . MAIN_DB_PREFIX .
"commande_fournisseur_dispatch as fd4";
473 $sqlReceptionFourn .=
" WHERE fd4.fk_commande = cf4.rowid AND cf4.entity IN (" .
getEntity(!empty($conf->global->STOCK_CALCULATE_VIRTUAL_STOCK_TRANSVERSE_MODE) ?
'stock' :
'supplier_order') .
")";
474 $sqlReceptionFourn .=
" AND fd4.fk_product = p.rowid";
475 $sqlReceptionFourn .=
" AND cf4.fk_statut IN (3,4))";
477 $sqlCommandesFourn =
'0';
478 $sqlReceptionFourn =
'0';
481 if (isModEnabled(
'mrp')) {
482 $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";
483 $sqlProductionToConsume .=
" FROM " . MAIN_DB_PREFIX .
"mrp_mo as mm5,";
484 $sqlProductionToConsume .=
" " . MAIN_DB_PREFIX .
"mrp_production as mp5";
485 $sqlProductionToConsume .=
" WHERE mm5.rowid = mp5.fk_mo AND mm5.entity IN (" .
getEntity(!empty($conf->global->STOCK_CALCULATE_VIRTUAL_STOCK_TRANSVERSE_MODE) ?
'stock' :
'mo') .
")";
486 $sqlProductionToConsume .=
" AND mp5.fk_product = p.rowid";
487 $sqlProductionToConsume .=
" AND mp5.role IN ('toconsume', 'consumed')";
488 $sqlProductionToConsume .=
" AND mm5.status IN (1,2))";
490 $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";
491 $sqlProductionToProduce .=
" FROM " . MAIN_DB_PREFIX .
"mrp_mo as mm5,";
492 $sqlProductionToProduce .=
" " . MAIN_DB_PREFIX .
"mrp_production as mp5";
493 $sqlProductionToProduce .=
" WHERE mm5.rowid = mp5.fk_mo AND mm5.entity IN (" .
getEntity(!empty($conf->global->STOCK_CALCULATE_VIRTUAL_STOCK_TRANSVERSE_MODE) ?
'stock' :
'mo') .
")";
494 $sqlProductionToProduce .=
" AND mp5.fk_product = p.rowid";
495 $sqlProductionToProduce .=
" AND mp5.role IN ('toproduce', 'produced')";
496 $sqlProductionToProduce .=
" AND mm5.status IN (1,2))";
498 $sqlProductionToConsume =
'0';
499 $sqlProductionToProduce =
'0';
503 $sql .=
" (" . $sqldesiredtock .
" >= 0 AND (" . $sqldesiredtock .
" > SUM(" . $db->ifsql(
"s.reel IS NULL",
"0",
"s.reel") .
')';
504 $sql .=
" - (" . $sqlCommandesCli .
" - " . $sqlExpeditionsCli .
") + (" . $sqlCommandesFourn .
" - " . $sqlReceptionFourn .
") + (" . $sqlProductionToProduce .
" - " . $sqlProductionToConsume .
")))";
506 if ($includeproductswithoutdesiredqty ==
'on') {
507 $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") .
")";
509 $sql .=
" (" . $sqlalertstock .
" >= 0 AND (" . $sqlalertstock .
" > SUM(" . $db->ifsql(
"s.reel IS NULL",
"0",
"s.reel") .
')';
511 $sql .=
" - (" . $sqlCommandesCli .
" - " . $sqlExpeditionsCli .
") + (" . $sqlCommandesFourn .
" - " . $sqlReceptionFourn .
") + (" . $sqlProductionToProduce .
" - " . $sqlProductionToConsume .
")))";
513 if (!empty($conf->global->STOCK_ALLOW_ADD_LIMIT_STOCK_BY_WAREHOUSE) && $fk_entrepot > 0) {
515 $sql .=
" pse.desiredstock > 0)";
518 if ($salert ==
'on') {
520 if ($includeproductswithoutdesiredqty ==
'on') {
521 $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") .
")";
523 $sql .= $sqlalertstock .
" >= 0 AND (" . $sqlalertstock .
" > SUM(" . $db->ifsql(
"s.reel IS NULL",
"0",
"s.reel") .
")";
525 $sql .=
" - (" . $sqlCommandesCli .
" - " . $sqlExpeditionsCli .
") + (" . $sqlCommandesFourn .
" - " . $sqlReceptionFourn .
") + (" . $sqlProductionToProduce .
" - " . $sqlProductionToConsume .
"))";
527 $alertchecked =
'checked';
531 $sql .=
"(" . $sqldesiredtock .
" >= 0 AND (" . $sqldesiredtock .
" > SUM(" . $db->ifsql(
"s.reel IS NULL",
"0",
"s.reel") .
")))";
533 if ($includeproductswithoutdesiredqty ==
'on') {
534 $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") .
')))';
536 $sql .=
" (" . $sqlalertstock .
" >= 0 AND (" . $sqlalertstock .
" > SUM(" . $db->ifsql(
"s.reel IS NULL",
"0",
"s.reel") .
')))';
539 if (!empty($conf->global->STOCK_ALLOW_ADD_LIMIT_STOCK_BY_WAREHOUSE) && $fk_entrepot > 0) {
541 $sql .=
" pse.desiredstock > 0)";
544 if ($salert ==
'on') {
546 if ($includeproductswithoutdesiredqty ==
'on') {
547 $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") .
"))";
549 $sql .=
" " . $sqlalertstock .
" >= 0 AND (" . $sqlalertstock .
" > SUM(" . $db->ifsql(
"s.reel IS NULL",
"0",
"s.reel") .
'))';
552 $alertchecked =
'checked';
556$includeproductswithoutdesiredqtychecked =
'';
557if ($includeproductswithoutdesiredqty ==
'on') {
558 $includeproductswithoutdesiredqtychecked =
'checked';
561$nbtotalofrecords =
'';
563 $result = $db->query($sql);
564 $nbtotalofrecords = $db->num_rows($result);
565 if (($page * $limit) > $nbtotalofrecords) {
571$sql .= $db->order($sortfield, $sortorder);
572$sql .= $db->plimit($limit + 1, $offset);
575$resql = $db->query($sql);
581$num = $db->num_rows($resql);
584$helpurl =
'EN:Module_Stocks_En|FR:Module_Stock|';
585$helpurl .=
'ES:Módulo_Stocks';
591$head[0][0] = DOL_URL_ROOT .
'/product/stock/replenish.php';
593$head[0][2] =
'replenish';
595$head[1][0] = DOL_URL_ROOT .
'/product/stock/replenishorders.php';
596$head[1][1] = $langs->trans(
"ReplenishmentOrders");
597$head[1][2] =
'replenishorders';
604print
'<span class="opacitymedium">' . $langs->trans(
"ReplenishmentStatusDesc") .
'</span>' .
"\n";
608if (empty($fk_entrepot) && !empty($conf->global->STOCK_ALLOW_ADD_LIMIT_STOCK_BY_WAREHOUSE)) {
609 print
'<span class="opacitymedium">' . $langs->trans(
"ReplenishmentStatusDescPerWarehouse") .
'</span>' .
"\n";
612if ($usevirtualstock == 1) {
613 print $langs->trans(
"CurentSelectionMode") .
': ';
614 print
'<span class="a-mesure">' . $langs->trans(
"UseVirtualStock") .
'</span>';
615 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>';
618if ($usevirtualstock == 0) {
619 print $langs->trans(
"CurentSelectionMode") .
': ';
620 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>';
621 print
' <span class="a-mesure">' . $langs->trans(
"UsePhysicalStock") .
'</span>';
626print
'<form name="formFilterWarehouse" method="POST" action="' . $_SERVER[
"PHP_SELF"] .
'">';
627print
'<input type="hidden" name="token" value="' . newToken() .
'">';
628print
'<input type="hidden" name="action" value="filter">';
629print
'<input type="hidden" name="search_ref" value="' . $search_ref .
'">';
630print
'<input type="hidden" name="search_label" value="' . $search_label .
'">';
631print
'<input type="hidden" name="salert" value="' . $salert .
'">';
632print
'<input type="hidden" name="includeproductswithoutdesiredqty" value="' . $includeproductswithoutdesiredqty .
'">';
633print
'<input type="hidden" name="draftorder" value="' . $draftorder .
'">';
634print
'<input type="hidden" name="mode" value="' . $mode .
'">';
635if ($limit > 0 && $limit != $conf->liste_limit) {
636 print
'<input type="hidden" name="limit" value="' . $limit .
'">';
638if (!empty($conf->global->STOCK_ALLOW_ADD_LIMIT_STOCK_BY_WAREHOUSE)) {
639 print
'<div class="inline-block valignmiddle" style="padding-right: 20px;">';
640 print $langs->trans(
'Warehouse') .
' ' . $formproduct->selectWarehouses($fk_entrepot,
'fk_entrepot',
'', 1);
643print
'<div class="inline-block valignmiddle" style="padding-right: 20px;">';
644$filter =
'(fournisseur:=:1)';
645print $langs->trans(
'Supplier') .
' ' . $form->select_company($fk_supplier,
'fk_supplier', $filter, 1);
648$parameters = array();
649$reshook = $hookmanager->executeHooks(
'printFieldPreListTitle', $parameters);
650if (empty($reshook)) {
651 print $hookmanager->resPrint;
654print
'<div class="inline-block valignmiddle">';
655print
'<input type="submit" class="button smallpaddingimp" name="valid" value="' . $langs->trans(
'ToFilter') .
'">';
660print
'<form action="' . $_SERVER[
"PHP_SELF"] .
'" method="POST" name="formulaire">';
661print
'<input type="hidden" name="token" value="' . newToken() .
'">';
662print
'<input type="hidden" name="fk_supplier" value="' . $fk_supplier .
'">';
663print
'<input type="hidden" name="fk_entrepot" value="' . $fk_entrepot .
'">';
664print
'<input type="hidden" name="sortfield" value="' . $sortfield .
'">';
665print
'<input type="hidden" name="sortorder" value="' . $sortorder .
'">';
666print
'<input type="hidden" name="type" value="' . $type .
'">';
667print
'<input type="hidden" name="linecount" value="' . $num .
'">';
668print
'<input type="hidden" name="action" value="order">';
669print
'<input type="hidden" name="mode" value="' . $mode .
'">';
672if ($search_ref || $search_label || $sall || $salert || $draftorder ||
GETPOST(
'search',
'alpha')) {
673 $filters =
'&search_ref=' . urlencode($search_ref) .
'&search_label=' . urlencode($search_label);
674 $filters .=
'&sall=' . urlencode($sall);
675 $filters .=
'&salert=' . urlencode($salert);
676 $filters .=
'&draftorder=' . urlencode($draftorder);
677 $filters .=
'&mode=' . urlencode($mode);
678 if ($fk_supplier > 0) {
679 $filters .=
'&fk_supplier=' . urlencode($fk_supplier);
681 if ($fk_entrepot > 0) {
682 $filters .=
'&fk_entrepot=' . urlencode($fk_entrepot);
685 $filters =
'&search_ref=' . urlencode($search_ref) .
'&search_label=' . urlencode($search_label);
686 $filters .=
'&fourn_id=' . urlencode($fourn_id);
687 $filters .= (isset($type) ?
'&type=' . urlencode($type) :
'');
688 $filters .=
'&=' . urlencode($salert);
689 $filters .=
'&draftorder=' . urlencode($draftorder);
690 $filters .=
'&mode=' . urlencode($mode);
691 if ($fk_supplier > 0) {
692 $filters .=
'&fk_supplier=' . urlencode($fk_supplier);
694 if ($fk_entrepot > 0) {
695 $filters .=
'&fk_entrepot=' . urlencode($fk_entrepot);
698if ($limit > 0 && $limit != $conf->liste_limit) {
699 $filters .=
'&limit=' . ((int) $limit);
701if (!empty($includeproductswithoutdesiredqty)) $filters .=
'&includeproductswithoutdesiredqty=' . urlencode($includeproductswithoutdesiredqty);
702if (!empty($salert)) $filters .=
'&salert=' . urlencode($salert);
704$param = (isset($type) ?
'&type=' . urlencode($type) :
'');
705$param .=
'&fourn_id=' . urlencode($fourn_id) .
'&search_label=' . urlencode($search_label) .
'&includeproductswithoutdesiredqty=' . urlencode($includeproductswithoutdesiredqty) .
'&salert=' . urlencode($salert) .
'&draftorder=' . urlencode($draftorder);
706$param .=
'&search_ref=' . urlencode($search_ref);
707$param .=
'&mode=' . urlencode($mode);
708$param .=
'&fk_supplier=' . urlencode($fk_supplier);
709$param .=
'&fk_entrepot=' . urlencode($fk_entrepot);
710if (!empty($includeproductswithoutdesiredqty)) $param .=
'&includeproductswithoutdesiredqty=' . urlencode($includeproductswithoutdesiredqty);
711if (!empty($salert)) $param .=
'&salert=' . urlencode($salert);
713$stocklabel = $langs->trans(
'Stock');
714$stocklabelbis = $langs->trans(
'Stock');
716if ($usevirtualstock == 1) {
717 $stocklabel = $langs->trans(
'VirtualStock');
718 $stocktooltip = $langs->trans(
"VirtualStockDesc");
720if ($usevirtualstock == 0) {
721 $stocklabel = $langs->trans(
'PhysicalStock');
723if (!empty($conf->global->STOCK_ALLOW_ADD_LIMIT_STOCK_BY_WAREHOUSE) && $fk_entrepot > 0) {
724 $stocklabelbis = $stocklabel .
' (Selected warehouse)';
725 $stocklabel .=
' (' . $langs->trans(
"AllWarehouses") .
')';
727$texte = $langs->trans(
'Replenishment');
732if (!empty($conf->global->REPLENISH_ALLOW_VARIABLESIZELIST)) {
765print
'<div class="div-table-responsive-no-min">';
766print
'<table class="liste centpercent">';
769print
'<tr class="liste_titre_filter">';
770print
'<td class="liste_titre"> </td>';
771print
'<td class="liste_titre"><input class="flat" type="text" name="search_ref" size="8" value="' .
dol_escape_htmltag($search_ref) .
'"></td>';
772print
'<td class="liste_titre"><input class="flat" type="text" name="search_label" size="8" value="' .
dol_escape_htmltag($search_label) .
'"></td>';
773if (isModEnabled(
"service") && $type == 1) {
774 print
'<td class="liste_titre"> </td>';
776print
'<td class="liste_titre right">' . $form->textwithpicto($langs->trans(
'IncludeEmptyDesiredStock'), $langs->trans(
'IncludeProductWithUndefinedAlerts')) .
' <input type="checkbox" id="includeproductswithoutdesiredqty" name="includeproductswithoutdesiredqty" ' . (!empty($includeproductswithoutdesiredqtychecked) ? $includeproductswithoutdesiredqtychecked :
'') .
'></td>';
777print
'<td class="liste_titre right"></td>';
778print
'<td class="liste_titre right">' . $langs->trans(
'AlertOnly') .
' <input type="checkbox" id="salert" name="salert" ' . (!empty($alertchecked) ? $alertchecked :
'') .
'></td>';
779if (!empty($conf->global->STOCK_ALLOW_ADD_LIMIT_STOCK_BY_WAREHOUSE) && $fk_entrepot > 0) {
780 print
'<td class="liste_titre"> </td>';
782print
'<td class="liste_titre right">';
783if (!empty($conf->global->STOCK_REPLENISH_ADD_CHECKBOX_INCLUDE_DRAFT_ORDER)) {
784 print $langs->trans(
'IncludeAlsoDraftOrders') .
' <input type="checkbox" id="draftorder" name="draftorder" ' . (!empty($draftchecked) ? $draftchecked :
'') .
'>';
787print
'<td class="liste_titre"> </td>';
789$parameters = array(
'param' => $param,
'sortfield' => $sortfield,
'sortorder' => $sortorder);
790$reshook = $hookmanager->executeHooks(
'printFieldListOption', $parameters);
791print $hookmanager->resPrint;
793print
'<td class="liste_titre maxwidthsearch right">';
794$searchpicto = $form->showFilterAndCheckAddButtons(0);
800print
'<tr class="liste_titre">';
804if (isModEnabled(
"service") && $type == 1) {
805 print_liste_field_titre(
'Duration', $_SERVER[
"PHP_SELF"],
'p.duration', $param,
'',
'', $sortfield, $sortorder,
'center ');
807print_liste_field_titre(
'DesiredStock', $_SERVER[
"PHP_SELF"],
'p.desiredstock', $param,
'',
'', $sortfield, $sortorder,
'right ');
808print_liste_field_titre(
'StockLimitShort', $_SERVER[
"PHP_SELF"],
'p.seuil_stock_alerte', $param,
'',
'', $sortfield, $sortorder,
'right ');
809print_liste_field_titre($stocklabel, $_SERVER[
"PHP_SELF"],
'stock_physique', $param,
'',
'', $sortfield, $sortorder,
'right ', $stocktooltip);
810if (!empty($conf->global->STOCK_ALLOW_ADD_LIMIT_STOCK_BY_WAREHOUSE) && $fk_entrepot > 0) {
811 print_liste_field_titre($stocklabelbis, $_SERVER[
"PHP_SELF"],
'stock_real_warehouse', $param,
'',
'', $sortfield, $sortorder,
'right ');
814print_liste_field_titre(
'StockToBuy', $_SERVER[
"PHP_SELF"],
'', $param,
'',
'', $sortfield, $sortorder,
'right ');
815print_liste_field_titre(
'SupplierRef', $_SERVER[
"PHP_SELF"],
'', $param,
'',
'', $sortfield, $sortorder,
'right ');
818$parameters = array(
'param' => $param,
'sortfield' => $sortfield,
'sortorder' => $sortorder);
819$reshook = $hookmanager->executeHooks(
'printFieldListTitle', $parameters);
820print $hookmanager->resPrint;
824while ($i < ($limit ? min($num, $limit) : $num)) {
825 $objp = $db->fetch_object($resql);
827 if (!empty($conf->global->STOCK_SUPPORTS_SERVICES) || $objp->fk_product_type == 0) {
828 $result = $prod->fetch($objp->rowid);
834 $prod->load_stock(
'warehouseopen, warehouseinternal' . (!$usevirtualstock ?
', novirtual' :
''), $draftchecked);
838 $sql =
'SELECT label,description';
839 $sql .=
' FROM ' . MAIN_DB_PREFIX .
'product_lang';
840 $sql .=
' WHERE fk_product = ' . ((int) $objp->rowid);
841 $sql .=
" AND lang = '" . $db->escape($langs->getDefaultLang()) .
"'";
844 $resqlm = $db->query($sql);
846 $objtp = $db->fetch_object($resqlm);
847 if (!empty($objtp->description)) {
848 $objp->description = $objtp->description;
850 if (!empty($objtp->label)) {
851 $objp->label = $objtp->label;
857 if ($usevirtualstock) {
859 $stock = $prod->stock_theorique;
862 $stock = $prod->stock_reel;
863 if (!empty($prod->stock_warehouse[$fk_entrepot])) {
864 $stockwarehouse = $prod->stock_warehouse[$fk_entrepot]->real;
869 if (isset($draftchecked)) {
870 $result = $prod->load_stats_commande_fournisseur(0,
'0,1,2,3,4');
871 } elseif (!$usevirtualstock) {
872 $result = $prod->load_stats_commande_fournisseur(0,
'1,2,3,4');
875 if (!$usevirtualstock) {
876 $result = $prod->load_stats_reception(0,
'4');
881 $ordered = $prod->stats_commande_fournisseur[
'qty'] - $prod->stats_reception[
'qty'];
883 $desiredstock = $objp->desiredstock;
884 $alertstock = $objp->seuil_stock_alerte;
885 $desiredstockwarehouse = (!empty($objp->desiredstockpse) ? $objp->desiredstockpse : 0);
886 $alertstockwarehouse = (!empty($objp->seuil_stock_alertepse) ? $objp->seuil_stock_alertepse : 0);
889 if ($alertstock && ($stock < $alertstock)) {
890 $warning =
img_warning($langs->trans(
'StockTooLow')) .
' ';
892 $warningwarehouse =
'';
893 if ($alertstockwarehouse && ($stockwarehouse < $alertstockwarehouse)) {
894 $warningwarehouse =
img_warning($langs->trans(
'StockTooLow')) .
' ';
900 if (empty($usevirtualstock)) {
901 $stocktobuy = max(max($desiredstock, $alertstock) - $stock - $ordered, 0);
903 $stocktobuy = max(max($desiredstock, $alertstock) - $stock, 0);
905 if (empty($usevirtualstock)) {
906 $stocktobuywarehouse = max(max($desiredstockwarehouse, $alertstockwarehouse) - $stockwarehouse - $ordered, 0);
908 $stocktobuywarehouse = max(max($desiredstockwarehouse, $alertstockwarehouse) - $stockwarehouse, 0);
913 $stockforcompare = ($usevirtualstock ? $stock : $stock + $ordered);
921 $picto =
img_picto($langs->trans(
"NoPendingReceptionOnSupplierOrder"),
'help');
924 print
'<tr class="oddeven">';
927 print
'<td><input type="checkbox" class="check" name="choose' . $i .
'"></td>';
929 print
'<td class="nowrap">' . $prod->getNomUrl(1,
'stock') .
'</td>';
931 print
'<td class="tdoverflowmax200" title="' .
dol_escape_htmltag($objp->label) .
'">';
933 print
'<input type="hidden" name="desc' . $i .
'" value="' .
dol_escape_htmltag($objp->description) .
'">';
936 if (isModEnabled(
"service") && $type == 1) {
938 if (preg_match(
'/([0-9]+)y/i', $objp->duration, $regs)) {
939 $duration = $regs[1] .
' ' . $langs->trans(
'DurationYear');
940 } elseif (preg_match(
'/([0-9]+)m/i', $objp->duration, $regs)) {
941 $duration = $regs[1] .
' ' . $langs->trans(
'DurationMonth');
942 } elseif (preg_match(
'/([0-9]+)d/i', $objp->duration, $regs)) {
943 $duration = $regs[1] .
' ' . $langs->trans(
'DurationDay');
945 $duration = $objp->duration;
947 print
'<td class="center">' . $duration .
'</td>';
951 print
'<td class="right">' . ((!empty($conf->global->STOCK_ALLOW_ADD_LIMIT_STOCK_BY_WAREHOUSE) && $fk_entrepot > 0) > 0 ? $desiredstockwarehouse : $desiredstock) .
'</td>';
954 print
'<td class="right">' . ((!empty($conf->global->STOCK_ALLOW_ADD_LIMIT_STOCK_BY_WAREHOUSE) && $fk_entrepot > 0) > 0 ? $alertstockwarehouse : $alertstock) .
'</td>';
957 print
'<td class="right">' . $warning . $stock;
958 print
'<!-- stock returned by main sql is ' . $objp->stock_physique .
' -->';
962 if (!empty($conf->global->STOCK_ALLOW_ADD_LIMIT_STOCK_BY_WAREHOUSE) && $fk_entrepot > 0) {
963 print
'<td class="right">' . $warningwarehouse . $stockwarehouse .
'</td>';
967 print
'<td class="right"><a href="replenishorders.php?search_product=' . $prod->id .
'">' . $ordered .
'</a> ' . $picto .
'</td>';
970 $tobuy = (!empty($conf->global->STOCK_ALLOW_ADD_LIMIT_STOCK_BY_WAREHOUSE) && $fk_entrepot > 0) > 0 ? $stocktobuywarehouse : $stocktobuy;
971 print
'<td class="right"><input type="text" size="4" name="tobuy' . $i .
'" value="' . $tobuy .
'"></td>';
974 print
'<td class="right">';
975 print $form->select_product_fourn_price($prod->id,
'fourn' . $i, $fk_supplier);
979 $parameters = array(
'objp' => $objp,
'i' => $i,
'tobuy' => $tobuy);
980 $reshook = $hookmanager->executeHooks(
'printFieldListValue', $parameters);
981 print $hookmanager->resPrint;
990 if (isModEnabled(
"service") && $type == 1) {
993 if (!empty($conf->global->STOCK_ALLOW_ADD_LIMIT_STOCK_BY_WAREHOUSE) && $fk_entrepot > 0) {
996 print
'<tr><td colspan="' . $colspan .
'">';
997 print
'<span class="opacitymedium">';
998 print $langs->trans(
"None");
1003$parameters = array(
'sql' => $sql);
1004$reshook = $hookmanager->executeHooks(
'printFieldListFooter', $parameters);
1005print $hookmanager->resPrint;
1015$value = $langs->trans(
"CreateOrders");
1016print
'<div class="center"><input type="submit" class="button" name="valid" value="' . $value .
'"></div>';
1024<script type="text/javascript">
1025function toggle(source)
1027 checkboxes = document.getElementsByClassName("check");
1028 for (var i=0; i < checkboxes.length;i++) {
1029 if (!checkboxes[i].disabled) {
1030 checkboxes[i].checked = source.checked;
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($titre, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='')
Load a title with picto.
img_warning($titlealt='default', $moreatt='', $morecss='pictowarning')
Show warning logo.
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_print_error($db='', $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
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 dolibarr global constant int value.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
print_liste_field_titre($name, $file="", $field="", $begin="", $moreparam="", $moreattrib="", $sortfield="", $sortorder="", $prefix="", $tooltip="", $forcenowrapcolumntitle=0)
Show title line of an array.
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.
print_barre_liste($titre, $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.
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.