diff --git a/htdocs/core/menus/init_menu_auguria.sql b/htdocs/core/menus/init_menu_auguria.sql index 0d95d94c721..86b8a58e68f 100644 --- a/htdocs/core/menus/init_menu_auguria.sql +++ b/htdocs/core/menus/init_menu_auguria.sql @@ -110,7 +110,7 @@ insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, left insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->stock->enabled', __HANDLER__, 'left', 3102__+MAX_llx_menu__, 'products', '', 3100__+MAX_llx_menu__, '/product/stock/list.php', 'List', 1, 'stocks', '$user->rights->stock->lire', '', 2, 1, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->stock->enabled', __HANDLER__, 'left', 3104__+MAX_llx_menu__, 'products', '', 3100__+MAX_llx_menu__, '/product/stock/mouvement.php', 'Movements', 1, 'stocks', '$user->rights->stock->mouvement->lire', '', 2, 3, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->stock->enabled && $conf->fournisseur->enabled', __HANDLER__, 'left', 3105__+MAX_llx_menu__, 'products', '', 3100__+MAX_llx_menu__, '/product/stock/replenish.php', 'Replenishments', 1, 'stocks', '$user->rights->stock->mouvement->creer && $user->rights->fournisseur->lire', '', 2, 4, __ENTITY__); -insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->stock->enabled', __HANDLER__, 'left', 3106__+MAX_llx_menu__, 'products', '', 3100__+MAX_llx_menu__, '/product/stock/massstockmove.php', 'StockTransfer', 1, 'stocks', '$user->rights->stock->mouvement->creer', '', 2, 5, __ENTITY__); +insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->stock->enabled', __HANDLER__, 'left', 3106__+MAX_llx_menu__, 'products', '', 3100__+MAX_llx_menu__, '/product/stock/massstockmove.php', 'MassStockTransferShort', 1, 'stocks', '$user->rights->stock->mouvement->creer', '', 2, 5, __ENTITY__); -- Product - Categories insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->categorie->enabled', __HANDLER__, 'left', 3200__+MAX_llx_menu__, 'products', 'cat', 3__+MAX_llx_menu__, '/categories/index.php?leftmenu=cat&type=0', 'Categories', 0, 'categories', '$user->rights->categorie->lire', '', 2, 4, __ENTITY__); diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php index 816d6d9cd8b..eff98bba3a6 100644 --- a/htdocs/core/menus/standard/eldy.lib.php +++ b/htdocs/core/menus/standard/eldy.lib.php @@ -1133,7 +1133,7 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu $newmenu->add("/product/stock/list.php", $langs->trans("List"), 1, $user->rights->stock->lire); $newmenu->add("/product/stock/mouvement.php", $langs->trans("Movements"), 1, $user->rights->stock->mouvement->lire); if ($conf->fournisseur->enabled) $newmenu->add("/product/stock/replenish.php", $langs->trans("Replenishment"), 1, $user->rights->stock->mouvement->creer && $user->rights->fournisseur->lire); - $newmenu->add("/product/stock/massstockmove.php", $langs->trans("StockTransfer"), 1, $user->rights->stock->mouvement->creer); + $newmenu->add("/product/stock/massstockmove.php", $langs->trans("MassStockTransferShort"), 1, $user->rights->stock->mouvement->creer); } // Expeditions diff --git a/htdocs/langs/en_US/stocks.lang b/htdocs/langs/en_US/stocks.lang index 943e988b2f7..e6b9f82730c 100644 --- a/htdocs/langs/en_US/stocks.lang +++ b/htdocs/langs/en_US/stocks.lang @@ -34,7 +34,8 @@ LastMovements=Last movements Units=Units Unit=Unit StockCorrection=Correct stock -StockTransfer=Stock movement +StockTransfer=Transfer stock +MassStockTransferShort=Mass stock transfer StockMovement=Stock movement StockMovements=Stock movements LabelMovement=Movement label diff --git a/htdocs/product/stock/massstockmove.php b/htdocs/product/stock/massstockmove.php index 652ec947a37..7d62699b425 100644 --- a/htdocs/product/stock/massstockmove.php +++ b/htdocs/product/stock/massstockmove.php @@ -325,7 +325,7 @@ $title = $langs->trans('MassMovement'); llxHeader('', $title); -print load_fiche_titre($langs->trans("MassStockMovement")); +print load_fiche_titre($langs->trans("MassStockTransferShort")); $titletoadd=$langs->trans("Select"); $titletoaddnoent=$langs->transnoentitiesnoconv("Select"); diff --git a/htdocs/product/stock/mouvement.php b/htdocs/product/stock/mouvement.php index 32edd0b4e9d..190bf676c8a 100644 --- a/htdocs/product/stock/mouvement.php +++ b/htdocs/product/stock/mouvement.php @@ -54,16 +54,18 @@ $search_warehouse = trim(GETPOST("search_warehouse")); $search_inventorycode = trim(GETPOST("search_inventorycode")); $search_user = trim(GETPOST("search_user")); $search_batch = trim(GETPOST("search_batch")); + $limit = GETPOST('limit')?GETPOST('limit','int'):$conf->liste_limit; $page = GETPOST("page",'int'); $sortfield = GETPOST("sortfield",'alpha'); $sortorder = GETPOST("sortorder",'alpha'); if ($page < 0) $page = 0; $offset = $limit * $page; - if (! $sortfield) $sortfield="m.datem"; if (! $sortorder) $sortorder="DESC"; +$pdluoid=GETPOST('pdluoid','int'); + if (GETPOST("button_removefilter_x") || GETPOST("button_removefilter")) // Both test are required to be compatible with all browsers { $year=''; @@ -152,6 +154,171 @@ if ($action == "correct_stock") if (! $error) $action=''; } +// Transfer stock from a warehouse to another warehouse +if ($action == "transfert_stock" && ! $cancel) +{ + $product = new Product($db); + if (! empty($product_id)) $result=$product->fetch($product_id); + + if (! (GETPOST("id_entrepot_destination",'int') > 0)) + { + setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Warehouse")), null, 'errors'); + $error++; + $action='transfert'; + } + if (empty($product_id)) + { + $error++; + setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Product")), null, 'errors'); + $action='transfert'; + } + if (! GETPOST("nbpiece",'int')) + { + setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("NumberOfUnit")), null, 'errors'); + $error++; + $action='transfert'; + } + if ($id == GETPOST("id_entrepot_destination",'int')) + { + setEventMessages($langs->trans("ErrorSrcAndTargetWarehouseMustDiffers"), null, 'errors'); + $error++; + $action='transfert'; + } + + if (! empty($conf->productbatch->enabled)) + { + $product = new Product($db); + $result=$product->fetch($product_id); + + if ($product->hasbatch() && ! GETPOST("batch_number")) + { + setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("batch_number")), null, 'errors'); + $error++; + $action='transfert'; + } + } + + if (! $error) + { + if ($id) + { + $object = new Entrepot($db); + $result=$object->fetch($id); + + $db->begin(); + + $product->load_stock(); // Load array product->stock_warehouse + + // Define value of products moved + $pricesrc=0; + //if (isset($product->stock_warehouse[GETPOST("id_entrepot_source")]->pmp)) $pricesrc=$product->stock_warehouse[GETPOST("id_entrepot_source")]->pmp; + if (isset($product->pmp)) $pricesrc=$product->pmp; + $pricedest=$pricesrc; + + if ($product->hasbatch()) + { + $pdluo = new Productbatch($db); + + if ($pdluoid > 0) + { + $result=$pdluo->fetch($pdluoid); + if ($result) + { + $srcwarehouseid=$pdluo->warehouseid; + $batch=$pdluo->batch; + $eatby=$pdluo->eatby; + $sellby=$pdluo->sellby; + } + else + { + setEventMessages($pdluo->error, $pdluo->errors, 'errors'); + $error++; + } + } + else + { + $srcwarehouseid=$id; + $batch=GETPOST('batch_number'); + $eatby=$d_eatby; + $sellby=$d_sellby; + } + + if (! $error) + { + // Remove stock + $result1=$product->correct_stock_batch( + $user, + $srcwarehouseid, + GETPOST("nbpiece",'int'), + 1, + GETPOST("label",'san_alpha'), + $pricesrc, + $eatby,$sellby,$batch, + GETPOST('inventorycode') + ); + // Add stock + $result2=$product->correct_stock_batch( + $user, + GETPOST("id_entrepot_destination",'int'), + GETPOST("nbpiece",'int'), + 0, + GETPOST("label",'san_alpha'), + $pricedest, + $eatby,$sellby,$batch, + GETPOST('inventorycode') + ); + } + } + else + { + // Remove stock + $result1=$product->correct_stock( + $user, + $id, + GETPOST("nbpiece"), + 1, + GETPOST("label"), + $pricesrc, + GETPOST('inventorycode') + ); + + // Add stock + $result2=$product->correct_stock( + $user, + GETPOST("id_entrepot_destination"), + GETPOST("nbpiece"), + 0, + GETPOST("label"), + $pricedest, + GETPOST('inventorycode') + ); + } + if (! $error && $result1 >= 0 && $result2 >= 0) + { + $db->commit(); + + if ($backtopage) + { + header("Location: ".$backtopage); + exit; + } + else + { + header("Location: mouvement.php?id=".$object->id); + exit; + } + } + else + { + setEventMessages($product->error, $product->errors, 'errors'); + $db->rollback(); + $action='transfert'; + } + } + } +} + + /* * View @@ -451,7 +618,7 @@ if ($resql) /* */ /* ************************************************************************** */ - if (empty($action) && $id) + if (empty($action) && $id > 0) { print "
\n"; @@ -460,16 +627,17 @@ if ($resql) print ''.$langs->trans("StockCorrection").''; } - /*if ($user->rights->stock->mouvement->creer) + if ($user->rights->stock->mouvement->creer) { - print ''.$langs->trans("StockMovement").''; - }*/ + print ''.$langs->trans("StockTransfer").''; + } + print '

