From 313838c7aba800297bb3658eaa5ca960ab2053e4 Mon Sep 17 00:00:00 2001 From: lainwir3d Date: Tue, 10 Aug 2021 14:48:23 +0400 Subject: [PATCH 01/15] Merge branch stock_decrease_on_credit_invoice --- htdocs/admin/stock.php | 20 ++++++++++++++++++ htdocs/commande/list.php | 2 +- htdocs/compta/facture/card.php | 15 ++++++++----- htdocs/compta/facture/class/facture.class.php | 21 ++++++++++++++++--- htdocs/core/actions_massactions.inc.php | 7 ++++++- htdocs/core/class/conf.class.php | 2 ++ htdocs/langs/en_US/stocks.lang | 1 + htdocs/langs/fr_FR/stocks.lang | 1 + htdocs/product/class/product.class.php | 18 ++++++++++++---- htdocs/product/stock/product.php | 1 + htdocs/reception/list.php | 2 +- 11 files changed, 75 insertions(+), 15 deletions(-) diff --git a/htdocs/admin/stock.php b/htdocs/admin/stock.php index e8f59727c07..79440475f36 100644 --- a/htdocs/admin/stock.php +++ b/htdocs/admin/stock.php @@ -222,6 +222,26 @@ if (!empty($conf->facture->enabled)) { 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 519e9c0e6a9..e0784217a0f 100644 --- a/htdocs/commande/list.php +++ b/htdocs/commande/list.php @@ -930,7 +930,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); print ' ('.$langs->trans("AutoValidationNotPossibleWhenStockIsDecreasedOnInvoiceValidation").')'; } else { diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index 943214ebff7..b9dc0ddd2e0 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -621,7 +621,7 @@ if (empty($reshook)) { } // 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); @@ -681,7 +681,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); @@ -3915,7 +3915,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); @@ -3988,7 +3993,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); @@ -4045,7 +4050,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 7164c4e547a..4447b3524cc 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -2348,7 +2348,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"); @@ -2822,7 +2827,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"); @@ -3116,7 +3126,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 703fd5d4771..48345942c77 100644 --- a/htdocs/core/actions_massactions.inc.php +++ b/htdocs/core/actions_massactions.inc.php @@ -1199,7 +1199,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 2b19e0db134..22a78c2abc3 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; $this->global->STOCK_CALCULATE_ON_SHIPMENT = 1; $this->global->STOCK_CALCULATE_ON_SHIPMENT_CLOSE = 0; diff --git a/htdocs/langs/en_US/stocks.lang b/htdocs/langs/en_US/stocks.lang index 0c412beed6e..6348e52a07a 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 a907598ff61..a4e8a8c7142 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 diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index d5dce55b2ba..05c9fc4dac9 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -2981,14 +2981,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 ".MAIN_DB_PREFIX."facturedet fd "; $sql .= " JOIN ".MAIN_DB_PREFIX."facture f ON fd.fk_facture = f.rowid "; $sql .= " JOIN ".MAIN_DB_PREFIX."element_element el ON el.fk_target = f.rowid and el.targettype = 'facture' and sourcetype = 'commande'"; $sql .= " JOIN ".MAIN_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); @@ -5391,11 +5396,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 not exclusive with STOCK_CALCULATE_ON_SHIPMENT(_CLOSE) + $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/stock/product.php b/htdocs/product/stock/product.php index f522e61bec2..b07660270d1 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/reception/list.php b/htdocs/reception/list.php index b83afc3f37d..eaa7a4ef212 100644 --- a/htdocs/reception/list.php +++ b/htdocs/reception/list.php @@ -679,7 +679,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 { From a720cd73abc9abe1b0947ca77b153757be0839a0 Mon Sep 17 00:00:00 2001 From: lainwir3d Date: Wed, 1 Sep 2021 16:37:40 +0400 Subject: [PATCH 02/15] [TEMPORARY] Document REST API: Disable ECM file listing for the moment. --- htdocs/api/class/api_documents.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/api/class/api_documents.class.php b/htdocs/api/class/api_documents.class.php index 44c3b1fcb52..fabc186d11e 100644 --- a/htdocs/api/class/api_documents.class.php +++ b/htdocs/api/class/api_documents.class.php @@ -503,7 +503,7 @@ class Documents extends DolibarrApi if ($result < 0) { throw new RestException(503, 'Error when retrieve ecm list : '.$this->db->lasterror()); } elseif (is_array($ecmfile->lines) && count($ecmfile->lines) > 0) { - $filearray['ecmfiles_infos'] = $ecmfile->lines; + //$filearray['ecmfiles_infos'] = $ecmfile->lines; } } } From aabc4e14feae32e2bb7caa76315780ebb9af2fde Mon Sep 17 00:00:00 2001 From: lainwir3d Date: Sun, 5 Sep 2021 15:03:21 +0400 Subject: [PATCH 03/15] Increase max memory to 512MB. --- htdocs/main.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index 1d09b9f9887..4699fc1b9f1 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; From 11e6ae6c1185a2bfad7000aa1969b367271490b4 Mon Sep 17 00:00:00 2001 From: lainwir3d Date: Mon, 6 Sep 2021 12:07:48 +0400 Subject: [PATCH 04/15] Oine external user login quick fix. --- htdocs/user/class/api_users.class.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/htdocs/user/class/api_users.class.php b/htdocs/user/class/api_users.class.php index 66d842c3564..f835c7d624f 100644 --- a/htdocs/user/class/api_users.class.php +++ b/htdocs/user/class/api_users.class.php @@ -152,7 +152,8 @@ class Users extends DolibarrApi */ public function get($id, $includepermissions = 0) { - if (empty(DolibarrApiAccess::$user->rights->user->user->lire) && empty(DolibarrApiAccess::$user->admin) && $id != 0 && DolibarrApiAccess::$user->id != $id) { + if (empty(DolibarrApiAccess::$user->rights->user->user->lire) && empty(DolibarrApiAccess::$user->admin) && + !(!empty(DolibarrApiAccess::$user->rights->user->self->creer) && (DolibarrApiAccess::$user->id == $id))) { throw new RestException(401, 'Not allowed'); } @@ -173,6 +174,7 @@ class Users extends DolibarrApi $this->useraccount->getRights(); } + $this->useraccount->societe_id = $this->useraccount->socid; return $this->_cleanObjectDatas($this->useraccount); } @@ -294,6 +296,8 @@ class Users extends DolibarrApi $this->useraccount->user_group_list = $this->_cleanUserGroupListDatas($userGroupList); + $this->useraccount->societe_id = $this->useraccount->socid; + //var_dump($this->useraccount); die(); return $this->_cleanObjectDatas($this->useraccount); } From dfafb3ccef527658545ba875df7bf7bbd08325f9 Mon Sep 17 00:00:00 2001 From: lainwir3d Date: Fri, 1 Apr 2022 18:48:47 +0400 Subject: [PATCH 05/15] CustomersInvoicesAndPayments export: add line buyprice --- htdocs/core/modules/modFacture.class.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/core/modules/modFacture.class.php b/htdocs/core/modules/modFacture.class.php index ef341c83e89..e55a69fc818 100644 --- a/htdocs/core/modules/modFacture.class.php +++ b/htdocs/core/modules/modFacture.class.php @@ -254,7 +254,7 @@ class modFacture extends DolibarrModules 'none.rest'=>'Rest', 'f.note_private'=>"NotePrivate", 'f.note_public'=>"NotePublic", 'f.fk_user_author'=>'CreatedById', 'uc.login'=>'CreatedByLogin', 'f.fk_user_valid'=>'ValidatedById', 'uv.login'=>'ValidatedByLogin', 'pj.ref'=>'ProjectRef', 'pj.title'=>'ProjectLabel', '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' @@ -277,7 +277,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.label'=>'Text', 'fd.description'=>"Text", 'fd.subprice'=>"Numeric", 'fd.tva_tx'=>"Numeric", + 'pj.ref'=>'Text', 'pj.title'=>'Text', 'fd.rowid'=>'Numeric', 'fd.label'=>'Text', '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' @@ -290,7 +290,7 @@ class modFacture extends DolibarrModules 's.rowid'=>"company", 's.nom'=>'company', 'ps.nom'=>'company', 's.code_client'=>'company', 's.address'=>'company', 's.zip'=>'company', 's.town'=>'company', 'c.code'=>'company', 'cd.nom'=>'company', 's.phone'=>'company', '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', 'pj.ref'=>'project', 'pj.title'=>'project', 'fd.rowid'=>'invoice_line', 'fd.label'=>"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' From 948f0c32b688377573f5693b14eb8467de7266c6 Mon Sep 17 00:00:00 2001 From: lainwir3d Date: Fri, 8 Apr 2022 16:09:37 +0400 Subject: [PATCH 06/15] Supplier order dispatch : retrieve line price from order when deleting dispatch line. This will allows custom cost price to be reverted back in triggers and such later. --- htdocs/fourn/commande/dispatch.php | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/htdocs/fourn/commande/dispatch.php b/htdocs/fourn/commande/dispatch.php index a1ddef959a0..44463fbb0a9 100644 --- a/htdocs/fourn/commande/dispatch.php +++ b/htdocs/fourn/commande/dispatch.php @@ -406,12 +406,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) { From 0120608e210eaa6cd9bf81cc3f21c05d684bd06c Mon Sep 17 00:00:00 2001 From: lainwir3d Date: Wed, 2 Mar 2022 16:39:03 +0400 Subject: [PATCH 07/15] Display delta quantity in inventories. --- htdocs/product/inventory/inventory.php | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/htdocs/product/inventory/inventory.php b/htdocs/product/inventory/inventory.php index 6a6d4c345ce..bd1863e8f8d 100644 --- a/htdocs/product/inventory/inventory.php +++ b/htdocs/product/inventory/inventory.php @@ -885,6 +885,11 @@ if ($object->id > 0) { 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 print ''; @@ -916,6 +921,7 @@ if ($object->id > 0) { print ''; print ''; // Actions + print ''; print ''; print ''; print ''; @@ -995,9 +1001,7 @@ if ($object->id > 0) { print ''; print ''; - // Real quantity if ($object->status == $object::STATUS_DRAFT || $object->status == $object::STATUS_VALIDATED) { - print ''; $qty_view = GETPOST("id_".$obj->rowid) && price2num(GETPOST("id_".$obj->rowid), 'MS') >= 0 ? GETPOST("id_".$obj->rowid) : $obj->qty_view; //if (!$hasinput && $qty_view !== null && $obj->qty_stock != $qty_view) { @@ -1005,12 +1009,20 @@ if ($object->id > 0) { $hasinput = true; } + // Real quantity + print ''; print ''; print img_picto('', 'eraser', 'class="opacitymedium"'); print ''; print ''; print ''; + // Delta quantity + $dt = $obj->qty_view - $obj->qty_stock; + print ''; + if($dt != 0) print $dt; + print ''; + // Picto delete line print ''; print ''.img_delete().''; @@ -1018,9 +1030,17 @@ if ($object->id > 0) { print ''; print ''; } else { + // Real quantity 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); From fdddd512d73fa8b462c7180d8e2f5deb17bf4830 Mon Sep 17 00:00:00 2001 From: lainwir3d Date: Thu, 28 Apr 2022 15:42:49 +0400 Subject: [PATCH 08/15] CLOSE #20736 Allow extrafields SQL filters on REST API product lookup --- htdocs/product/class/api_products.class.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/htdocs/product/class/api_products.class.php b/htdocs/product/class/api_products.class.php index 0f21b2aac3c..c55a5b6aba4 100644 --- a/htdocs/product/class/api_products.class.php +++ b/htdocs/product/class/api_products.class.php @@ -173,9 +173,10 @@ class Products extends DolibarrApi * @param int $variant_filter Use this param to filter list (0 = all, 1=products without variants, 2=parent of variants, 3=variants only) * @param bool $pagination_data If this parameter is set to true the response will include pagination data. Default value is false. Page starts from 0 * @param int $includestockdata Load also information about stock (slower) + * @param bool $allow_extrafields_sqlfilters Allow sqlfilters to contain extrafields filter (slower). * @return array Array of product objects */ - public function index($sortfield = "t.ref", $sortorder = 'ASC', $limit = 100, $page = 0, $mode = 0, $category = 0, $sqlfilters = '', $ids_only = false, $variant_filter = 0, $pagination_data = false, $includestockdata = 0) + public function index($sortfield = "t.ref", $sortorder = 'ASC', $limit = 100, $page = 0, $mode = 0, $category = 0, $sqlfilters = '', $ids_only = false, $variant_filter = 0, $pagination_data = false, $includestockdata = 0, $allow_extrafields_sqlfilters = false) { global $db, $conf; @@ -192,6 +193,11 @@ class Products extends DolibarrApi if ($category > 0) { $sql .= ", ".MAIN_DB_PREFIX."categorie_product as c"; } + + if ($allow_extrafields_sqlfilters) { + $sql .= " LEFT JOIN llx_product_extrafields AS ef ON ef.fk_object = t.rowid"; + } + $sql .= ' WHERE t.entity IN ('.getEntity('product').')'; if ($variant_filter == 1) { From fb4a1782661d43775f45350f44a1c935464f5d53 Mon Sep 17 00:00:00 2001 From: lainwir3d Date: Thu, 28 Apr 2022 22:56:44 +0400 Subject: [PATCH 09/15] Fix typo and switch to old join style. --- htdocs/product/class/api_products.class.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/htdocs/product/class/api_products.class.php b/htdocs/product/class/api_products.class.php index c55a5b6aba4..5d6cb5ef31c 100644 --- a/htdocs/product/class/api_products.class.php +++ b/htdocs/product/class/api_products.class.php @@ -195,7 +195,7 @@ class Products extends DolibarrApi } if ($allow_extrafields_sqlfilters) { - $sql .= " LEFT JOIN llx_product_extrafields AS ef ON ef.fk_object = t.rowid"; + $sql .= ", ".MAIN_DB_PREFIX."product_extrafields AS ef"; } $sql .= ' WHERE t.entity IN ('.getEntity('product').')'; @@ -223,6 +223,11 @@ class Products extends DolibarrApi // Show only services $sql .= " AND t.fk_product_type = 1"; } + + if ($allow_extrafields_sqlfilters) { + $sql .= " AND ef.fk_object = t.rowid"; + } + // Add sql filters if ($sqlfilters) { $errormessage = ''; From 906eb02076a4609eba2f4114c26cf7585776551e Mon Sep 17 00:00:00 2001 From: lainwir3d Date: Sat, 30 Apr 2022 13:24:44 +0400 Subject: [PATCH 10/15] Product REST API: Always JOIN extrafields table. --- htdocs/product/class/api_products.class.php | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/htdocs/product/class/api_products.class.php b/htdocs/product/class/api_products.class.php index 5d6cb5ef31c..45ba2e61afd 100644 --- a/htdocs/product/class/api_products.class.php +++ b/htdocs/product/class/api_products.class.php @@ -173,10 +173,9 @@ class Products extends DolibarrApi * @param int $variant_filter Use this param to filter list (0 = all, 1=products without variants, 2=parent of variants, 3=variants only) * @param bool $pagination_data If this parameter is set to true the response will include pagination data. Default value is false. Page starts from 0 * @param int $includestockdata Load also information about stock (slower) - * @param bool $allow_extrafields_sqlfilters Allow sqlfilters to contain extrafields filter (slower). * @return array Array of product objects */ - public function index($sortfield = "t.ref", $sortorder = 'ASC', $limit = 100, $page = 0, $mode = 0, $category = 0, $sqlfilters = '', $ids_only = false, $variant_filter = 0, $pagination_data = false, $includestockdata = 0, $allow_extrafields_sqlfilters = false) + public function index($sortfield = "t.ref", $sortorder = 'ASC', $limit = 100, $page = 0, $mode = 0, $category = 0, $sqlfilters = '', $ids_only = false, $variant_filter = 0, $pagination_data = false, $includestockdata = 0) { global $db, $conf; @@ -194,9 +193,7 @@ class Products extends DolibarrApi $sql .= ", ".MAIN_DB_PREFIX."categorie_product as c"; } - if ($allow_extrafields_sqlfilters) { - $sql .= ", ".MAIN_DB_PREFIX."product_extrafields AS ef"; - } + $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product_extrafields AS ef ON (ef.fk_object = t.rowid)"; $sql .= ' WHERE t.entity IN ('.getEntity('product').')'; @@ -224,10 +221,6 @@ class Products extends DolibarrApi $sql .= " AND t.fk_product_type = 1"; } - if ($allow_extrafields_sqlfilters) { - $sql .= " AND ef.fk_object = t.rowid"; - } - // Add sql filters if ($sqlfilters) { $errormessage = ''; From 3a50976a4e9bef859169d27f8a49421846c1257b Mon Sep 17 00:00:00 2001 From: lainwir3d Date: Sat, 30 Apr 2022 15:59:22 +0400 Subject: [PATCH 11/15] Revert "Oine external user login quick fix." This reverts commit 37f7c86b3cdb873d1e369ab86f8e83a23dba886e. --- htdocs/user/class/api_users.class.php | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/htdocs/user/class/api_users.class.php b/htdocs/user/class/api_users.class.php index f835c7d624f..66d842c3564 100644 --- a/htdocs/user/class/api_users.class.php +++ b/htdocs/user/class/api_users.class.php @@ -152,8 +152,7 @@ class Users extends DolibarrApi */ public function get($id, $includepermissions = 0) { - if (empty(DolibarrApiAccess::$user->rights->user->user->lire) && empty(DolibarrApiAccess::$user->admin) && - !(!empty(DolibarrApiAccess::$user->rights->user->self->creer) && (DolibarrApiAccess::$user->id == $id))) { + if (empty(DolibarrApiAccess::$user->rights->user->user->lire) && empty(DolibarrApiAccess::$user->admin) && $id != 0 && DolibarrApiAccess::$user->id != $id) { throw new RestException(401, 'Not allowed'); } @@ -174,7 +173,6 @@ class Users extends DolibarrApi $this->useraccount->getRights(); } - $this->useraccount->societe_id = $this->useraccount->socid; return $this->_cleanObjectDatas($this->useraccount); } @@ -296,8 +294,6 @@ class Users extends DolibarrApi $this->useraccount->user_group_list = $this->_cleanUserGroupListDatas($userGroupList); - $this->useraccount->societe_id = $this->useraccount->socid; - //var_dump($this->useraccount); die(); return $this->_cleanObjectDatas($this->useraccount); } From 40f0bb1b94603eb97cb65810e397fe93d3a7f73d Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 1 May 2022 12:23:02 +0200 Subject: [PATCH 12/15] Update api_products.class.php --- htdocs/product/class/api_products.class.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/htdocs/product/class/api_products.class.php b/htdocs/product/class/api_products.class.php index 45ba2e61afd..4108ed79075 100644 --- a/htdocs/product/class/api_products.class.php +++ b/htdocs/product/class/api_products.class.php @@ -188,13 +188,11 @@ class Products extends DolibarrApi $socid = DolibarrApiAccess::$user->socid ? DolibarrApiAccess::$user->socid : ''; $sql = "SELECT t.rowid, t.ref, t.ref_ext"; - $sql .= " FROM ".MAIN_DB_PREFIX."product as t"; + $sql .= " FROM ".$this->db->prefix()."product as t"; + $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product_extrafields AS ef ON ef.fk_object = t.rowid"; // So we will be able to filter on extrafields if ($category > 0) { $sql .= ", ".MAIN_DB_PREFIX."categorie_product as c"; } - - $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product_extrafields AS ef ON (ef.fk_object = t.rowid)"; - $sql .= ' WHERE t.entity IN ('.getEntity('product').')'; if ($variant_filter == 1) { From 9e45c9ababbb58d9d0c5bce2c812fc1cfcc44c25 Mon Sep 17 00:00:00 2001 From: lainwir3d Date: Wed, 5 Oct 2022 00:54:50 +0400 Subject: [PATCH 13/15] =?UTF-8?q?Stock=20=C3=A0=20date:=20fix=20computing?= =?UTF-8?q?=20of=20different=20values.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- htdocs/langs/fr_FR/stocks.lang | 1 + htdocs/product/stock/stockatdate.php | 52 ++++++++++++++++++++++++---- 2 files changed, 46 insertions(+), 7 deletions(-) diff --git a/htdocs/langs/fr_FR/stocks.lang b/htdocs/langs/fr_FR/stocks.lang index a4e8a8c7142..8e9ff7de452 100644 --- a/htdocs/langs/fr_FR/stocks.lang +++ b/htdocs/langs/fr_FR/stocks.lang @@ -113,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/product/stock/stockatdate.php b/htdocs/product/stock/stockatdate.php index 340fd7dc0df..28e2281e145 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 '); @@ -476,6 +489,8 @@ print $hookmanager->resPrint; print "\n"; $totalbuyingprice = 0; +$totalcostprice = 0; +$totalsellprice = 0; $i = 0; while ($i < ($limit ? min($num, $limit) : $num)) { @@ -564,18 +579,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); @@ -616,7 +654,7 @@ if ($mode == 'future') { } print ''.$langs->trans("Totalforthispage").''; -print ''.price(price2num($totalbuyingprice, 'MT')).''; +print ''.price(price2num($totalbuyingprice, 'MT')).''.price(price2num($totalcostprice, 'MT')).''.price(price2num($totalsellprice, 'MT')).''; if (empty($date) || !$dateIsValid) { print ''.$langs->trans("EnterADateCriteria").''; From 46a420dbd914fbd31a0bd753c9d990bc024f073c Mon Sep 17 00:00:00 2001 From: lainwir3d Date: Thu, 20 Oct 2022 16:17:13 +0400 Subject: [PATCH 14/15] Inventory - adding same product multiple time will increase / decrease qty --- htdocs/product/inventory/inventory.php | 56 ++++++++++++++++++++++++-- 1 file changed, 52 insertions(+), 4 deletions(-) diff --git a/htdocs/product/inventory/inventory.php b/htdocs/product/inventory/inventory.php index b801c064af0..f8f827b0bc2 100644 --- a/htdocs/product/inventory/inventory.php +++ b/htdocs/product/inventory/inventory.php @@ -308,6 +308,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++; @@ -317,7 +340,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'); } @@ -341,7 +364,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; @@ -363,6 +386,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(); } } } @@ -937,7 +985,6 @@ if ($object->id > 0) { $cacheOfProducts = array(); $cacheOfWarehouses = array(); - //$sql = ''; $resql = $db->query($sql); if ($resql) { @@ -1003,7 +1050,8 @@ if ($object->id > 0) { print ''; 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 != '') { From 1c8263f5b4687d90e824409a6a3b55546744ab12 Mon Sep 17 00:00:00 2001 From: lainwir3d Date: Mon, 5 Dec 2022 13:53:51 +0400 Subject: [PATCH 15/15] Virtual stock calculation: do not take into account credit bills --- htdocs/product/class/product.class.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index 05c9fc4dac9..49d316a45d1 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -5396,9 +5396,9 @@ 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); - if(!empty($conf->global->STOCK_CALCULATE_ON_CREDIT_BILL)) { // this is not exclusive with STOCK_CALCULATE_ON_SHIPMENT(_CLOSE) - $this->stock_theorique -= $stock_commande_client; - } + //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;