diff --git a/andromeida.midsuit.project/src/andromedia/midsuit/factory/MID_DocFactory.java b/andromeida.midsuit.project/src/andromedia/midsuit/factory/MID_DocFactory.java index f2fff3f..b7c5bbb 100644 --- a/andromeida.midsuit.project/src/andromedia/midsuit/factory/MID_DocFactory.java +++ b/andromeida.midsuit.project/src/andromedia/midsuit/factory/MID_DocFactory.java @@ -13,9 +13,11 @@ import org.compiere.util.CLogger; import org.compiere.util.DB; import org.compiere.util.Env; +import andromedia.midsuit.doc.MID_DocAnalysis; import andromedia.midsuit.doc.MID_DocInvoice; import andromedia.midsuit.doc.MID_DocMRPPPO; import andromedia.midsuit.doc.MID_DocMidRequsiition; +import andromedia.midsuit.model.MID_Analysis; import andromedia.midsuit.model.MID_MRequisitionTrx; import andromedia.midsuit.model.MID_PPO; @@ -57,6 +59,8 @@ public class MID_DocFactory implements IDocFactory{ return new MID_DocMidRequsiition(as,rs,trxName); if(tableName.equals(MID_PPO.Table_Name)) 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)) { s_log.log(Level.SEVERE,"IN"); return new MID_DocInvoice(as, rs, trxName);} diff --git a/edii.midsuit.project/src/edii/midsuit/factory/MID_ValidatorFactory.java b/edii.midsuit.project/src/edii/midsuit/factory/MID_ValidatorFactory.java index f5229aa..c46d177 100644 --- a/edii.midsuit.project/src/edii/midsuit/factory/MID_ValidatorFactory.java +++ b/edii.midsuit.project/src/edii/midsuit/factory/MID_ValidatorFactory.java @@ -4,11 +4,13 @@ import org.adempiere.base.event.AbstractEventHandler; import org.adempiere.base.event.IEventTopics; import org.adempiere.exceptions.AdempiereException; import org.compiere.model.MOrder; +import org.compiere.model.MProductionLine; import org.compiere.model.PO; import org.compiere.util.CLogger; import org.osgi.service.event.Event; import edii.midsuit.validator.EDI_OrderValidator; +import edii.midsuit.validator.EDI_ProductionLineValidator; public class MID_ValidatorFactory extends AbstractEventHandler { public CLogger log = CLogger.getCLogger(MID_ValidatorFactory.class); @@ -17,23 +19,10 @@ public class MID_ValidatorFactory extends AbstractEventHandler { protected void doHandleEvent(Event event) { 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)) msg = EDI_OrderValidator.executeEvent(event, getPO(event)); -// if (getPO(event).get_TableName().equals(MRMA.Table_Name)) -// msg = MID_RMAValidator.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)); + if (getPO(event).get_TableName().equals(MProductionLine.Table_Name)) + msg = EDI_ProductionLineValidator.executeEvent(event, getPO(event)); logEvent(event, getPO(event), msg); } @@ -45,7 +34,6 @@ public class MID_ValidatorFactory extends AbstractEventHandler { @Override protected void initialize() { - // registerTableEvent(IEventTopics.DOC_BEFORE_COMPLETE, Table_Name); registerTableEvent(IEventTopics.DOC_BEFORE_COMPLETE, MOrder.Table_Name); registerTableEvent(IEventTopics.PO_BEFORE_CHANGE, MOrder.Table_Name); diff --git a/edii.midsuit.project/src/edii/midsuit/process/EDI_ProductionCreate.java b/edii.midsuit.project/src/edii/midsuit/process/EDI_ProductionCreate.java new file mode 100644 index 0000000..8b66f96 --- /dev/null +++ b/edii.midsuit.project/src/edii/midsuit/process/EDI_ProductionCreate.java @@ -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 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"); + } + } +} diff --git a/edii.midsuit.project/src/edii/midsuit/validator/EDI_ProductionLineValidator.java b/edii.midsuit.project/src/edii/midsuit/validator/EDI_ProductionLineValidator.java new file mode 100644 index 0000000..fc5cd0f --- /dev/null +++ b/edii.midsuit.project/src/edii/midsuit/validator/EDI_ProductionLineValidator.java @@ -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 ""; + } +}