MRP: fix Plan Qty vs Scheduled Receipt Qty issues
This commit is contained in:
parent
7c0e11a051
commit
c627e298fb
|
@ -16,11 +16,14 @@
|
|||
*****************************************************************************/
|
||||
package org.compiere.model;
|
||||
|
||||
import java.math.*;
|
||||
import java.sql.*;
|
||||
import java.util.*;
|
||||
import java.util.logging.*;
|
||||
import org.compiere.util.*;
|
||||
import java.math.BigDecimal;
|
||||
import java.sql.ResultSet;
|
||||
import java.util.Properties;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.adempiere.exceptions.AdempiereException;
|
||||
import org.compiere.util.DB;
|
||||
import org.compiere.util.Env;
|
||||
/**
|
||||
* Requisition Line Model
|
||||
*
|
||||
|
@ -29,6 +32,8 @@ import org.compiere.util.*;
|
|||
*/
|
||||
public class MRequisitionLine extends X_M_RequisitionLine
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* Standard Constructor
|
||||
* @param ctx context
|
||||
|
@ -96,6 +101,18 @@ public class MRequisitionLine extends X_M_RequisitionLine
|
|||
m_C_BPartner_ID = partner_ID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Ordered Qty
|
||||
* @return Ordered Qty
|
||||
*/
|
||||
public BigDecimal getQtyOrdered()
|
||||
{
|
||||
if (getC_OrderLine_ID() > 0)
|
||||
return getQty();
|
||||
else
|
||||
return Env.ZERO;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Parent
|
||||
* @return parent
|
||||
|
@ -123,8 +140,7 @@ public class MRequisitionLine extends X_M_RequisitionLine
|
|||
m_M_PriceList_ID = getParent().getM_PriceList_ID();
|
||||
if (m_M_PriceList_ID == 0)
|
||||
{
|
||||
log.log(Level.SEVERE, "PriceList unknown!");
|
||||
return;
|
||||
throw new AdempiereException("PriceList unknown!");
|
||||
}
|
||||
setPrice (m_M_PriceList_ID);
|
||||
} // setPrice
|
||||
|
@ -177,7 +193,7 @@ public class MRequisitionLine extends X_M_RequisitionLine
|
|||
if (getM_AttributeSetInstance_ID() != 0 && getC_Charge_ID() != 0)
|
||||
setM_AttributeSetInstance_ID(0);
|
||||
//
|
||||
if (getPriceActual().compareTo(Env.ZERO) == 0)
|
||||
if (getPriceActual().signum() == 0)
|
||||
setPrice();
|
||||
setLineNetAmt();
|
||||
return true;
|
||||
|
@ -222,7 +238,7 @@ public class MRequisitionLine extends X_M_RequisitionLine
|
|||
+ "(SELECT COALESCE(SUM(LineNetAmt),0) FROM M_RequisitionLine rl "
|
||||
+ "WHERE r.M_Requisition_ID=rl.M_Requisition_ID) "
|
||||
+ "WHERE M_Requisition_ID=" + getM_Requisition_ID();
|
||||
int no = DB.executeUpdate(sql, get_TrxName());
|
||||
int no = DB.executeUpdateEx(sql, get_TrxName());
|
||||
if (no != 1)
|
||||
log.log(Level.SEVERE, "Header update #" + no);
|
||||
m_parent = null;
|
||||
|
|
|
@ -53,16 +53,11 @@ public class LiberoValidator implements ModelValidator
|
|||
} // LiberoValidator
|
||||
|
||||
/** Logger */
|
||||
private static CLogger log = CLogger.getCLogger(LiberoValidator.class);
|
||||
private CLogger log = CLogger.getCLogger(getClass());
|
||||
/** Client */
|
||||
private int m_AD_Client_ID = -1;
|
||||
|
||||
|
||||
/**
|
||||
* Initialize Validation
|
||||
* @param engine validation engine
|
||||
* @param client client
|
||||
*/
|
||||
public void initialize (ModelValidationEngine engine, MClient client)
|
||||
{
|
||||
//client = null for global validator
|
||||
|
@ -77,7 +72,6 @@ public class LiberoValidator implements ModelValidator
|
|||
engine.addModelChange(MOrder.Table_Name, this);
|
||||
engine.addModelChange(MOrderLine.Table_Name, this);
|
||||
engine.addModelChange(MRequisitionLine.Table_Name, this);
|
||||
engine.addModelChange(MClient.Table_Name, this);
|
||||
engine.addModelChange(X_M_ForecastLine.Table_Name, this);
|
||||
engine.addModelChange(MDDOrder.Table_Name, this);
|
||||
engine.addModelChange(MDDOrderLine.Table_Name, this);
|
||||
|
@ -88,18 +82,13 @@ public class LiberoValidator implements ModelValidator
|
|||
//engine.addModelChange(MProjectTask.Table_Name, this);
|
||||
} // initialize
|
||||
|
||||
/**
|
||||
* Model Change of a monitored Table.
|
||||
* Called after PO.beforeSave/PO.beforeDelete
|
||||
* when you called addModelChange for the table
|
||||
* @param po persistent object
|
||||
* @param type TYPE_
|
||||
* @return error message or null
|
||||
* @exception Exception if the recipient wishes the change to be not accept.
|
||||
*/
|
||||
public String modelChange (PO po, int type) throws Exception
|
||||
{
|
||||
log.info(po.get_TableName() + " Type: "+type);
|
||||
if (po.get_TableName().equals(MOrder.Table_Name) && (type == TYPE_AFTER_CHANGE ))
|
||||
{
|
||||
MPPMRP.C_Order((MOrder)po, false);
|
||||
}
|
||||
if (po.get_TableName().equals(MOrderLine.Table_Name) && ( type == TYPE_AFTER_NEW || type == TYPE_AFTER_CHANGE ))
|
||||
{
|
||||
MOrderLine ol = (MOrderLine)po;
|
||||
|
@ -263,35 +252,9 @@ public class LiberoValidator implements ModelValidator
|
|||
return null;
|
||||
} // modelChange
|
||||
|
||||
/**
|
||||
* Validate Document.
|
||||
* Called as first step of DocAction.prepareIt
|
||||
* when you called addDocValidate for the table.
|
||||
* Note that totals, etc. may not be correct.
|
||||
* @param po persistent object
|
||||
* @param timing see TIMING_ constants
|
||||
* @return error message or null
|
||||
*/
|
||||
public String docValidate (PO po, int timing)
|
||||
{
|
||||
log.info(po.get_TableName() + " Timing: "+timing);
|
||||
// Ignore all after Complete events
|
||||
//if (timing == TIMING_AFTER_COMPLETE)
|
||||
// return null;
|
||||
|
||||
if (timing == TIMING_AFTER_COMPLETE) {
|
||||
if (po.get_TableName().equals(MOrder.Table_Name))
|
||||
{
|
||||
/** Order Discount Example *
|
||||
MOrder order = (MOrder)po;
|
||||
String error = orderDiscount(order);
|
||||
if (error != null)
|
||||
return error;
|
||||
/** Order Discount Example */
|
||||
log.info(po.toString());
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
} // docValidate
|
||||
|
||||
|
@ -307,7 +270,6 @@ public class LiberoValidator implements ModelValidator
|
|||
*/
|
||||
public String login (int AD_Org_ID, int AD_Role_ID, int AD_User_ID)
|
||||
{
|
||||
log.info("AD_User_ID=" + AD_User_ID);
|
||||
return null;
|
||||
} // login
|
||||
|
||||
|
@ -320,16 +282,4 @@ public class LiberoValidator implements ModelValidator
|
|||
{
|
||||
return m_AD_Client_ID;
|
||||
} // getAD_Client_ID
|
||||
|
||||
|
||||
/**
|
||||
* String Representation
|
||||
* @return info
|
||||
*/
|
||||
public String toString ()
|
||||
{
|
||||
StringBuffer sb = new StringBuffer ("LiberoValidator");
|
||||
return sb.toString ();
|
||||
} // toString
|
||||
|
||||
} // LiberoValidator
|
||||
|
|
|
@ -18,10 +18,12 @@ package org.eevolution.model;
|
|||
import java.math.BigDecimal;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.compiere.model.MDocType;
|
||||
import org.compiere.model.MLocator;
|
||||
import org.compiere.model.MOrder;
|
||||
import org.compiere.model.MOrderLine;
|
||||
import org.compiere.model.MProduct;
|
||||
import org.compiere.model.MRequisition;
|
||||
|
@ -29,11 +31,11 @@ import org.compiere.model.MRequisitionLine;
|
|||
import org.compiere.model.MResource;
|
||||
import org.compiere.model.MResourceType;
|
||||
import org.compiere.model.MTable;
|
||||
import org.compiere.model.MWarehouse;
|
||||
import org.compiere.model.Query;
|
||||
import org.compiere.model.X_C_DocType;
|
||||
import org.compiere.model.X_M_Forecast;
|
||||
import org.compiere.model.X_M_ForecastLine;
|
||||
import org.compiere.process.DocAction;
|
||||
import org.compiere.util.DB;
|
||||
import org.compiere.util.Env;
|
||||
import org.compiere.util.TimeUtil;
|
||||
|
@ -49,7 +51,7 @@ import org.compiere.wf.MWorkflow;
|
|||
* @author Teo Sarca, www.arhipac.ro
|
||||
*/
|
||||
public class MPPMRP extends X_PP_MRP
|
||||
{
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**************************************************************************
|
||||
|
@ -92,76 +94,68 @@ public class MPPMRP extends X_PP_MRP
|
|||
*/
|
||||
public static void M_ForecastLine(X_M_ForecastLine fl, boolean delete)
|
||||
{
|
||||
String sql = null;
|
||||
String trxName = fl.get_TrxName();
|
||||
Properties m_ctx =fl.getCtx();
|
||||
Properties ctx =fl.getCtx();
|
||||
if (delete)
|
||||
{
|
||||
sql = "DELETE FROM PP_MRP WHERE M_ForecastLine_ID = "+ fl.getM_ForecastLine_ID() +" AND AD_Client_ID = " + fl.getAD_Client_ID();
|
||||
DB.executeUpdateEx(sql, trxName);
|
||||
final String sql = "DELETE FROM PP_MRP WHERE M_ForecastLine_ID=? AND AD_Client_ID=?";
|
||||
DB.executeUpdateEx(sql, new Object[]{fl.get_ID(), fl.getAD_Client_ID()}, trxName);
|
||||
return;
|
||||
}
|
||||
|
||||
MWarehouse[] w = MWarehouse.getForOrg(m_ctx, fl.getAD_Org_ID());
|
||||
X_M_Forecast f = new X_M_Forecast(m_ctx, fl.getM_Forecast_ID(), trxName);
|
||||
String WhereClause = "M_ForecastLine_ID=?";
|
||||
MPPMRP mrp = (MPPMRP)MTable.get(m_ctx, MPPMRP.Table_ID).getPO(WhereClause, new Object[]{fl.getM_ForecastLine_ID()}, trxName);
|
||||
if(mrp!=null)
|
||||
{
|
||||
mrp.setAD_Org_ID(fl.getAD_Org_ID());
|
||||
mrp.setDescription(f.getDescription());
|
||||
mrp.setName("MRP");
|
||||
mrp.setQty(fl.getQty());
|
||||
/*
|
||||
mrp.setDatePromised(fl.getDatePromised());
|
||||
mrp.setDateStartSchedule(fl.getDatePromised());
|
||||
mrp.setDateFinishSchedule(fl.getDatePromised());
|
||||
mrp.setDateOrdered(fl.getDatePromised());
|
||||
mrp.setM_Product_ID(fl.getM_Product_ID());
|
||||
*/
|
||||
mrp.setDatePromised(fl.getDatePromised());
|
||||
mrp.setDateStartSchedule(mrp.getDatePromised());
|
||||
mrp.setDateFinishSchedule(mrp.getDatePromised());
|
||||
mrp.setDateOrdered(mrp.getDatePromised());
|
||||
mrp.setM_Product_ID(fl.getM_Product_ID());
|
||||
int M_Warehouse_ID = fl.getM_Warehouse_ID();
|
||||
if(M_Warehouse_ID == 0)
|
||||
{
|
||||
mrp.setM_Warehouse_ID(w[0].getM_Warehouse_ID());
|
||||
}
|
||||
else
|
||||
{
|
||||
mrp.setM_Warehouse_ID(M_Warehouse_ID);
|
||||
}
|
||||
mrp.setDocStatus("IP");
|
||||
mrp.saveEx();
|
||||
}
|
||||
else
|
||||
X_M_Forecast f = new X_M_Forecast(ctx, fl.getM_Forecast_ID(), trxName);
|
||||
MPPMRP mrp = new Query(ctx, MPPMRP.Table_Name, "M_ForecastLine_ID=?", trxName)
|
||||
.setParameters(new Object[]{fl.get_ID()})
|
||||
.first();
|
||||
if (mrp == null)
|
||||
{
|
||||
mrp = new MPPMRP(m_ctx, 0,trxName);
|
||||
mrp = new MPPMRP(ctx, 0, trxName);
|
||||
mrp.setM_Forecast_ID(fl.getM_Forecast_ID());
|
||||
mrp.setM_ForecastLine_ID(fl.getM_ForecastLine_ID());
|
||||
mrp.setAD_Org_ID(fl.getAD_Org_ID());
|
||||
mrp.setName("MRP");
|
||||
mrp.setDescription(f.getDescription());
|
||||
mrp.setM_Forecast_ID(f.getM_Forecast_ID());
|
||||
mrp.setQty(fl.getQty());
|
||||
/*mrp.setDatePromised(fl.getDatePromised());
|
||||
mrp.setDateStartSchedule(fl.getDatePromised());
|
||||
mrp.setDateFinishSchedule(fl.getDatePromised());
|
||||
mrp.setDateOrdered(fl.getDatePromised());*/
|
||||
mrp.setDatePromised(fl.getDatePromised());
|
||||
mrp.setDateStartSchedule(mrp.getDatePromised());
|
||||
mrp.setDateFinishSchedule(mrp.getDatePromised());
|
||||
mrp.setDateOrdered(mrp.getDatePromised());
|
||||
mrp.setM_Product_ID(fl.getM_Product_ID());
|
||||
mrp.setM_Warehouse_ID(fl.getM_Warehouse_ID());
|
||||
mrp.setDocStatus("IP");
|
||||
mrp.setOrderType(MPPMRP.ORDERTYPE_Forecast);
|
||||
mrp.setTypeMRP(MPPMRP.TYPEMRP_Demand);
|
||||
mrp.saveEx();
|
||||
}
|
||||
|
||||
return;
|
||||
mrp.setAD_Org_ID(fl.getAD_Org_ID());
|
||||
mrp.setDescription(f.getDescription());
|
||||
mrp.setName("MRP");
|
||||
mrp.setQty(fl.getQty());
|
||||
mrp.setDatePromised(fl.getDatePromised());
|
||||
mrp.setDateStartSchedule(mrp.getDatePromised());
|
||||
mrp.setDateFinishSchedule(mrp.getDatePromised());
|
||||
mrp.setDateOrdered(mrp.getDatePromised());
|
||||
mrp.setM_Product_ID(fl.getM_Product_ID());
|
||||
mrp.setM_Warehouse_ID(fl.getM_Warehouse_ID());
|
||||
mrp.setDocStatus(DocAction.STATUS_InProgress);
|
||||
mrp.saveEx();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create MRP record based in Order
|
||||
* @param MOrder
|
||||
* @param delete Indicate if this record is delete
|
||||
* @return
|
||||
*/
|
||||
public static void C_Order(MOrder o, boolean delete)
|
||||
{
|
||||
String trxName = o.get_TrxName();
|
||||
final String whereClause = COLUMNNAME_C_Order_ID+"=? AND AD_Client_ID=?";
|
||||
Object[] params = new Object[]{o.get_ID(), o.getAD_Client_ID()};
|
||||
if (delete)
|
||||
{
|
||||
final String sql = "DELETE FROM PP_MRP WHERE "+whereClause;
|
||||
DB.executeUpdateEx(sql, params, trxName);
|
||||
return;
|
||||
}
|
||||
if (o.is_ValueChanged(MOrder.COLUMNNAME_DocStatus))
|
||||
{
|
||||
List<MPPMRP> list = new Query(o.getCtx(), MPPMRP.Table_Name, whereClause, trxName)
|
||||
.setParameters(params)
|
||||
.list();
|
||||
for (MPPMRP mrp : list) {
|
||||
mrp.setDocStatus(o.getDocStatus());
|
||||
mrp.saveEx();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -509,36 +503,21 @@ public class MPPMRP extends X_PP_MRP
|
|||
}
|
||||
mrp.setName("MRP");
|
||||
mrp.setDescription(rl.getDescription());
|
||||
mrp.setQty(rl.getQty());
|
||||
mrp.setDatePromised(r.getDateRequired());
|
||||
mrp.setDateStartSchedule(r.getDateRequired());
|
||||
mrp.setDateFinishSchedule(r.getDateRequired());
|
||||
mrp.setDateOrdered(r.getDateRequired());
|
||||
mrp.setM_Product_ID(rl.getM_Product_ID());
|
||||
mrp.setM_Warehouse_ID(r.getM_Warehouse_ID());
|
||||
mrp.setDocStatus(r.getDocStatus());
|
||||
mrp.setM_Warehouse_ID(r.getM_Warehouse_ID());
|
||||
// We create a MRP record only for Not Ordered Qty. The Order will generate a MRP record for Ordered Qty.
|
||||
mrp.setQty(rl.getQty().subtract(rl.getQtyOrdered()));
|
||||
// MRP record for a requisition will be ALWAYS Drafted because
|
||||
// a requisition generates just Planned Orders (which is a wish list)
|
||||
// and not Scheduled Receipts
|
||||
mrp.setDocStatus(DocAction.STATUS_Drafted);
|
||||
mrp.saveEx();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create MRP record based in Requisition
|
||||
* @param MRequisitio Requisition
|
||||
* @param delete Indicate if this record is delete
|
||||
*/
|
||||
public static void M_Requisition(MRequisition r)
|
||||
{
|
||||
final String whereClause = "M_Requisition_ID=? AND AD_Client_ID=?";
|
||||
MPPMRP mrp = new Query(r.getCtx(), MPPMRP.Table_Name, whereClause, r.get_TrxName())
|
||||
.setParameters(new Object[]{r.getM_Requisition_ID(), r.getAD_Client_ID()})
|
||||
.first();
|
||||
if(mrp != null)
|
||||
{
|
||||
mrp.setDocStatus(r.getDocStatus());
|
||||
mrp.saveEx();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get Qty Onhand
|
||||
* @param AD_Client_ID
|
||||
|
|
Loading…
Reference in New Issue