diff --git a/JasperReports/src/org/compiere/report/ReportStarter.java b/JasperReports/src/org/compiere/report/ReportStarter.java index ca29653b5d..2754a20d94 100644 --- a/JasperReports/src/org/compiere/report/ReportStarter.java +++ b/JasperReports/src/org/compiere/report/ReportStarter.java @@ -75,6 +75,7 @@ import org.compiere.model.X_AD_PInstance_Para; import org.compiere.print.MPrintFormat; import org.compiere.print.PrintUtil; import org.compiere.print.ReportCtl; +import org.compiere.print.ServerReportCtl; import org.compiere.process.ClientProcess; import org.compiere.process.ProcessCall; import org.compiere.process.ProcessInfo; @@ -493,13 +494,13 @@ public class ReportStarter implements ProcessCall, ClientProcess // Get print format and print info parameters if (pip!=null) { for (int i=0; i 0) + { + boolean result = runJasperProcess(Record_ID, re, true, printerName); + return(result); + } + else + // Standard Print Format (Non-Jasper) + // ================================== + { + createOutput(re, printerName); + ReportEngine.printConfirm (type, Record_ID); + } + } + return true; + } // StartDocumentPrint + + + /** + * Runs a Jasper process that prints the record + * + * @param format + * @param Record_ID + * @param re + * @param IsDirectPrint + * @param printerName + * @return + */ + public static boolean runJasperProcess(int Record_ID, ReportEngine re, boolean IsDirectPrint, String printerName) { + MPrintFormat format = re.getPrintFormat(); + ProcessInfo pi = new ProcessInfo ("", format.getJasperProcess_ID()); + pi.setPrintPreview( !IsDirectPrint ); + pi.setRecord_ID ( Record_ID ); + Vector jasperPrintParams = new Vector(); + ProcessInfoParameter pip; + if (printerName!=null && printerName.trim().length()>0) { + // Override printer name + pip = new ProcessInfoParameter(PARAM_PRINTER_NAME, printerName, null, null, null); + jasperPrintParams.add(pip); + } + pip = new ProcessInfoParameter(PARAM_PRINT_FORMAT, format, null, null, null); + jasperPrintParams.add(pip); + pip = new ProcessInfoParameter(PARAM_PRINT_INFO, re.getPrintInfo(), null, null, null); + jasperPrintParams.add(pip); + + pi.setParameter(jasperPrintParams.toArray(new ProcessInfoParameter[]{})); + + ServerProcessCtl.process(null, // Parent set to null for synchronous processing, see bugtracker 3010932 + pi, + null); + + boolean result = true; + return(result); + } + + /** + * Create output (server only) + * + * @param re + * @param printerName + */ + private static void createOutput(ReportEngine re, String printerName) + { + if (printerName!=null) { + re.getPrintInfo().setPrinterName(printerName); + } + re.print(); + } + + + /** + * Create Report. + * Called from ProcessCtl. + * - Check special reports first, if not, create standard Report + * + * @param parent The window which invoked the printing + * @param WindowNo The windows number which invoked the printing + * @param pi process info + * @param IsDirectPrint if true, prints directly - otherwise View + * @return true if created + */ + static public boolean start (ASyncProcess parent, ProcessInfo pi) + { + + /** + * Order Print + */ + if (pi.getAD_Process_ID() == 110) // C_Order + return startDocumentPrint(ReportEngine.ORDER, null, pi.getRecord_ID(), null); + if (pi.getAD_Process_ID() == MProcess.getProcess_ID("Rpt PP_Order", null)) // C_Order + return startDocumentPrint(ReportEngine.MANUFACTURING_ORDER, null, pi.getRecord_ID(), null); + if (pi.getAD_Process_ID() == MProcess.getProcess_ID("Rpt DD_Order", null)) // C_Order + return startDocumentPrint(ReportEngine.DISTRIBUTION_ORDER, null, pi.getRecord_ID(), null); + else if (pi.getAD_Process_ID() == 116) // C_Invoice + return startDocumentPrint(ReportEngine.INVOICE, null, pi.getRecord_ID(), null); + else if (pi.getAD_Process_ID() == 117) // M_InOut + return startDocumentPrint(ReportEngine.SHIPMENT, null, pi.getRecord_ID(), null); + else if (pi.getAD_Process_ID() == 217) // C_Project + return startDocumentPrint(ReportEngine.PROJECT, null, pi.getRecord_ID(), null); + else if (pi.getAD_Process_ID() == 276) // C_RfQResponse + return startDocumentPrint(ReportEngine.RFQ, null, pi.getRecord_ID(), null); + else if (pi.getAD_Process_ID() == 159) // Dunning + return startDocumentPrint(ReportEngine.DUNNING, null, pi.getRecord_ID(), null); + else if (pi.getAD_Process_ID() == 202 // Financial Report + || pi.getAD_Process_ID() == 204) // Financial Statement + return startFinReport (pi); + /******************** + * Standard Report + *******************/ + return startStandardReport (pi); + } // create + + /************************************************************************** + * Start Standard Report. + * - Get Table Info & submit + * @param pi Process Info + * @param IsDirectPrint if true, prints directly - otherwise View + * @return true if OK + */ + static public boolean startStandardReport (ProcessInfo pi, boolean IsDirectPrint) + { + pi.setPrintPreview(!IsDirectPrint); + return startStandardReport(pi); + } + + /************************************************************************** + * Start Standard Report. + * - Get Table Info & submit.
+ * A report can be created from: + *
    + *
  1. attached MPrintFormat, if any (see {@link ProcessInfo#setTransientObject(Object)}, {@link ProcessInfo#setSerializableObject(java.io.Serializable)} + *
  2. process information (AD_Process.AD_PrintFormat_ID, AD_Process.AD_ReportView_ID) + *
+ * @param pi Process Info + * @param IsDirectPrint if true, prints directly - otherwise View + * @return true if OK + */ + static public boolean startStandardReport (ProcessInfo pi) + { + ReportEngine re = null; + // + // Create Report Engine by using attached MPrintFormat (if any) + Object o = pi.getTransientObject(); + if (o == null) + o = pi.getSerializableObject(); + if (o != null && o instanceof MPrintFormat) { + Properties ctx = Env.getCtx(); + MPrintFormat format = (MPrintFormat)o; + String TableName = MTable.getTableName(ctx, format.getAD_Table_ID()); + MQuery query = MQuery.get (ctx, pi.getAD_PInstance_ID(), TableName); + PrintInfo info = new PrintInfo(pi); + re = new ReportEngine(ctx, format, query, info); + createOutput(re, null); + return true; + } + // + // Create Report Engine normally + else { + re = ReportEngine.get(Env.getCtx(), pi); + if (re == null) + { + pi.setSummary("No ReportEngine"); + return false; + } + } + + createOutput(re, null); + return true; + } // startStandardReport + + /** + * Start Financial Report. + * @param pi Process Info + * @return true if OK + */ + static public boolean startFinReport (ProcessInfo pi) + { + int AD_Client_ID = Env.getAD_Client_ID(Env.getCtx()); + + // Create Query from Parameters + String TableName = pi.getAD_Process_ID() == 202 ? "T_Report" : "T_ReportStatement"; + MQuery query = MQuery.get (Env.getCtx(), pi.getAD_PInstance_ID(), TableName); + + // Get PrintFormat + MPrintFormat format = (MPrintFormat)pi.getTransientObject(); + if (format == null) + format = (MPrintFormat)pi.getSerializableObject(); + if (format == null) + { + s_log.log(Level.SEVERE, "startFinReport - No PrintFormat"); + return false; + } + PrintInfo info = new PrintInfo(pi); + + ReportEngine re = new ReportEngine(Env.getCtx(), format, query, info); + createOutput(re, null); + return true; + } // startFinReport + + +} diff --git a/base/src/org/compiere/process/InvoicePrint.java b/base/src/org/compiere/process/InvoicePrint.java index bef513b8e7..a8f99a0fa8 100644 --- a/base/src/org/compiere/process/InvoicePrint.java +++ b/base/src/org/compiere/process/InvoicePrint.java @@ -32,6 +32,7 @@ import org.compiere.model.PrintInfo; import org.compiere.model.X_C_Invoice; import org.compiere.print.MPrintFormat; import org.compiere.print.ReportEngine; +import org.compiere.print.ServerReportCtl; import org.compiere.util.AdempiereUserError; import org.compiere.util.DB; import org.compiere.util.EMail; @@ -336,8 +337,11 @@ public class InvoicePrint extends SvrProcess } else { - re.print(); - // ReportCtl.startDocumentPrint(ReportEngine.INVOICE, C_Invoice_ID, null, 0, true); + ServerReportCtl.startDocumentPrint(ReportEngine.INVOICE, + null, // No custom print format + C_Invoice_ID, + null // No custom printer + ); count++; printed = true; } diff --git a/base/src/org/compiere/process/ServerProcessCtl.java b/base/src/org/compiere/process/ServerProcessCtl.java new file mode 100644 index 0000000000..787db91448 --- /dev/null +++ b/base/src/org/compiere/process/ServerProcessCtl.java @@ -0,0 +1,492 @@ +package org.compiere.process; + +import java.io.InvalidClassException; +import java.lang.reflect.UndeclaredThrowableException; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.util.logging.Level; +import org.adempiere.util.ProcessUtil; +import org.compiere.apps.Waiting; +import org.compiere.db.CConnection; +import org.compiere.interfaces.Server; +import org.compiere.model.MPInstance; +import org.compiere.model.MRule; +import org.compiere.print.ServerReportCtl; +import org.compiere.util.ASyncProcess; +import org.compiere.util.CLogger; +import org.compiere.util.DB; +import org.compiere.util.Env; +import org.compiere.util.Msg; +import org.compiere.util.Trx; +import org.compiere.wf.MWFProcess; + +public class ServerProcessCtl implements Runnable { + + /** Static Logger */ + private static CLogger log = CLogger.getCLogger (ServerProcessCtl.class); + + /** Parent */ + ASyncProcess m_parent; + /** Process Info */ + ProcessInfo m_pi; + private Trx m_trx; + private Waiting m_waiting; + private boolean m_IsServerProcess = false; + + /************************************************************************** + * Constructor + * @param parent Container & ASyncProcess + * @param pi Process info + * @param trx Transaction + */ + public ServerProcessCtl (ASyncProcess parent, ProcessInfo pi, Trx trx) + { + m_parent = parent; + m_pi = pi; + m_trx = trx; // handled correctly + } // ProcessCtl + + /** + * Process Control + * + * - Get Instance ID + * - Get Parameters + * - execute (lock - start process - unlock) + * + * Creates a ProcessCtl instance, which calls + * lockUI and unlockUI if parent is a ASyncProcess + *
+ * Called from APanel.cmd_print, APanel.actionButton and + * VPaySelect.cmd_generate + * + * @param parent ASyncProcess & Container + * @param pi ProcessInfo process info + * @param trx Transaction + * @return worker started ProcessCtl instance or null for workflow + */ + public static ServerProcessCtl process (ASyncProcess parent, ProcessInfo pi, Trx trx) + { + log.fine("ServerProcess - " + pi); + + MPInstance instance = null; + try + { + instance = new MPInstance(Env.getCtx(), pi.getAD_Process_ID(), pi.getRecord_ID()); + } + catch (Exception e) + { + pi.setSummary (e.getLocalizedMessage()); + pi.setError (true); + log.warning(pi.toString()); + return null; + } + catch (Error e) + { + pi.setSummary (e.getLocalizedMessage()); + pi.setError (true); + log.warning(pi.toString()); + return null; + } + if (!instance.save()) + { + pi.setSummary (Msg.getMsg(Env.getCtx(), "ProcessNoInstance")); + pi.setError (true); + return null; + } + pi.setAD_PInstance_ID (instance.getAD_PInstance_ID()); + + // execute + ServerProcessCtl worker = new ServerProcessCtl(parent, pi, trx); + if (parent != null) + { + //asynchrous + worker.start(); + } + else + { + //synchrous + worker.run(); + } + return worker; + } // execute + + /** + * Run this process in a new thread + */ + public void start() + { + Thread thread = new Thread(this); + // Set thread name + if (m_pi != null) + thread.setName(m_pi.getTitle()+"-"+m_pi.getAD_PInstance_ID()); + thread.start(); + } + + /** + * Execute Process Instance and Lock UI. + * Calls lockUI and unlockUI if parent is a ASyncProcess + *
+	 *		- Get Process Information
+	 *      - Call Class
+	 *		- Submit SQL Procedure
+	 *		- Run SQL Procedure
+	 *	
+ */ + public void run () + { + log.fine("AD_PInstance_ID=" + m_pi.getAD_PInstance_ID() + + ", Record_ID=" + m_pi.getRecord_ID()); + + // Get Process Information: Name, Procedure Name, ClassName, IsReport, IsDirectPrint + String ProcedureName = ""; + String JasperReport = ""; + int AD_ReportView_ID = 0; + int AD_Workflow_ID = 0; + boolean IsReport = false; + boolean isPrintPreview = m_pi.isPrintPreview(); + + // + String sql = "SELECT p.Name, p.ProcedureName,p.ClassName, p.AD_Process_ID," // 1..4 + + " p.isReport,p.IsDirectPrint,p.AD_ReportView_ID,p.AD_Workflow_ID," // 5..8 + + " CASE WHEN COALESCE(p.Statistic_Count,0)=0 THEN 0 ELSE p.Statistic_Seconds/p.Statistic_Count END CASE," + + " p.IsServerProcess, p.JasperReport " + + "FROM AD_Process p" + + " INNER JOIN AD_PInstance i ON (p.AD_Process_ID=i.AD_Process_ID) " + + "WHERE p.IsActive='Y'" + + " AND i.AD_PInstance_ID=?"; + if (!Env.isBaseLanguage(Env.getCtx(), "AD_Process")) + sql = "SELECT t.Name, p.ProcedureName,p.ClassName, p.AD_Process_ID," // 1..4 + + " p.isReport, p.IsDirectPrint,p.AD_ReportView_ID,p.AD_Workflow_ID," // 5..8 + + " CASE WHEN COALESCE(p.Statistic_Count,0)=0 THEN 0 ELSE p.Statistic_Seconds/p.Statistic_Count END CASE," + + " p.IsServerProcess, p.JasperReport " + + "FROM AD_Process p" + + " INNER JOIN AD_PInstance i ON (p.AD_Process_ID=i.AD_Process_ID) " + + " INNER JOIN AD_Process_Trl t ON (p.AD_Process_ID=t.AD_Process_ID" + + " AND t.AD_Language='" + Env.getAD_Language(Env.getCtx()) + "') " + + "WHERE p.IsActive='Y'" + + " AND i.AD_PInstance_ID=?"; + // + PreparedStatement pstmt = null; + ResultSet rs = null; + try + { + pstmt = DB.prepareStatement(sql, + ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, null); + pstmt.setInt(1, m_pi.getAD_PInstance_ID()); + rs = pstmt.executeQuery(); + if (rs.next()) + { + m_pi.setTitle (rs.getString(1)); + if (m_waiting != null) + m_waiting.setTitle(m_pi.getTitle()); + ProcedureName = rs.getString(2); + m_pi.setClassName (rs.getString(3)); + m_pi.setAD_Process_ID (rs.getInt(4)); + // Report + if ("Y".equals(rs.getString(5))) + { + IsReport = true; + } + AD_ReportView_ID = rs.getInt(7); + AD_Workflow_ID = rs.getInt(8); + // + int estimate = rs.getInt(9); + if (estimate != 0) + { + m_pi.setEstSeconds (estimate + 1); // admin overhead + if (m_waiting != null) + m_waiting.setTimerEstimate(m_pi.getEstSeconds()); + } + m_IsServerProcess = "Y".equals(rs.getString(10)); + JasperReport = rs.getString(11); + } + else + log.log(Level.SEVERE, "No AD_PInstance_ID=" + m_pi.getAD_PInstance_ID()); + } + catch (Throwable e) + { + m_pi.setSummary (Msg.getMsg(Env.getCtx(), "ProcessNoProcedure") + " " + e.getLocalizedMessage(), true); + log.log(Level.SEVERE, "run", e); + return; + } + finally + { + DB.close(rs, pstmt); + rs = null; pstmt = null; + } + + // No PL/SQL Procedure + if (ProcedureName == null) + ProcedureName = ""; + + + /********************************************************************** + * Workflow + */ + if (AD_Workflow_ID > 0) + { + startWorkflow (AD_Workflow_ID); + return; + } + + // Clear Jasper Report class if default - to be executed later + boolean isJasper = false; + if (JasperReport != null && JasperReport.trim().length() > 0) { + isJasper = true; + if (ProcessUtil.JASPER_STARTER_CLASS.equals(m_pi.getClassName())) { + m_pi.setClassName(null); + } + } + + /********************************************************************** + * Start Optional Class + */ + if (m_pi.getClassName() != null) + { + if (isJasper) + { + m_pi.setReportingProcess(true); + } + + // Run Class + if (!startProcess()) + { + return; + } + + // No Optional SQL procedure ... done + if (!IsReport && ProcedureName.length() == 0) + { + return; + } + // No Optional Report ... done + if (IsReport && AD_ReportView_ID == 0 && ! isJasper) + { + return; + } + } + + /********************************************************************** + * Report submission + */ + // Optional Pre-Report Process + if (IsReport && ProcedureName.length() > 0) + { + m_pi.setReportingProcess(true); + if (!startDBProcess(ProcedureName)) + { + return; + } + } // Pre-Report + + if (isJasper) + { + m_pi.setReportingProcess(true); + m_pi.setClassName(ProcessUtil.JASPER_STARTER_CLASS); + startProcess(); + return; + } + + if (IsReport) + { + m_pi.setReportingProcess(true); + // Start Report ----------------------------------------------- + boolean ok = ServerReportCtl.start(m_parent, m_pi); + m_pi.setSummary("Report", !ok); + } + /********************************************************************** + * Process submission + */ + else + { + if (!startDBProcess (ProcedureName)) + { + return; + } + // Success - getResult + ProcessInfoUtil.setSummaryFromDB(m_pi); + } // *** Process submission *** + // log.fine(Log.l3_Util, "ProcessCtl.run - done"); + } // run + + /************************************************************************** + * Start Workflow. + * + * @param AD_Workflow_ID workflow + * @return true if started + */ + protected boolean startWorkflow (int AD_Workflow_ID) + { + log.fine(AD_Workflow_ID + " - " + m_pi); + boolean started = false; + if (m_IsServerProcess) + { + Server server = CConnection.get().getServer(); + try + { + if (server != null) + { // See ServerBean + m_pi = server.workflow (Env.getRemoteCallCtx(Env.getCtx()), m_pi, AD_Workflow_ID); + log.finest("server => " + m_pi); + started = true; + } + } + catch (Exception ex) + { + log.log(Level.SEVERE, "AppsServer error", ex); + started = false; + } + } + // Run locally + if (!started && !m_IsServerProcess) + { + if (m_trx != null) + m_pi.setTransactionName(m_trx.getTrxName()); + MWFProcess wfProcess = ProcessUtil.startWorkFlow(Env.getCtx(), m_pi, AD_Workflow_ID); + started = wfProcess != null; + } + return started; + } // startWorkflow + + /************************************************************************** + * Start Java Process Class. + * instanciate the class implementing the interface ProcessCall. + * The class can be a Server/Client class (when in Package + * org adempiere.process or org.compiere.model) or a client only class + * (e.g. in org.compiere.report) + * + * @return true if success + */ + protected boolean startProcess () + { + log.fine(m_pi.toString()); + boolean started = false; + + //hengsin, bug [ 1633995 ] + boolean clientOnly = false; + if (! m_pi.getClassName().toLowerCase().startsWith(MRule.SCRIPT_PREFIX)) { + try { + Class processClass = Class.forName(m_pi.getClassName()); + if (ClientProcess.class.isAssignableFrom(processClass)) + clientOnly = true; + } catch (Exception e) {} + } + + if (m_IsServerProcess && !clientOnly) + { + Server server = CConnection.get().getServer(); + try + { + if (server != null) + { + // See ServerBean + m_pi = server.process (Env.getRemoteCallCtx(Env.getCtx()), m_pi); + log.finest("server => " + m_pi); + started = true; + } + } + catch (UndeclaredThrowableException ex) + { + Throwable cause = ex.getCause(); + if (cause != null) + { + if (cause instanceof InvalidClassException) + log.log(Level.SEVERE, "Version Server <> Client: " + + cause.toString() + " - " + m_pi, ex); + else + log.log(Level.SEVERE, "AppsServer error(1b): " + + cause.toString() + " - " + m_pi, ex); + } + else + log.log(Level.SEVERE, " AppsServer error(1) - " + + m_pi, ex); + started = false; + } + catch (Exception ex) + { + Throwable cause = ex.getCause(); + if (cause == null) + cause = ex; + log.log(Level.SEVERE, "AppsServer error - " + m_pi, cause); + started = false; + } + } + // Run locally + if (!started && (!m_IsServerProcess || clientOnly )) + { + if (m_pi.getClassName().toLowerCase().startsWith(MRule.SCRIPT_PREFIX)) { + return ProcessUtil.startScriptProcess(Env.getCtx(), m_pi, m_trx); + } else { + return ProcessUtil.startJavaProcess(Env.getCtx(), m_pi, m_trx); + } + } + return !m_pi.isError(); + } // startProcess + + + /************************************************************************** + * Start Database Process + * @param ProcedureName PL/SQL procedure name + * @return true if success + */ + protected boolean startDBProcess (String ProcedureName) + { + // execute on this thread/connection + log.fine(ProcedureName + "(" + m_pi.getAD_PInstance_ID() + ")"); + boolean started = false; + String trxName = m_trx != null ? m_trx.getTrxName() : null; + if (m_IsServerProcess) + { + Server server = CConnection.get().getServer(); + try + { + if (server != null) + { // See ServerBean + m_pi = server.dbProcess(m_pi, ProcedureName); + log.finest("server => " + m_pi); + started = true; + } + } + catch (UndeclaredThrowableException ex) + { + Throwable cause = ex.getCause(); + if (cause != null) + { + if (cause instanceof InvalidClassException) + log.log(Level.SEVERE, "Version Server <> Client: " + + cause.toString() + " - " + m_pi, ex); + else + log.log(Level.SEVERE, "AppsServer error(1b): " + + cause.toString() + " - " + m_pi, ex); + } + else + { + log.log(Level.SEVERE, " AppsServer error(1) - " + + m_pi, ex); + cause = ex; + } + m_pi.setSummary (Msg.getMsg(Env.getCtx(), "ProcessRunError") + " " + cause.getLocalizedMessage()); + m_pi.setError (true); + return false; + } + catch (Exception ex) + { + Throwable cause = ex.getCause(); + if (cause == null) + cause = ex; + log.log(Level.SEVERE, "AppsServer error - " + m_pi, cause); + m_pi.setSummary (Msg.getMsg(Env.getCtx(), "ProcessRunError") + " " + cause.getLocalizedMessage()); + m_pi.setError (true); + return false; + } + } + + //try locally + if (!started) + { + return ProcessUtil.startDatabaseProcedure(m_pi, ProcedureName, m_trx); + } + return true; + } // startDBProcess + +} diff --git a/client/src/org/compiere/print/ReportCtl.java b/client/src/org/compiere/print/ReportCtl.java index 46cabe43e6..dc9dbec0eb 100644 --- a/client/src/org/compiere/print/ReportCtl.java +++ b/client/src/org/compiere/print/ReportCtl.java @@ -55,12 +55,6 @@ public class ReportCtl { } // ReportCtrl - /** - * Constants used to pass process parameters to Jasper Process - */ - public static final String PARAM_PRINTER_NAME = "PRINTER_NAME"; - public static final String PARAM_PRINT_FORMAT = "PRINT_FORMAT"; - public static final String PARAM_PRINT_INFO = "PRINT_INFO"; /** Static Logger */ private static CLogger s_log = CLogger.getCLogger (ReportCtl.class); @@ -331,47 +325,7 @@ public class ReportCtl // ============================== if(format.getJasperProcess_ID() > 0) { - ProcessInfo pi = new ProcessInfo ("", format.getJasperProcess_ID()); - pi.setPrintPreview( !IsDirectPrint ); - pi.setRecord_ID ( Record_ID ); - Vector jasperPrintParams = new Vector(); - ProcessInfoParameter pip; - if (printerName!=null && printerName.trim().length()>0) { - // Override printer name - pip = new ProcessInfoParameter(PARAM_PRINTER_NAME, printerName, null, null, null); - jasperPrintParams.add(pip); - } - pip = new ProcessInfoParameter(PARAM_PRINT_FORMAT, format, null, null, null); - jasperPrintParams.add(pip); - pip = new ProcessInfoParameter(PARAM_PRINT_INFO, re.getPrintInfo(), null, null, null); - jasperPrintParams.add(pip); - - pi.setParameter(jasperPrintParams.toArray(new ProcessInfoParameter[]{})); - - // Execute Process - if (Ini.isClient()) - { - ProcessCtl.process(null, // Parent set to null for synchronous processing, see bugtracker 3010932 - WindowNo, - pi, - null); - } - else - { - try - { - ClassLoader loader = Thread.currentThread().getContextClassLoader(); - if (loader == null) - loader = ReportCtl.class.getClassLoader(); - Class clazz = loader.loadClass("org.adempiere.webui.apps.WProcessCtl"); - Method method = clazz.getDeclaredMethod("process", ASyncProcess.class, Integer.TYPE, ProcessInfo.class, Trx.class); - method.invoke(null, parent, WindowNo, pi, null); - } - catch (Exception e) - { - throw new AdempiereException(e); - } - } + ServerReportCtl.runJasperProcess(Record_ID, re, IsDirectPrint, printerName); } else // Standard Print Format (Non-Jasper)