1

Adempierein ,有可能Inventory Stock变成负数。使其变为负数的方法之一是当我们投入Quantity超过Internal Use InventoryStock Availablein 时Warehouse

例子

Product Info
------------
Product    || Qty
Fertilizer || 15

产品信息中显示当前Qty为。然后我制作内部使用库存文件 Fertilizer15

Internal Use Inventory
----------------------
Product    || Qty
Fertilizer || 25

当我完成它时,Quantity将是-10。如何防止在超过Internal Use Inventory时完成,以免出现负库存QuantityAvailable Stock

4

3 回答 3

2

这是 Adempiere 特意设计的功能。在某些情况下,允许库存变为负数,因为在这些情况下感觉最好让流程完成,但如果是负数,它突出了必须解决的问题。在内部使用的情况下,警告用户,如果他们继续,库存将变为负数。

要更改此标准功能,您需要修改

org.compiere.model.MInventory.completeIt()

但是,如果您直接更改代码,则使您的版本与基本 Adempiere 保持同步甚至只是应用补丁都会变得更加困难。

推荐的方法是添加一个Model Validator。这是一种监视底层数据模型并允许在特定事件发生时注入额外代码/逻辑的机制。

您想要的事件是文档事件 TIMING_BEFORE_COMPLETE。您将创建一个新的模型验证器,如链接中所述,将其注册到 Adempiere 的应用程序字典中,并且由于您希望代码在执行Inventory Document Type时触发,您将添加一个类似这样的方法

public String docValidate (PO po, int timing)
{
   if (timing == TIMING_BEFORE_COMPLETE) {
      if (po.get_TableName().equals(MInventory.Table_Name))
      {
          // your code to be executed 
          // it is executed just before any (internal or physical)
          // Inventory is Completed
      }
   }
   return null;
} //    docValidate

一句警告;内部使用功能与实物盘点(即库存盘点)功能使用的相同!他们只是在 Adempiere 有不同的窗口。因此,请务必在应用任何更改后测试这两个功能。从核心org.compiere.model.MInventory提示您如何区分两者。

//Get Quantity Internal Use
BigDecimal qtyDiff = line.getQtyInternalUse().negate();
//If Quantity Internal Use = Zero Then Physical Inventory  Else Internal Use Inventory
if (qtyDiff.signum() == 0)
于 2015-10-16T08:42:23.093 回答
0

添加 Colin 先生的答案,请参阅以下代码以限制基于 M_Inventory 的交易的负库存。您也可以在 M_Inout 和 M_Movement 表中考虑相同的概念。

for (MInventoryLine line : mInventory.getLines(true))
            {           
                String blockNegativeQty = MSysConfig.getValue("BLOCK_NEGATIVE_QUANTITY_IN_MATERIAL_ISSUE","Y", getAD_Client_ID());
                if(blockNegativeQty.equals("Y"))
                {           

                    //Always check the on Hand Qty not Qty Book Value. The old Drafted Qty Book Value may be changed alredy. 
                    String sql = "SELECT adempiere.bomqtyonhand(?, ?, ?)"; 
                    BigDecimal onhandQty = DB.getSQLValueBD(line.get_TrxName(), sql, line.getM_Product_ID(), mInventory.getM_Warehouse_ID()
                                    , line.getM_Locator_ID());

                    BigDecimal QtyMove = onhandQty.subtract(line.getQtyInternalUse());

                    if(QtyMove.compareTo(Env.ZERO) < 0)
                    {
                        log.warning("Negative Movement Quantity is restricted. Qty On Hand = " + onhandQty 
                                + " AND Qty Internal Use = " + line.getQtyInternalUse() 
                                + ". The Movement Qty is = " + QtyMove);

                        negativeCount ++;

                        negativeProducts = negativeProducts + line.getM_Product().getName() + ": " + onhandQty + " ; ";                         
                    }
                }                   
            }
            if(negativeCount > 0)
            {
                m_processMsg = "Negative Inventory Restricted. "
                        + " Restriction has been enabled through the client level system configurator."
                        + " Products : " + negativeProducts;
            }
            return m_processMsg;
于 2019-07-31T16:36:37.183 回答
0

为了防止库存为负,您可以使用两种方法

  1. 代码中的标注
  2. 之前保存方法
  1. 为了在 Callout 中应用它,您需要创建一个 Callout 类并在定位器处获取当前的 Stock Qty,然后从输入的 Qty 中减去 qty,如果结果小于 0,则显示错误。将此应用于数量字段,您将获得所需的结果。

  2. 这是稍微好一点的方法,因为这不需要在代码中完全创建一个新类,并且会完全消耗更少的内存,在代码中搜索 MInventoryLine 类,然后在其中搜索 beforesave() 。添加相同的代码(获取库存,然后从输入的数量中减去)。beforesave() 中的代码将是这样的

        if (your condition here)    {   log.saveError("Could Not Save - Error", "Qty less than 0");  return false;      }
    

现在我假设您知道创建标注和设计条件的基本代码,如果您需要任何帮助,请告诉我。

于 2015-10-19T04:55:41.937 回答