diff --git a/htdocs/admin/stock.php b/htdocs/admin/stock.php
index 4e9957fe48d..d0554f2d3c8 100644
--- a/htdocs/admin/stock.php
+++ b/htdocs/admin/stock.php
@@ -49,6 +49,10 @@ if($action)
{
$res = dolibarr_set_const($db, "STOCK_USERSTOCK_AUTOCREATE", GETPOST('STOCK_USERSTOCK_AUTOCREATE','alpha'),'chaine',0,'',$conf->entity);
}
+ if ($action == 'STOCK_ALLOW_NEGATIVE_TRANSFER')
+ {
+ $res = dolibarr_set_const($db, "STOCK_ALLOW_NEGATIVE_TRANSFER", GETPOST('STOCK_ALLOW_NEGATIVE_TRANSFER','alpha'),'chaine',0,'',$conf->entity);
+ }
// Mode of stock decrease
if ($action == 'STOCK_CALCULATE_ON_BILL'
|| $action == 'STOCK_CALCULATE_ON_VALIDATE_ORDER'
@@ -427,6 +431,22 @@ print ''
print '';
print "\n";
print "\n";
+
+$var=!$var;
+
+print "
";
+print '| '.$langs->trans("WarehouseAllowNegativeTransfer").' | ';
+
+print '';
+print "';
+print " | \n";
+print "
\n";
+
print '
';
/* I keep the option/feature, but hidden to end users for the moment. If feature is used by module, no need to have users see it.
diff --git a/htdocs/core/modules/modStock.class.php b/htdocs/core/modules/modStock.class.php
index 7bdf5d1d641..bc3ba80903d 100644
--- a/htdocs/core/modules/modStock.class.php
+++ b/htdocs/core/modules/modStock.class.php
@@ -71,7 +71,9 @@ class modStock extends DolibarrModules
$this->langfiles = array("stocks");
// Constants
- $this->const = array();
+ $this->const = array(
+ 0=>array('STOCK_ALLOW_NEGATIVE_TRANSFER','chaine','1','',1)
+ );
// Boxes
$this->boxes = array();
diff --git a/htdocs/langs/en_US/stocks.lang b/htdocs/langs/en_US/stocks.lang
index c1ba6f73159..dc3dfa4fb96 100644
--- a/htdocs/langs/en_US/stocks.lang
+++ b/htdocs/langs/en_US/stocks.lang
@@ -133,6 +133,8 @@ StockMustBeEnoughForShipment= Stock level must be enough to add product/service
MovementLabel=Label of movement
InventoryCode=Movement or inventory code
IsInPackage=Contained into package
+WarehouseAllowNegativeTransfer=Allow transfer even without stock
+qtyToTranferIsNotEnough=You don't have enough stock from your source warehouse
ShowWarehouse=Show warehouse
MovementCorrectStock=Stock correction for product %s
MovementTransferStock=Stock transfer of product %s into another warehouse
diff --git a/htdocs/product/stock/product.php b/htdocs/product/stock/product.php
index 56504432840..4c92c353027 100644
--- a/htdocs/product/stock/product.php
+++ b/htdocs/product/stock/product.php
@@ -232,96 +232,117 @@ if ($action == "transfert_stock" && ! $cancel)
if (isset($object->pmp)) $pricesrc=$object->pmp;
$pricedest=$pricesrc;
- if ($object->hasbatch())
+ $do_tranfer = true;
+ if (empty($conf->global->STOCK_ALLOW_NEGATIVE_TRANSFER))
{
- $pdluo = new Productbatch($db);
-
- if ($pdluoid > 0)
+ $fk_warehouse_source = GETPOST("id_entrepot");
+ $nb_unit = GETPOST("nbpiece",'int');
+
+ if (empty($object->stock_warehouse[$fk_warehouse_source]->real) || $object->stock_warehouse[$fk_warehouse_source]->real < $nb_unit)
{
- $result=$pdluo->fetch($pdluoid);
- if ($result)
+ $do_tranfer = false;
+ $result1 = $result2 = -1;
+ $action='';
+ $object->error = $langs->trans('qtyToTranferIsNotEnough');
+ }
+ }
+
+ if ($do_tranfer)
+ {
+
+ if ($object->hasbatch())
+ {
+ $pdluo = new Productbatch($db);
+
+ if ($pdluoid > 0)
{
- $srcwarehouseid=$pdluo->warehouseid;
- $batch=$pdluo->batch;
- $eatby=$pdluo->eatby;
- $sellby=$pdluo->sellby;
+ $result=$pdluo->fetch($pdluoid);
+ if ($result)
+ {
+ $srcwarehouseid=$pdluo->warehouseid;
+ $batch=$pdluo->batch;
+ $eatby=$pdluo->eatby;
+ $sellby=$pdluo->sellby;
+ }
+ else
+ {
+ setEventMessages($pdluo->error, $pdluo->errors, 'errors');
+ $error++;
+ }
}
else
{
- setEventMessages($pdluo->error, $pdluo->errors, 'errors');
- $error++;
+ $srcwarehouseid=GETPOST('id_entrepot','int');
+ $batch=GETPOST('batch_number');
+ $eatby=$d_eatby;
+ $sellby=$d_sellby;
+ }
+
+ if (! $error)
+ {
+ // Remove stock
+ $result1=$object->correct_stock_batch(
+ $user,
+ $srcwarehouseid,
+ GETPOST("nbpiece",'int'),
+ 1,
+ GETPOST("label",'san_alpha'),
+ $pricesrc,
+ $eatby,$sellby,$batch,
+ GETPOST('inventorycode')
+ );
+ if ($result1 < 0) $error++;
+ }
+ if (! $error)
+ {
+ // Add stock
+ $result2=$object->correct_stock_batch(
+ $user,
+ GETPOST("id_entrepot_destination",'int'),
+ GETPOST("nbpiece",'int'),
+ 0,
+ GETPOST("label",'san_alpha'),
+ $pricedest,
+ $eatby,$sellby,$batch,
+ GETPOST('inventorycode')
+ );
+ if ($result2 < 0) $error++;
}
}
else
{
- $srcwarehouseid=GETPOST('id_entrepot','int');
- $batch=GETPOST('batch_number');
- $eatby=$d_eatby;
- $sellby=$d_sellby;
+ if (! $error)
+ {
+ // Remove stock
+ $result1=$object->correct_stock(
+ $user,
+ GETPOST("id_entrepot"),
+ GETPOST("nbpiece"),
+ 1,
+ GETPOST("label"),
+ $pricesrc,
+ GETPOST('inventorycode')
+ );
+ if ($result1 < 0) $error++;
+ }
+ if (! $error)
+ {
+ // Add stock
+ $result2=$object->correct_stock(
+ $user,
+ GETPOST("id_entrepot_destination"),
+ GETPOST("nbpiece"),
+ 0,
+ GETPOST("label"),
+ $pricedest,
+ GETPOST('inventorycode')
+ );
+ if ($result2 < 0) $error++;
+ }
}
- if (! $error)
- {
- // Remove stock
- $result1=$object->correct_stock_batch(
- $user,
- $srcwarehouseid,
- GETPOST("nbpiece",'int'),
- 1,
- GETPOST("label",'san_alpha'),
- $pricesrc,
- $eatby,$sellby,$batch,
- GETPOST('inventorycode')
- );
- if ($result1 < 0) $error++;
- }
- if (! $error)
- {
- // Add stock
- $result2=$object->correct_stock_batch(
- $user,
- GETPOST("id_entrepot_destination",'int'),
- GETPOST("nbpiece",'int'),
- 0,
- GETPOST("label",'san_alpha'),
- $pricedest,
- $eatby,$sellby,$batch,
- GETPOST('inventorycode')
- );
- if ($result2 < 0) $error++;
- }
- }
- else
- {
- if (! $error)
- {
- // Remove stock
- $result1=$object->correct_stock(
- $user,
- GETPOST("id_entrepot"),
- GETPOST("nbpiece"),
- 1,
- GETPOST("label"),
- $pricesrc,
- GETPOST('inventorycode')
- );
- if ($result1 < 0) $error++;
- }
- if (! $error)
- {
- // Add stock
- $result2=$object->correct_stock(
- $user,
- GETPOST("id_entrepot_destination"),
- GETPOST("nbpiece"),
- 0,
- GETPOST("label"),
- $pricedest,
- GETPOST('inventorycode')
- );
- if ($result2 < 0) $error++;
- }
}
+
if (! $error && $result1 >= 0 && $result2 >= 0)
{
$db->commit();