'; } $param=''; - if ($id) $param.='&id='.$id; + if ($id > 0) $param.='&id='.$id; if ($search_movement) $param.='&search_movement='.urlencode($search_movement); if ($search_inventorycode) $param.='&search_inventorycode='.urlencode($search_inventorycode); if ($search_product_ref) $param.='&search_product_ref='.urlencode($search_product_ref); @@ -479,11 +647,11 @@ if ($resql) if (!empty($snom)) $param.='&snom='.urlencode($snom); // FIXME $snom is not defined if ($search_user) $param.='&search_user='.urlencode($search_user); if ($idproduct > 0) $param.='&idproduct='.$idproduct; - if ($id) print_barre_liste($texte, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder,'',$num, $nbtotalofrecords,''); + if ($id > 0) print_barre_liste($texte, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder,'',$num, $nbtotalofrecords,''); else print_barre_liste($texte, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder,'',$num, $nbtotalofrecords); print '
'; - if ($id) print ''; + if ($id > 0) print ''; print ''; print ""; @@ -498,7 +666,7 @@ if ($resql) print_liste_field_titre($langs->trans("l_eatby"),$_SERVER["PHP_SELF"],'m.eatby','',$param,'align="center"',$sortfield,$sortorder); print_liste_field_titre($langs->trans("l_sellby"),$_SERVER["PHP_SELF"],'m.sellby','',$param,'align="center"',$sortfield,$sortorder); } - print_liste_field_titre($langs->trans("Warehouse"),$_SERVER["PHP_SELF"], "","",$param,"",$sortfield,$sortorder); // We are on a specific warehouse card, no filter on other should be possible + if (! $id > 0) print_liste_field_titre($langs->trans("Warehouse"),$_SERVER["PHP_SELF"], "","",$param,"",$sortfield,$sortorder); // We are on a specific warehouse card, no filter on other should be possible print_liste_field_titre($langs->trans("Author"),$_SERVER["PHP_SELF"], "m.fk_user_author","",$param,"",$sortfield,$sortorder); print_liste_field_titre($langs->trans("InventoryCodeShort"),$_SERVER["PHP_SELF"], "m.inventorycode","",$param,"",$sortfield,$sortorder); print_liste_field_titre($langs->trans("LabelMovement"),$_SERVER["PHP_SELF"], "m.label","",$param,"",$sortfield,$sortorder); @@ -532,9 +700,12 @@ if ($resql) print ''; } // Warehouse - print ''; + if (! $id > 0) + { + print ''; + } // Author print ''; - print ''; - print ''; + print ''; + print ''; + print ''; } // Warehouse - print '\n"; + if (! $id > 0) + { + print '\n"; + } // Author print ''; // Serial / Eat-by date - if ((! empty($conf->productbatch->enabled)) && is_object($product) && $product->hasbatch()) + if (! empty($conf->productbatch->enabled) && + (($object->element == 'product' && $object->hasbatch()) + || ($object->element == 'stock')) + ) { print ''; - print ''; print ''; @@ -101,7 +104,7 @@ } // Label of mouvement of id of inventory - $valformovementlabel=((GETPOST("label") && (GETPOST('label') != $langs->trans("MovementCorrectStock",''))) ? GETPOST("label") : $langs->trans("MovementCorrectStock", $product->ref)); + $valformovementlabel=((GETPOST("label") && (GETPOST('label') != $langs->trans("MovementCorrectStock",''))) ? GETPOST("label") : $langs->trans("MovementCorrectStock", $productref)); print ''; print ''; print '
'; - print ''; - print ''; + print ''; + print ''; print ''; @@ -598,17 +769,20 @@ if ($resql) // Batch if (! empty($conf->productbatch->enabled)) { - print ''.$objp->batch.''. dol_print_date($objp->eatby,'day') .''. dol_print_date($objp->sellby,'day') .''.$objp->batch.''. dol_print_date($objp->eatby,'day') .''. dol_print_date($objp->sellby,'day') .''; - $warehousestatic->id=$objp->entrepot_id; - $warehousestatic->libelle=$objp->stock; - $warehousestatic->lieu=$objp->lieu; - print $warehousestatic->getNomUrl(1); - print "'; + $warehousestatic->id=$objp->entrepot_id; + $warehousestatic->libelle=$objp->stock; + $warehousestatic->lieu=$objp->lieu; + print $warehousestatic->getNomUrl(1); + print "'; $userstatic->id=$objp->fk_user_author; diff --git a/htdocs/product/stock/product.php b/htdocs/product/stock/product.php index ba083cc1527..5b26f215adb 100644 --- a/htdocs/product/stock/product.php +++ b/htdocs/product/stock/product.php @@ -648,7 +648,7 @@ if (empty($action) && $object->id) //if (($user->rights->stock->mouvement->creer) && ! $object->hasbatch()) if ($user->rights->stock->mouvement->creer) { - print ''.$langs->trans("StockMovement").''; + print ''.$langs->trans("StockTransfer").''; } print ''; @@ -753,7 +753,7 @@ if ($resql) { print "\n".'
'; print img_picto($langs->trans("Tranfer"),'uparrow','class="hideonsmartphone"').' '; - print 'id.'">'.$langs->trans("StockMovement").''; + print 'id.'">'.$langs->trans("StockTransfer").''; // Disabled, because edition of stock content must use the "Correct stock menu". // Do not use this, or data will be wrong (bad tracking of movement label, inventory code, ... //print 'id.'#'.$pdluo->id.'">'; diff --git a/htdocs/product/stock/tpl/stockcorrection.tpl.php b/htdocs/product/stock/tpl/stockcorrection.tpl.php index 90a7468a351..d9f02781fd5 100644 --- a/htdocs/product/stock/tpl/stockcorrection.tpl.php +++ b/htdocs/product/stock/tpl/stockcorrection.tpl.php @@ -15,13 +15,13 @@ * along with this program. If not, see . * * $object must be defined - * $product can be defined */ ?> element == 'product') $productref = $object->ref; $langs->load("productbatch"); @@ -81,10 +81,13 @@ print '
'.$langs->trans("batch_number").''; + print 'element == 'stock'?'': ' class="fieldrequired"').'>'.$langs->trans("batch_number").''; print ''; print '
'.$langs->trans("MovementLabel").''; diff --git a/htdocs/product/stock/tpl/stocktransfer.tpl.php b/htdocs/product/stock/tpl/stocktransfer.tpl.php index 0f13a5452da..1c0448192f1 100644 --- a/htdocs/product/stock/tpl/stocktransfer.tpl.php +++ b/htdocs/product/stock/tpl/stocktransfer.tpl.php @@ -14,17 +14,20 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . * - * $product must be defined + * $object must be defined * $backtopage */ ?> element == 'product') $productref = $object->ref; $langs->load("productbatch"); + if (empty($id)) $id = $object->id; + $pdluoid=GETPOST('pdluoid','int'); $pdluo = new Productbatch($db); @@ -44,7 +47,7 @@ print load_fiche_titre($langs->trans("StockTransfer"),'','title_generic.png'); - print ''."\n"; + print ''."\n"; print ''; print ''; print ''; @@ -54,28 +57,37 @@ } print ''; + // Source warehouse or product print ''; - print ''; + print ''; } - else + if ($object->element == 'stock') { - print $formproduct->selectWarehouses((GETPOST("dwid")?GETPOST("dwid",'int'):(GETPOST('id_entrepot_source')?GETPOST('id_entrepot_source','int'):'ifone')),'id_entrepot_source','',1); + print ''; + print ''; } - print ''; + print ''; print ''; print ''; - // Eat-by date - if ((! empty($conf->productbatch->enabled)) && $product->hasbatch()) + // Serial / Eat-by date + if (! empty($conf->productbatch->enabled) && + (($object->element == 'product' && $object->hasbatch()) + || ($object->element == 'stock')) + ) { print ''; - print ''; print ''; @@ -90,7 +102,7 @@ } // Label - $valformovementlabel=(GETPOST("label")?GETPOST("label"):$langs->trans("MovementTransferStock", $product->ref)); + $valformovementlabel=(GETPOST("label")?GETPOST("label"):$langs->trans("MovementTransferStock", $productref)); print ''; print ''; print '
'.$langs->trans("WarehouseSource").''; - if ($pdluoid > 0) + if ($object->element == 'product') { - print $formproduct->selectWarehouses($pdluo->warehouseid,'id_entrepot_source','',1,1); + print ''.$langs->trans("WarehouseSource").''; + print $formproduct->selectWarehouses((GETPOST("dwid")?GETPOST("dwid",'int'):(GETPOST('id_entrepot')?GETPOST('id_entrepot','int'):'ifone')),'id_entrepot','',1); + print ''.$langs->trans("Product").''; + print $form->select_produits(GETPOST('product_id'),'product_id',(empty($conf->global->STOCK_SUPPORTS_SERVICES)?'0':'')); + print ''.$langs->trans("WarehouseTarget").''; print $formproduct->selectWarehouses(GETPOST('id_entrepot_destination'),'id_entrepot_destination','',1); print ''.$langs->trans("NumberOfUnit").'
'.$langs->trans("batch_number").''; + print 'element == 'stock'?'': ' class="fieldrequired"').'>'.$langs->trans("batch_number").''; print ' 0 ? ' disabled':'').' value="'.(GETPOST('batch_number')?GETPOST('batch_number'):$pdluo->batch).'">'; // If form was opened for a specific pdluoid, field is disabled print '
'.$langs->trans("MovementLabel").'';