Enabled Jasper Report printing from server processes.
This fix also fixes bug 3017049 - Direct print doesn't work with JasperReports. There is unfortunately some duplication of code that would look nicer with inheritance but that can be next step, now at least it works and this is a crucial function for organizations that use Jasper Reports for invoices etc. Link to SF Tracker: http://sourceforge.net/support/tracker.php?aid=2973199
This commit is contained in:
parent
d02a51799c
commit
4b76addfa3
|
@ -75,6 +75,7 @@ import org.compiere.model.X_AD_PInstance_Para;
|
||||||
import org.compiere.print.MPrintFormat;
|
import org.compiere.print.MPrintFormat;
|
||||||
import org.compiere.print.PrintUtil;
|
import org.compiere.print.PrintUtil;
|
||||||
import org.compiere.print.ReportCtl;
|
import org.compiere.print.ReportCtl;
|
||||||
|
import org.compiere.print.ServerReportCtl;
|
||||||
import org.compiere.process.ClientProcess;
|
import org.compiere.process.ClientProcess;
|
||||||
import org.compiere.process.ProcessCall;
|
import org.compiere.process.ProcessCall;
|
||||||
import org.compiere.process.ProcessInfo;
|
import org.compiere.process.ProcessInfo;
|
||||||
|
@ -493,13 +494,13 @@ public class ReportStarter implements ProcessCall, ClientProcess
|
||||||
// Get print format and print info parameters
|
// Get print format and print info parameters
|
||||||
if (pip!=null) {
|
if (pip!=null) {
|
||||||
for (int i=0; i<pip.length; i++) {
|
for (int i=0; i<pip.length; i++) {
|
||||||
if (ReportCtl.PARAM_PRINT_FORMAT.equalsIgnoreCase(pip[i].getParameterName())) {
|
if (ServerReportCtl.PARAM_PRINT_FORMAT.equalsIgnoreCase(pip[i].getParameterName())) {
|
||||||
printFormat = (MPrintFormat)pip[i].getParameter();
|
printFormat = (MPrintFormat)pip[i].getParameter();
|
||||||
}
|
}
|
||||||
if (ReportCtl.PARAM_PRINT_INFO.equalsIgnoreCase(pip[i].getParameterName())) {
|
if (ServerReportCtl.PARAM_PRINT_INFO.equalsIgnoreCase(pip[i].getParameterName())) {
|
||||||
printInfo = (PrintInfo)pip[i].getParameter();
|
printInfo = (PrintInfo)pip[i].getParameter();
|
||||||
}
|
}
|
||||||
if (ReportCtl.PARAM_PRINTER_NAME.equalsIgnoreCase(pip[i].getParameterName())) {
|
if (ServerReportCtl.PARAM_PRINTER_NAME.equalsIgnoreCase(pip[i].getParameterName())) {
|
||||||
printerName = (String)pip[i].getParameter();
|
printerName = (String)pip[i].getParameter();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -552,7 +553,7 @@ public class ReportStarter implements ProcessCall, ClientProcess
|
||||||
try {
|
try {
|
||||||
conn = getConnection();
|
conn = getConnection();
|
||||||
jasperPrint = JasperFillManager.fillReport( jasperReport, params, conn);
|
jasperPrint = JasperFillManager.fillReport( jasperReport, params, conn);
|
||||||
if (reportData.isDirectPrint())
|
if (reportData.isDirectPrint() || !processInfo.isPrintPreview())
|
||||||
{
|
{
|
||||||
log.info( "ReportStarter.startProcess print report -" + jasperPrint.getName());
|
log.info( "ReportStarter.startProcess print report -" + jasperPrint.getName());
|
||||||
//RF 1906632
|
//RF 1906632
|
||||||
|
|
|
@ -0,0 +1,267 @@
|
||||||
|
package org.compiere.print;
|
||||||
|
|
||||||
|
import java.awt.Container;
|
||||||
|
import java.util.Properties;
|
||||||
|
import java.util.Vector;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
import org.compiere.apps.ProcessCtl;
|
||||||
|
import org.compiere.apps.ProcessParameter;
|
||||||
|
import org.compiere.model.MPInstance;
|
||||||
|
import org.compiere.model.MProcess;
|
||||||
|
import org.compiere.model.MQuery;
|
||||||
|
import org.compiere.model.MTable;
|
||||||
|
import org.compiere.model.PrintInfo;
|
||||||
|
import org.compiere.process.ProcessInfo;
|
||||||
|
import org.compiere.process.ProcessInfoParameter;
|
||||||
|
import org.compiere.process.ServerProcessCtl;
|
||||||
|
import org.compiere.util.ASyncProcess;
|
||||||
|
import org.compiere.util.CLogger;
|
||||||
|
import org.compiere.util.Env;
|
||||||
|
import org.compiere.util.Ini;
|
||||||
|
import org.compiere.util.Msg;
|
||||||
|
import org.compiere.util.Trx;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public class ServerReportCtl {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 (ServerReportCtl.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start Document Print for Type with specified printer.
|
||||||
|
* @param type document type in ReportEngine
|
||||||
|
* @param Record_ID id
|
||||||
|
* @param parent The window which invoked the printing
|
||||||
|
* @param WindowNo The windows number which invoked the printing
|
||||||
|
* @param printerName Specified printer name
|
||||||
|
* @return true if success
|
||||||
|
*/
|
||||||
|
public static boolean startDocumentPrint (int type, MPrintFormat customPrintFormat, int Record_ID, String printerName)
|
||||||
|
{
|
||||||
|
ReportEngine re = ReportEngine.get (Env.getCtx(), type, Record_ID);
|
||||||
|
if (re == null)
|
||||||
|
{
|
||||||
|
CLogger log = CLogger.getCLogger(ServerReportCtl.class);
|
||||||
|
log.warning("NoDocPrintFormat");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (customPrintFormat!=null) {
|
||||||
|
// Use custom print format if available
|
||||||
|
re.setPrintFormat(customPrintFormat);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (re.getPrintFormat()!=null)
|
||||||
|
{
|
||||||
|
MPrintFormat format = re.getPrintFormat();
|
||||||
|
|
||||||
|
// We have a Jasper Print Format
|
||||||
|
// ==============================
|
||||||
|
if(format.getJasperProcess_ID() > 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<ProcessInfoParameter> jasperPrintParams = new Vector<ProcessInfoParameter>();
|
||||||
|
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.<br>
|
||||||
|
* A report can be created from:
|
||||||
|
* <ol>
|
||||||
|
* <li>attached MPrintFormat, if any (see {@link ProcessInfo#setTransientObject(Object)}, {@link ProcessInfo#setSerializableObject(java.io.Serializable)}
|
||||||
|
* <li>process information (AD_Process.AD_PrintFormat_ID, AD_Process.AD_ReportView_ID)
|
||||||
|
* </ol>
|
||||||
|
* @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
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -32,6 +32,7 @@ import org.compiere.model.PrintInfo;
|
||||||
import org.compiere.model.X_C_Invoice;
|
import org.compiere.model.X_C_Invoice;
|
||||||
import org.compiere.print.MPrintFormat;
|
import org.compiere.print.MPrintFormat;
|
||||||
import org.compiere.print.ReportEngine;
|
import org.compiere.print.ReportEngine;
|
||||||
|
import org.compiere.print.ServerReportCtl;
|
||||||
import org.compiere.util.AdempiereUserError;
|
import org.compiere.util.AdempiereUserError;
|
||||||
import org.compiere.util.DB;
|
import org.compiere.util.DB;
|
||||||
import org.compiere.util.EMail;
|
import org.compiere.util.EMail;
|
||||||
|
@ -336,8 +337,11 @@ public class InvoicePrint extends SvrProcess
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
re.print();
|
ServerReportCtl.startDocumentPrint(ReportEngine.INVOICE,
|
||||||
// ReportCtl.startDocumentPrint(ReportEngine.INVOICE, C_Invoice_ID, null, 0, true);
|
null, // No custom print format
|
||||||
|
C_Invoice_ID,
|
||||||
|
null // No custom printer
|
||||||
|
);
|
||||||
count++;
|
count++;
|
||||||
printed = true;
|
printed = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
* <code>
|
||||||
|
* - Get Instance ID
|
||||||
|
* - Get Parameters
|
||||||
|
* - execute (lock - start process - unlock)
|
||||||
|
* </code>
|
||||||
|
* Creates a ProcessCtl instance, which calls
|
||||||
|
* lockUI and unlockUI if parent is a ASyncProcess
|
||||||
|
* <br>
|
||||||
|
* 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
|
||||||
|
* <pre>
|
||||||
|
* - Get Process Information
|
||||||
|
* - Call Class
|
||||||
|
* - Submit SQL Procedure
|
||||||
|
* - Run SQL Procedure
|
||||||
|
* </pre>
|
||||||
|
*/
|
||||||
|
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
|
||||||
|
|
||||||
|
}
|
|
@ -55,12 +55,6 @@ public class ReportCtl
|
||||||
{
|
{
|
||||||
} // ReportCtrl
|
} // 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 */
|
/** Static Logger */
|
||||||
private static CLogger s_log = CLogger.getCLogger (ReportCtl.class);
|
private static CLogger s_log = CLogger.getCLogger (ReportCtl.class);
|
||||||
|
@ -331,47 +325,7 @@ public class ReportCtl
|
||||||
// ==============================
|
// ==============================
|
||||||
if(format.getJasperProcess_ID() > 0)
|
if(format.getJasperProcess_ID() > 0)
|
||||||
{
|
{
|
||||||
ProcessInfo pi = new ProcessInfo ("", format.getJasperProcess_ID());
|
ServerReportCtl.runJasperProcess(Record_ID, re, IsDirectPrint, printerName);
|
||||||
pi.setPrintPreview( !IsDirectPrint );
|
|
||||||
pi.setRecord_ID ( Record_ID );
|
|
||||||
Vector<ProcessInfoParameter> jasperPrintParams = new Vector<ProcessInfoParameter>();
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
// Standard Print Format (Non-Jasper)
|
// Standard Print Format (Non-Jasper)
|
||||||
|
|
Loading…
Reference in New Issue