/****************************************************************************** * Product: Adempiere ERP & CRM Smart Business Solution * * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * * under the terms version 2 of the GNU General Public License as published * * by the Free Software Foundation. This program is distributed in the hope * * that it will be useful, but WITHOUT ANY WARRANTY; without even the implied * * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * * with this program; if not, write to the Free Software Foundation, Inc., * * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * * For the text or an alternative of this public license, you may reach us * * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA * * or via info@compiere.org or http://www.compiere.org/license.html * *****************************************************************************/ package org.globalqss.model; import java.lang.reflect.Method; import java.math.BigDecimal; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.Properties; import java.util.logging.Level; import javax.script.ScriptEngine; import org.compiere.model.MBPartner; import org.compiere.model.MBPartnerLocation; import org.compiere.model.MRule; import org.compiere.util.AdempiereUserError; import org.compiere.util.DB; import org.compiere.util.Env; /** * Model class for concept * * @author Carlos Ruiz - globalqss */ public class MLCODIANConcept extends X_LCO_DIAN_Concept { /** * */ private static final long serialVersionUID = 8280094742826097467L; /************************************************************************** * Default Constructor * @param ctx context * @param MLCOInvoiceWithholding_ID id * @param trxName transaction */ public MLCODIANConcept (Properties ctx, int LCO_DIAN_Concept_ID, String trxName) { super(ctx, LCO_DIAN_Concept_ID, trxName); } // MLCODIANConcept /** * Load Constructor * @param ctx context * @param rs result set * @param trxName transaction */ public MLCODIANConcept(Properties ctx, ResultSet rs, String trxName) { super(ctx, rs, trxName); } // MLCODIANConcept /** * Calculate the sources and insert corresponding schedule lines * @param sendScheduleProcess the process * @param format the format * @return count of lines inserted * @throws AdempiereUserError */ public int calculateSources(X_LCO_DIAN_SendSchedule sendScheduleProcess, int bpID) throws Exception { int cnt = 0; MBPartner bp = null; MBPartnerLocation bpl = null; if (bpID > 0) { bp = MBPartner.get(getCtx(), bpID); bpl = bp.getLocation(0); if (bpl == null) throw new AdempiereUserError("No BPLocation for BPartner = " + bp.getC_BPartner_ID() + " / " + bp.getName()); } // for each position in sources String sql = "SELECT DISTINCT dcs.CalcColumnPosition " + "FROM LCO_DIAN_ConceptSource dcs " + "WHERE dcs.LCO_DIAN_Concept_ID=? AND dcs.IsActive='Y' AND dcs.CalcColumnPosition>0" + "ORDER BY dcs.CalcColumnPosition"; PreparedStatement pstmt = null; ResultSet rs = null; try { X_LCO_DIAN_SendScheduleLine dssl = null; pstmt = DB.prepareStatement(sql, get_TrxName()); pstmt.setInt(1, getLCO_DIAN_Concept_ID()); rs = pstmt.executeQuery(); // for each position while (rs.next()) { int position = rs.getInt(1); String sqlsrc = "SELECT dcs.* " + "FROM LCO_DIAN_ConceptSource dcs " + "WHERE dcs.LCO_DIAN_Concept_ID=? AND dcs.IsActive='Y' AND dcs.CalcColumnPosition=?"; PreparedStatement pstmtsrc = null; ResultSet rssrc = null; BigDecimal amtTotal = Env.ZERO; try { pstmtsrc = DB.prepareStatement(sqlsrc, get_TrxName()); pstmtsrc.setInt(1, getLCO_DIAN_Concept_ID()); pstmtsrc.setInt(2, position); rssrc = pstmtsrc.executeQuery(); // for each source while (rssrc.next()) { X_LCO_DIAN_ConceptSource conceptSource = new X_LCO_DIAN_ConceptSource(getCtx(), rssrc, get_TrxName()); // calculate the source BigDecimal amtSrc = processSource(sendScheduleProcess, bpID, conceptSource); // sum if (amtSrc != null) amtTotal = amtTotal.add(amtSrc); } } finally { DB.close(rssrc, pstmtsrc); rssrc = null; pstmtsrc = null; } if (amtTotal != null && amtTotal.compareTo(Env.ZERO) != 0) { if (dssl == null) { dssl = new X_LCO_DIAN_SendScheduleLine (getCtx(), 0, get_TrxName()); dssl.setLCO_DIAN_Concept_ID(getLCO_DIAN_Concept_ID()); dssl.setLCO_DIAN_SendSchedule_ID(sendScheduleProcess.getLCO_DIAN_SendSchedule_ID()); if (bpID > 0) dssl.setC_BPartner_ID(bpID); if (bpl != null) dssl.setC_BPartner_Location_ID(bpl.getC_BPartner_Location_ID()); } // insert into position dssl.set_ValueOfColumn("FieldAmt" + position, amtTotal); } } if (dssl != null) { dssl.saveEx(); cnt++; dssl = null; } } catch (Exception e) { throw e; } finally { DB.close(rs, pstmt); rs = null; pstmt = null; } return cnt; } /** * Process the source calling the expression and returning the value * @param sendScheduleProcess the process * @param format the format * @throws Exception */ private BigDecimal processSource(X_LCO_DIAN_SendSchedule sendScheduleProcess, int bpID, X_LCO_DIAN_ConceptSource conceptSource) throws Exception { BigDecimal retValue = null; String retValueStr = null; String msg = null; String cmd = conceptSource.getFieldExpression(); if (cmd == null || cmd.length() == 0) { msg = "FieldExpression not defined"; throw new AdempiereUserError(msg); } if (cmd.toLowerCase().startsWith(MRule.SCRIPT_PREFIX)) { MRule rule = MRule.get(getCtx(), cmd.substring(MRule.SCRIPT_PREFIX.length())); if (rule == null) { msg = "Callout " + cmd + " not found"; throw new AdempiereUserError(msg); } if ( ! (rule.getEventType().equals(MRule.EVENTTYPE_Callout) && rule.getRuleType().equals(MRule.RULETYPE_JSR223ScriptingAPIs))) { msg = "Callout " + cmd + " must be of type JSR 223 and event Callout"; throw new AdempiereUserError(msg); } ScriptEngine engine = rule.getScriptEngine(); // Window context are W_ // Login context are G_ MRule.setContext(engine, getCtx(), 0); // now add the callout parameters windowNo, tab, field, value, oldValue to the engine // Method arguments context are A_ engine.put(MRule.ARGUMENTS_PREFIX + "Ctx", getCtx()); engine.put(MRule.ARGUMENTS_PREFIX + "SendSchedule", sendScheduleProcess); engine.put(MRule.ARGUMENTS_PREFIX + "C_BPartner_ID", Integer.valueOf(bpID)); engine.put(MRule.ARGUMENTS_PREFIX + "ConceptSource", conceptSource); engine.put(MRule.ARGUMENTS_PREFIX + "TrxName", get_TrxName()); try { retValueStr = engine.eval(rule.getScript()).toString(); retValue = new BigDecimal(retValueStr); } catch (Exception e) { msg = "Callout Script Invalid: " + e.toString(); log.log(Level.SEVERE, msg, e); throw new AdempiereUserError("Error executing script " + cmd); } } else { Object call = null; String methodName = null; int methodStart = cmd.lastIndexOf('.'); try { if (methodStart != -1) // no class { Class<?> cClass = Class.forName(cmd.substring(0,methodStart)); call = cClass.newInstance(); methodName = cmd.substring(methodStart+1); } } catch (Exception e) { msg = "Callout Invalid: " + cmd + " (" + e.toString() + ")"; throw new AdempiereUserError(msg); } if (call == null || methodName == null ||methodName.length() == 0) { msg = "Callout Invalid: " + methodName; throw new AdempiereUserError(msg); } try { if (methodName == null || methodName.length() == 0) throw new IllegalArgumentException ("No Method Name"); Method method = call.getClass().getMethod(methodName, Properties.class, X_LCO_DIAN_SendSchedule.class, Integer.class, X_LCO_DIAN_ConceptSource.class, String.class); // Call Method try { retValue = (BigDecimal) method.invoke(call, getCtx(), sendScheduleProcess, new Integer(bpID), conceptSource, get_TrxName()); } catch (Exception e) { Throwable ex = e.getCause(); // InvocationTargetException if (ex == null) ex = e; log.log(Level.SEVERE, "start: " + methodName, ex); ex.printStackTrace(System.err); retValueStr = ex.getLocalizedMessage(); throw new AdempiereUserError("Error invoking callout " + cmd + " " + retValueStr); } return retValue; } catch (Exception e) { msg = "Callout Invalid: " + e.toString(); log.log(Level.SEVERE, msg, e); throw new AdempiereUserError("Error with method callout " + cmd); } } return retValue; } } // MLCODIANConcept