diff --git a/htdocs/langs/en_US/stocks.lang b/htdocs/langs/en_US/stocks.lang index d79158ab01b..efa5257498c 100644 --- a/htdocs/langs/en_US/stocks.lang +++ b/htdocs/langs/en_US/stocks.lang @@ -167,8 +167,8 @@ MovementTransferStock=Stock transfer of product %s into another warehouse InventoryCodeShort=Inv./Mov. code NoPendingReceptionOnSupplierOrder=No pending reception due to open purchase order ThisSerialAlreadyExistWithDifferentDate=This lot/serial number (%s) already exists but with different eatby or sellby date (found %s but you enter %s). -OpenAll=Open for all actions -OpenInternal=Open only for internal actions +OpenAnyMovement=Open (all movement) +OpenInternal=Open (only internal movement) UseDispatchStatus=Use a dispatch status (approve/refuse) for product lines on purchase order reception OptionMULTIPRICESIsOn=Option "several prices per segment" is on. It means a product has several selling price so value for sell can't be calculated ProductStockWarehouseCreated=Stock limit for alert and desired optimal stock correctly created diff --git a/htdocs/langs/fr_FR/stocks.lang b/htdocs/langs/fr_FR/stocks.lang index c03fe42f01e..9db98593448 100644 --- a/htdocs/langs/fr_FR/stocks.lang +++ b/htdocs/langs/fr_FR/stocks.lang @@ -169,8 +169,8 @@ MovementTransferStock=Transfert de stock du produit %s dans un autre entrepôt InventoryCodeShort=Code Inv./Mouv. NoPendingReceptionOnSupplierOrder=Pas de réception en attente consécutive à des commandes fournisseurs ThisSerialAlreadyExistWithDifferentDate=Ce lot/numéro de série (%s) existe déjà mais avec des dates de consommation ou péremption différente (trouvé %s mais vous avez entré %s). -OpenAll=Accepte tous les mouvements -OpenInternal=Limité aux mouvements internes +OpenAnyMovement=Ouvert (tous les mouvements) +OpenInternal=Ouvert (limité aux mouvements internes) UseDispatchStatus=Utiliser un statut de contrôle (approuvé / refusé) pour les lignes de produits lors de la réception de la commande OptionMULTIPRICESIsOn=L'option "plusieurs prix par tranches" est activée. Cela signifie qu'un produit à plusieurs prix de vente donc sa valeur de vente ne peut être calculée. ProductStockWarehouseCreated=Alerte de limite de stock et de stock désiré ajoutée diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index aa07673f5cc..fdc50d5fe87 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -5154,9 +5154,10 @@ class Product extends CommonObject /** * Load information about stock of a product into ->stock_reel, ->stock_warehouse[] (including stock_warehouse[idwarehouse]->detail_batch for batch products) * This function need a lot of load. If you use it on list, use a cache to execute it once for each product id. - * If ENTREPOT_EXTRA_STATUS set, filtering on warehouse status possible. + * If ENTREPOT_EXTRA_STATUS is set, filtering on warehouse status is possible. * * @param string $option '' = Load all stock info, also from closed and internal warehouses, 'nobatch', 'novirtual' + * You can also filter on 'warehouseclosed', 'warehouseopen', 'warehouseinternal' * @param int $includedraftpoforvirtual Include draft status of PO for virtual stock calculation * @return int < 0 if KO, > 0 if OK * @see load_virtual_stock(), loadBatchInfo() @@ -5170,16 +5171,20 @@ class Product extends CommonObject $this->stock_warehouse = array(); $this->stock_theorique = 0; + // Set filter on warehouse status $warehouseStatus = array(); - if (preg_match('/warehouseclosed/', $option)) { - $warehouseStatus[] = Entrepot::STATUS_CLOSED; + $warehouseStatus[Entrepot::STATUS_CLOSED] = Entrepot::STATUS_CLOSED; } if (preg_match('/warehouseopen/', $option)) { - $warehouseStatus[] = Entrepot::STATUS_OPEN_ALL; + $warehouseStatus[Entrepot::STATUS_OPEN_ALL] = Entrepot::STATUS_OPEN_ALL; } if (preg_match('/warehouseinternal/', $option)) { - $warehouseStatus[] = Entrepot::STATUS_OPEN_INTERNAL; + if (!empty($conf->global->ENTREPOT_EXTRA_STATUS)) { + $warehouseStatus[Entrepot::STATUS_OPEN_INTERNAL] = Entrepot::STATUS_OPEN_INTERNAL; + } else { + $warehouseStatus[Entrepot::STATUS_OPEN_ALL] = Entrepot::STATUS_OPEN_ALL; + } } $sql = "SELECT ps.rowid, ps.reel, ps.fk_entrepot"; @@ -5188,7 +5193,7 @@ class Product extends CommonObject $sql .= " WHERE w.entity IN (".getEntity('stock').")"; $sql .= " AND w.rowid = ps.fk_entrepot"; $sql .= " AND ps.fk_product = ".$this->id; - if (!empty($conf->global->ENTREPOT_EXTRA_STATUS) && count($warehouseStatus)) { + if (count($warehouseStatus)) { $sql .= " AND w.statut IN (".$this->db->sanitize(implode(',', $warehouseStatus)).")"; } diff --git a/htdocs/product/stock/card.php b/htdocs/product/stock/card.php index 876ced9892c..5ea58da6deb 100644 --- a/htdocs/product/stock/card.php +++ b/htdocs/product/stock/card.php @@ -332,7 +332,7 @@ if ($action == 'create') { // Status print ''.$langs->trans("Status").''; - print ''; foreach ($object->statuts as $key => $value) { if ($key == 1) { print ''; @@ -341,6 +341,7 @@ if ($action == 'create') { } } print ''; + print ajax_combobox('warehousestatus'); print ''; // Other attributes @@ -678,13 +679,13 @@ if ($action == 'create') { } } - //print ''.dol_print_date($objp->datem).''; print ''; + $parameters = array('obj'=>$objp); $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; - print ""; + $productstatic->id = $objp->rowid; $productstatic->ref = $objp->ref; $productstatic->label = $objp->produit; @@ -701,11 +702,13 @@ if ($action == 'create') { $productstatic->accountancy_code_buy = $objp->accountancy_code_buy; $productstatic->accountancy_code_buy_intra = $objp->accountancy_code_buy_intra; $productstatic->accountancy_code_buy_export = $objp->accountancy_code_buy_export; + + print ""; print $productstatic->getNomUrl(1, 'stock', 16); print ''; // Label - print ''.$objp->produit.''; + print ''.dol_escape_htmltag($objp->produit).''; print ''; $valtoshow = price(price2num($objp->value, 'MS'), 0, '', 0, 0); // TODO replace with a qty() function @@ -723,10 +726,10 @@ if ($action == 'create') { print ''; } // Price buy PMP - print ''.price(price2num($objp->ppmp, 'MU')).''; + print ''.price(price2num($objp->ppmp, 'MU')).''; // Total PMP - print ''.price(price2num($objp->ppmp * $objp->value, 'MT')).''; + print ''.price(price2num($objp->ppmp * $objp->value, 'MT')).''; $totalvalue += price2num($objp->ppmp * $objp->value, 'MT'); // Price sell min @@ -871,7 +874,7 @@ if ($action == 'create') { // Status print ''.$langs->trans("Status").''; - print ''; foreach ($object->statuts as $key => $value) { if ($key == $object->statut) { print ''; @@ -880,6 +883,8 @@ if ($action == 'create') { } } print ''; + print ajax_combobox('warehousestatus'); + print ''; // Other attributes diff --git a/htdocs/product/stock/class/entrepot.class.php b/htdocs/product/stock/class/entrepot.class.php index 6667246d7ed..92df16fa867 100644 --- a/htdocs/product/stock/class/entrepot.class.php +++ b/htdocs/product/stock/class/entrepot.class.php @@ -173,7 +173,7 @@ class Entrepot extends CommonObject $this->statuts[self::STATUS_CLOSED] = 'Closed2'; if (!empty($conf->global->ENTREPOT_EXTRA_STATUS)) { - $this->statuts[self::STATUS_OPEN_ALL] = 'OpenAll'; + $this->statuts[self::STATUS_OPEN_ALL] = 'OpenAnyMovement'; $this->statuts[self::STATUS_OPEN_INTERNAL] = 'OpenInternal'; } else { $this->statuts[self::STATUS_OPEN_ALL] = 'Opened'; diff --git a/htdocs/product/stock/product.php b/htdocs/product/stock/product.php index ef1393dfb63..a00feb194a0 100644 --- a/htdocs/product/stock/product.php +++ b/htdocs/product/stock/product.php @@ -916,6 +916,7 @@ if (!$variants) { print ''; print ''; print ''; + if ((!empty($conf->productbatch->enabled)) && $object->hasbatch()) { $colspan = 3; print ''; @@ -979,6 +980,8 @@ if (!$variants) { $stock_real = price2num($obj->reel, 'MS'); print ''; + + // Warehouse print ''; print $entrepotstatic->getNomUrl(1); if (!empty($conf->use_javascript_ajax) && !empty($conf->productbatch->enabled) && $object->hasbatch()) { @@ -987,25 +990,28 @@ if (!$variants) { print ''; } print ''; + print ''.$stock_real.($stock_real < 0 ? ' '.img_warning() : '').''; + // PMP - print ''.(price2num($object->pmp) ? price2num($object->pmp, 'MU') : '').''; + print ''.(price2num($object->pmp) ? price2num($object->pmp, 'MU') : '').''; + // Value purchase - print ''.(price2num($object->pmp) ? price(price2num($object->pmp * $obj->reel, 'MT')) : '').''; + print ''.(price2num($object->pmp) ? price(price2num($object->pmp * $obj->reel, 'MT')) : '').''; + // Sell price print ''; - if (empty($conf->global->PRODUIT_MULTIPRICES)) { - print price(price2num($object->price, 'MU'), 1); - } else { - print $langs->trans("Variable"); + print price(price2num($object->price, 'MU'), 1); + if (!empty($conf->global->PRODUIT_MULTIPRICES)) { + print $form->textwithpicto('', $langs->trans("Variable")); } print ''; + // Value sell - print ''; - if (empty($conf->global->PRODUIT_MULTIPRICES)) { - print price(price2num($object->price * $obj->reel, 'MT'), 1); - } else { - print $langs->trans("Variable"); + print ''; + print price(price2num($object->price * $obj->reel, 'MT'), 1); + if (!empty($conf->global->PRODUIT_MULTIPRICES)) { + print $form->textwithpicto('', $langs->trans("Variable")); } print ''; print ''; @@ -1117,10 +1123,9 @@ if (!$variants) { print $totalvalue ? price(price2num($totalvalue, 'MT'), 1) : ' '; print ''; print ''; - if (empty($conf->global->PRODUIT_MULTIPRICES)) { - print ($total ? price($totalvaluesell / $total, 1) : ' '); - } else { - print $langs->trans("Variable"); + print ($total ? price($totalvaluesell / $total, 1) : ' '); + if (!empty($conf->global->PRODUIT_MULTIPRICES)) { + print $form->textwithpicto('', $langs->trans("Variable")); } print ''; // Value to sell