diff --git a/htdocs/admin/stock.php b/htdocs/admin/stock.php index e1fc7fc1d3a..fccf6d2f9df 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/admin/workflow.php b/htdocs/admin/workflow.php index 09156e08588..1b6fa5bebe7 100644 --- a/htdocs/admin/workflow.php +++ b/htdocs/admin/workflow.php @@ -91,15 +91,21 @@ $workflowcodes = array( ), // Automatic classification of order - 'WORKFLOW_ORDER_CLASSIFY_SHIPPED_SHIPPING'=>array( + 'WORKFLOW_ORDER_CLASSIFY_SHIPPED_SHIPPING'=>array( // when shipping validated 'family'=>'classify_order', 'position'=>40, 'enabled'=>(!empty($conf->expedition->enabled) && !empty($conf->commande->enabled)), 'picto'=>'order' ), - 'WORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_ORDER'=>array( + 'WORKFLOW_ORDER_CLASSIFY_SHIPPED_SHIPPING_CLOSED'=>array( // when shipping closed 'family'=>'classify_order', 'position'=>41, + 'enabled'=>(!empty($conf->expedition->enabled) && !empty($conf->commande->enabled)), + 'picto'=>'order' + ), + 'WORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_ORDER'=>array( + 'family'=>'classify_order', + 'position'=>42, 'enabled'=>(!empty($conf->facture->enabled) && !empty($conf->commande->enabled)), 'picto'=>'order', 'warning'=>'' diff --git a/htdocs/api/class/api_documents.class.php b/htdocs/api/class/api_documents.class.php index 3b6e89c6643..df0feb98a3f 100644 --- a/htdocs/api/class/api_documents.class.php +++ b/htdocs/api/class/api_documents.class.php @@ -473,7 +473,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; } } } diff --git a/htdocs/commande/list.php b/htdocs/commande/list.php index e2ea9b2222c..bb1bb6ab1a6 100644 --- a/htdocs/commande/list.php +++ b/htdocs/commande/list.php @@ -912,7 +912,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 e01d71a1020..3cd33d36314 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -637,7 +637,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); @@ -697,7 +697,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); @@ -3914,7 +3914,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); @@ -3987,7 +3992,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); @@ -4029,7 +4034,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 f8f246924e3..4a7550d0ef8 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -2300,7 +2300,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"); @@ -2735,7 +2740,12 @@ class Facture extends CommonInvoice $result = $this->thirdparty->set_as_client(); // Si active on decremente le produit principal et ses composants a la validation de facture - 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"); @@ -3028,7 +3038,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 c2538421bfe..3eb60db9e15 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/ajax/security.php b/htdocs/core/ajax/security.php index 066e5b7812d..0056120c6bd 100644 --- a/htdocs/core/ajax/security.php +++ b/htdocs/core/ajax/security.php @@ -53,7 +53,7 @@ top_httphead(); // Registering the location of boxes if (isset($_GET['action']) && !empty($_GET['action'])) { - if ($_GET['action'] == 'getrandompassword' && $user->admin) { + if ($_GET['action'] == 'getrandompassword' && ($user->admin || $user->rights->api->apikey->generate)) { require_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php'; $generic = $_GET['generic'] ? true : false; echo getRandomPassword($generic); diff --git a/htdocs/core/class/conf.class.php b/htdocs/core/class/conf.class.php index 60ee78bbff5..20d52ce043e 100644 --- a/htdocs/core/class/conf.class.php +++ b/htdocs/core/class/conf.class.php @@ -531,6 +531,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/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 869aa2343bc..8ec912f1026 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -6898,6 +6898,7 @@ function getCommonSubstitutionArray($outputlangs, $onlykey = 0, $exclude = null, if ($onlykey) { $substitutionarray['__ID__'] = '__ID__'; $substitutionarray['__REF__'] = '__REF__'; + $substitutionarray['__NEWREF__'] = '__NEWREF__'; $substitutionarray['__REF_CLIENT__'] = '__REF_CLIENT__'; $substitutionarray['__REF_SUPPLIER__'] = '__REF_SUPPLIER__'; $substitutionarray['__NOTE_PUBLIC__'] = '__NOTE_PUBLIC__'; @@ -6978,6 +6979,7 @@ function getCommonSubstitutionArray($outputlangs, $onlykey = 0, $exclude = null, } else { $substitutionarray['__ID__'] = $object->id; $substitutionarray['__REF__'] = $object->ref; + $substitutionarray['__NEWREF__'] = $object->newref; $substitutionarray['__REF_CLIENT__'] = (isset($object->ref_client) ? $object->ref_client : (isset($object->ref_customer) ? $object->ref_customer : null)); $substitutionarray['__REF_SUPPLIER__'] = (isset($object->ref_supplier) ? $object->ref_supplier : null); $substitutionarray['__NOTE_PUBLIC__'] = (isset($object->note_public) ? $object->note_public : null); @@ -7221,6 +7223,10 @@ function getCommonSubstitutionArray($outputlangs, $onlykey = 0, $exclude = null, if (is_object($object) && $object->element == 'supplier_proposal') { $substitutionarray['__URL_SUPPLIER_PROPOSAL__'] = DOL_MAIN_URL_ROOT."/supplier_proposal/card.php?id=".$object->id; } + if (is_object($object) && $object->element == 'shipping') { + $substitutionarray['__URL_SHIPMENT__'] = DOL_MAIN_URL_ROOT."/expedition/card.php?id=".$object->id; + } + } if (is_object($object) && $object->element == 'action') { diff --git a/htdocs/core/modules/modApi.class.php b/htdocs/core/modules/modApi.class.php index bf7fc2777ae..96fb2b955ff 100644 --- a/htdocs/core/modules/modApi.class.php +++ b/htdocs/core/modules/modApi.class.php @@ -134,16 +134,18 @@ class modApi extends DolibarrModules // Permissions $this->rights = array(); // Permission array used by this module + $this->rights_admin_allowed = 1; // Admin is always granted of permission (even when module is disabled) + $r = 0; // Add here list of permission defined by an id, a label, a boolean and two constant strings. // Example: - // $this->rights[$r][0] = $this->numero + $r; // Permission id (must not be already used) - // $this->rights[$r][1] = 'Permision label'; // Permission label - // $this->rights[$r][3] = 0; // Permission by default for new user (0/1) - // $this->rights[$r][4] = 'level1'; // In php code, permission will be checked by test if ($user->rights->permkey->level1->level2) - // $this->rights[$r][5] = 'level2'; // In php code, permission will be checked by test if ($user->rights->permkey->level1->level2) - // $r++; + $this->rights[$r][0] = $this->numero + $r; // Permission id (must not be already used) + $this->rights[$r][1] = 'Générer / modifier la clé API des utilisateurs'; // Permission label + $this->rights[$r][3] = 0; // Permission by default for new user (0/1) + $this->rights[$r][4] = 'apikey'; // In php code, permission will be checked by test if ($user->rights->permkey->level1->level2) + $this->rights[$r][5] = 'generate'; // In php code, permission will be checked by test if ($user->rights->permkey->level1->level2) + $r++; // Main menu entries diff --git a/htdocs/core/modules/modWorkflow.class.php b/htdocs/core/modules/modWorkflow.class.php index fbf7927ed1c..eaaf15d40a1 100644 --- a/htdocs/core/modules/modWorkflow.class.php +++ b/htdocs/core/modules/modWorkflow.class.php @@ -87,6 +87,7 @@ class modWorkflow extends DolibarrModules 0=>array('WORKFLOW_ORDER_CLASSIFY_BILLED_PROPAL', 'chaine', '1', 'WORKFLOW_ORDER_CLASSIFY_BILLED_PROPAL', 0, 'current', 0), 1=>array('WORKFLOW_INVOICE_CLASSIFY_BILLED_PROPAL', 'chaine', '1', 'WORKFLOW_INVOICE_CLASSIFY_BILLED_PROPAL', 0, 'current', 0), 2=>array('WORKFLOW_ORDER_CLASSIFY_SHIPPED_SHIPPING', 'chaine', '1', 'WORKFLOW_ORDER_CLASSIFY_SHIPPED_SHIPPING', 0, 'current', 0), + 3=>array('WORKFLOW_ORDER_CLASSIFY_SHIPPED_SHIPPING_CLOSED', 'chaine', '1', 'WORKFLOW_ORDER_CLASSIFY_SHIPPED_SHIPPING_CLOSED', 0, 'current', 0), 4=>array('WORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_ORDER', 'chaine', '1', 'WORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_ORDER', 0, 'current', 0), 5=>array('WORKFLOW_ORDER_CLASSIFY_BILLED_SUPPLIER_PROPOSAL', 'chaine', '1', 'WORKFLOW_ORDER_CLASSIFY_BILLED_SUPPLIER_PROPOSAL', 0, 'current', 0), 6=>array('WORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_SUPPLIER_ORDER', 'chaine', '1', 'WORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_SUPPLIER_ORDER', 0, 'current', 0), diff --git a/htdocs/core/triggers/interface_20_modWorkflow_WorkflowManager.class.php b/htdocs/core/triggers/interface_20_modWorkflow_WorkflowManager.class.php index 0ea378672c1..42be57e7193 100644 --- a/htdocs/core/triggers/interface_20_modWorkflow_WorkflowManager.class.php +++ b/htdocs/core/triggers/interface_20_modWorkflow_WorkflowManager.class.php @@ -285,10 +285,15 @@ class InterfaceWorkflowManager extends DolibarrTriggers } } - if ($action == 'SHIPPING_VALIDATE') { + if (($action == 'SHIPPING_VALIDATE') || ($action == 'SHIPPING_CLOSED')) { dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - if (!empty($conf->commande->enabled) && !empty($conf->expedition->enabled) && !empty($conf->workflow->enabled) && !empty($conf->global->WORKFLOW_ORDER_CLASSIFY_SHIPPED_SHIPPING)) { + if (!empty($conf->commande->enabled) && !empty($conf->expedition->enabled) && !empty($conf->workflow->enabled) && + ( + (!empty($conf->global->WORKFLOW_ORDER_CLASSIFY_SHIPPED_SHIPPING) && ($action == 'SHIPPING_VALIDATE')) || + (!empty($conf->global->WORKFLOW_ORDER_CLASSIFY_SHIPPED_SHIPPING_CLOSED) && ($action == 'SHIPPING_CLOSED')) + ) + ) { $qtyshipped = array(); $qtyordred = array(); require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php'; @@ -348,6 +353,30 @@ class InterfaceWorkflowManager extends DolibarrTriggers } } + // classify billed reception + if ($action == 'BILL_SUPPLIER_VALIDATE') { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id, LOG_DEBUG); + + if (!empty($conf->reception->enabled) && !empty($conf->global->WORKFLOW_BILL_ON_RECEPTION)) { + $object->fetchObjectLinked('', 'reception', $object->id, $object->element); + if (!empty($object->linkedObjects)) { + $totalonlinkedelements = 0; + foreach ($object->linkedObjects['reception'] as $element) { + if ($element->statut == Reception::STATUS_VALIDATED) { + $totalonlinkedelements += $element->total_ht; + } + } + dol_syslog("Amount of linked proposals = ".$totalonlinkedelements.", of invoice = ".$object->total_ht.", egality is ".($totalonlinkedelements == $object->total_ht), LOG_DEBUG); + if ($totalonlinkedelements == $object->total_ht) { + foreach ($object->linkedObjects['reception'] as $element) { + $ret = $element->setBilled(); + } + } + } + return $ret; + } + } + return 0; } diff --git a/htdocs/expedition/class/api_shipments.class.php b/htdocs/expedition/class/api_shipments.class.php index 2a4b6765b4e..3b4070b138b 100644 --- a/htdocs/expedition/class/api_shipments.class.php +++ b/htdocs/expedition/class/api_shipments.class.php @@ -626,6 +626,53 @@ class Shipments extends DolibarrApi } */ + /** + * Close a shipment (Classify it as "Delivered") + * + * @param int $id Expedition ID + * @param int $notrigger Disabled triggers + * + * @url POST {id}/close + * + * @return int + */ + public function close($id, $notrigger = 0) + { + if (!DolibarrApiAccess::$user->rights->expedition->creer) { + throw new RestException(401); + } + + $result = $this->shipment->fetch($id); + if (!$result) { + throw new RestException(404, 'Shipment not found'); + } + + if (!DolibarrApi::_checkAccessToResource('expedition', $this->commande->id)) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + + $result = $this->shipment->setClosed(); + if ($result == 0) { + throw new RestException(304, 'Error nothing done. May be object is already closed'); + } + if ($result < 0) { + throw new RestException(500, 'Error when closing Order: '.$this->commande->error); + } + + $result = $this->shipment->fetch($id); + if (!$result) { + throw new RestException(404, 'Shipment not found'); + } + + if (!DolibarrApi::_checkAccessToResource('expedition', $this->commande->id)) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + + $this->shipment->fetchObjectLinked(); + + return $this->_cleanObjectDatas($this->shipment); + } + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore /** * Clean sensible object datas diff --git a/htdocs/langs/en_US/stocks.lang b/htdocs/langs/en_US/stocks.lang index 16917384460..707b94e151d 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/en_US/workflow.lang b/htdocs/langs/en_US/workflow.lang index 15fd8ef07c2..fafbc6e8d8a 100644 --- a/htdocs/langs/en_US/workflow.lang +++ b/htdocs/langs/en_US/workflow.lang @@ -13,6 +13,7 @@ descWORKFLOW_INVOICE_CLASSIFY_BILLED_PROPAL=Classify linked source proposal as b descWORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_ORDER=Classify linked source sales order as billed when customer invoice is validated (and if the amount of the invoice is the same as the total amount of the linked order) descWORKFLOW_INVOICE_CLASSIFY_BILLED_ORDER=Classify linked source sales order as billed when customer invoice is set to paid (and if the amount of the invoice is the same as the total amount of the linked order) descWORKFLOW_ORDER_CLASSIFY_SHIPPED_SHIPPING=Classify linked source sales order as shipped when a shipment is validated (and if the quantity shipped by all shipments is the same as in the order to update) +descWORKFLOW_ORDER_CLASSIFY_SHIPPED_SHIPPING_CLOSED=Classify linked source sales order as shipped when a shipment is closed (and if the quantity shipped by all shipments is the same as in the order to update) # Autoclassify purchase order descWORKFLOW_ORDER_CLASSIFY_BILLED_SUPPLIER_PROPOSAL=Classify linked source vendor proposal as billed when vendor invoice is validated (and if the amount of the invoice is the same as the total amount of the linked proposal) descWORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_SUPPLIER_ORDER=Classify linked source purchase order as billed when vendor invoice is validated (and if the amount of the invoice is the same as the total amount of the linked order) diff --git a/htdocs/langs/fr_FR/stocks.lang b/htdocs/langs/fr_FR/stocks.lang index 27feec29992..9f1d2bfce97 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/main.inc.php b/htdocs/main.inc.php index 9753f4b3d83..c6115062f3a 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 55c48be5088..3029f439267 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -2948,14 +2948,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); @@ -5305,11 +5310,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 0e4cf4b6a20..6134f402371 100644 --- a/htdocs/product/stock/product.php +++ b/htdocs/product/stock/product.php @@ -724,6 +724,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 2d6600dcc45..9903bbf6689 100644 --- a/htdocs/reception/list.php +++ b/htdocs/reception/list.php @@ -675,7 +675,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 { diff --git a/htdocs/user/card.php b/htdocs/user/card.php index 68218ab16bd..f3e43bc02a9 100644 --- a/htdocs/user/card.php +++ b/htdocs/user/card.php @@ -1782,7 +1782,7 @@ if ($action == 'create' || $action == 'adduserldap') { print ''."\n"; // API key - if (!empty($conf->api->enabled) && ($user->id == $id || $user->admin)) { + if (!empty($conf->api->enabled) && ($user->id == $id || $user->admin || $user->rights->api->apikey->generate)) { print ''.$langs->trans("ApiKey").''; print ''; if (!empty($object->api_key)) { @@ -2305,7 +2305,7 @@ if ($action == 'create' || $action == 'adduserldap') { print "\n"; // API key - if (!empty($conf->api->enabled) && ($user->id == $id || $user->admin)) { + if (!empty($conf->api->enabled) && ($user->id == $id || $user->admin || $user->rights->api->apikey->generate)) { print ''.$langs->trans("ApiKey").''; print ''; print ''; diff --git a/htdocs/user/class/api_users.class.php b/htdocs/user/class/api_users.class.php index e0cbd849092..914bdcae386 100644 --- a/htdocs/user/class/api_users.class.php +++ b/htdocs/user/class/api_users.class.php @@ -151,7 +151,8 @@ class Users extends DolibarrApi */ public function get($id, $includepermissions = 0) { - if (empty(DolibarrApiAccess::$user->rights->user->user->lire) && empty(DolibarrApiAccess::$user->admin)) { + 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'); } @@ -172,6 +173,7 @@ class Users extends DolibarrApi $this->useraccount->getRights(); } + $this->useraccount->societe_id = $this->useraccount->socid; return $this->_cleanObjectDatas($this->useraccount); } @@ -256,7 +258,7 @@ class Users extends DolibarrApi */ public function getInfo($includepermissions = 0) { - if (empty(DolibarrApiAccess::$user->rights->user->user->lire) && empty(DolibarrApiAccess::$user->admin)) { + if(empty(DolibarrApiAccess::$user->rights->user->self->creer) && empty(DolibarrApiAccess::$user->rights->user->user->lire) && empty(DolibarrApiAccess::$user->admin)) { throw new RestException(401, 'Not allowed'); } @@ -283,6 +285,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); }