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("DeStockOnCreditBill").''; +print ''; +if (!empty($conf->facture->enabled)) +{ + if ($conf->use_javascript_ajax) { + print ajax_constantonoff('STOCK_CALCULATE_ON_CREDIT_BILL'); + } else { + $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes")); + print $form->selectarray("STOCK_CALCULATE_ON_CREDIT_BILL", $arrval, $conf->global->STOCK_CALCULATE_ON_CREDIT_BILL); + } +} +else +{ + print $langs->trans("ModuleMustBeEnabledFirst", $langs->transnoentitiesnoconv("Module30Name")); +} +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 ''; - if (price2num($objp->estimatedvalue, 'MT')) { - print ''.price(price2num($objp->estimatedvalue, 'MT'), 1).''; + //if (price2num($objp->estimatedvalue, 'MT')) { + // print ''.price(price2num($objp->estimatedvalue, 'MT'), 1).''; + if (price2num($objp->pmp * $stock, 'MT')) { + print ''.price(price2num($objp->pmp * $stock, 'MT'), 1).''; } else { print ''; } - $totalbuyingprice += $objp->estimatedvalue; + //$totalbuyingprice += $objp->estimatedvalue; + $totalbuyingprice += $objp->pmp * $stock; print ''; + // buyprice value + print ''; + //if (price2num($objp->estimated_cost_price, 'MT')) { + // print price(price2num($objp->estimated_cost_price, 'MT'), 1); + if (price2num($objp->cost_price * $stock, 'MT')) { + print price(price2num($objp->cost_price * $stock, 'MT'), 1); + } else { + print ''; + } + //$totalcostprice += $objp->estimated_cost_price; + $totalcostprice += $objp->cost_price * $stock; + print ''; + + // Selling value print ''; if (empty($conf->global->PRODUIT_MULTIPRICES)) { print price(price2num($objp->sellvalue, 'MT'), 1); + $totalsellprice += $objp->sellvalue; + } else if (!empty($conf->global->PRICE_LEVEL_FOR_WAREHOUSE_SELL_PRICE)){ + //print price(price2num($objp->sellvalue_multiprice, 'MT'), 1); + //$totalsellprice += $objp->sellvalue_multiprice; + print price(price2num($objp->multiprice * $stock, 'MT'), 1); + $totalsellprice += $objp->multiprice * $stock; } else { $htmltext = $langs->trans("OptionMULTIPRICESIsOn"); print $form->textwithtooltip(''.$langs->trans("Variable").'', $htmltext); @@ -620,6 +658,8 @@ if ($mode == 'future') { $colspan++; } +print ''.$langs->trans("Totalforthispage").''; +print ''.price(price2num($totalbuyingprice, 'MT')).''.price(price2num($totalcostprice, 'MT')).''.price(price2num($totalsellprice, 'MT')).''; if (empty($date) || !$dateIsValid) { print ''.$langs->trans("EnterADateCriteria").''; diff --git a/htdocs/reception/list.php b/htdocs/reception/list.php index 5cdbb201d87..273b664452b 100644 --- a/htdocs/reception/list.php +++ b/htdocs/reception/list.php @@ -715,7 +715,7 @@ if ($massaction == 'createbills') { 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); print ' ('.$langs->trans("AutoValidationNotPossibleWhenStockIsDecreasedOnInvoiceValidation").')'; } else {