diff --git a/htdocs/admin/stock.php b/htdocs/admin/stock.php
index a23f3127ca8..ecd4a4344b9 100644
--- a/htdocs/admin/stock.php
+++ b/htdocs/admin/stock.php
@@ -222,6 +222,26 @@ if (isModEnabled('facture')) {
print "\n\n";
$found++;
+print '
';
print '| '.$langs->trans("DeStockOnValidateOrder").' | ';
diff --git a/htdocs/commande/list.php b/htdocs/commande/list.php
index 2211422f3c5..cb5d071f539 100644
--- a/htdocs/commande/list.php
+++ b/htdocs/commande/list.php
@@ -1294,7 +1294,7 @@ if ($resql) {
print $langs->trans('ValidateInvoices');
print '';
print '';
- if (!empty($conf->stock->enabled) && !empty($conf->global->STOCK_CALCULATE_ON_BILL)) {
+ if (!empty($conf->stock->enabled) && (!empty($conf->global->STOCK_CALCULATE_ON_BILL) || !empty($conf->global->STOCK_CALCULATE_ON_CREDIT_BILL) ) ) {
print $form->selectyesno('validate_invoices', 0, 1, 1);
$langs->load("errors");
print ' ('.$langs->trans("WarningAutoValNotPossibleWhenStockIsDecreasedOnInvoiceVal").')';
diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php
index bd2204b6be9..a42737b76a6 100644
--- a/htdocs/compta/facture/card.php
+++ b/htdocs/compta/facture/card.php
@@ -635,7 +635,7 @@ if (empty($reshook)) {
$object->fetch_thirdparty();
// Check for warehouse
- if ($object->type != Facture::TYPE_DEPOSIT && !empty($conf->global->STOCK_CALCULATE_ON_BILL)) {
+ if ( ($object->type != Facture::TYPE_DEPOSIT && !empty($conf->global->STOCK_CALCULATE_ON_BILL)) || ($object->type == Facture::TYPE_CREDIT_NOTE && !empty($conf->global->STOCK_CALCULATE_ON_CREDIT_BILL)) ) {
$qualified_for_stock_change = 0;
if (empty($conf->global->STOCK_SUPPORTS_SERVICES)) {
$qualified_for_stock_change = $object->hasProductsOrServices(2);
@@ -695,7 +695,7 @@ if (empty($reshook)) {
$object->fetch_thirdparty();
// Check parameters
- if ($object->type != Facture::TYPE_DEPOSIT && !empty($conf->global->STOCK_CALCULATE_ON_BILL)) {
+ if ( ($object->type != Facture::TYPE_DEPOSIT && !empty($conf->global->STOCK_CALCULATE_ON_BILL)) || ($object->type == Facture::TYPE_CREDIT_NOTE && !empty($conf->global->STOCK_CALCULATE_ON_CREDIT_BILL)) ) {
$qualified_for_stock_change = 0;
if (empty($conf->global->STOCK_SUPPORTS_SERVICES)) {
$qualified_for_stock_change = $object->hasProductsOrServices(2);
@@ -3981,7 +3981,12 @@ if ($action == 'create') {
$text = $langs->trans('ConfirmDeleteBill', $object->ref);
$formquestion = array();
- if ($object->type != Facture::TYPE_DEPOSIT && !empty($conf->global->STOCK_CALCULATE_ON_BILL) && $object->statut >= 1) {
+ if ($object->statut >= 1 &&
+ (
+ ($object->type != Facture::TYPE_DEPOSIT && !empty($conf->global->STOCK_CALCULATE_ON_BILL)) ||
+ ($object->type == Facture::TYPE_CREDIT_NOTE && !empty($conf->global->STOCK_CALCULATE_ON_CREDIT_BILL))
+ )
+ ) {
$qualified_for_stock_change = 0;
if (empty($conf->global->STOCK_SUPPORTS_SERVICES)) {
$qualified_for_stock_change = $object->hasProductsOrServices(2);
@@ -4054,7 +4059,7 @@ if ($action == 'create') {
}
$formquestion = array();
- if ($object->type != Facture::TYPE_DEPOSIT && !empty($conf->global->STOCK_CALCULATE_ON_BILL)) {
+ if ( ($object->type != Facture::TYPE_DEPOSIT && !empty($conf->global->STOCK_CALCULATE_ON_BILL)) || ($object->type == Facture::TYPE_CREDIT_NOTE && !empty($conf->global->STOCK_CALCULATE_ON_CREDIT_BILL)) ) {
$qualified_for_stock_change = 0;
if (empty($conf->global->STOCK_SUPPORTS_SERVICES)) {
$qualified_for_stock_change = $object->hasProductsOrServices(2);
@@ -4111,7 +4116,7 @@ if ($action == 'create') {
$text = $langs->trans('ConfirmUnvalidateBill', $object->ref);
$formquestion = array();
- if ($object->type != Facture::TYPE_DEPOSIT && !empty($conf->global->STOCK_CALCULATE_ON_BILL)) {
+ if (($object->type != Facture::TYPE_DEPOSIT && !empty($conf->global->STOCK_CALCULATE_ON_BILL)) || ($object->type == Facture::TYPE_CREDIT_NOTE && !empty($conf->global->STOCK_CALCULATE_ON_CREDIT_BILL)) ) {
$qualified_for_stock_change = 0;
if (empty($conf->global->STOCK_SUPPORTS_SERVICES)) {
$qualified_for_stock_change = $object->hasProductsOrServices(2);
diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php
index c1e5856ab87..59f2cc2386a 100644
--- a/htdocs/compta/facture/class/facture.class.php
+++ b/htdocs/compta/facture/class/facture.class.php
@@ -2681,7 +2681,12 @@ class Facture extends CommonInvoice
}
// If we decrease stock on invoice validation, we increase back if a warehouse id was provided
- if ($this->type != self::TYPE_DEPOSIT && $result >= 0 && !empty($conf->stock->enabled) && !empty($conf->global->STOCK_CALCULATE_ON_BILL) && $idwarehouse != -1) {
+ if ( $result >= 0 && !empty($conf->stock->enabled) && $idwarehouse != -1 &&
+ (
+ ($this->type != self::TYPE_DEPOSIT && !empty($conf->global->STOCK_CALCULATE_ON_BILL)) ||
+ ($this->type == self::TYPE_CREDIT_NOTE && !empty($conf->global->STOCK_CALCULATE_ON_CREDIT_BILL))
+ )
+ ) {
require_once DOL_DOCUMENT_ROOT.'/product/stock/class/mouvementstock.class.php';
$langs->load("agenda");
@@ -3188,7 +3193,12 @@ class Facture extends CommonInvoice
$result = $this->thirdparty->set_as_client();
// If active we decrement the main product and its components at invoice validation
- if ($this->type != self::TYPE_DEPOSIT && $result >= 0 && !empty($conf->stock->enabled) && !empty($conf->global->STOCK_CALCULATE_ON_BILL) && $idwarehouse > 0) {
+ if ( $result >= 0 && !empty($conf->stock->enabled) && $idwarehouse > 0 &&
+ (
+ ($this->type != self::TYPE_DEPOSIT && !empty($conf->global->STOCK_CALCULATE_ON_BILL)) ||
+ ($this->type == self::TYPE_CREDIT_NOTE && !empty($conf->global->STOCK_CALCULATE_ON_CREDIT_BILL))
+ )
+ ) {
require_once DOL_DOCUMENT_ROOT.'/product/stock/class/mouvementstock.class.php';
$langs->load("agenda");
@@ -3501,7 +3511,12 @@ class Facture extends CommonInvoice
}
// If we decrease stock on invoice validation, we increase back
- if ($this->type != self::TYPE_DEPOSIT && $result >= 0 && !empty($conf->stock->enabled) && !empty($conf->global->STOCK_CALCULATE_ON_BILL)) {
+ if ( $result >= 0 && !empty($conf->stock->enabled) &&
+ (
+ ($this->type != self::TYPE_DEPOSIT && !empty($conf->global->STOCK_CALCULATE_ON_BILL)) ||
+ ($this->type == self::TYPE_CREDIT_NOTE && !empty($conf->global->STOCK_CALCULATE_ON_CREDIT_BILL))
+ )
+ ) {
require_once DOL_DOCUMENT_ROOT.'/product/stock/class/mouvementstock.class.php';
$langs->load("agenda");
diff --git a/htdocs/core/actions_massactions.inc.php b/htdocs/core/actions_massactions.inc.php
index 51407d4ff8f..1343cb1bb09 100644
--- a/htdocs/core/actions_massactions.inc.php
+++ b/htdocs/core/actions_massactions.inc.php
@@ -912,7 +912,12 @@ if ($action == 'remove_file') {
if (!$error && $massaction == 'validate' && $permissiontoadd) {
$objecttmp = new $objectclass($db);
- if (($objecttmp->element == 'facture' || $objecttmp->element == 'invoice') && !empty($conf->stock->enabled) && !empty($conf->global->STOCK_CALCULATE_ON_BILL)) {
+ if ( !empty($conf->stock->enabled) && ($objecttmp->element == 'facture' || $objecttmp->element == 'invoice') &&
+ (
+ !empty($conf->global->STOCK_CALCULATE_ON_BILL) ||
+ !empty($conf->global->STOCK_CALCULATE_ON_CREDIT_BILL)
+ )
+ ) {
$langs->load("errors");
setEventMessages($langs->trans('ErrorMassValidationNotAllowedWhenStockIncreaseOnAction'), null, 'errors');
$error++;
diff --git a/htdocs/core/class/conf.class.php b/htdocs/core/class/conf.class.php
index 44a510ef157..dd46e26cd2e 100644
--- a/htdocs/core/class/conf.class.php
+++ b/htdocs/core/class/conf.class.php
@@ -615,6 +615,8 @@ class Conf
if (!empty($this->productbatch->enabled)) {
$this->global->STOCK_CALCULATE_ON_BILL = 0;
+ $this->global->STOCK_CALCULATE_ON_INVOICE_BILL = 0;
+ $this->global->STOCK_CALCULATE_ON_CREDIT_BILL = 0;
$this->global->STOCK_CALCULATE_ON_VALIDATE_ORDER = 0;
if (empty($this->global->STOCK_CALCULATE_ON_SHIPMENT_CLOSE)) $this->global->STOCK_CALCULATE_ON_SHIPMENT = 1;
if (empty($this->global->STOCK_CALCULATE_ON_SHIPMENT)) $this->global->STOCK_CALCULATE_ON_SHIPMENT_CLOSE = 1;
diff --git a/htdocs/core/modules/modFacture.class.php b/htdocs/core/modules/modFacture.class.php
index 23b9ea85639..4e6fcb55ce0 100644
--- a/htdocs/core/modules/modFacture.class.php
+++ b/htdocs/core/modules/modFacture.class.php
@@ -545,7 +545,7 @@ class modFacture extends DolibarrModules
}
$this->export_fields_array[$r] = $this->export_fields_array[$r] + array(
'fd.rowid'=>'LineId', 'fd.description'=>"LineDescription",
- 'fd.subprice'=>"LineUnitPrice", 'fd.tva_tx'=>"LineVATRate", 'fd.qty'=>"LineQty", 'fd.total_ht'=>"LineTotalHT", 'fd.total_tva'=>"LineTotalVAT",
+ 'fd.subprice'=>"LineUnitPrice", 'fd.buy_price_ht'=>"CostPrice", 'fd.tva_tx'=>"LineVATRate", 'fd.qty'=>"LineQty", 'fd.total_ht'=>"LineTotalHT", 'fd.total_tva'=>"LineTotalVAT",
'fd.total_ttc'=>"LineTotalTTC", 'fd.date_start'=>"DateStart", 'fd.date_end'=>"DateEnd", 'fd.special_code'=>'SpecialCode',
'fd.product_type'=>"TypeOfLineServiceOrProduct", 'fd.fk_product'=>'ProductId', 'p.ref'=>'ProductRef', 'p.label'=>'ProductLabel',
$alias_product_perentity . '.accountancy_code_sell'=>'ProductAccountancySellCode'
@@ -558,7 +558,7 @@ class modFacture extends DolibarrModules
'f.total_ht'=>"Numeric", 'f.total_ttc'=>"Numeric", 'f.total_tva'=>"Numeric", 'f.localtax1'=>'Numeric', 'f.localtax2'=>'Numeric', 'f.paye'=>"Boolean", 'f.fk_statut'=>'Numeric', 'f.close_code'=>'Text', 'f.close_note'=>'Text',
'none.rest'=>"NumericCompute",
'f.note_private'=>"Text", 'f.note_public'=>"Text", 'f.fk_user_author'=>'Numeric', 'uc.login'=>'Text', 'f.fk_user_valid'=>'Numeric', 'uv.login'=>'Text',
- 'pj.ref'=>'Text', 'pj.title'=>'Text', 'fd.rowid'=>'Numeric', 'fd.description'=>"Text", 'fd.subprice'=>"Numeric", 'fd.tva_tx'=>"Numeric",
+ 'pj.ref'=>'Text', 'pj.title'=>'Text', 'fd.rowid'=>'Numeric', 'fd.description'=>"Text", 'fd.subprice'=>"Numeric", 'fd.buy_price_ht'=>'Numeric', 'fd.tva_tx'=>"Numeric",
'fd.qty'=>"Numeric", 'fd.total_ht'=>"Numeric", 'fd.total_tva'=>"Numeric", 'fd.total_ttc'=>"Numeric", 'fd.date_start'=>"Date", 'fd.date_end'=>"Date",
'fd.special_code'=>'Numeric', 'fd.product_type'=>"Numeric", 'fd.fk_product'=>'List:product:label', 'p.ref'=>'Text', 'p.label'=>'Text',
$alias_product_perentity . '.accountancy_code_sell'=>'Text',
@@ -571,7 +571,7 @@ class modFacture extends DolibarrModules
's.siren'=>'company', 's.siret'=>'company', 's.ape'=>'company', 's.idprof4'=>'company', 's.code_compta'=>'company', 's.code_compta_fournisseur'=>'company', 's.tva_intra'=>'company',
't.libelle'=>'company', // 'ce.code'=>'company', 'cfj.libelle'=>'company'
'pj.ref'=>'project', 'pj.title'=>'project', 'fd.rowid'=>'invoice_line', 'fd.description'=>"invoice_line",
- 'fd.subprice'=>"invoice_line", 'fd.total_ht'=>"invoice_line", 'fd.total_tva'=>"invoice_line", 'fd.total_ttc'=>"invoice_line", 'fd.tva_tx'=>"invoice_line",
+ 'fd.subprice'=>"invoice_line", 'fd.buy_price_ht'=>"invoice_line", 'fd.total_ht'=>"invoice_line", 'fd.total_tva'=>"invoice_line", 'fd.total_ttc'=>"invoice_line", 'fd.tva_tx'=>"invoice_line",
'fd.qty'=>"invoice_line", 'fd.date_start'=>"invoice_line", 'fd.date_end'=>"invoice_line", 'fd.special_code'=>'invoice_line',
'fd.product_type'=>'invoice_line', 'fd.fk_product'=>'product', 'p.ref'=>'product', 'p.label'=>'product', $alias_product_perentity . '.accountancy_code_sell'=>'product',
'f.fk_user_author'=>'user', 'uc.login'=>'user', 'f.fk_user_valid'=>'user', 'uv.login'=>'user'
diff --git a/htdocs/fourn/commande/dispatch.php b/htdocs/fourn/commande/dispatch.php
index 0c9152eefca..7333adf80b8 100644
--- a/htdocs/fourn/commande/dispatch.php
+++ b/htdocs/fourn/commande/dispatch.php
@@ -407,12 +407,24 @@ if ($action == 'confirm_deleteline' && $confirm == 'yes' && $permissiontoreceive
$qty = $supplierorderdispatch->qty;
$entrepot = $supplierorderdispatch->fk_entrepot;
$product = $supplierorderdispatch->fk_product;
- $price = price2num(GETPOST('price', 'alpha'), 'MU');
$comment = $supplierorderdispatch->comment;
$eatby = $supplierorderdispatch->eatby;
$sellby = $supplierorderdispatch->sellby;
$batch = $supplierorderdispatch->batch;
+ if (!empty($conf->global->SUPPLIER_ORDER_CAN_UPDATE_BUYINGPRICE_DURING_RECEIPT)) {
+ $price = price2num(GETPOST('price', 'alpha'), 'MU');
+ }else{
+ $cfl = new CommandeFournisseurLigne($db);
+ $ret = $cfl->fetch($supplierorderdispatch->fk_commandefourndet);
+ if($ret > 0){
+ $price = $cfl->subprice;
+ $price = price2num($price * (1 - ($cfl->remise_percent / 100.0)), 'MU');
+ }else{
+ $price = "0";
+ }
+ }
+
$result = $supplierorderdispatch->delete($user);
}
if ($result < 0) {
diff --git a/htdocs/langs/en_US/stocks.lang b/htdocs/langs/en_US/stocks.lang
index 47483bb8f3b..042bd317414 100644
--- a/htdocs/langs/en_US/stocks.lang
+++ b/htdocs/langs/en_US/stocks.lang
@@ -76,6 +76,7 @@ OrderDispatch=Item receipts
RuleForStockManagementDecrease=Choose Rule for automatic stock decrease (manual decrease is always possible, even if an automatic decrease rule is activated)
RuleForStockManagementIncrease=Choose Rule for automatic stock increase (manual increase is always possible, even if an automatic increase rule is activated)
DeStockOnBill=Decrease real stocks on validation of customer invoice/credit note
+DeStockOnCreditBill=Decrease (increase) real stocks on validation of customer credit (only) note
DeStockOnValidateOrder=Decrease real stocks on validation of sales order
DeStockOnShipment=Decrease real stocks on shipping validation
DeStockOnShipmentOnClosing=Decrease real stocks when shipping is set to closed
diff --git a/htdocs/langs/fr_FR/stocks.lang b/htdocs/langs/fr_FR/stocks.lang
index a0642c4c627..a4151b6150d 100644
--- a/htdocs/langs/fr_FR/stocks.lang
+++ b/htdocs/langs/fr_FR/stocks.lang
@@ -77,6 +77,7 @@ RuleForStockManagementDecrease=Règle de gestion des décrémentations automatiq
RuleForStockManagementIncrease=Règle de gestion des incrémentations de stock (l'incrémentation manuelle est toujours possible, même si une incrémentation automatique est activée)
DeStockOnBill=Décrémenter les stocks physiques sur validation des factures/avoirs clients
DeStockOnValidateOrder=Décrémenter les stocks physiques sur validation des commandes clients
+DeStockOnCreditBill=Décrémenter (incrémenter) les stocks physiques sur validation des avoirs (uniquement) clients
DeStockOnShipment=Décrémenter les stocks physiques sur validation des expéditions
DeStockOnShipmentOnClosing=Décrémenter les stocks physiques au classement "clôturée" de l'expédition
ReStockOnBill=Incrémenter les stocks physiques sur validation des factures/avoirs fournisseurs
@@ -112,6 +113,7 @@ EstimatedStockValueSellShort=Valeur à la vente
EstimatedStockValueSell=Valeur vente
EstimatedStockValueShort=Valorisation achat (PMP)
EstimatedStockValue=Valorisation à l'achat (PMP)
+EstimatedStockCostPrice=Valorisation à l'achat (Prix de revient)
DeleteAWarehouse=Supprimer un entrepôt
ConfirmDeleteWarehouse=Êtes-vous sûr de vouloir supprimer l'entrepôt %s ?
PersonalStock=Stock personnel %s
diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php
index 98de8c12e5c..7776d3c4aef 100644
--- a/htdocs/main.inc.php
+++ b/htdocs/main.inc.php
@@ -36,7 +36,7 @@
* \brief File that defines environment for Dolibarr GUI pages only (file not required by scripts)
*/
-//@ini_set('memory_limit', '128M'); // This may be useless if memory is hard limited by your PHP
+@ini_set('memory_limit', '512M'); // This may be useless if memory is hard limited by your PHP
// For optional tuning. Enabled if environment variable MAIN_SHOW_TUNING_INFO is defined.
$micro_start_time = 0;
diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php
index 9f2f05f3330..39f23e445e5 100644
--- a/htdocs/product/class/product.class.php
+++ b/htdocs/product/class/product.class.php
@@ -3008,14 +3008,19 @@ class Product extends CommonObject
// If stock decrease is on invoice validation, the theorical stock continue to
// count the orders to ship in theorical stock when some are already removed b invoice validation.
// If option DECREASE_ONLY_UNINVOICEDPRODUCTS is on, we make a compensation.
- if (!empty($conf->global->STOCK_CALCULATE_ON_BILL)) {
+ if (!empty($conf->global->STOCK_CALCULATE_ON_BILL) || !empty($conf->global->STOCK_CALCULATE_ON_CREDIT_BILL) ) {
if (!empty($conf->global->DECREASE_ONLY_UNINVOICEDPRODUCTS)) {
$adeduire = 0;
$sql = "SELECT sum(fd.qty) as count FROM ".$this->db->prefix()."facturedet fd ";
$sql .= " JOIN ".$this->db->prefix()."facture f ON fd.fk_facture = f.rowid ";
$sql .= " JOIN ".$this->db->prefix()."element_element el ON el.fk_target = f.rowid and el.targettype = 'facture' and sourcetype = 'commande'";
$sql .= " JOIN ".$this->db->prefix()."commande c ON el.fk_source = c.rowid ";
- $sql .= " WHERE c.fk_statut IN (".$this->db->sanitize($filtrestatut).") AND c.facture = 0 AND fd.fk_product = ".((int) $this->id);
+
+ if(!empty($conf->global->STOCK_CALCULATE_ON_BILL)){
+ $sql .= " WHERE c.fk_statut IN (".$this->db->sanitize($filtrestatut).") AND c.facture = 0 AND fd.fk_product = ".((int) $this->id);
+ }else if(!empty($conf->global->STOCK_CALCULATE_ON_CREDIT_BILL)){
+ $sql .= " WHERE c.fk_statut IN (".$this->db->sanitize($filtrestatut).") AND c.facture = 0 AND fd.fk_product = ".((int) $this->id)." AND f.type = ".Facture::TYPE_CREDIT_NOTE;
+ }
dol_syslog(__METHOD__.":: sql $sql", LOG_NOTICE);
$resql = $this->db->query($sql);
@@ -5514,11 +5519,16 @@ class Product extends CommonObject
// Stock decrease mode
if (!empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT) || !empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT_CLOSE)) {
$this->stock_theorique -= ($stock_commande_client - $stock_sending_client);
- } elseif (!empty($conf->global->STOCK_CALCULATE_ON_VALIDATE_ORDER)) {
+ //if(!empty($conf->global->STOCK_CALCULATE_ON_CREDIT_BILL)) { // this is wrong and doesn't work ($stock_commande_client is counted two times)
+ // $this->stock_theorique -= $stock_commande_client;
+ //}
+
+ }elseif (!empty($conf->global->STOCK_CALCULATE_ON_VALIDATE_ORDER)) {
$this->stock_theorique += 0;
- } elseif (!empty($conf->global->STOCK_CALCULATE_ON_BILL)) {
+ }elseif (!empty($conf->global->STOCK_CALCULATE_ON_BILL) || !empty($conf->global->STOCK_CALCULATE_ON_CREDIT_BILL)) {
$this->stock_theorique -= $stock_commande_client;
}
+
// Stock Increase mode
if (!empty($conf->global->STOCK_CALCULATE_ON_RECEPTION) || !empty($conf->global->STOCK_CALCULATE_ON_RECEPTION_CLOSE)) {
$this->stock_theorique += ($stock_commande_fournisseur - $stock_reception_fournisseur);
diff --git a/htdocs/product/inventory/inventory.php b/htdocs/product/inventory/inventory.php
index 4719fe00ce8..a841ac16d9b 100644
--- a/htdocs/product/inventory/inventory.php
+++ b/htdocs/product/inventory/inventory.php
@@ -335,6 +335,29 @@ if (empty($reshook)) {
include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php';*/
if (GETPOST('addline', 'alpha')) {
+
+ $sql = 'SELECT id.rowid, id.datec as date_creation, id.tms as date_modification, id.fk_inventory, id.fk_warehouse,';
+ $sql .= ' id.fk_product, id.batch, id.qty_stock, id.qty_view, id.qty_regulated';
+ $sql .= ' FROM '.MAIN_DB_PREFIX.'inventorydet as id';
+ $sql .= ' WHERE id.fk_inventory = '.((int) $object->id);
+ $sql .= ' AND id.fk_product = '.$fk_product;
+
+ $inventoryline = new InventoryLine($db);
+ $lineExists = $false;
+ $db->begin();
+ $resql = $db->query($sql);
+ if ($resql) {
+ $num = $db->num_rows($resql);
+ $i = 0;
+ if($num > 0){
+ $line = $db->fetch_object($resql);
+ if($inventoryline->fetch($line->rowid) > 0){
+ $lineExists = true;
+ //var_dump($inventoryline); die();
+ }
+ }
+ }
+
$qty= (GETPOST('qtytoadd') != '' ? price2num(GETPOST('qtytoadd', 'MS')) : null);
if ($fk_warehouse <= 0) {
$error++;
@@ -344,7 +367,7 @@ if (empty($reshook)) {
$error++;
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Product")), null, 'errors');
}
- if (price2num(GETPOST('qtytoadd'), 'MS') < 0) {
+ if (!$lineExists && price2num(GETPOST('qtytoadd'), 'MS') < 0) {
$error++;
setEventMessages($langs->trans("FieldCannotBeNegative", $langs->transnoentitiesnoconv("RealQty")), null, 'errors');
}
@@ -368,7 +391,7 @@ if (empty($reshook)) {
setEventMessages($langs->trans("ErrorProductDoesNotNeedBatchNumber", $tmpproduct->ref), null, 'errors');
}
}
- if (!$error) {
+ if (!$error && !$lineExists) {
$tmp = new InventoryLine($db);
$tmp->fk_inventory = $object->id;
$tmp->fk_warehouse = $fk_warehouse;
@@ -390,6 +413,31 @@ if (empty($reshook)) {
$_POST['batch'] = '';
$_POST['qtytoadd'] = '';
}
+ }else if(!$error){
+
+ if(($inventoryline->qty_view + ((int) $qty)) < 0){
+ $error++;
+ setEventMessages($langs->trans("FieldCannotBeNegative", $langs->transnoentitiesnoconv("RealQty")), null, 'errors');
+ }else{
+ $inventoryline->qty_view += ((int) $qty); // price2num
+ $inventoryline->update($user);
+ //var_dump($fk_product); die();
+
+ if ($result < 0) {
+ $langs->load("errors");
+ setEventMessages("Erreur inconnue lors de la mise à jour du champ", null, 'errors');
+ } else {
+ setEventMessages("Quantité ajoutée ou soustraite à la ligne existante", null);
+ // Clear var
+ $_POST['batch'] = '';
+ $_POST['qtytoadd'] = '';
+ }
+ }
+ }
+ if (! $error) {
+ $db->commit();
+ } else {
+ $db->rollback();
}
}
}
@@ -916,12 +964,17 @@ if ($object->id > 0) {
print ' | '.$langs->trans('PMPExpected').' | ';
print ''.$langs->trans('ExpectedValuation').' | ';
print ''.$form->textwithpicto($langs->trans("RealQty"), $langs->trans("InventoryRealQtyHelp")).' | ';
+ print ''.$langs->trans("Delta").' | ';
print ''.$langs->trans('PMPReal').' | ';
print ''.$langs->trans('RealValuation').' | ';
} else {
print '';
print $form->textwithpicto($langs->trans("RealQty"), $langs->trans("InventoryRealQtyHelp"));
print ' | ';
+
+ print '';
+ print $langs->trans("Delta");
+ print ' | ';
}
if ($object->status == $object::STATUS_DRAFT || $object->status == $object::STATUS_VALIDATED) {
// Actions or link to stock movement
@@ -968,6 +1021,7 @@ if ($object->id > 0) {
print '';
}
// Actions
+ print ' | ';
print '';
print '';
print ' | ';
@@ -983,7 +1037,6 @@ if ($object->id > 0) {
$cacheOfProducts = array();
$cacheOfWarehouses = array();
-
//$sql = '';
$resql = $db->query($sql);
if ($resql) {
@@ -1054,9 +1107,9 @@ if ($object->id > 0) {
print '';
print '';
- // Real quantity
if ($object->status == $object::STATUS_DRAFT || $object->status == $object::STATUS_VALIDATED) {
- $qty_view = GETPOST("id_".$obj->rowid) && price2num(GETPOST("id_".$obj->rowid), 'MS') >= 0 ? GETPOST("id_".$obj->rowid) : $obj->qty_view;
+ //$qty_view = GETPOST("id_".$obj->rowid) && price2num(GETPOST("id_".$obj->rowid), 'MS') >= 0 ? GETPOST("id_".$obj->rowid) : $obj->qty_view;
+ $qty_view = $obj->qty_view;
//if (!$hasinput && $qty_view !== null && $obj->qty_stock != $qty_view) {
if ($qty_view != '') {
@@ -1083,6 +1136,13 @@ if ($object->id > 0) {
print '';
print '';
+ // Delta quantity
+ $dt = $obj->qty_view - $obj->qty_stock;
+ print '';
+ if($dt != 0) print $dt;
+ print ' | ';
+
+
//PMP Real
print '';
@@ -1105,6 +1165,13 @@ if ($object->id > 0) {
print '';
print '';
print ' | ';
+
+ // Delta quantity
+ $dt = $obj->qty_view - $obj->qty_stock;
+ print '';
+ if($dt != 0) print $dt;
+ print ' | ';
+
}
// Picto delete line
@@ -1130,6 +1197,12 @@ if ($object->id > 0) {
print $obj->qty_view; // qty found
print '';
+ // Delta quantity
+ $dt = $obj->qty_view - $obj->qty_stock;
+ print '';
+ if($dt != 0) print $dt;
+ print ' | ';
+
//PMP Real
print '';
if (! empty($obj->pmp_real)) $pmp_real = $obj->pmp_real;
@@ -1148,7 +1221,14 @@ if ($object->id > 0) {
print ' | ';
print $obj->qty_view; // qty found
print ' | ';
+
+ // Delta quantity
+ $dt = $obj->qty_view - $obj->qty_stock;
+ print '';
+ if($dt != 0) print $dt;
+ print ' | ';
}
+ print '';
if ($obj->fk_movement > 0) {
$stockmovment = new MouvementStock($db);
$stockmovment->fetch($obj->fk_movement);
diff --git a/htdocs/product/stock/product.php b/htdocs/product/stock/product.php
index 6af0e105b47..f3b96715582 100644
--- a/htdocs/product/stock/product.php
+++ b/htdocs/product/stock/product.php
@@ -730,6 +730,7 @@ if ($id > 0 || $ref) {
$text_stock_options .= (!empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT) || !empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT_CLOSE) ? '- '.$langs->trans("DeStockOnShipment").' ' : '');
$text_stock_options .= (!empty($conf->global->STOCK_CALCULATE_ON_VALIDATE_ORDER) ? '- '.$langs->trans("DeStockOnValidateOrder").' ' : '');
$text_stock_options .= (!empty($conf->global->STOCK_CALCULATE_ON_BILL) ? '- '.$langs->trans("DeStockOnBill").' ' : '');
+ $text_stock_options .= (!empty($conf->global->STOCK_CALCULATE_ON_CREDIT_BILL) ? '- '.$langs->trans("DeStockOnCreditBill").' ' : '');
$text_stock_options .= (!empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_BILL) ? '- '.$langs->trans("ReStockOnBill").' ' : '');
$text_stock_options .= (!empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER) ? '- '.$langs->trans("ReStockOnValidateOrder").' ' : '');
$text_stock_options .= (!empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER) ? '- '.$langs->trans("ReStockOnDispatchOrder").' ' : '');
diff --git a/htdocs/product/stock/stockatdate.php b/htdocs/product/stock/stockatdate.php
index 0b7baf643ff..7a85397b014 100644
--- a/htdocs/product/stock/stockatdate.php
+++ b/htdocs/product/stock/stockatdate.php
@@ -242,14 +242,26 @@ $num = 0;
$title = $langs->trans('StockAtDate');
+if (!empty($conf->global->PRODUIT_MULTIPRICES) && !empty($conf->global->PRICE_LEVEL_FOR_WAREHOUSE_SELL_PRICE)){
+ $sqlmultiprice .= 'SELECT price FROM '.MAIN_DB_PREFIX.'product_price WHERE fk_product=p.rowid AND price_level='.$conf->global->PRICE_LEVEL_FOR_WAREHOUSE_SELL_PRICE.' ORDER BY date_price DESC LIMIT 1';
+}
+
+
$sql = 'SELECT p.rowid, p.ref, p.label, p.description, p.price,';
-$sql .= ' p.price_ttc, p.price_base_type, p.fk_product_type, p.desiredstock, p.seuil_stock_alerte,';
+$sql .= ' p.price_ttc, p.price_base_type, p.pmp, p.cost_price, p.fk_product_type, p.desiredstock, p.seuil_stock_alerte,';
$sql .= ' p.tms as datem, p.duration, p.tobuy, p.stock, ';
if ($fk_warehouse > 0) {
- $sql .= " SUM(p.pmp * ps.reel) as estimatedvalue, SUM(p.price * ps.reel) as sellvalue";
+ $sql .= " SUM(p.pmp * ps.reel) as estimatedvalue, SUM(p.cost_price * ps.reel) AS estimated_cost_price, SUM(p.price * ps.reel) as sellvalue";
$sql .= ', SUM(ps.reel) as stock_reel';
} else {
- $sql .= " SUM(p.pmp * p.stock) as estimatedvalue, SUM(p.price * p.stock) as sellvalue";
+ $sql .= " SUM(p.pmp * p.stock) as estimatedvalue, SUM(p.cost_price * p.stock) AS estimated_cost_price, SUM(p.price * p.stock) as sellvalue";
+}
+if (!empty($conf->global->PRODUIT_MULTIPRICES) && !empty($conf->global->PRICE_LEVEL_FOR_WAREHOUSE_SELL_PRICE)){
+ if ($fk_warehouse > 0) {
+ $sql .= ', ('.$sqlmultiprice.') AS multiprice, ('.$sqlmultiprice.') * ps.reel AS sellvalue_multiprice';
+ } else {
+ $sql .= ', ('.$sqlmultiprice.') AS multiprice, ('.$sqlmultiprice.') * p.stock AS sellvalue_multiprice';
+ }
}
// Add fields from hooks
$parameters = array();
@@ -462,6 +474,7 @@ if ($mode == 'future') {
} else {
print_liste_field_titre($stocklabel, $_SERVER["PHP_SELF"], '', $param, '', '', $sortfield, $sortorder, 'right ');
print_liste_field_titre("EstimatedStockValue", $_SERVER["PHP_SELF"], "estimatedvalue", '', $param, '', $sortfield, $sortorder, 'right ', $langs->trans("AtDate"), 1);
+ print_liste_field_titre("EstimatedStockCostPrice", $_SERVER["PHP_SELF"], "estimatedvalue", '', $param, '', $sortfield, $sortorder, 'right ', $langs->trans("AtDate"), 1);
print_liste_field_titre("EstimatedStockValueSell", $_SERVER["PHP_SELF"], "", '', $param, '', $sortfield, $sortorder, 'right ', $langs->trans("AtDate"), 1);
print_liste_field_titre('', $_SERVER["PHP_SELF"]);
print_liste_field_titre('CurrentStock', $_SERVER["PHP_SELF"], $fieldtosortcurrentstock, $param, '', '', $sortfield, $sortorder, 'right ');
@@ -478,6 +491,8 @@ print " |
\n";
$totalbuyingprice = 0;
$totalcurrentstock = 0;
$totalvirtualstock = 0;
+$totalcostprice = 0;
+$totalsellprice = 0;
$i = 0;
while ($i < ($limit ? min($num, $limit) : $num)) {
@@ -568,18 +583,41 @@ while ($i < ($limit ? min($num, $limit) : $num)) {
// PMP value
print '