This is best way to management the transaction when calculate MRP, I made 3 test:

1.- Calculate MRP in single transaction, this case show large locks in DB of PP_MRP table set in wait other transaction as create SO,PO,REQ,etc
2.- Calculate MRP all transaction independents this drop the large lock in DB
3.- Calculate MRP with single transaction and commits for each document, So this test is that get best result.

kind regards
Victor Perez
www.e-evolution.com
This commit is contained in:
vpj-cd 2008-09-11 03:42:00 +00:00
parent 7613b20989
commit 42b66d7d2d
1 changed files with 47 additions and 39 deletions

View File

@ -26,7 +26,6 @@ import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import org.adempiere.exceptions.AdempiereException;
import org.adempiere.exceptions.DBException;
import org.compiere.model.MBPartner;
@ -158,8 +157,8 @@ public class MRP extends SvrProcess
if (doc==null || doc.length == 0)
{
log.log(Level.SEVERE,"Not found default document type for docbasetype "+ MDocType.DOCBASETYPE_PurchaseRequisition);
MNote note = new MNote(getCtx(), MMessage.getAD_Message_ID (getCtx(), "SequenceDocNotFound"), Planner_ID,MPPMRP.Table_ID, 0,Msg.getMsg(getCtx(), "SequenceDocNotFound"),Msg.getMsg(getCtx(), "SequenceDocNotFound"),null);
note.save();
MNote note = new MNote(getCtx(), MMessage.getAD_Message_ID (getCtx(), "SequenceDocNotFound"), Planner_ID,MPPMRP.Table_ID, 0,Msg.getMsg(getCtx(), "SequenceDocNotFound"),Msg.getMsg(getCtx(), "SequenceDocNotFound"),get_TrxName());
note.saveEx();
return Msg.getMsg(getCtx(), "SequenceDocNotFound");
}
else
@ -169,8 +168,8 @@ public class MRP extends SvrProcess
if (doc==null || doc.length == 0) {
log.severe ("Not found default document type for docbasetype " + MDocType.DOCBASETYPE_ManufacturingOrder);
MNote note = new MNote (getCtx(), MMessage.getAD_Message_ID (getCtx(), "SequenceDocNotFound"), Planner_ID , MPPMRP.Table_ID , 0 , Msg.getMsg(getCtx(), "SequenceDocNotFound") , Msg.getMsg(getCtx(), "SequenceDocNotFound"),null);
note.save();
MNote note = new MNote (getCtx(), MMessage.getAD_Message_ID (getCtx(), "SequenceDocNotFound"), Planner_ID , MPPMRP.Table_ID , 0 , Msg.getMsg(getCtx(), "SequenceDocNotFound") , Msg.getMsg(getCtx(), "SequenceDocNotFound"),get_TrxName());
note.saveEx();
return Msg.getMsg(getCtx(), Msg.getMsg(getCtx(), "SequenceDocNotFound"));
}
else
@ -180,8 +179,8 @@ public class MRP extends SvrProcess
if (doc==null || doc.length == 0) {
log.severe ("Not found default document type for docbasetype " + MDocType.DOCBASETYPE_DistributionOrder);
MNote note = new MNote (getCtx(), MMessage.getAD_Message_ID (getCtx(), "SequenceDocNotFound"), Planner_ID , MPPMRP.Table_ID , 0 , Msg.getMsg(getCtx(), "SequenceDocNotFound") , Msg.getMsg(getCtx(), "SequenceDocNotFound"),null);
note.save();
MNote note = new MNote (getCtx(), MMessage.getAD_Message_ID (getCtx(), "SequenceDocNotFound"), Planner_ID , MPPMRP.Table_ID , 0 , Msg.getMsg(getCtx(), "SequenceDocNotFound") , Msg.getMsg(getCtx(), "SequenceDocNotFound"),get_TrxName());
note.saveEx();
return Msg.getMsg(getCtx(), Msg.getMsg(getCtx(), "SequenceDocNotFound"));
}
else
@ -203,7 +202,7 @@ public class MRP extends SvrProcess
parameters.add(p_S_Resource_ID);
}
List <MResource> plants = new Query(getCtx(), MResource.Table_Name, whereClause.toString(), null)
List <MResource> plants = new Query(getCtx(), MResource.Table_Name, whereClause.toString(), get_TrxName())
.setParameters(parameters)
.list();
@ -221,7 +220,7 @@ public class MRP extends SvrProcess
}
List <MOrg> organizations = new Query(getCtx(),MOrg.Table_Name, whereClause.toString(), null)
List <MOrg> organizations = new Query(getCtx(),MOrg.Table_Name, whereClause.toString(), get_TrxName())
.setParameters(parameters)
.list();
@ -262,15 +261,18 @@ public class MRP extends SvrProcess
{
// Delete Manufacturing Order with Close Status from MRP Table
String sql = "DELETE FROM PP_MRP WHERE OrderType = 'MOP' AND DocStatus='CL' AND AD_Client_ID=" + AD_Client_ID + " AND AD_Org_ID=" + AD_Org_ID + " AND M_Warehouse_ID="+M_Warehouse_ID + " AND S_Resource_ID="+S_Resource_ID ;
DB.executeUpdateEx(sql, null);
DB.executeUpdateEx(sql, get_TrxName());
commit();
// Delete Requisition with Status Close from MRP Table
sql = "DELETE FROM PP_MRP WHERE OrderType = 'POR' AND DocStatus='CL' AND AD_Client_ID = " + AD_Client_ID + " AND AD_Org_ID=" + AD_Org_ID+ " AND M_Warehouse_ID="+M_Warehouse_ID + " AND S_Resource_ID="+S_Resource_ID;
DB.executeUpdateEx(sql, null);
DB.executeUpdateEx(sql, get_TrxName());
commit();
// Delete Action Notice
sql = "DELETE FROM AD_Note WHERE AD_Table_ID=? AND AD_Client_ID=? AND AD_Org_ID=?";
DB.executeUpdateEx(sql, new Object[]{MPPMRP.Table_ID, AD_Client_ID, AD_Org_ID}, null);
DB.executeUpdateEx(sql, new Object[]{MPPMRP.Table_ID, AD_Client_ID, AD_Org_ID}, get_TrxName());
commit();
if (p_IsRequiredDRP)
{
@ -311,9 +313,9 @@ public class MRP extends SvrProcess
Timestamp POQDateStartSchedule = null;
// Mark all supply MRP records as available
DB.executeUpdateEx("UPDATE PP_MRP SET IsAvailable ='Y' WHERE TypeMRP = 'S' AND AD_Client_ID = " + AD_Client_ID+" AND AD_Org_ID=" + AD_Org_ID + " AND M_Warehouse_ID=" + M_Warehouse_ID ,null);
int lowlevel = MPPMRP.getMaxLowLevel(getCtx(), null);
DB.executeUpdateEx("UPDATE PP_MRP SET IsAvailable ='Y' WHERE TypeMRP = 'S' AND AD_Client_ID = " + AD_Client_ID+" AND AD_Org_ID=" + AD_Org_ID + " AND M_Warehouse_ID=" + M_Warehouse_ID ,get_TrxName());
commit();
int lowlevel = MPPMRP.getMaxLowLevel(getCtx(), get_TrxName());
log.info("Low Level Is :"+lowlevel);
// Calculate MRP for all levels
for (int level = 0 ; level <= lowlevel ; level++)
@ -329,7 +331,7 @@ public class MRP extends SvrProcess
+ " AND mrp.DatePromised <= ?"
+ " AND COALESCE(p.LowLevel,0) = ? "
+" ORDER BY mrp.M_Product_ID , mrp.DatePromised ";
pstmt = DB.prepareStatement (sql, null);
pstmt = DB.prepareStatement (sql, get_TrxName());
pstmt.setString(1, MPPMRP.TYPEMRP_Demand);
pstmt.setInt(2, AD_Client_ID);
pstmt.setInt(3, AD_Org_ID);
@ -454,7 +456,7 @@ public class MRP extends SvrProcess
private void setProduct(int AD_Client_ID , int AD_Org_ID, int S_Resource_ID , int M_Warehouse_ID, MProduct product)
{
//find data product planning demand
MPPProductPlanning pp = MPPProductPlanning.find(getCtx() ,AD_Org_ID , M_Warehouse_ID, S_Resource_ID , product.getM_Product_ID(), null);
MPPProductPlanning pp = MPPProductPlanning.find(getCtx() ,AD_Org_ID , M_Warehouse_ID, S_Resource_ID , product.getM_Product_ID(), get_TrxName());
DatePromisedTo = null;
DatePromisedFrom = null;
if (pp != null)
@ -500,7 +502,7 @@ public class MRP extends SvrProcess
if(product.isPurchased())
{
int C_BPartner_ID = 0;
MProductPO[] ppos = MProductPO.getOfProduct(getCtx(), product.getM_Product_ID(), null);
MProductPO[] ppos = MProductPO.getOfProduct(getCtx(), product.getM_Product_ID(), get_TrxName());
for (int i = 0; i < ppos.length; i++)
{
if (ppos[i].isCurrentVendor() && ppos[i].getC_BPartner_ID() != 0)
@ -522,7 +524,7 @@ public class MRP extends SvrProcess
}
}
QtyProjectOnHand = MPPMRP.getQtyOnHand(getCtx(), m_product_planning.getM_Warehouse_ID() , m_product_planning.getM_Product_ID(), null);
QtyProjectOnHand = MPPMRP.getQtyOnHand(getCtx(), m_product_planning.getM_Warehouse_ID() , m_product_planning.getM_Product_ID(), get_TrxName());
if(m_product_planning.getSafetyStock().signum() > 0
&& m_product_planning.getSafetyStock().compareTo(QtyProjectOnHand) > 0)
{
@ -544,7 +546,7 @@ public class MRP extends SvrProcess
m_product_planning.getM_Warehouse_ID()
};
QtyScheduledReceipts = DB.getSQLValueBD(null, "SELECT COALESCE(SUM(Qty),0) FROM PP_MRP WHERE "+whereClause, params);
DB.executeUpdateEx("UPDATE PP_MRP SET IsAvailable = 'N' WHERE "+whereClause, params, null);
DB.executeUpdateEx("UPDATE PP_MRP SET IsAvailable = 'N' WHERE "+whereClause, params, get_TrxName());
log.info("QtyScheduledReceipts :" + QtyScheduledReceipts);
//QtyProjectOnHand = QtyProjectOnHand.add(QtyScheduledReceipts);
@ -696,7 +698,6 @@ public class MRP extends SvrProcess
}
//get the warehouse in transit
MWarehouse[] wsts = MWarehouse.getInTransitForOrg(getCtx(), source.getAD_Org_ID());
//MWarehouse transit = getWarehouseTransit(source.getAD_Org_ID());
if (wsts == null)
{
@ -714,25 +715,21 @@ public class MRP extends SvrProcess
{
//Org Must be linked to BPartner
//MOrg org = MOrg.get(getCtx(), locator_to.getAD_Org_ID());
MOrg org = getOrg(locator_to.getAD_Org_ID());
int C_BPartner_ID = org.getLinkedC_BPartner_ID(null);
int C_BPartner_ID = org.getLinkedC_BPartner_ID(get_TrxName());
if (C_BPartner_ID == 0)
{
createMRPNote("DRP-020", PP_MRP_ID, product);
continue;
}
//MBPartner bp = MBPartner.get(getCtx(), C_BPartner_ID);
MBPartner bp = getBPartner(C_BPartner_ID);
// Try found some order with Shipper , Business Partner and Doc Status = Draft
// Consolidate the demand in a single order for each Shipper , Business Partner , DemandDateStartSchedule
//String date = DB.TO_DATE(DemandDateStartSchedule);
//order = (MDDOrder) MTable.get(getCtx(), MDDOrder.Table_Name).getPO("M_Shipper_ID ="+network_line.getM_Shipper_ID()+" AND C_BPartner_ID="+bp.getC_BPartner_ID() +" AND DatePromised=" + date + " AND DocStatus='DR'", get_TrxName());
order = getDDOrder(network_line.getM_Shipper_ID(), bp.getC_BPartner_ID(),DemandDateStartSchedule);
if (order == null)
{
order = new MDDOrder(getCtx() , 0 , null);
order = new MDDOrder(getCtx() , 0 , get_TrxName());
order.setAD_Org_ID(target.getAD_Org_ID());
order.setC_BPartner_ID(C_BPartner_ID);
//order.setAD_User_ID(bp.getPrimaryAD_User_ID());
@ -748,6 +745,7 @@ public class MRP extends SvrProcess
//order.setSalesRep_ID(m_product_planning.getPlanner_ID());
order.setSalesRep_ID(bp.getPrimaryAD_User_ID());
order.saveEx();
String key = network_line.getM_Shipper_ID()+"#"+C_BPartner_ID+"#"+DemandDateStartSchedule+"DR";
@ -758,7 +756,7 @@ public class MRP extends SvrProcess
BigDecimal QtyOrdered = QtyPlanned.multiply(network_line.getPercent()).divide(Env.ONEHUNDRED);
MDDOrderLine oline = new MDDOrderLine(getCtx(), 0 , null);
MDDOrderLine oline = new MDDOrderLine(getCtx(), 0 , get_TrxName());
oline.setDD_Order_ID(order.getDD_Order_ID());
oline.setM_Locator_ID(locator.getM_Locator_ID());
oline.setM_LocatorTo_ID(locator_to.getM_Locator_ID());
@ -767,14 +765,15 @@ public class MRP extends SvrProcess
oline.setDatePromised(DemandDateStartSchedule);
oline.setQtyEntered(QtyOrdered);
oline.setQtyOrdered(QtyOrdered);
oline.setTargetQty(MPPMRP.getQtyReserved(getCtx(), target.getM_Warehouse_ID(), m_product_planning.getM_Product_ID(), DemandDateStartSchedule, null));
oline.setTargetQty(MPPMRP.getQtyReserved(getCtx(), target.getM_Warehouse_ID(), m_product_planning.getM_Product_ID(), DemandDateStartSchedule, get_TrxName()));
oline.setIsInvoiced(false);
oline.saveEx();
// Set Correct Dates for Plan
final String whereClause = MPPMRP.COLUMNNAME_DD_OrderLine_ID+"=?";
List<MPPMRP> mrpList = new Query(getCtx(), MPPMRP.Table_Name, whereClause, null)
List<MPPMRP> mrpList = new Query(getCtx(), MPPMRP.Table_Name, whereClause, get_TrxName())
.setParameters(new Object[]{oline.getDD_OrderLine_ID()})
.list();
for (MPPMRP mrp : mrpList) {
@ -782,10 +781,13 @@ public class MRP extends SvrProcess
mrp.setS_Resource_ID(p_S_Resource_ID);
mrp.setDatePromised(TimeUtil.addDays(DemandDateStartSchedule , (m_product_planning.getDeliveryTime_Promised().add(transfertTime)).negate().intValue()));
mrp.setDateFinishSchedule(DemandDateStartSchedule);
mrp.saveEx();
}
}
commit();
}
private void createRequisition(int PP_MRP_ID, MProduct product, Timestamp DemandDateStartSchedule)
@ -796,7 +798,7 @@ public class MRP extends SvrProcess
int duration = m_product_planning.getDeliveryTime_Promised().intValue()
+ m_product_planning.getTransfertTime().intValue();
MRequisition req = new MRequisition(getCtx(),0, null);
MRequisition req = new MRequisition(getCtx(),0, get_TrxName());
req.setAD_User_ID(m_product_planning.getPlanner_ID());
req.setDateRequired(TimeUtil.addDays(DemandDateStartSchedule, 0 - duration));
req.setDescription("Generate from MRP"); // TODO: add translation
@ -806,6 +808,7 @@ public class MRP extends SvrProcess
req.saveEx();
MRequisitionLine reqline = new MRequisitionLine(req);
reqline.setLine(10);
reqline.setM_Product_ID(m_product_planning.getM_Product_ID());
@ -815,9 +818,10 @@ public class MRP extends SvrProcess
reqline.saveEx();
// Set Correct Dates for Plan
final String whereClause = MPPMRP.COLUMNNAME_M_Requisition_ID+"=?";
List<MPPMRP> mrpList = new Query(getCtx(), MPPMRP.Table_Name, whereClause, null)
List<MPPMRP> mrpList = new Query(getCtx(), MPPMRP.Table_Name, whereClause, get_TrxName())
.setParameters(new Object[]{req.getM_Requisition_ID()})
.list();
for (MPPMRP mrp : mrpList) {
@ -826,8 +830,9 @@ public class MRP extends SvrProcess
mrp.setDateStartSchedule(req.getDateRequired());
mrp.setDateFinishSchedule(DemandDateStartSchedule);
mrp.saveEx();
}
commit();
}
private void createPPOrder(int PP_MRP_ID, MProduct product, Timestamp DemandDateStartSchedule)
@ -839,7 +844,7 @@ public class MRP extends SvrProcess
}
log.info("Manufacturing Order Create");
MPPOrder order = new MPPOrder(getCtx(), 0, null);
MPPOrder order = new MPPOrder(getCtx(), 0, get_TrxName());
order.setLine(10);
order.setC_DocTypeTarget_ID(DocTypeMO);
order.setC_DocType_ID(DocTypeMO);
@ -857,7 +862,7 @@ public class MRP extends SvrProcess
order.setDatePromised(DemandDateStartSchedule);
if (m_product_planning.getDeliveryTime_Promised().signum() == 0)
order.setDateStartSchedule(TimeUtil.addDays(DemandDateStartSchedule, (MPPMRP.getDays(order.getCtx(), order.getS_Resource_ID(), order.getAD_Workflow_ID(), QtyPlanned, null).add(m_product_planning.getTransfertTime())).negate().intValue()));
order.setDateStartSchedule(TimeUtil.addDays(DemandDateStartSchedule, (MPPMRP.getDays(order.getCtx(), order.getS_Resource_ID(), order.getAD_Workflow_ID(), QtyPlanned, get_TrxName()).add(m_product_planning.getTransfertTime())).negate().intValue()));
else
order.setDateStartSchedule(TimeUtil.addDays(DemandDateStartSchedule, (m_product_planning.getDeliveryTime_Promised().add(m_product_planning.getTransfertTime())).negate().intValue()));
order.setDateFinishSchedule(DemandDateStartSchedule);
@ -875,18 +880,20 @@ public class MRP extends SvrProcess
order.setDocStatus(MPPOrder.DOCSTATUS_Drafted);
order.setDocAction(MPPOrder.DOCSTATUS_Completed);
order.saveEx();
commit();
}
private void deletePO(String tableName, String whereClause, Object[] params)
{
// TODO: refactor this method and move it to org.compiere.model.Query class
POResultSet<PO> rs = new Query(getCtx(), tableName, whereClause, null)
POResultSet<PO> rs = new Query(getCtx(), tableName, whereClause, get_TrxName())
.setParameters(params)
.scroll();
try {
while(rs.hasNext()) {
rs.next().deleteEx(true);
commit();
}
}
finally {
@ -909,8 +916,9 @@ public class MRP extends SvrProcess
MPPMRP.Table_ID, PP_MRP_ID,
product.getValue() + " " + product.getName(),
Msg.getMsg(getCtx(), msg.getValue()),
null);
note.save();
get_TrxName());
note.saveEx();
commit();
log.info(code+": "+note.getTextMsg());
}
@ -922,7 +930,7 @@ public class MRP extends SvrProcess
{
order = (MDDOrder) MTable.get(getCtx(), MDDOrder.Table_Name).
getPO("M_Shipper_ID = ? AND C_BPartner_ID=? AND DatePromised=? AND DocStatus=?",
new Object[]{M_Shipper_ID,C_BPartner_ID,DatePromised,"DR"}, null);
new Object[]{M_Shipper_ID,C_BPartner_ID,DatePromised,"DR"}, get_TrxName());
if(order != null)
dd_order_cache.put(key,order);
}