diff --git a/htdocs/admin/stock.php b/htdocs/admin/stock.php
index a4a9e91e3ff..75b665e0fda 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("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 56e66b9f759..840eee97ead 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);
@@ -3904,7 +3904,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);
@@ -3977,7 +3982,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);
@@ -4019,7 +4024,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 a28838756d9..67c3f6a040d 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 14685783564..c804e05e0ee 100644
--- a/htdocs/core/lib/functions.lib.php
+++ b/htdocs/core/lib/functions.lib.php
@@ -6892,6 +6892,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__';
@@ -6972,6 +6973,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);
@@ -7215,6 +7217,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 3c4c33628c4..f1bfe186bdf 100644
--- a/htdocs/langs/en_US/stocks.lang
+++ b/htdocs/langs/en_US/stocks.lang
@@ -75,6 +75,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 f0fe7235a77..68003ebe864 100644
--- a/htdocs/langs/fr_FR/stocks.lang
+++ b/htdocs/langs/fr_FR/stocks.lang
@@ -75,6 +75,7 @@ OrderDispatch=Réceptions
RuleForStockManagementDecrease=Règle de gestion des décrémentations automatiques de stock (la décrémentation manuelle est toujours possible, même si une décrémentation automatique est activée)
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
+DeStockOnCreditBill=Décrémenter (incrémenter) les stocks physiques sur validation des avoirs (uniquement) clients
DeStockOnValidateOrder=Décrémenterr les stocks physiques sur validation des commandes clients
DeStockOnShipment=Décrémenter les stocks physiques sur validation des expéditions
DeStockOnShipmentOnClosing=Décrémente les stocks physiques au classement "clôturée" de l'expédition
diff --git a/htdocs/langs/fr_FR/workflow.lang b/htdocs/langs/fr_FR/workflow.lang
index 2af480afa83..13fbbace793 100644
--- a/htdocs/langs/fr_FR/workflow.lang
+++ b/htdocs/langs/fr_FR/workflow.lang
@@ -13,6 +13,7 @@ descWORKFLOW_INVOICE_CLASSIFY_BILLED_PROPAL=Classer la/les proposition(s) commer
descWORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_ORDER=Classer la/les commande(s) client(s) source(s) facturée(s) à la validation de la facture client (et si le montant de la facture est le même que le montant total des commandes liées)
descWORKFLOW_INVOICE_CLASSIFY_BILLED_ORDER=Classer la/les commande(s) client(s) source(s) à Facturée quand une facture client est passée à Payé (et si le montant de la facture est identique à la somme des commandes sources)
descWORKFLOW_ORDER_CLASSIFY_SHIPPED_SHIPPING=Classer la commande source à expédiée à la validation d'une expédition (et si les quantités expédiées dans le bon d'expédition sont les même que dans la commande mise à jour)
+descWORKFLOW_ORDER_CLASSIFY_SHIPPED_SHIPPING_CLOSED=Classer la commande source à expédiée à la cloture d'une expédition (et si les quantités expédiées dans le bon d'expédition sont les même que dans la commande mise à jour)
# Autoclassify purchase order
descWORKFLOW_ORDER_CLASSIFY_BILLED_SUPPLIER_PROPOSAL=Classer la ou les proposition(s) commerciale(s) fournisseur sources facturées quand une facture fournisseur est validée (et si le montant de la facture est le même que le total des propositions sources liées)
descWORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_SUPPLIER_ORDER=Classer la ou les commande(s) fournisseur(s) de source(s) à facturée(s) lorsque la facture fournisseur est validée (et si le montant de la facture est le même que le montant total des commandes liées)
diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php
index 07ab0949a10..f1ea6352c38 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 8622e293906..1f7656507e0 100644
--- a/htdocs/user/card.php
+++ b/htdocs/user/card.php
@@ -1786,7 +1786,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 '