diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index c4931944c57..e9375f91e30 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -4104,15 +4104,14 @@ function getTitleFieldOfList($name, $thead = 0, $file = "", $field = "", $begin //var_dump('field='.$field.' field1='.$field1.' sortfield='.$sortfield.' sortfield1='.$sortfield1); // If field is used as sort criteria we use a specific css class liste_titre_sel // Example if (sortfield,field)=("nom","xxx.nom") or (sortfield,field)=("nom","nom") + $liste_titre = 'liste_titre'; if ($field1 && ($sortfield1 == $field1 || $sortfield1 == preg_replace("/^[^\.]+\./", "", $field1))) { - $out .= '<'.$tag.' class="'.$prefix.'liste_titre_sel" '.$moreattrib; - $out .= (($field && empty($conf->global->MAIN_DISABLE_WRAPPING_ON_COLUMN_TITLE) && preg_match('/^[a-zA-Z_0-9\s\.\-:&;]*$/', $name)) ? ' title="'.dol_escape_htmltag($langs->trans($name)).'"' : ''); - $out .= '>'; - } else { - $out .= '<'.$tag.' class="'.$prefix.'liste_titre" '.$moreattrib; - $out .= (($field && empty($conf->global->MAIN_DISABLE_WRAPPING_ON_COLUMN_TITLE) && preg_match('/^[a-zA-Z_0-9\s\.\-:&;]*$/', $name)) ? ' title="'.dol_escape_htmltag($langs->trans($name)).'"' : ''); - $out .= '>'; + $liste_titre = 'liste_titre_sel'; } + $out .= '<'.$tag.' class="'.$prefix.$liste_titre.'" '.$moreattrib; + //$out .= (($field && empty($conf->global->MAIN_DISABLE_WRAPPING_ON_COLUMN_TITLE) && preg_match('/^[a-zA-Z_0-9\s\.\-:&;]*$/', $name)) ? ' title="'.dol_escape_htmltag($langs->trans($name)).'"' : ''); + $out .= (($field && empty($conf->global->MAIN_DISABLE_WRAPPING_ON_COLUMN_TITLE)) ? ' title="'.dol_escape_htmltag($langs->trans($name)).'"' : ''); + $out .= '>'; if (empty($thead) && $field && empty($disablesortlink)) // If this is a sort field { diff --git a/htdocs/product/stock/class/mouvementstock.class.php b/htdocs/product/stock/class/mouvementstock.class.php index ca6e39c2b07..534b9300158 100644 --- a/htdocs/product/stock/class/mouvementstock.class.php +++ b/htdocs/product/stock/class/mouvementstock.class.php @@ -211,6 +211,7 @@ class MouvementStock extends CommonObject { if (empty($batch)) { + $langs->load("errors"); $this->errors[] = $langs->transnoentitiesnoconv("ErrorTryToMakeMoveOnProductRequiringBatchData", $product->ref); dol_syslog("Try to make a movement of a product with status_batch on without any batch data"); diff --git a/htdocs/product/stock/product.php b/htdocs/product/stock/product.php index 858058ef684..54d57bf5d75 100644 --- a/htdocs/product/stock/product.php +++ b/htdocs/product/stock/product.php @@ -195,7 +195,7 @@ if ($action == 'setdesiredstock' && !empty($user->rights->produit->creer)) // Correct stock if ($action == "correct_stock" && !$cancel) { - if (!(GETPOST("id_entrepot") > 0)) + if (!(GETPOST("id_entrepot", 'int') > 0)) { setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Warehouse")), null, 'errors'); $error++; diff --git a/htdocs/product/stock/replenish.php b/htdocs/product/stock/replenish.php index 08fb9d6a1f0..98b9f54b2ff 100644 --- a/htdocs/product/stock/replenish.php +++ b/htdocs/product/stock/replenish.php @@ -312,6 +312,9 @@ if (!empty($conf->global->STOCK_ALLOW_ADD_LIMIT_STOCK_BY_WAREHOUSE) && $fk_entre $sql .= ' '.$sqldesiredtock.' as desiredstockcombined, '.$sqlalertstock.' as seuil_stock_alertecombined,'; $sql .= ' s.fk_product,'; $sql .= ' SUM('.$db->ifsql("s.reel IS NULL", "0", "s.reel").') as stock_physique'; +if (!empty($conf->global->STOCK_ALLOW_ADD_LIMIT_STOCK_BY_WAREHOUSE) && $fk_entrepot > 0) { + $sql .= ', SUM('.$db->ifsql("s.reel IS NULL OR s.fk_entrepot <> ".$fk_entrepot, "0", "s.reel").') as stock_real_warehouse'; +} // Add fields from hooks $parameters = array(); @@ -530,18 +533,20 @@ if (empty($fk_warhouse) && !empty($conf->global->STOCK_ALLOW_ADD_LIMIT_STOCK_BY_ if ($usevirtualstock == 1) { print $langs->trans("CurentSelectionMode").': '; - print $langs->trans("CurentlyUsingVirtualStock").' - '; - print ''.$langs->trans("UsePhysicalStock").'
'; + print $langs->trans("CurentlyUsingVirtualStock"); + print ' ('.$langs->trans("UsePhysicalStock").')'; + print '
'; } if ($usevirtualstock == 0) { print $langs->trans("CurentSelectionMode").': '; - print $langs->trans("CurentlyUsingPhysicalStock").' - '; - print ''.$langs->trans("UseVirtualStock").'
'; + print $langs->trans("CurentlyUsingPhysicalStock"); + print ' ('.$langs->trans("UseVirtualStock").')'; + print '
'; } print '
'."\n"; -print '
'; +print ''; print ''; print ''; print ''; @@ -636,11 +641,13 @@ $param .= '&fk_supplier='.$fk_supplier; $param .= '&fk_entrepot='.$fk_entrepot; $stocklabel = $langs->trans('Stock'); +$stocklabelbis = $langs->trans('Stock'); if ($usevirtualstock == 1) $stocklabel = $langs->trans('VirtualStock'); if ($usevirtualstock == 0) $stocklabel = $langs->trans('PhysicalStock'); if (!empty($conf->global->STOCK_ALLOW_ADD_LIMIT_STOCK_BY_WAREHOUSE) && $fk_entrepot > 0) { - $stocklabel .= ' ('.$langs->trans("AllWarehouses").')'; + $stocklabelbis = $stocklabel.' (Selected warehouse)'; + $stocklabel .= ' ('.$langs->trans("AllWarehouses").')'; } $texte = $langs->trans('Replenishment'); @@ -689,6 +696,10 @@ if (!empty($conf->service->enabled) && $type == 1) print ''.$form->textwithpicto($langs->trans('IncludeEmptyDesiredStock'), $langs->trans('IncludeProductWithUndefinedAlerts')).' '; print ''; print ''.$langs->trans('AlertOnly').' '; +if (!empty($conf->global->STOCK_ALLOW_ADD_LIMIT_STOCK_BY_WAREHOUSE) && $fk_entrepot > 0) +{ + print ' '; +} print ''; if (! empty($conf->global->STOCK_REPLENISH_ADD_CHECKBOX_INCLUDE_DRAFT_ORDER)) { print $langs->trans('IncludeAlsoDraftOrders').' '; @@ -715,6 +726,10 @@ if (!empty($conf->service->enabled) && $type == 1) print_liste_field_titre('Dura print_liste_field_titre('DesiredStock', $_SERVER["PHP_SELF"], 'p.desiredstock', $param, '', '', $sortfield, $sortorder, 'right '); print_liste_field_titre('StockLimitShort', $_SERVER["PHP_SELF"], 'p.seuil_stock_alerte', $param, '', '', $sortfield, $sortorder, 'right '); print_liste_field_titre($stocklabel, $_SERVER["PHP_SELF"], 'stock_physique', $param, '', '', $sortfield, $sortorder, 'right '); +if (!empty($conf->global->STOCK_ALLOW_ADD_LIMIT_STOCK_BY_WAREHOUSE) && $fk_entrepot > 0) +{ + print_liste_field_titre($stocklabelbis, $_SERVER["PHP_SELF"], 'stock_real_warehouse', $param, '', '', $sortfield, $sortorder, 'right '); +} print_liste_field_titre('Ordered', $_SERVER["PHP_SELF"], '', $param, '', '', $sortfield, $sortorder, 'right '); print_liste_field_titre('StockToBuy', $_SERVER["PHP_SELF"], '', $param, '', '', $sortfield, $sortorder, 'right '); print_liste_field_titre('SupplierRef', $_SERVER["PHP_SELF"], '', $param, '', '', $sortfield, $sortorder, 'right '); @@ -757,8 +772,10 @@ while ($i < ($limit ? min($num, $limit) : $num)) { // If option to increase/decrease is not on an object validation, virtual stock may differs from physical stock. $stock = $prod->stock_theorique; + //TODO $stockwarehouse = $prod->stock_warehouse[$fk_entrepot]->; } else { $stock = $prod->stock_reel; + $stockwarehouse = $prod->stock_warehouse[$fk_entrepot]->real; } // Force call prod->load_stats_xxx to choose status to count (otherwise it is loaded by load_stock function) @@ -774,20 +791,29 @@ while ($i < ($limit ? min($num, $limit) : $num)) //print $prod->stats_reception['qty']; $ordered = $prod->stats_commande_fournisseur['qty'] - $prod->stats_reception['qty']; - $desiredstock = ($objp->desiredstockpse ? $objp->desiredstockpse : $objp->desiredstock); - $alertstock = ($objp->seuil_stock_alertepse ? $objp->seuil_stock_alertepse : $objp->seuil_stock_alerte); + $desiredstock = $objp->desiredstock; + $alertstock = $objp->seuil_stock_alerte; + $desiredstockwarehouse = ($objp->desiredstockpse ? $objp->desiredstockpse : ''); + $alertstockwarehouse = ($objp->seuil_stock_alertepse ? $objp->seuil_stock_alertepse : ''); $warning = ''; if ($alertstock && ($stock < $alertstock)) { $warning = img_warning($langs->trans('StockTooLow')).' '; } + $warningwarehouse = ''; + if ($alertstockwarehouse && ($stockwarehouse < $alertstockwarehouse)) + { + $warningwarehouse = img_warning($langs->trans('StockTooLow')).' '; + } //depending on conf, use either physical stock or //virtual stock to compute the stock to buy value if (empty($usevirtualstock)) $stocktobuy = max(max($desiredstock, $alertstock) - $stock - $ordered, 0); else $stocktobuy = max(max($desiredstock, $alertstock) - $stock, 0); //ordered is already in $stock in virtual mode + if (empty($usevirtualstock)) $stocktobuywarehouse = max(max($desiredstockwarehouse, $alertstockwarehouse) - $stockwarehouse - $ordered, 0); + else $stocktobuywarehouse = max(max($desiredstockwarehouse, $alertstockwarehouse) - $stockwarehouse, 0); //ordered is already in $stock in virtual mode $picto = ''; if ($ordered > 0) @@ -803,57 +829,67 @@ while ($i < ($limit ? min($num, $limit) : $num)) $picto = img_picto($langs->trans("NoPendingReceptionOnSupplierOrder"), 'help'); } - print ''; + $variants = $prod->hasVariants(); + if (!$variants || !empty($conf->global->VARIANT_ALLOW_STOCK_MOVEMENT_ON_VARIANT_PARENT)) { + print ''; - // Select field - print ''; + // Select field + print ''; - print ''.$prod->getNomUrl(1, '').''; + print ''.$prod->getNomUrl(1, 'stock').''; - print ''.$objp->label; - print ''; // TODO Remove this and make a fetch to get description when creating order instead of a GETPOST - print ''; + print ''.$objp->label; + print ''; // TODO Remove this and make a fetch to get description when creating order instead of a GETPOST + print ''; - if (!empty($conf->service->enabled) && $type == 1) - { - if (preg_match('/([0-9]+)y/i', $objp->duration, $regs)) { - $duration = $regs[1].' '.$langs->trans('DurationYear'); - } elseif (preg_match('/([0-9]+)m/i', $objp->duration, $regs)) { - $duration = $regs[1].' '.$langs->trans('DurationMonth'); - } elseif (preg_match('/([0-9]+)d/i', $objp->duration, $regs)) { - $duration = $regs[1].' '.$langs->trans('DurationDay'); - } else { - $duration = $objp->duration; + if (!empty($conf->service->enabled) && $type == 1) + { + $regs = array(); + if (preg_match('/([0-9]+)y/i', $objp->duration, $regs)) { + $duration = $regs[1].' '.$langs->trans('DurationYear'); + } elseif (preg_match('/([0-9]+)m/i', $objp->duration, $regs)) { + $duration = $regs[1].' '.$langs->trans('DurationMonth'); + } elseif (preg_match('/([0-9]+)d/i', $objp->duration, $regs)) { + $duration = $regs[1].' '.$langs->trans('DurationDay'); + } else { + $duration = $objp->duration; + } + print ''.$duration.''; } - print ''.$duration.''; + + // Desired stock + print ''.($fk_entrepot > 0 ? $desiredstockwarehouse : $desiredstock).''; + + // Limit stock for alert + print ''.($fk_entrepot > 0 ? $alertstockwarehouse : $alertstock).''; + + // Current stock (all warehouses) + print ''.$warning.$stock.''; + + // Current stock (warehouse selected only) + if (!empty($conf->global->STOCK_ALLOW_ADD_LIMIT_STOCK_BY_WAREHOUSE) && $fk_entrepot > 0) + { + print ''.$warningwarehouse.$stockwarehouse.''; + } + + // Already ordered + print ''.$ordered.' '.$picto.''; + + // To order + print ''; + + // Supplier + print ''; + print $form->select_product_fourn_price($prod->id, 'fourn'.$i, $fk_supplier); + print ''; + + // Fields from hook + $parameters = array('objp'=>$objp); + $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; + + print ''; } - - // Desired stock - print ''.$desiredstock.''; - - // Limit stock for alert - print ''.$alertstock.''; - - // Current stock (all warehouses) - print ''.$warning.$stock.''; - - // Already ordered - print ''.$ordered.' '.$picto.''; - - // To order - print ''; - - // Supplier - print ''; - print $form->select_product_fourn_price($prod->id, 'fourn'.$i, $fk_supplier); - print ''; - - // Fields from hook - $parameters = array('objp'=>$objp); - $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters); // Note that $action and $object may have been modified by hook - print $hookmanager->resPrint; - - print ''; } $i++; }