Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into develop
This commit is contained in:
commit
6ff71792a0
@ -715,7 +715,7 @@ if ($resql)
|
||||
|
||||
// Get local and virtual stock and store it into cache
|
||||
if (empty($productstat_cache[$generic_commande->lines[$lig]->fk_product])) {
|
||||
$generic_product->load_stock();
|
||||
$generic_product->load_stock('nobatch');
|
||||
//$generic_product->load_virtual_stock(); Already included into load_stock
|
||||
$productstat_cache[$generic_commande->lines[$lig]->fk_product]['stock_reel'] = $generic_product->stock_reel;
|
||||
$productstat_cachevirtual[$generic_commande->lines[$lig]->fk_product]['stock_reel'] = $generic_product->stock_theorique;
|
||||
@ -723,7 +723,7 @@ if ($resql)
|
||||
$generic_product->stock_reel = $productstat_cache[$generic_commande->lines[$lig]->fk_product]['stock_reel'];
|
||||
$generic_product->stock_theorique = $productstat_cachevirtual[$generic_commande->lines[$lig]->fk_product]['stock_reel'] = $generic_product->stock_theorique;
|
||||
}
|
||||
|
||||
|
||||
if (empty($conf->global->SHIPPABLE_ORDER_ICON_IN_LIST)) // Default code. Default is when this option is not set, setting it create strange result
|
||||
{
|
||||
$text_info .= $generic_commande->lines[$lig]->qty.' X '.$generic_commande->lines[$lig]->ref.' '.dol_trunc($generic_commande->lines[$lig]->product_label, 25);
|
||||
|
||||
@ -2057,17 +2057,27 @@ class Form
|
||||
{
|
||||
global $langs,$conf;
|
||||
global $price_level, $status, $finished;
|
||||
|
||||
|
||||
$selected_input_value='';
|
||||
if (! empty($conf->use_javascript_ajax) && ! empty($conf->global->PRODUIT_USE_SEARCH_TO_SELECT))
|
||||
{
|
||||
if ($selected > 0)
|
||||
{
|
||||
require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
|
||||
$producttmpselect = new Product($this->db);
|
||||
$producttmpselect->fetch($selected);
|
||||
$selected_input_value=$producttmpselect->ref;
|
||||
unset($producttmpselect);
|
||||
}
|
||||
|
||||
if (!empty($conf->global->SUPPLIER_ORDER_WITH_NOPRICEDEFINED))
|
||||
{
|
||||
print '<input type="hidden" id="idprod" name="idprod" value="0" />';
|
||||
}
|
||||
// mode=2 means suppliers products
|
||||
$urloption=($socid > 0?'socid='.$socid.'&':'').'htmlname='.$htmlname.'&outjson=1&price_level='.$price_level.'&type='.$filtertype.'&mode=2&status='.$status.'&finished='.$finished;
|
||||
print ajax_autocompleter('', $htmlname, DOL_URL_ROOT.'/product/ajax/products.php', $urloption, $conf->global->PRODUIT_USE_SEARCH_TO_SELECT, 0, $ajaxoptions);
|
||||
print ($hidelabel?'':$langs->trans("RefOrLabel").' : ').'<input type="text" size="20" name="search_'.$htmlname.'" id="search_'.$htmlname.'">';
|
||||
print ajax_autocompleter($selected, $htmlname, DOL_URL_ROOT.'/product/ajax/products.php', $urloption, $conf->global->PRODUIT_USE_SEARCH_TO_SELECT, 0, $ajaxoptions);
|
||||
print ($hidelabel?'':$langs->trans("RefOrLabel").' : ').'<input type="text" size="20" name="search_'.$htmlname.'" id="search_'.$htmlname.'" value="'.$selected_input_value.'">';
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2089,7 +2099,7 @@ class Form
|
||||
* @param string $filtertype Filter on product type (''=nofilter, 0=product, 1=service)
|
||||
* @param string $filtre Pour filtre sql
|
||||
* @param string $filterkey Filtre des produits
|
||||
* @param int $statut -1=Return all products, 0=Products not on sell, 1=Products on sell
|
||||
* @param int $statut -1=Return all products, 0=Products not on sell, 1=Products on sell (not used here, a filter on tobuy is already hard coded in request)
|
||||
* @param int $outputmode 0=HTML select string, 1=Array
|
||||
* @param int $limit Limit of line number
|
||||
* @return array Array of keys for json
|
||||
@ -2106,7 +2116,7 @@ class Form
|
||||
$sql = "SELECT p.rowid, p.label, p.ref, p.price, p.duration, p.fk_product_type,";
|
||||
$sql.= " pfp.ref_fourn, pfp.rowid as idprodfournprice, pfp.price as fprice, pfp.quantity, pfp.remise_percent, pfp.remise, pfp.unitprice,";
|
||||
$sql.= " pfp.fk_supplier_price_expression, pfp.fk_product, pfp.tva_tx, pfp.fk_soc, s.nom as name,";
|
||||
$sql.= " pfp.supplier_reputation";
|
||||
$sql.= " pfp.supplier_reputation";
|
||||
$sql.= " FROM ".MAIN_DB_PREFIX."product as p";
|
||||
$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product_fournisseur_price as pfp ON p.rowid = pfp.fk_product";
|
||||
if ($socid) $sql.= " AND pfp.fk_soc = ".$socid;
|
||||
|
||||
@ -136,7 +136,8 @@ function ajax_autocompleter($selected, $htmlname, $url, $urloption='', $minLengt
|
||||
minLength: '.$minLength.',
|
||||
select: function( event, ui ) { // Function ran once new value has been selected into javascript combo
|
||||
console.log("Call change on input '.$htmlname.' because of select definition of autocomplete select call on input#search_'.$htmlname.'");
|
||||
$("#'.$htmlname.'").val(ui.item.id).trigger("change"); // Select new value
|
||||
console.log("Selected id = "+ui.item.id+" - If this value is null, it means you select a record with key that is null so selection is not effective");
|
||||
$("#'.$htmlname.'").val(ui.item.id).trigger("change"); // Select new value
|
||||
// Disable an element
|
||||
if (options.option_disabled) {
|
||||
if (ui.item.disabled) {
|
||||
@ -179,7 +180,7 @@ function ajax_autocompleter($selected, $htmlname, $url, $urloption='', $minLengt
|
||||
}
|
||||
});
|
||||
}
|
||||
console.log("ajax_autocompleter new value selected, we trigger change on original component");
|
||||
console.log("ajax_autocompleter new value selected, we trigger change on original component so field #search_'.$htmlname.'");
|
||||
$("#search_'.$htmlname.'").trigger("change"); // We have changed value of the combo select, we must be sure to trigger all js hook binded on this event. This is required to trigger other javascript change method binded on original field by other code.
|
||||
}
|
||||
,delay: 500
|
||||
|
||||
@ -66,6 +66,8 @@ ALTER TABLE llx_product ADD COLUMN height_units tinyint DEFAULT NULL;
|
||||
|
||||
ALTER TABLE llx_product ADD COLUMN default_vat_code varchar(10) after cost_price;
|
||||
|
||||
ALTER TABLE llx_product MODIFY COLUMN stock real;
|
||||
|
||||
CREATE TABLE llx_categorie_user
|
||||
(
|
||||
fk_categorie integer NOT NULL,
|
||||
|
||||
@ -79,7 +79,7 @@ create table llx_product
|
||||
surface_units tinyint DEFAULT NULL,
|
||||
volume float DEFAULT NULL,
|
||||
volume_units tinyint DEFAULT NULL,
|
||||
stock integer, -- Current physical stock (dernormalized field)
|
||||
stock real, -- Current physical stock (dernormalized field)
|
||||
pmp double(24,8) DEFAULT 0 NOT NULL, -- To store valuation of stock calculated using average price method, for this product
|
||||
fifo double(24,8), -- To store valuation of stock calculated using fifo method, for this product
|
||||
lifo double(24,8), -- To store valuation of stock calculated using lifo method, for this product
|
||||
|
||||
@ -24,8 +24,8 @@ create table llx_stock_mouvement
|
||||
datem datetime, -- Date and hour of movement
|
||||
fk_product integer NOT NULL, -- Id of product
|
||||
batch varchar(30) DEFAULT NULL, -- Lot or serial number
|
||||
eatby date DEFAULT NULL, -- Eatby date
|
||||
sellby date DEFAULT NULL, -- Sellby date
|
||||
eatby date DEFAULT NULL, -- Eatby date (deprecated, we should get value from batch number in table llx_product_lot)
|
||||
sellby date DEFAULT NULL, -- Sellby date (deprecated, we should get value from batch number in table llx_product_lot)
|
||||
fk_entrepot integer NOT NULL, -- Id warehouse
|
||||
value real, -- Qty of movement
|
||||
price double(24,8) DEFAULT 0, -- Entry price (used to calculate PMP, FIFO or LIFO value)
|
||||
|
||||
@ -1850,7 +1850,7 @@ class Product extends CommonObject
|
||||
}
|
||||
}
|
||||
|
||||
// We should not load stock at each fetch. If someone need stock, he must call load_stock after fetch.
|
||||
// We should not load stock during the fetch. If someone need stock of product, he must call load_stock after fetching product.
|
||||
//$res=$this->load_stock();
|
||||
// instead we just init the stock_warehouse array
|
||||
$this->stock_warehouse = array();
|
||||
@ -2847,7 +2847,7 @@ class Product extends CommonObject
|
||||
|
||||
//print "XXX We add id=".$id." - label=".$label." - nb=".$nb." - multiply=".$multiply." fullpath=".$compl_path.$label."\n";
|
||||
$this->fetch($id); // Load product
|
||||
$this->load_stock(); // Load stock
|
||||
$this->load_stock('nobatch,novirtual'); // Load stock to get true this->stock_reel
|
||||
$this->res[]= array(
|
||||
'id'=>$id, // Id product
|
||||
'id_parent'=>$id_parent,
|
||||
|
||||
@ -103,6 +103,13 @@ if ($type=='0') $result=restrictedArea($user,'produit','','','','','',$objcanvas
|
||||
else if ($type=='1') $result=restrictedArea($user,'service','','','','','',$objcanvas);
|
||||
else $result=restrictedArea($user,'produit|service','','','','','',$objcanvas);
|
||||
|
||||
// Define virtualdiffersfromphysical
|
||||
$virtualdiffersfromphysical=0;
|
||||
if (! empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT) || ! empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER))
|
||||
{
|
||||
$virtualdiffersfromphysical=1; // According to increase/decrease stock options, virtual and physical stock may differs.
|
||||
}
|
||||
|
||||
// List of fields to search into when doing a "search in all"
|
||||
$fieldstosearchall = array(
|
||||
'p.ref'=>"Ref",
|
||||
@ -142,8 +149,9 @@ $arrayfields=array(
|
||||
'p.minbuyprice'=>array('label'=>$langs->trans("BuyingPriceMinShort"), 'checked'=>1, 'enabled'=>(! empty($user->rights->fournisseur->lire))),
|
||||
'p.seuil_stock_alerte'=>array('label'=>$langs->trans("StockLimit"), 'checked'=>0, 'enabled'=>(! empty($conf->stock->enabled) && $user->rights->stock->lire && $contextpage != 'service')),
|
||||
'p.desiredstock'=>array('label'=>$langs->trans("DesiredStock"), 'checked'=>1, 'enabled'=>(! empty($conf->stock->enabled) && $user->rights->stock->lire && $contextpage != 'service')),
|
||||
'p.tobatch'=>array('label'=>$langs->trans("ManageLotSerial"), 'checked'=>0, 'enabled'=>(! empty($conf->productbatch->enabled))),
|
||||
'p.stock'=>array('label'=>$langs->trans("PhysicalStock"), 'checked'=>1, 'enabled'=>(! empty($conf->stock->enabled) && $user->rights->stock->lire && $contextpage != 'service')),
|
||||
'stock_virtual'=>array('label'=>$langs->trans("VirtualStock"), 'checked'=>1, 'enabled'=>(! empty($conf->stock->enabled) && $user->rights->stock->lire && $contextpage != 'service' && $virtualdiffersfromphysical)),
|
||||
'p.tobatch'=>array('label'=>$langs->trans("ManageLotSerial"), 'checked'=>0, 'enabled'=>(! empty($conf->productbatch->enabled))),
|
||||
'p.accountancy_code_sell'=>array('label'=>$langs->trans("ProductAccountancySellCode"), 'checked'=>0),
|
||||
'p.accountancy_code_buy'=>array('label'=>$langs->trans("ProductAccountancyBuyCode"), 'checked'=>0),
|
||||
'p.datec'=>array('label'=>$langs->trans("DateCreation"), 'checked'=>0, 'position'=>500),
|
||||
@ -160,6 +168,7 @@ if (is_array($extrafields->attribute_label) && count($extrafields->attribute_lab
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Actions
|
||||
@ -428,8 +437,9 @@ else
|
||||
if (! empty($arrayfields['p.minbuyprice']['checked'])) print_liste_field_titre($arrayfields['p.minbuyprice']['label'], $_SERVER["PHP_SELF"],"","",$param,'align="right"',$sortfield,$sortorder);
|
||||
if (! empty($arrayfields['p.seuil_stock_alerte']['checked'])) print_liste_field_titre($arrayfields['p.seuil_stock_alerte']['label'], $_SERVER["PHP_SELF"],"p.seuil_stock_alerte","",$param,'align="right"',$sortfield,$sortorder);
|
||||
if (! empty($arrayfields['p.desiredstock']['checked'])) print_liste_field_titre($arrayfields['p.desiredstock']['label'], $_SERVER["PHP_SELF"],"p.desiredstock","",$param,'align="right"',$sortfield,$sortorder);
|
||||
if (! empty($arrayfields['p.tobatch']['checked'])) print_liste_field_titre($arrayfields['p.tobatch']['label'], $_SERVER["PHP_SELF"],"p.tobatch","",$param,'align="center"',$sortfield,$sortorder);
|
||||
if (! empty($arrayfields['p.stock']['checked'])) print_liste_field_titre($arrayfields['p.stock']['label'], $_SERVER["PHP_SELF"],"p.stock","",$param,'align="right"',$sortfield,$sortorder);
|
||||
if (! empty($arrayfields['stock_virtual']['checked'])) print_liste_field_titre($arrayfields['stock_virtual']['label'], $_SERVER["PHP_SELF"],"","",$param,'align="right"',$sortfield,$sortorder);
|
||||
if (! empty($arrayfields['p.tobatch']['checked'])) print_liste_field_titre($arrayfields['p.tobatch']['label'], $_SERVER["PHP_SELF"],"p.tobatch","",$param,'align="center"',$sortfield,$sortorder);
|
||||
if (! empty($arrayfields['p.accountancy_code_sell']['checked'])) print_liste_field_titre($arrayfields['p.accountancy_code_sell']['label'], $_SERVER["PHP_SELF"],"p.accountancy_code_sell","",$param,'',$sortfield,$sortorder);
|
||||
if (! empty($arrayfields['p.accountancy_code_buy']['checked'])) print_liste_field_titre($arrayfields['p.accountancy_code_buy']['label'], $_SERVER["PHP_SELF"],"p.accountancy_code_buy","",$param,'',$sortfield,$sortorder);
|
||||
if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label))
|
||||
@ -515,11 +525,13 @@ else
|
||||
print ' ';
|
||||
print '</td>';
|
||||
}
|
||||
// To batch
|
||||
if (! empty($arrayfields['p.tobatch']['checked'])) print '<td class="liste_titre center">'.$form->selectyesno($search_tobatch, '', '', '', 1).'</td>';
|
||||
// Stock
|
||||
if (! empty($arrayfields['p.stock']['checked'])) print '<td class="liste_titre"> </td>';
|
||||
// Accountancy code sell
|
||||
// Stock
|
||||
if (! empty($arrayfields['stock_virtual']['checked'])) print '<td class="liste_titre"> </td>';
|
||||
// To batch
|
||||
if (! empty($arrayfields['p.tobatch']['checked'])) print '<td class="liste_titre center">'.$form->selectyesno($search_tobatch, '', '', '', 1).'</td>';
|
||||
// Accountancy code sell
|
||||
if (! empty($arrayfields['p.accountancy_code_sell']['checked'])) print '<td class="liste_titre"><input class="flat" type="text" name="search_accountancy_code_sell" size="6" value="'.dol_escape_htmltag($search_accountancy_code_sell).'"></td>';
|
||||
// Accountancy code sell
|
||||
if (! empty($arrayfields['p.accountancy_code_buy']['checked'])) print '<td class="liste_titre"><input class="flat" type="text" name="search_accountancy_code_buy" size="6" value="'.dol_escape_htmltag($search_accountancy_code_buy).'"></td>';
|
||||
@ -600,7 +612,16 @@ else
|
||||
$product_static->status_buy = $objp->tobuy;
|
||||
$product_static->status = $objp->tosell;
|
||||
$product_static->entity = $objp->entity;
|
||||
|
||||
|
||||
if (! empty($conf->stock->enabled) && $user->rights->stock->lire && $type != 1) // To optimize call of load_stock
|
||||
{
|
||||
if ($objp->fk_product_type != 1) // Not a service
|
||||
{
|
||||
$product_static->load_stock('nobatch'); // Load stock_reel + stock_warehouse. This also call load_virtual_stock()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$var=!$var;
|
||||
print '<tr '.$bc[$var].'>';
|
||||
|
||||
@ -681,15 +702,6 @@ else
|
||||
print '</td>';
|
||||
}
|
||||
|
||||
if (! empty($conf->stock->enabled) && $user->rights->stock->lire && $type != 1) // To optimize call of load_stock
|
||||
{
|
||||
if ($objp->fk_product_type != 1) // Not a service
|
||||
{
|
||||
$product_static->id = $objp->rowid;
|
||||
$product_static->load_stock('nobatch'); // Load stock_reel + stock_warehouse + batch detail. This also call load_virtual_stock()
|
||||
}
|
||||
}
|
||||
|
||||
// Limit alert
|
||||
if (! empty($arrayfields['p.seuil_stock_alerte']['checked']))
|
||||
{
|
||||
@ -710,24 +722,35 @@ else
|
||||
}
|
||||
print '</td>';
|
||||
}
|
||||
// Lot/Serial
|
||||
if (! empty($arrayfields['p.tobatch']['checked']))
|
||||
{
|
||||
print '<td align="center">';
|
||||
print yn($objp->tobatch);
|
||||
print '</td>';
|
||||
}
|
||||
// Stock
|
||||
if (! empty($arrayfields['p.stock']['checked']))
|
||||
{
|
||||
print '<td align="right">';
|
||||
if ($objp->fk_product_type != 1)
|
||||
{
|
||||
if ($product_static->stock_reel < $objp->seuil_stock_alerte) print img_warning($langs->trans("StockTooLow")).' ';
|
||||
if ($objp->seuil_stock_alerte != '' && $product_static->stock_reel < (float) $objp->seuil_stock_alerte) print img_warning($langs->trans("StockTooLow")).' ';
|
||||
print $product_static->stock_reel;
|
||||
}
|
||||
print '</td>';
|
||||
}
|
||||
// Stock
|
||||
if (! empty($arrayfields['stock_virtual']['checked']))
|
||||
{
|
||||
print '<td align="right">';
|
||||
if ($objp->fk_product_type != 1)
|
||||
{
|
||||
if ($objp->seuil_stock_alerte != '' && $product_static->stock_theorique < (float) $objp->seuil_stock_alerte) print img_warning($langs->trans("StockTooLow")).' ';
|
||||
print $product_static->stock_theorique;
|
||||
}
|
||||
print '</td>';
|
||||
}
|
||||
// Lot/Serial
|
||||
if (! empty($arrayfields['p.tobatch']['checked']))
|
||||
{
|
||||
print '<td align="center">';
|
||||
print yn($objp->tobatch);
|
||||
print '</td>';
|
||||
}
|
||||
// Accountancy code sell
|
||||
if (! empty($arrayfields['p.accountancy_code_sell']['checked'])) print '<td>'.$objp->accountancy_code_sell.'</td>';
|
||||
// Accountancy code sell
|
||||
|
||||
@ -84,6 +84,13 @@ if (! empty($_POST["button_removefilter_x"]))
|
||||
$toolowstock='';
|
||||
}
|
||||
|
||||
// Define virtualdiffersfromphysical
|
||||
$virtualdiffersfromphysical=0;
|
||||
if (! empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT) || ! empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER))
|
||||
{
|
||||
$virtualdiffersfromphysical=1; // According to increase/decrease stock options, virtual and physical stock may differs.
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
@ -192,11 +199,11 @@ if ($resql)
|
||||
|
||||
if ($sref || $snom || $sall || GETPOST('search'))
|
||||
{
|
||||
print_barre_liste($texte, $page, $_SERVER["PHP_SELF"], "&sref=".$sref."&snom=".$snom."&sall=".$sall."&tosell=".$tosell."&tobuy=".$tobuy.(!empty($search_categ) ? '&search_categ='.$search_categ : '').(!empty($toolowstock) ? '&toolowstock='.$toolowstock : ''), $sortfield, $sortorder,'',$num);
|
||||
print_barre_liste($texte, $page, $_SERVER["PHP_SELF"], "&sref=".$sref."&snom=".$snom."&sall=".$sall."&tosell=".$tosell."&tobuy=".$tobuy.(!empty($search_categ) ? '&search_categ='.$search_categ : '').(!empty($toolowstock) ? '&toolowstock='.$toolowstock : ''), $sortfield, $sortorder,'',$num, 0, 'title_products');
|
||||
}
|
||||
else
|
||||
{
|
||||
print_barre_liste($texte, $page, $_SERVER["PHP_SELF"], "&sref=$sref&snom=$snom&fourn_id=$fourn_id".(isset($type)?"&type=$type":"").(!empty($search_categ) ? '&search_categ='.$search_categ : '').(!empty($toolowstock) ? '&toolowstock='.$toolowstock : ''), $sortfield, $sortorder,'',$num);
|
||||
print_barre_liste($texte, $page, $_SERVER["PHP_SELF"], "&sref=$sref&snom=$snom&fourn_id=$fourn_id".(isset($type)?"&type=$type":"").(!empty($search_categ) ? '&search_categ='.$search_categ : '').(!empty($toolowstock) ? '&toolowstock='.$toolowstock : ''), $sortfield, $sortorder,'',$num, 0, 'title_products');
|
||||
}
|
||||
|
||||
if (! empty($catid))
|
||||
@ -251,9 +258,8 @@ if ($resql)
|
||||
if (! empty($conf->service->enabled) && $type == 1) print_liste_field_titre($langs->trans("Duration"), $_SERVER["PHP_SELF"], "p.duration",$param,"",'align="center"',$sortfield,$sortorder);
|
||||
print_liste_field_titre($langs->trans("StockLimit"), $_SERVER["PHP_SELF"], "p.seuil_stock_alerte",$param,"",'align="right"',$sortfield,$sortorder);
|
||||
print_liste_field_titre($langs->trans("DesiredStock"), $_SERVER["PHP_SELF"], "p.desiredstock",$param,"",'align="right"',$sortfield,$sortorder);
|
||||
print_liste_field_titre($langs->trans("PhysicalStock"), $_SERVER["PHP_SELF"], "stock_physique",$param,"",'align="right"',$sortfield,$sortorder);
|
||||
// TODO Add info of running suppliers/customers orders
|
||||
//print_liste_field_titre($langs->trans("TheoreticalStock"),$_SERVER["PHP_SELF"], "stock_theorique",$param,"",'align="right"',$sortfield,$sortorder);
|
||||
print_liste_field_titre($langs->trans("PhysicalStock"), $_SERVER["PHP_SELF"], "",$param,"",'align="right"',$sortfield,$sortorder);
|
||||
if ($virtualdiffersfromphysical) print_liste_field_titre($langs->trans("VirtualStock"),$_SERVER["PHP_SELF"], "stock_theorique",$param,"",'align="right"',$sortfield,$sortorder);
|
||||
print_liste_field_titre('');
|
||||
print_liste_field_titre($langs->trans("Status").' ('.$langs->trans("Sell").')',$_SERVER["PHP_SELF"], "p.tosell",$param,"",'align="right"',$sortfield,$sortorder);
|
||||
print_liste_field_titre($langs->trans("Status").' ('.$langs->trans("Buy").')',$_SERVER["PHP_SELF"], "p.tobuy",$param,"",'align="right"',$sortfield,$sortorder);
|
||||
@ -267,16 +273,18 @@ if ($resql)
|
||||
print '<td class="liste_titre">';
|
||||
print '<input class="flat" type="text" name="snom" size="8" value="'.$snom.'">';
|
||||
print '</td>';
|
||||
// Duration
|
||||
if (! empty($conf->service->enabled) && $type == 1)
|
||||
{
|
||||
print '<td class="liste_titre">';
|
||||
print ' ';
|
||||
print '</td>';
|
||||
}
|
||||
// Lot/Serial
|
||||
// Stock limit
|
||||
print '<td class="liste_titre"> </td>';
|
||||
print '<td class="liste_titre" align="right"> </td>';
|
||||
print '<td class="liste_titre"> </td>';
|
||||
if ($virtualdiffersfromphysical) print '<td class="liste_titre"> </td>';
|
||||
print '<td class="liste_titre"> </td>';
|
||||
print '<td class="liste_titre"> </td>';
|
||||
print '<td class="liste_titre" align="right">';
|
||||
@ -309,15 +317,23 @@ if ($resql)
|
||||
}
|
||||
}
|
||||
|
||||
$var=!$var;
|
||||
print '<tr '.$bc[$var].'><td class="nowrap">';
|
||||
$product_static->ref=$objp->ref;
|
||||
$product_static->id=$objp->rowid;
|
||||
$product_static->label = $objp->label;
|
||||
$product_static->label = $objp->label;
|
||||
$product_static->type=$objp->fk_product_type;
|
||||
$product_static->entity=$objp->entity;
|
||||
if (! empty($conf->stock->enabled) && $user->rights->stock->lire && $type != 1) // To optimize call of load_stock
|
||||
{
|
||||
if ($objp->fk_product_type != 1) // Not a service
|
||||
{
|
||||
$product_static->load_stock('nobatch'); // Load stock_reel + stock_warehouse. This also call load_virtual_stock()
|
||||
}
|
||||
}
|
||||
|
||||
$var=!$var;
|
||||
print '<tr '.$bc[$var].'><td class="nowrap">';
|
||||
print $product_static->getNomUrl(1,'',24);
|
||||
//if ($objp->stock_theorique < $objp->seuil_stock_alerte) print ' '.img_warning($langs->trans("StockTooLow"));
|
||||
|
||||
print '</td>';
|
||||
print '<td>'.$objp->label.'</td>';
|
||||
|
||||
@ -333,10 +349,19 @@ if ($resql)
|
||||
//print '<td align="right">'.$objp->stock_theorique.'</td>';
|
||||
print '<td align="right">'.$objp->seuil_stock_alerte.'</td>';
|
||||
print '<td align="right">'.$objp->desiredstock.'</td>';
|
||||
// Real stock
|
||||
print '<td align="right">';
|
||||
if ($objp->seuil_stock_alerte && ($objp->stock_physique < $objp->seuil_stock_alerte)) print img_warning($langs->trans("StockTooLow")).' ';
|
||||
if ($objp->seuil_stock_alerte != '' && ($objp->stock_physique < $objp->seuil_stock_alerte)) print img_warning($langs->trans("StockTooLow")).' ';
|
||||
print $objp->stock_physique;
|
||||
print '</td>';
|
||||
// Virtual stock
|
||||
if ($virtualdiffersfromphysical)
|
||||
{
|
||||
print '<td align="right">';
|
||||
if ($objp->seuil_stock_alerte != '' && ($product_static->stock_theorique < $objp->seuil_stock_alerte)) print img_warning($langs->trans("StockTooLow")).' ';
|
||||
print $product_static->stock_theorique;
|
||||
print '</td>';
|
||||
}
|
||||
print '<td align="right"><a href="'.DOL_URL_ROOT.'/product/stock/mouvement.php?idproduct='.$product_static->id.'">'.$langs->trans("Movements").'</a></td>';
|
||||
print '<td align="right" class="nowrap">'.$product_static->LibStatut($objp->statut,5,0).'</td>';
|
||||
print '<td align="right" class="nowrap">'.$product_static->LibStatut($objp->tobuy,5,1).'</td>';
|
||||
|
||||
@ -204,11 +204,11 @@ if ($resql)
|
||||
|
||||
if ($sref || $snom || $sall || GETPOST('search'))
|
||||
{
|
||||
print_barre_liste($texte, $page, $_SERVER["PHP_SELF"], "&sref=".$sref."&snom=".$snom."&sall=".$sall."&tosell=".$tosell."&tobuy=".$tobuy, $sortfield, $sortorder,'',$num);
|
||||
print_barre_liste($texte, $page, $_SERVER["PHP_SELF"], "&sref=".$sref."&snom=".$snom."&sall=".$sall."&tosell=".$tosell."&tobuy=".$tobuy, $sortfield, $sortorder,'',$num, 0, 'title_products');
|
||||
}
|
||||
else
|
||||
{
|
||||
print_barre_liste($texte, $page, $_SERVER["PHP_SELF"], "&sref=$sref&snom=$snom&fourn_id=$fourn_id".(isset($type)?"&type=$type":""), $sortfield, $sortorder,'',$num);
|
||||
print_barre_liste($texte, $page, $_SERVER["PHP_SELF"], "&sref=$sref&snom=$snom&fourn_id=$fourn_id".(isset($type)?"&type=$type":""), $sortfield, $sortorder,'',$num, 0, 'title_products');
|
||||
}
|
||||
|
||||
if (! empty($catid))
|
||||
|
||||
@ -252,25 +252,12 @@ class MouvementStock extends CommonObject
|
||||
|
||||
// Calculate new PMP.
|
||||
$newpmp=0;
|
||||
//$newpmpwarehouse=0;
|
||||
if (! $error)
|
||||
{
|
||||
// Note: PMP is calculated on stock input only (type of movement = 0 or 3). If type == 0 or 3, qty should be > 0.
|
||||
// Note: Price should always be >0 or 0. PMP should be always >0 (calculated on input)
|
||||
if (($type == 0 || $type == 3) && $price > 0)
|
||||
{
|
||||
// If we will change PMP for the warehouse we edit and the product, we must first check/clean that PMP is defined
|
||||
// on every stock entry with old value (so global updated value will match recalculated value from product_stock)
|
||||
/* $sql = "UPDATE ".MAIN_DB_PREFIX."product_stock SET pmp = ".($oldpmp?$oldpmp:'0');
|
||||
$sql.= " WHERE pmp = 0 AND fk_product = ".$fk_product;
|
||||
dol_syslog(get_class($this)."::_create", LOG_DEBUG);
|
||||
$resql=$this->db->query($sql);
|
||||
if (! $resql)
|
||||
{
|
||||
$this->errors[]=$this->db->lasterror();
|
||||
$error = -4;
|
||||
}
|
||||
*/
|
||||
$oldqtytouse=($oldqty >= 0?$oldqty:0);
|
||||
// We make a test on oldpmp>0 to avoid to use normal rule on old data with no pmp field defined
|
||||
if ($oldpmp > 0) $newpmp=price2num((($oldqtytouse * $oldpmp) + ($qty * $price)) / ($oldqtytouse + $qty), 'MU');
|
||||
@ -278,13 +265,8 @@ class MouvementStock extends CommonObject
|
||||
{
|
||||
$newpmp=$price; // For this product, PMP was not yet set. We set it to input price.
|
||||
}
|
||||
/*
|
||||
$oldqtywarehousetouse=$oldqtywarehouse;
|
||||
if ($oldpmpwarehouse > 0) $newpmpwarehouse=price2num((($oldqtywarehousetouse * $oldpmpwarehouse) + ($qty * $price)) / ($oldqtywarehousetouse + $qty), 'MU');
|
||||
else $newpmpwarehouse=$price;
|
||||
*/
|
||||
//print "oldqtytouse=".$oldqtytouse." oldpmp=".$oldpmp." oldqtywarehousetouse=".$oldqtywarehousetouse." oldpmpwarehouse=".$oldpmpwarehouse." ";
|
||||
//print "qty=".$qty." newpmp=".$newpmp." newpmpwarehouse=".$newpmpwarehouse;
|
||||
//print "oldqtytouse=".$oldqtytouse." oldpmp=".$oldpmp." oldqtywarehousetouse=".$oldqtywarehousetouse." ";
|
||||
//print "qty=".$qty." newpmp=".$newpmp;
|
||||
//exit;
|
||||
}
|
||||
else if ($type == 1 || $type == 2)
|
||||
@ -295,7 +277,6 @@ class MouvementStock extends CommonObject
|
||||
else
|
||||
{
|
||||
$newpmp = $oldpmp;
|
||||
//$newpmpwarehouse = $oldpmpwarehouse;
|
||||
}
|
||||
}
|
||||
|
||||
@ -339,11 +320,13 @@ class MouvementStock extends CommonObject
|
||||
// Update PMP and denormalized value of stock qty at product level
|
||||
if (! $error)
|
||||
{
|
||||
$sql = "UPDATE ".MAIN_DB_PREFIX."product SET pmp = ".$newpmp.", stock = ".$this->db->ifsql("stock IS NULL", 0, "stock") . " + ".$qty;
|
||||
//$sql = "UPDATE ".MAIN_DB_PREFIX."product SET pmp = ".$newpmp.", stock = ".$this->db->ifsql("stock IS NULL", 0, "stock") . " + ".$qty;
|
||||
//$sql.= " WHERE rowid = ".$fk_product;
|
||||
// Update pmp + denormalized fields because we change content of produt_stock. Warning: Do not use "SET p.stock", does not works with pgsql
|
||||
$sql = "UPDATE ".MAIN_DB_PREFIX."product as p SET p.pmp = ".$newpmp.", ";
|
||||
$sql.= " stock=(SELECT SUM(ps.reel) FROM llx_product_stock ps WHERE ps.fk_product = p.rowid)";
|
||||
$sql.= " WHERE rowid = ".$fk_product;
|
||||
// May be this request is better:
|
||||
// UPDATE llx_product p SET p.stock= (SELECT SUM(ps.reel) FROM llx_product_stock ps WHERE ps.fk_product = p.rowid);
|
||||
|
||||
print $sql;
|
||||
dol_syslog(get_class($this)."::_create", LOG_DEBUG);
|
||||
$resql=$this->db->query($sql);
|
||||
if (! $resql)
|
||||
|
||||
@ -185,7 +185,7 @@ if ($action == 'createmovements')
|
||||
{
|
||||
$result=$product->fetch($id_product);
|
||||
|
||||
$product->load_stock(); // Load array product->stock_warehouse
|
||||
$product->load_stock('novirtual'); // Load array product->stock_warehouse
|
||||
|
||||
// Define value of products moved
|
||||
$pricesrc=0;
|
||||
|
||||
@ -207,11 +207,10 @@ if ($action == "transfert_stock" && ! $cancel)
|
||||
|
||||
$db->begin();
|
||||
|
||||
$product->load_stock(); // Load array product->stock_warehouse
|
||||
$product->load_stock('novirtual'); // 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;
|
||||
|
||||
|
||||
@ -185,7 +185,7 @@ if ($action == "correct_stock" && ! $cancel)
|
||||
// Transfer stock from a warehouse to another warehouse
|
||||
if ($action == "transfert_stock" && ! $cancel)
|
||||
{
|
||||
if (! (GETPOST("id_entrepot_source",'int') > 0) || ! (GETPOST("id_entrepot_destination",'int') > 0))
|
||||
if (! (GETPOST("id_entrepot",'int') > 0) || ! (GETPOST("id_entrepot_destination",'int') > 0))
|
||||
{
|
||||
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Warehouse")), null, 'errors');
|
||||
$error++;
|
||||
@ -197,7 +197,7 @@ if ($action == "transfert_stock" && ! $cancel)
|
||||
$error++;
|
||||
$action='transfert';
|
||||
}
|
||||
if (GETPOST("id_entrepot_source",'int') == GETPOST("id_entrepot_destination",'int'))
|
||||
if (GETPOST("id_entrepot",'int') == GETPOST("id_entrepot_destination",'int'))
|
||||
{
|
||||
setEventMessages($langs->trans("ErrorSrcAndTargetWarehouseMustDiffers"), null, 'errors');
|
||||
$error++;
|
||||
@ -225,7 +225,7 @@ if ($action == "transfert_stock" && ! $cancel)
|
||||
|
||||
$db->begin();
|
||||
|
||||
$object->load_stock(); // Load array product->stock_warehouse
|
||||
$object->load_stock('novirtual'); // Load array product->stock_warehouse
|
||||
|
||||
// Define value of products moved
|
||||
$pricesrc=0;
|
||||
@ -254,7 +254,7 @@ if ($action == "transfert_stock" && ! $cancel)
|
||||
}
|
||||
else
|
||||
{
|
||||
$srcwarehouseid=GETPOST('id_entrepot_source','int');
|
||||
$srcwarehouseid=GETPOST('id_entrepot','int');
|
||||
$batch=GETPOST('batch_number');
|
||||
$eatby=$d_eatby;
|
||||
$sellby=$d_sellby;
|
||||
@ -291,7 +291,7 @@ if ($action == "transfert_stock" && ! $cancel)
|
||||
// Remove stock
|
||||
$result1=$object->correct_stock(
|
||||
$user,
|
||||
GETPOST("id_entrepot_source"),
|
||||
GETPOST("id_entrepot"),
|
||||
GETPOST("nbpiece"),
|
||||
1,
|
||||
GETPOST("label"),
|
||||
@ -390,6 +390,7 @@ if ($id > 0 || $ref)
|
||||
{
|
||||
$object = new Product($db);
|
||||
$result = $object->fetch($id,$ref);
|
||||
|
||||
$object->load_stock();
|
||||
|
||||
$help_url='EN:Module_Stocks_En|FR:Module_Stock|ES:Módulo_Stocks';
|
||||
@ -480,7 +481,6 @@ if ($id > 0 || $ref)
|
||||
print '</td></tr>';
|
||||
|
||||
// Real stock
|
||||
$object->load_stock();
|
||||
$text_stock_options = '';
|
||||
$text_stock_options.= (! empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT)?$langs->trans("DeStockOnShipment").'<br>':'');
|
||||
$text_stock_options.= (! empty($conf->global->STOCK_CALCULATE_ON_VALIDATE_ORDER)?$langs->trans("DeStockOnValidateOrder").'<br>':'');
|
||||
@ -702,9 +702,10 @@ if ($resql)
|
||||
$entrepotstatic->id=$obj->rowid;
|
||||
$entrepotstatic->libelle=$obj->label;
|
||||
$entrepotstatic->lieu=$obj->lieu;
|
||||
$stock_real = round($obj->reel, 10);
|
||||
print '<tr '.$bc[$var].'>';
|
||||
print '<td colspan="4">'.$entrepotstatic->getNomUrl(1).'</td>';
|
||||
print '<td align="right">'.$obj->reel.($obj->reel<0?' '.img_warning():'').'</td>';
|
||||
print '<td align="right">'.$stock_real.($stock_real < 0 ?' '.img_warning():'').'</td>';
|
||||
// PMP
|
||||
print '<td align="right">'.(price2num($object->pmp)?price2num($object->pmp,'MU'):'').'</td>';
|
||||
// Value purchase
|
||||
|
||||
@ -69,6 +69,13 @@ if (!$sortorder) {
|
||||
$sortorder = 'ASC';
|
||||
}
|
||||
|
||||
// Define virtualdiffersfromphysical
|
||||
$virtualdiffersfromphysical=0;
|
||||
if (! empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT) || ! empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER))
|
||||
{
|
||||
$virtualdiffersfromphysical=1; // According to increase/decrease stock options, virtual and physical stock may differs.
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Actions
|
||||
@ -227,20 +234,6 @@ if ($action == 'order' && isset($_POST['valid']))
|
||||
|
||||
$form = new Form($db);
|
||||
|
||||
$virtualdiffersfromphysical=0;
|
||||
if (! empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT) || ! empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER))
|
||||
{
|
||||
$virtualdiffersfromphysical=1; // According to increase/decrease stock options, virtual and physical stock may differs.
|
||||
}
|
||||
|
||||
$usevirtualstock=-1;
|
||||
if ($virtualdiffersfromphysical)
|
||||
{
|
||||
$usevirtualstock=(! empty($conf->global->STOCK_USE_VIRTUAL_STOCK)?1:0);
|
||||
if ($mode=='virtual') $usevirtualstock=1;
|
||||
if ($mode=='physical') $usevirtualstock=0;
|
||||
}
|
||||
|
||||
$title = $langs->trans('Status');
|
||||
|
||||
$sql = 'SELECT p.rowid, p.ref, p.label, p.price,';
|
||||
|
||||
@ -411,7 +411,8 @@ function getProductOrService($authentication,$id='',$ref='',$ref_ext='',$lang=''
|
||||
'localtax1_tx' => $product->localtax1_tx,
|
||||
'localtax2_tx' => $product->localtax2_tx,
|
||||
|
||||
'stock_real' => $product->stock_reel,
|
||||
'stock_real' => $product->stock_reel,
|
||||
'stock_virtual' => $product->stock_theorique,
|
||||
'stock_alert' => $product->seuil_stock_alerte,
|
||||
'pmp' => $product->pmp,
|
||||
'import_key' => $product->import_key,
|
||||
@ -572,7 +573,7 @@ function createProductOrService($authentication,$product)
|
||||
require_once DOL_DOCUMENT_ROOT.'/product/stock/class/entrepot.class.php';
|
||||
|
||||
$savstockreal=$newobject->stock_reel;
|
||||
$newobject->load_stock(); // This overwrite ->stock_reel
|
||||
$newobject->load_stock('novirtual,nobatch'); // This overwrite ->stock_reel, surely 0 because we have just created product
|
||||
$getstockreal = $newobject->stock_reel;
|
||||
|
||||
if ($savstockreal != $getstockreal)
|
||||
@ -741,7 +742,7 @@ function updateProductOrService($authentication,$product)
|
||||
require_once DOL_DOCUMENT_ROOT.'/product/stock/class/entrepot.class.php';
|
||||
|
||||
$savstockreal=$newobject->stock_reel;
|
||||
$newobject->load_stock(); // This overwrite ->stock_reel
|
||||
$newobject->load_stock('novirtual,nobatch'); // This overwrite ->stock_reel
|
||||
$getstockreal = $newobject->stock_reel;
|
||||
|
||||
if ($savstockreal != $getstockreal)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user