NEW Add option "Stock can be negative". Off by default.
This commit is contained in:
parent
1195e3bf0c
commit
97b03e225b
@ -323,63 +323,73 @@ $found++;
|
||||
|
||||
print '</table>';
|
||||
|
||||
print '<br>';
|
||||
print '<table class="noborder" width="100%">';
|
||||
print '<tr class="liste_titre">';
|
||||
print " <td>".$langs->trans("RuleForStockAvailability")."</td>\n";
|
||||
print " <td align=\"right\" width=\"160\"> </td>\n";
|
||||
print '</tr>'."\n";
|
||||
|
||||
$var=!$var;
|
||||
print "<tr ".$bc[$var].">";
|
||||
print '<td width="60%">'.$langs->trans("WarehouseAllowNegativeTransfer").'</td>';
|
||||
print '<td width="160" align="right">';
|
||||
print "<form method=\"post\" action=\"stock.php\">";
|
||||
print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
|
||||
print "<input type=\"hidden\" name=\"action\" value=\"STOCK_ALLOW_NEGATIVE_TRANSFER\">";
|
||||
print $form->selectyesno("STOCK_ALLOW_NEGATIVE_TRANSFER",$conf->global->STOCK_ALLOW_NEGATIVE_TRANSFER,1);
|
||||
print '<input type="submit" class="button" value="'.$langs->trans("Modify").'">';
|
||||
print '</form>';
|
||||
print "</td>\n";
|
||||
print "</tr>\n";
|
||||
|
||||
// Option to force stock to be enough before adding a line into document
|
||||
if ($conf->invoice->enabled || $conf->order->enabled || $conf->expedition->enabled)
|
||||
{
|
||||
print '<br>';
|
||||
print '<table class="noborder" width="100%">';
|
||||
print '<tr class="liste_titre">';
|
||||
print " <td>".$langs->trans("RuleForStockAvailability")."</td>\n";
|
||||
print " <td align=\"right\" width=\"160\"> </td>\n";
|
||||
print '</tr>'."\n";
|
||||
|
||||
if($conf->invoice->enabled) {
|
||||
$var = !$var;
|
||||
print "<tr ".$bc[$var].">";
|
||||
print '<td width="60%">'.$langs->trans("StockMustBeEnoughForInvoice").'</td>';
|
||||
print '<td width="160" align="right">';
|
||||
print "<form method=\"post\" action=\"stock.php\">";
|
||||
print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
|
||||
print "<input type=\"hidden\" name=\"action\" value=\"STOCK_MUST_BE_ENOUGH_FOR_INVOICE\">";
|
||||
print $form->selectyesno("STOCK_MUST_BE_ENOUGH_FOR_INVOICE",$conf->global->STOCK_MUST_BE_ENOUGH_FOR_INVOICE,1);
|
||||
print '<input type="submit" class="button" value="'.$langs->trans("Modify").'">';
|
||||
print '</form>';
|
||||
print "</td>\n";
|
||||
print "</tr>\n";
|
||||
}
|
||||
|
||||
if($conf->order->enabled) {
|
||||
$var = !$var;
|
||||
print "<tr ".$bc[$var].">";
|
||||
print '<td width="60%">'.$langs->trans("StockMustBeEnoughForOrder").'</td>';
|
||||
print '<td width="160" align="right">';
|
||||
print "<form method=\"post\" action=\"stock.php\">";
|
||||
print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
|
||||
print "<input type=\"hidden\" name=\"action\" value=\"STOCK_MUST_BE_ENOUGH_FOR_ORDER\">";
|
||||
print $form->selectyesno("STOCK_MUST_BE_ENOUGH_FOR_ORDER",$conf->global->STOCK_MUST_BE_ENOUGH_FOR_ORDER,1);
|
||||
print '<input type="submit" class="button" value="'.$langs->trans("Modify").'">';
|
||||
print '</form>';
|
||||
print "</td>\n";
|
||||
print "</tr>\n";
|
||||
}
|
||||
|
||||
if($conf->expedition->enabled) {
|
||||
$var = !$var;
|
||||
print "<tr ".$bc[$var].">";
|
||||
print '<td width="60%">'.$langs->trans("StockMustBeEnoughForShipment").'</td>';
|
||||
print '<td width="160" align="right">';
|
||||
print "<form method=\"post\" action=\"stock.php\">";
|
||||
print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
|
||||
print "<input type=\"hidden\" name=\"action\" value=\"STOCK_MUST_BE_ENOUGH_FOR_SHIPMENT\">";
|
||||
print $form->selectyesno("STOCK_MUST_BE_ENOUGH_FOR_SHIPMENT",$conf->global->STOCK_MUST_BE_ENOUGH_FOR_SHIPMENT,1);
|
||||
print '<input type="submit" class="button" value="'.$langs->trans("Modify").'">';
|
||||
print '</form>';
|
||||
print "</td>\n";
|
||||
print "</tr>\n";
|
||||
}
|
||||
print '</table>';
|
||||
if($conf->invoice->enabled) {
|
||||
$var = !$var;
|
||||
print "<tr ".$bc[$var].">";
|
||||
print '<td width="60%">'.$langs->trans("StockMustBeEnoughForInvoice").'</td>';
|
||||
print '<td width="160" align="right">';
|
||||
print "<form method=\"post\" action=\"stock.php\">";
|
||||
print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
|
||||
print "<input type=\"hidden\" name=\"action\" value=\"STOCK_MUST_BE_ENOUGH_FOR_INVOICE\">";
|
||||
print $form->selectyesno("STOCK_MUST_BE_ENOUGH_FOR_INVOICE",$conf->global->STOCK_MUST_BE_ENOUGH_FOR_INVOICE,1);
|
||||
print '<input type="submit" class="button" value="'.$langs->trans("Modify").'">';
|
||||
print '</form>';
|
||||
print "</td>\n";
|
||||
print "</tr>\n";
|
||||
}
|
||||
|
||||
if($conf->order->enabled) {
|
||||
$var = !$var;
|
||||
print "<tr ".$bc[$var].">";
|
||||
print '<td width="60%">'.$langs->trans("StockMustBeEnoughForOrder").'</td>';
|
||||
print '<td width="160" align="right">';
|
||||
print "<form method=\"post\" action=\"stock.php\">";
|
||||
print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
|
||||
print "<input type=\"hidden\" name=\"action\" value=\"STOCK_MUST_BE_ENOUGH_FOR_ORDER\">";
|
||||
print $form->selectyesno("STOCK_MUST_BE_ENOUGH_FOR_ORDER",$conf->global->STOCK_MUST_BE_ENOUGH_FOR_ORDER,1);
|
||||
print '<input type="submit" class="button" value="'.$langs->trans("Modify").'">';
|
||||
print '</form>';
|
||||
print "</td>\n";
|
||||
print "</tr>\n";
|
||||
}
|
||||
|
||||
if($conf->expedition->enabled) {
|
||||
$var = !$var;
|
||||
print "<tr ".$bc[$var].">";
|
||||
print '<td width="60%">'.$langs->trans("StockMustBeEnoughForShipment").'</td>';
|
||||
print '<td width="160" align="right">';
|
||||
print "<form method=\"post\" action=\"stock.php\">";
|
||||
print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
|
||||
print "<input type=\"hidden\" name=\"action\" value=\"STOCK_MUST_BE_ENOUGH_FOR_SHIPMENT\">";
|
||||
print $form->selectyesno("STOCK_MUST_BE_ENOUGH_FOR_SHIPMENT",$conf->global->STOCK_MUST_BE_ENOUGH_FOR_SHIPMENT,1);
|
||||
print '<input type="submit" class="button" value="'.$langs->trans("Modify").'">';
|
||||
print '</form>';
|
||||
print "</td>\n";
|
||||
print "</tr>\n";
|
||||
}
|
||||
print '</table>';
|
||||
|
||||
$virtualdiffersfromphysical=0;
|
||||
if (! empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT)
|
||||
|| ! empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER)
|
||||
@ -432,21 +442,6 @@ print '</form>';
|
||||
print "</td>\n";
|
||||
print "</tr>\n";
|
||||
|
||||
$var=!$var;
|
||||
|
||||
print "<tr ".$bc[$var].">";
|
||||
print '<td width="60%">'.$langs->trans("WarehouseAllowNegativeTransfer").'</td>';
|
||||
|
||||
print '<td width="160" align="right">';
|
||||
print "<form method=\"post\" action=\"stock.php\">";
|
||||
print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
|
||||
print "<input type=\"hidden\" name=\"action\" value=\"STOCK_ALLOW_NEGATIVE_TRANSFER\">";
|
||||
print $form->selectyesno("STOCK_ALLOW_NEGATIVE_TRANSFER",$conf->global->STOCK_ALLOW_NEGATIVE_TRANSFER,1);
|
||||
print '<input type="submit" class="button" value="'.$langs->trans("Modify").'">';
|
||||
print '</form>';
|
||||
print "</td>\n";
|
||||
print "</tr>\n";
|
||||
|
||||
print '<br>';
|
||||
|
||||
/* 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.
|
||||
|
||||
@ -114,13 +114,13 @@ RecordMovement=Record transfert
|
||||
ReceivingForSameOrder=Receipts for this order
|
||||
StockMovementRecorded=Stock movements recorded
|
||||
RuleForStockAvailability=Rules on stock requirements
|
||||
StockMustBeEnoughForInvoice=Stock level must be enough to add product/service to invoice
|
||||
StockMustBeEnoughForOrder=Stock level must be enough to add product/service to order
|
||||
StockMustBeEnoughForShipment= Stock level must be enough to add product/service to shipment
|
||||
StockMustBeEnoughForInvoice=Stock level must be enough to add product/service to invoice (even if real stock change occurs later on another event)
|
||||
StockMustBeEnoughForOrder=Stock level must be enough to add product/service to order (even if stock change occurs later on another event)
|
||||
StockMustBeEnoughForShipment= Stock level must be enough to add product/service to shipment (even if stock change occurs later on another event)
|
||||
MovementLabel=Label of movement
|
||||
InventoryCode=Movement or inventory code
|
||||
IsInPackage=Contained into package
|
||||
WarehouseAllowNegativeTransfer=Allow transfer even without stock
|
||||
WarehouseAllowNegativeTransfer=Stock can be negative
|
||||
qtyToTranferIsNotEnough=You don't have enough stock from your source warehouse
|
||||
ShowWarehouse=Show warehouse
|
||||
MovementCorrectStock=Stock correction for product %s
|
||||
|
||||
@ -494,11 +494,13 @@ class Productbatch extends CommonObject
|
||||
if ($fk_product > 0)
|
||||
{
|
||||
$sql.= ", pl.eatby as eatby, pl.sellby as sellby";
|
||||
// TODO May add extrafields to ?
|
||||
}
|
||||
$sql.= " FROM ".MAIN_DB_PREFIX."product_batch as t";
|
||||
if ($fk_product > 0)
|
||||
{
|
||||
$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product_lot as pl ON pl.fk_product = ".$fk_product." AND pl.batch = t.batch";
|
||||
// TODO May add extrafields to ?
|
||||
}
|
||||
$sql.= " WHERE fk_product_stock=".$fk_product_stock;
|
||||
if ($with_qty) $sql.= " AND t.qty <> 0";
|
||||
@ -523,7 +525,7 @@ class Productbatch extends CommonObject
|
||||
$tmp->qty = $obj->qty;
|
||||
$tmp->import_key = $obj->import_key;
|
||||
|
||||
array_push($ret,$tmp);
|
||||
$ret[$tmp->batch] = $tmp; // $ret is for a $fk_product_stock and unique key is on $fk_product_stock+batch
|
||||
$i++;
|
||||
}
|
||||
$db->free($resql);
|
||||
|
||||
@ -240,31 +240,45 @@ class MouvementStock extends CommonObject
|
||||
}
|
||||
}
|
||||
|
||||
// TODO Check qty is ok for stock move.
|
||||
if (! empty($conf->productbatch->enabled) && $product->hasbatch() && ! $skip_batch)
|
||||
{
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
if (empty($conf->global->STOCK_ALLOW_NEGATIVE_TRANSFER) && in_array($type, array(1, 2)))
|
||||
{
|
||||
if (empty($product->stock_warehouse[$entrepot_id]->real) || $product->stock_warehouse[$entrepot_id]->real < abs($qty))
|
||||
{
|
||||
$this->error = $langs->trans('qtyToTranferIsNotEnough');
|
||||
$this->errors[] = $langs->trans('qtyToTranferIsNotEnough');
|
||||
$this->db->rollback();
|
||||
return -8;
|
||||
}
|
||||
}
|
||||
|
||||
// Define if we must make the stock change (If product type is a service or if stock is used also for services)
|
||||
$movestock=0;
|
||||
if ($product->type != Product::TYPE_SERVICE || ! empty($conf->global->STOCK_SUPPORTS_SERVICES)) $movestock=1;
|
||||
|
||||
// Check if stock is enough when qty is < 0
|
||||
// Note that qty should be > 0 with type 0 or 3, < 0 with type 1 or 2.
|
||||
if ($qty < 0 && empty($conf->global->STOCK_ALLOW_NEGATIVE_TRANSFER))
|
||||
{
|
||||
if (! empty($conf->productbatch->enabled) && $product->hasbatch() && ! $skip_batch)
|
||||
{
|
||||
$foundforbatch=0;
|
||||
$qtyisnotenough=0;
|
||||
foreach($product->stock_warehouse[$entrepot_id]->detail_batch as $batchcursor => $prodbatch)
|
||||
{
|
||||
if ($batch != $batchcursor) continue;
|
||||
$foundforbatch=1;
|
||||
if ($prodbatch->qty < abs($qty)) $qtyisnotenough=1;
|
||||
break;
|
||||
}
|
||||
if (! $foundforbatch || $qtyisnotenough)
|
||||
{
|
||||
$this->error = $langs->trans('qtyToTranferLotIsNotEnough');
|
||||
$this->errors[] = $langs->trans('qtyToTranferLotIsNotEnough');
|
||||
$this->db->rollback();
|
||||
return -8;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (empty($product->stock_warehouse[$entrepot_id]->real) || $product->stock_warehouse[$entrepot_id]->real < abs($qty))
|
||||
{
|
||||
$this->error = $langs->trans('qtyToTranferIsNotEnough');
|
||||
$this->errors[] = $langs->trans('qtyToTranferIsNotEnough');
|
||||
$this->db->rollback();
|
||||
return -8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($movestock && $entrepot_id > 0) // Change stock for current product, change for subproduct is done after
|
||||
{
|
||||
if(!empty($this->origin)) { // This is set by caller for tracking reason
|
||||
|
||||
Loading…
Reference in New Issue
Block a user