Production Order Batch
This commit is contained in:
parent
195bbe9efb
commit
988e99f8bc
|
|
@ -13,9 +13,11 @@ import org.compiere.util.CLogger;
|
||||||
import org.compiere.util.DB;
|
import org.compiere.util.DB;
|
||||||
import org.compiere.util.Env;
|
import org.compiere.util.Env;
|
||||||
|
|
||||||
|
import andromedia.midsuit.doc.MID_DocAnalysis;
|
||||||
import andromedia.midsuit.doc.MID_DocInvoice;
|
import andromedia.midsuit.doc.MID_DocInvoice;
|
||||||
import andromedia.midsuit.doc.MID_DocMRPPPO;
|
import andromedia.midsuit.doc.MID_DocMRPPPO;
|
||||||
import andromedia.midsuit.doc.MID_DocMidRequsiition;
|
import andromedia.midsuit.doc.MID_DocMidRequsiition;
|
||||||
|
import andromedia.midsuit.model.MID_Analysis;
|
||||||
import andromedia.midsuit.model.MID_MRequisitionTrx;
|
import andromedia.midsuit.model.MID_MRequisitionTrx;
|
||||||
import andromedia.midsuit.model.MID_PPO;
|
import andromedia.midsuit.model.MID_PPO;
|
||||||
|
|
||||||
|
|
@ -57,6 +59,8 @@ public class MID_DocFactory implements IDocFactory{
|
||||||
return new MID_DocMidRequsiition(as,rs,trxName);
|
return new MID_DocMidRequsiition(as,rs,trxName);
|
||||||
if(tableName.equals(MID_PPO.Table_Name))
|
if(tableName.equals(MID_PPO.Table_Name))
|
||||||
return new MID_DocMRPPPO(as, rs, trxName);
|
return new MID_DocMRPPPO(as, rs, trxName);
|
||||||
|
if(tableName.equals(MID_Analysis.Table_Name))
|
||||||
|
return new MID_DocAnalysis(as, rs, trxName);
|
||||||
if(tableName.equals(MInvoice.Table_Name)) {
|
if(tableName.equals(MInvoice.Table_Name)) {
|
||||||
s_log.log(Level.SEVERE,"IN");
|
s_log.log(Level.SEVERE,"IN");
|
||||||
return new MID_DocInvoice(as, rs, trxName);}
|
return new MID_DocInvoice(as, rs, trxName);}
|
||||||
|
|
|
||||||
|
|
@ -4,11 +4,13 @@ import org.adempiere.base.event.AbstractEventHandler;
|
||||||
import org.adempiere.base.event.IEventTopics;
|
import org.adempiere.base.event.IEventTopics;
|
||||||
import org.adempiere.exceptions.AdempiereException;
|
import org.adempiere.exceptions.AdempiereException;
|
||||||
import org.compiere.model.MOrder;
|
import org.compiere.model.MOrder;
|
||||||
|
import org.compiere.model.MProductionLine;
|
||||||
import org.compiere.model.PO;
|
import org.compiere.model.PO;
|
||||||
import org.compiere.util.CLogger;
|
import org.compiere.util.CLogger;
|
||||||
import org.osgi.service.event.Event;
|
import org.osgi.service.event.Event;
|
||||||
|
|
||||||
import edii.midsuit.validator.EDI_OrderValidator;
|
import edii.midsuit.validator.EDI_OrderValidator;
|
||||||
|
import edii.midsuit.validator.EDI_ProductionLineValidator;
|
||||||
|
|
||||||
public class MID_ValidatorFactory extends AbstractEventHandler {
|
public class MID_ValidatorFactory extends AbstractEventHandler {
|
||||||
public CLogger log = CLogger.getCLogger(MID_ValidatorFactory.class);
|
public CLogger log = CLogger.getCLogger(MID_ValidatorFactory.class);
|
||||||
|
|
@ -17,23 +19,10 @@ public class MID_ValidatorFactory extends AbstractEventHandler {
|
||||||
|
|
||||||
protected void doHandleEvent(Event event) {
|
protected void doHandleEvent(Event event) {
|
||||||
String msg = "";
|
String msg = "";
|
||||||
|
|
||||||
// if (getPO(event).get_TableName().equals(MOrderLandedCostAllocation.Table_Name))
|
|
||||||
// msg = SMT_LandedCostAllocationValidator.executeEvent(event, getPO(event));
|
|
||||||
if (getPO(event).get_TableName().equals(MOrder.Table_Name))
|
if (getPO(event).get_TableName().equals(MOrder.Table_Name))
|
||||||
msg = EDI_OrderValidator.executeEvent(event, getPO(event));
|
msg = EDI_OrderValidator.executeEvent(event, getPO(event));
|
||||||
// if (getPO(event).get_TableName().equals(MRMA.Table_Name))
|
if (getPO(event).get_TableName().equals(MProductionLine.Table_Name))
|
||||||
// msg = MID_RMAValidator.executeEvent(event, getPO(event));
|
msg = EDI_ProductionLineValidator.executeEvent(event, getPO(event));
|
||||||
// if (getPO(event).get_TableName().equals(MInOut.Table_Name))
|
|
||||||
// msg = MID_InOutValidator.executeEvent(event, getPO(event));
|
|
||||||
// if(getPO(event).get_TableName().equals(MInvoice.Table_Name))
|
|
||||||
// msg = MID_InvoiceValidator.executeEvent(event, getPO(event));
|
|
||||||
// if(getPO(event).get_TableName().equals(MPaymentAllocate.Table_Name))
|
|
||||||
// msg = MID_PaymentAllocateValidator.executeEvent(event, getPO(event));
|
|
||||||
// if(getPO(event).get_TableName().equals(MProductPrice.Table_Name))
|
|
||||||
// msg = MID_ProductPriceValidator.executeEvent(event, getPO(event));
|
|
||||||
// if(getPO(event).get_TableName().equals(MPriceList.Table_Name))
|
|
||||||
// msg = MID_PriceListValidator.executeEvent(event, getPO(event));
|
|
||||||
logEvent(event, getPO(event), msg);
|
logEvent(event, getPO(event), msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -45,7 +34,6 @@ public class MID_ValidatorFactory extends AbstractEventHandler {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void initialize() {
|
protected void initialize() {
|
||||||
|
|
||||||
// registerTableEvent(IEventTopics.DOC_BEFORE_COMPLETE, Table_Name);
|
// registerTableEvent(IEventTopics.DOC_BEFORE_COMPLETE, Table_Name);
|
||||||
registerTableEvent(IEventTopics.DOC_BEFORE_COMPLETE, MOrder.Table_Name);
|
registerTableEvent(IEventTopics.DOC_BEFORE_COMPLETE, MOrder.Table_Name);
|
||||||
registerTableEvent(IEventTopics.PO_BEFORE_CHANGE, MOrder.Table_Name);
|
registerTableEvent(IEventTopics.PO_BEFORE_CHANGE, MOrder.Table_Name);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,167 @@
|
||||||
|
package edii.midsuit.process;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
import org.compiere.model.I_M_ProductionPlan;
|
||||||
|
import org.compiere.model.MProduction;
|
||||||
|
import org.compiere.model.MProductionPlan;
|
||||||
|
import org.compiere.model.MSysConfig;
|
||||||
|
import org.compiere.model.Query;
|
||||||
|
import org.compiere.process.ProcessInfoParameter;
|
||||||
|
import org.compiere.process.SvrProcess;
|
||||||
|
import org.compiere.util.AdempiereUserError;
|
||||||
|
import org.compiere.util.DB;
|
||||||
|
import org.compiere.util.Env;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Process to create production lines based on the plans
|
||||||
|
* defined for a particular production header
|
||||||
|
* @author Paul Bowden
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class EDI_ProductionCreate extends SvrProcess {
|
||||||
|
|
||||||
|
private int p_M_Production_ID=0;
|
||||||
|
private MProduction m_production = null;
|
||||||
|
private boolean mustBeStocked = false; //not used
|
||||||
|
private boolean recreate = false;
|
||||||
|
private BigDecimal newQty = null;
|
||||||
|
//private int p_M_Locator_ID=0;
|
||||||
|
|
||||||
|
|
||||||
|
protected void prepare() {
|
||||||
|
|
||||||
|
ProcessInfoParameter[] para = getParameter();
|
||||||
|
for (int i = 0; i < para.length; i++)
|
||||||
|
{
|
||||||
|
String name = para[i].getParameterName();
|
||||||
|
if ("Recreate".equals(name))
|
||||||
|
recreate = "Y".equals(para[i].getParameter());
|
||||||
|
else if ("ProductionQty".equals(name))
|
||||||
|
newQty = (BigDecimal) para[i].getParameter();
|
||||||
|
else
|
||||||
|
log.log(Level.SEVERE, "Unknown Parameter: " + name);
|
||||||
|
}
|
||||||
|
|
||||||
|
p_M_Production_ID = getRecord_ID();
|
||||||
|
m_production = new MProduction(getCtx(), p_M_Production_ID, get_TrxName());
|
||||||
|
|
||||||
|
} //prepare
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String doIt() throws Exception {
|
||||||
|
|
||||||
|
if ( m_production.get_ID() == 0 )
|
||||||
|
throw new AdempiereUserError("Could not load production header");
|
||||||
|
|
||||||
|
if ( m_production.isProcessed() )
|
||||||
|
return "Already processed";
|
||||||
|
|
||||||
|
return createLines();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean costsOK(int M_Product_ID) throws AdempiereUserError {
|
||||||
|
// Warning will not work if non-standard costing is used
|
||||||
|
String sql = "SELECT ABS(((cc.currentcostprice-(SELECT SUM(c.currentcostprice*bom.bomqty)"
|
||||||
|
+ " FROM m_cost c"
|
||||||
|
+ " INNER JOIN m_product_bom bom ON (c.m_product_id=bom.m_productbom_id)"
|
||||||
|
+ " INNER JOIN m_costelement ce ON (c.m_costelement_id = ce.m_costelement_id AND ce.costingmethod = 'S')"
|
||||||
|
+ " WHERE bom.m_product_id = pp.m_product_id)"
|
||||||
|
+ " )/cc.currentcostprice))"
|
||||||
|
+ " FROM m_product pp"
|
||||||
|
+ " INNER JOIN m_cost cc on (cc.m_product_id=pp.m_product_id)"
|
||||||
|
+ " INNER JOIN m_costelement ce ON (cc.m_costelement_id=ce.m_costelement_id)"
|
||||||
|
+ " WHERE cc.currentcostprice > 0 AND pp.M_Product_ID = ?"
|
||||||
|
+ " AND ce.costingmethod='S'";
|
||||||
|
|
||||||
|
BigDecimal costPercentageDiff = DB.getSQLValueBD(get_TrxName(), sql, M_Product_ID);
|
||||||
|
|
||||||
|
if (costPercentageDiff == null)
|
||||||
|
{
|
||||||
|
costPercentageDiff = Env.ZERO;
|
||||||
|
String msg = "Could not retrieve costs";
|
||||||
|
if (MSysConfig.getBooleanValue(MSysConfig.MFG_ValidateCostsOnCreate, false, getAD_Client_ID())) {
|
||||||
|
throw new AdempiereUserError(msg);
|
||||||
|
} else {
|
||||||
|
log.warning(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( (costPercentageDiff.compareTo(new BigDecimal("0.005")))< 0 )
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String createLines() throws Exception {
|
||||||
|
|
||||||
|
int created = 0;
|
||||||
|
if (!m_production.isUseProductionPlan()) {
|
||||||
|
validateEndProduct(m_production.getM_Product_ID());
|
||||||
|
|
||||||
|
if (!recreate && "Y".equalsIgnoreCase(m_production.getIsCreated()))
|
||||||
|
throw new AdempiereUserError("Production already created.");
|
||||||
|
|
||||||
|
if (newQty != null )
|
||||||
|
m_production.setProductionQty(newQty);
|
||||||
|
|
||||||
|
m_production.deleteLines(get_TrxName());
|
||||||
|
created = m_production.createLines(mustBeStocked);
|
||||||
|
} else {
|
||||||
|
Query planQuery = new Query(getCtx(), I_M_ProductionPlan.Table_Name, "M_ProductionPlan.M_Production_ID=?", get_TrxName());
|
||||||
|
List<MProductionPlan> plans = planQuery.setParameters(m_production.getM_Production_ID()).list();
|
||||||
|
for(MProductionPlan plan : plans) {
|
||||||
|
validateEndProduct(plan.getM_Product_ID());
|
||||||
|
|
||||||
|
if (!recreate && "Y".equalsIgnoreCase(m_production.getIsCreated()))
|
||||||
|
throw new AdempiereUserError("Production already created.");
|
||||||
|
|
||||||
|
plan.deleteLines(get_TrxName());
|
||||||
|
int n = plan.createLines(mustBeStocked);
|
||||||
|
if ( n == 0 )
|
||||||
|
{return "Failed to create production lines"; }
|
||||||
|
created = created + n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( created == 0 )
|
||||||
|
{return "Failed to create production lines"; }
|
||||||
|
|
||||||
|
|
||||||
|
m_production.setIsCreated("Y");
|
||||||
|
m_production.save(get_TrxName());
|
||||||
|
StringBuilder msgreturn = new StringBuilder().append(created).append(" production lines were created");
|
||||||
|
return msgreturn.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validateEndProduct(int M_Product_ID) throws Exception {
|
||||||
|
isBom(M_Product_ID);
|
||||||
|
|
||||||
|
if (!costsOK(M_Product_ID)) {
|
||||||
|
String msg = "Excessive difference in standard costs";
|
||||||
|
if (MSysConfig.getBooleanValue(MSysConfig.MFG_ValidateCostsDifferenceOnCreate, false, getAD_Client_ID())) {
|
||||||
|
throw new AdempiereUserError("Excessive difference in standard costs");
|
||||||
|
} else {
|
||||||
|
log.warning(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void isBom(int M_Product_ID) throws Exception
|
||||||
|
{
|
||||||
|
String bom = DB.getSQLValueString(get_TrxName(), "SELECT isbom FROM M_Product WHERE M_Product_ID = ?", M_Product_ID);
|
||||||
|
if ("N".compareTo(bom) == 0)
|
||||||
|
{
|
||||||
|
throw new AdempiereUserError ("Attempt to create product line for Non Bill Of Materials");
|
||||||
|
}
|
||||||
|
int materials = DB.getSQLValue(get_TrxName(), "SELECT count(M_Product_BOM_ID) FROM M_Product_BOM WHERE M_Product_ID = ?", M_Product_ID);
|
||||||
|
if (materials == 0)
|
||||||
|
{
|
||||||
|
throw new AdempiereUserError ("Attempt to create product line for Bill Of Materials with no BOM Products");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
package edii.midsuit.validator;
|
||||||
|
|
||||||
|
import org.adempiere.base.event.IEventTopics;
|
||||||
|
import org.compiere.model.MProduction;
|
||||||
|
import org.compiere.model.MProductionLine;
|
||||||
|
import org.compiere.model.PO;
|
||||||
|
import org.compiere.util.DB;
|
||||||
|
import org.osgi.service.event.Event;
|
||||||
|
|
||||||
|
public class EDI_ProductionLineValidator {
|
||||||
|
public static String executeEvent(Event e, PO po) {
|
||||||
|
MProductionLine pl = (MProductionLine) po;
|
||||||
|
if (e.getTopic().equals(IEventTopics.PO_BEFORE_NEW))
|
||||||
|
return beforeNew(pl);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String beforeNew(MProductionLine pl) {
|
||||||
|
MProduction production = new MProduction(pl.getCtx(), pl.getM_Production_ID(), pl.get_TrxName());
|
||||||
|
int PS_PPO_ID = production.get_ValueAsInt("ps_ppo_ID");
|
||||||
|
if(pl.get_ValueAsInt("C_UOM_ID")==0)
|
||||||
|
pl.set_ValueNoCheck("C_UOM_ID", pl.getM_Product().getC_UOM_ID());
|
||||||
|
|
||||||
|
if(pl.isEndProduct() && PS_PPO_ID > 0) {
|
||||||
|
// MID_PPO PPO = new MID_PPO(pl.getCtx(), PS_PPO_ID, pl.get_TrxName());
|
||||||
|
// pl.setM_AttributeSetInstance_ID(PPO.get_ValueAsInt(X_M_ProductionLine.COLUMNNAME_M_AttributeSetInstance_ID));
|
||||||
|
String sqlExec = "SELECT M_AttributeSetInstance_ID "
|
||||||
|
+ " FROM PS_PPO WHERE PS_PPO_ID =?";
|
||||||
|
int M_AttributeSetInstance_ID = DB.getSQLValueEx(pl.get_TrxName(), sqlExec, new Object[] { PS_PPO_ID });
|
||||||
|
if(M_AttributeSetInstance_ID>0)
|
||||||
|
pl.setM_AttributeSetInstance_ID(M_AttributeSetInstance_ID);
|
||||||
|
}else {
|
||||||
|
String sqlExec = "SELECT M_AttributeSetInstance_ID " +
|
||||||
|
" FROM M_Storage S " +
|
||||||
|
" WHERE M_Product_ID = ? AND " +
|
||||||
|
" DateMaterialPolicy = (SELECT MIN(DateMaterialPolicy) FROM M_StorageOnHand SOH " +
|
||||||
|
" WHERE SOH.QtyOnHand>0 AND M_AttributeSetInstance_ID > 0 AND M_Product_ID = S.M_Product_ID)";
|
||||||
|
int M_AttributeSetInstance_ID = DB.getSQLValueEx(pl.get_TrxName(), sqlExec, new Object[] { pl.getM_Product_ID() });
|
||||||
|
if(M_AttributeSetInstance_ID>0)
|
||||||
|
pl.setM_AttributeSetInstance_ID(M_AttributeSetInstance_ID);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue