/****************************************************************************** * 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.compiere.print; import static org.compiere.model.SystemIDs.PROCESS_RPT_M_INVENTORY; import static org.compiere.model.SystemIDs.PROCESS_RPT_M_MOVEMENT; import java.awt.print.PrinterJob; import java.io.BufferedWriter; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.Writer; import java.net.URI; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Timestamp; import java.util.ArrayList; import java.util.List; import java.util.Locale; import java.util.Properties; import java.util.logging.Level; import javax.print.attribute.PrintRequestAttributeSet; import javax.print.attribute.standard.Copies; import javax.print.attribute.standard.JobName; import javax.print.event.PrintServiceAttributeEvent; import javax.print.event.PrintServiceAttributeListener; import org.adempiere.exceptions.AdempiereException; import org.compiere.model.MClient; import org.compiere.model.MColumn; import org.compiere.model.MDunningRunEntry; import org.compiere.model.MInOut; import org.compiere.model.MInventory; import org.compiere.model.MInvoice; import org.compiere.model.MLanguage; import org.compiere.model.MMovement; import org.compiere.model.MOrder; import org.compiere.model.MPInstance; import org.compiere.model.MPaySelectionCheck; import org.compiere.model.MProcess; import org.compiere.model.MProject; import org.compiere.model.MQuery; import org.compiere.model.MRfQResponse; import org.compiere.model.MSysConfig; import org.compiere.model.MTable; import org.compiere.model.PO; import org.compiere.model.PrintInfo; import org.compiere.print.layout.LayoutEngine; import org.compiere.print.layout.PrintDataEvaluatee; import org.compiere.process.ProcessInfo; import org.compiere.process.ProcessInfoParameter; import org.compiere.process.ServerProcessCtl; import org.compiere.tools.FileUtil; import org.compiere.util.CLogger; import org.compiere.util.DB; import org.compiere.util.Env; import org.compiere.util.Evaluator; import org.compiere.util.Ini; import org.compiere.util.Language; import org.compiere.util.Trx; import org.compiere.util.Util; import org.eevolution.model.MDDOrder; import org.eevolution.model.X_PP_Order; import org.idempiere.print.renderer.CSVReportRenderer; import org.idempiere.print.renderer.CSVReportRendererConfiguration; import org.idempiere.print.renderer.HTMLReportRenderer; import org.idempiere.print.renderer.HTMLReportRendererConfiguration; import org.idempiere.print.renderer.PDFReportRenderer; import org.idempiere.print.renderer.PDFReportRendererConfiguration; import org.idempiere.print.renderer.PSReportRenderer; import org.idempiere.print.renderer.PSReportRendererConfiguration; import org.idempiere.print.renderer.SSVReportRenderer; import org.idempiere.print.renderer.SSVReportRendererConfiguration; import org.idempiere.print.renderer.TabDelimitedReportRenderer; import org.idempiere.print.renderer.TabDelimitedReportRendererConfiguration; import org.idempiere.print.renderer.XLSReportRenderer; import org.idempiere.print.renderer.XLSReportRendererConfiguration; import org.idempiere.print.renderer.XLSXReportRenderer; import org.idempiere.print.renderer.XLSXReportRendererConfiguration; import org.idempiere.print.renderer.XMLReportRenderer; import org.idempiere.print.renderer.XMLReportRendererConfiguration; /** * Report Engine.
* For a given PrintFormat, create a Report. *

* Change log: *

* * @author Jorg Janke * @version $Id: ReportEngine.java,v 1.4 2006/10/08 06:52:51 comdivision Exp $ * * @author Teo Sarca, www.arhipac.ro *
  • BF [ 2828300 ] Error when printformat table differs from DOC_TABLES * https://sourceforge.net/p/adempiere/bugs/1995/ *
  • BF [ 2828886 ] Problem with reports from temporary tables * https://sourceforge.net/p/adempiere/bugs/2000/ * * FR 2872010 - Dunning Run for a complete Dunning (not just level) - Developer: Carlos Ruiz - globalqss - Sponsor: Metas */ public class ReportEngine implements PrintServiceAttributeListener { /** * Constructor * @param ctx context * @param pf Print Format * @param query Optional Query * @param info print info */ public ReportEngine (Properties ctx, MPrintFormat pf, MQuery query, PrintInfo info) { this(ctx, pf, query, info, null); } // ReportEngine /** * Create report engine with summary and null transaction * @param ctx * @param pf * @param query * @param info * @param isSummary */ public ReportEngine (Properties ctx, MPrintFormat pf, MQuery query, PrintInfo info, boolean isSummary) { this(ctx, pf, query, info, isSummary, null); } // ReportEngine /** * Create report engine with summary = false * @param ctx * @param pf * @param query * @param info * @param trxName */ public ReportEngine (Properties ctx, MPrintFormat pf, MQuery query, PrintInfo info, String trxName){ this(ctx, pf, query, info, false, trxName); } /** * Constructor * @param ctx context * @param pf Print Format * @param query Optional Query * @param info print info * @param isSummary * @param trxName */ public ReportEngine (Properties ctx, MPrintFormat pf, MQuery query, PrintInfo info, boolean isSummary, String trxName) { this(ctx, pf, query, info, false, trxName, 0); } /** * Set report engine with summary = false * @param ctx * @param pf * @param query * @param info * @param trxName * @param windowNo */ public ReportEngine (Properties ctx, MPrintFormat pf, MQuery query, PrintInfo info, String trxName, int windowNo){ this(ctx, pf, query, info, false, trxName, windowNo); } /** * Constructor * @param ctx context * @param pf Print Format * @param query Optional Query * @param info print info * @param isSummary * @param trxName * @param windowNo */ public ReportEngine (Properties ctx, MPrintFormat pf, MQuery query, PrintInfo info, boolean isSummary, String trxName, int windowNo) { m_summary = isSummary; if (pf == null) throw new IllegalArgumentException("ReportEngine - no PrintFormat"); if (log.isLoggable(Level.INFO)) log.info(pf + " -- " + query); m_ctx = ctx; // m_printFormat = pf; m_info = info; m_trxName = trxName; m_windowNo = windowNo; initName(); setQuery(query); // loads Data } // ReportEngine /** Static Logger */ private static CLogger log = CLogger.getCLogger (ReportEngine.class); /** Context */ private Properties m_ctx; /** Print Format */ private MPrintFormat m_printFormat; /** Print Info */ private PrintInfo m_info; /** Query */ private MQuery m_query; /** Query Data */ private PrintData m_printData; /** Layout */ private LayoutEngine m_layout = null; /** Printer */ private String m_printerName = Ini.getProperty(Ini.P_PRINTER); /** Transaction Name */ private String m_trxName = null; /** Where filter */ private String m_whereExtended = null; /** Window */ private int m_windowNo = 0; private int m_language_id = 0; private boolean m_summary = false; private String m_name = null; private boolean m_isReplaceTabContent = false; private List eventListeners = new ArrayList(); /** * Add report engine event listener * @param listener */ public void addEventListener(IReportEngineEventListener listener) { eventListeners.add(listener); } /** * Remove report engine event listener * @param listener * @return true if found and remove */ public boolean removeEventListener(IReportEngineEventListener listener) { return eventListeners.remove(listener); } /** * Set PrintFormat. * If Layout was created, re-create layout * @param pf print format */ public void setPrintFormat (MPrintFormat pf) { m_printFormat = pf; pf.reloadItems(); if (m_layout != null) { setPrintData(); m_layout.setPrintFormat(pf, false); m_layout.setPrintData(m_printData, m_query, true); // format changes data } IReportEngineEventListener[] listeners = eventListeners.toArray(new IReportEngineEventListener[0]); for(IReportEngineEventListener listener : listeners) { listener.onPrintFormatChanged(new ReportEngineEvent(this)); } } // setPrintFormat /** * Set Query and load PrintData.
    * If Layout was created, re-create layout.
    * Fire onQueryChanged event. * @param query query */ public void setQuery (MQuery query) { m_query = query; if (query == null) return; // setPrintData(); if (m_layout != null) m_layout.setPrintData(m_printData, m_query, true); IReportEngineEventListener[] listeners = eventListeners.toArray(new IReportEngineEventListener[0]); for(IReportEngineEventListener listener : listeners) { listener.onQueryChanged(new ReportEngineEvent(this)); } } // setQuery /** * Get Query * @return query */ public MQuery getQuery() { return m_query; } // getQuery /** * Load PrintData (m_printData) for Format restricted by Query.
    * Nothing loaded if there is no query. */ private void setPrintData() { if (m_query == null) return; DataEngine de = new DataEngine(m_printFormat.getLanguage(),m_trxName, m_windowNo); setPrintData(de.getPrintData (m_ctx, m_printFormat, m_query, m_summary)); } // setPrintData /** * Get PrintData * @return print data */ public PrintData getPrintData() { return m_printData; } // getPrintData /** * Set PrintData * @param printData printData */ public void setPrintData (PrintData printData) { if (printData == null) return; m_printData = printData; } // setPrintData /** * Layout * @see LayoutEngine */ private void layout() { if (m_printFormat == null) throw new IllegalStateException ("No print format"); if (m_printFormat.getJasperProcess_ID() > 0) return; if (m_printData == null) throw new IllegalStateException ("No print data (Delete Print Format and restart)"); m_layout = new LayoutEngine (m_printFormat, m_printData, m_query, m_info, m_trxName, m_windowNo); } // layout /** * Get Layout Engine * @return Layout engine */ public LayoutEngine getLayout() { if (m_layout == null) layout(); return m_layout; } // getLayout /** * Initialize Report Name */ public void initName() { Language language = m_printFormat.getLanguage(); String processFileNamePattern = m_printFormat.get_Translation(MPrintFormat.COLUMNNAME_FileNamePattern, language.getAD_Language()); if (m_info.getAD_Process_ID()>0) { MProcess process = new MProcess(Env.getCtx(), m_info.getAD_Process_ID(), m_trxName); if (process !=null && !Util.isEmpty(process.getFileNamePattern())) { processFileNamePattern = process.getFileNamePattern(); } } if(Util.isEmpty(processFileNamePattern)) { m_name = m_printFormat.get_Translation(MPrintFormat.COLUMNNAME_Name); } else { m_name = FileUtil.parseTitle(m_ctx, processFileNamePattern, m_info.getAD_Table_ID(), m_info.getRecord_ID(), m_windowNo, m_trxName); } } // initName /** * Get PrintFormat (Report) Name * @return name */ public String getName() { if (m_name==null) initName(); return m_name; } // getName /** * Get PrintFormat * @return print format */ public MPrintFormat getPrintFormat() { return m_printFormat; } // getPrintFormat /** * Get Print Info * @return info */ public PrintInfo getPrintInfo() { return m_info; } // getPrintInfo /** * Get PrintLayout (Report) Context * @return context */ public Properties getCtx() { return m_ctx; } // getCtx /** * Get Row Count * @return row count */ public int getRowCount() { return m_printData != null ? m_printData.getRowCount() : 0; } // getRowCount /** * Get Column Count * @return column count */ public int getColumnCount() { if (m_layout != null) return m_layout.getColumnCount(); return 0; } // getColumnCount /** * Print Report. Issue print job to printer. */ public void print () { if (log.isLoggable(Level.INFO)) log.info(m_info.toString()); if (m_layout == null) layout(); // Paper Attributes: media-printable-area, orientation-requested, media PrintRequestAttributeSet prats = m_layout.getPaper().getPrintRequestAttributeSet(); // add: copies, job-name, priority if (m_info.isDocumentCopy() || m_info.getCopies() < 1) prats.add (new Copies(1)); else prats.add (new Copies(m_info.getCopies())); Locale locale = Language.getLoginLanguage().getLocale(); prats.add(new JobName(m_printFormat.getName(), locale)); prats.add(PrintUtil.getJobPriority(m_layout.getNumberOfPages(), m_info.getCopies(), true)); try { // PrinterJob PrinterJob job = getPrinterJob(m_info.getPrinterName()); job.setPageable(m_layout.getPageable(false)); // no copy // Dialog try { if (m_info.isWithDialog() && !job.printDialog(prats)) return; } catch (Exception e) { log.log(Level.WARNING, "Operating System Print Issue, check & try again", e); return; } // submit boolean printCopy = m_info.isDocumentCopy() && m_info.getCopies() > 1; ArchiveEngine.get().archive(m_layout, m_info); PrintUtil.print(job, prats, false, printCopy); // Document: Print Copies if (printCopy) { if (log.isLoggable(Level.INFO)) log.info("Copy " + (m_info.getCopies()-1)); prats.add(new Copies(m_info.getCopies()-1)); job = getPrinterJob(m_info.getPrinterName()); job.setPageable (m_layout.getPageable(true)); // Copy PrintUtil.print(job, prats, false, false); } } catch (Exception e) { log.log(Level.SEVERE, "", e); } } // print /** * Print Service Attribute Listener. * @param psae event */ public void attributeUpdate(PrintServiceAttributeEvent psae) { /** PrintEvent on Win32 Printer : \\MAIN\HP LaserJet 5L PrintServiceAttributeSet - length=2 queued-job-count = 0 (class javax.print.attribute.standard.QueuedJobCount) printer-is-accepting-jobs = accepting-jobs (class javax.print.attribute.standard.PrinterIsAcceptingJobs) PrintEvent on Win32 Printer : \\MAIN\HP LaserJet 5L PrintServiceAttributeSet - length=1 queued-job-count = 1 (class javax.print.attribute.standard.QueuedJobCount) PrintEvent on Win32 Printer : \\MAIN\HP LaserJet 5L PrintServiceAttributeSet - length=1 queued-job-count = 0 (class javax.print.attribute.standard.QueuedJobCount) **/ if (log.isLoggable(Level.FINE)) log.fine("attributeUpdate - " + psae); } // attributeUpdate /** * Get PrinterJob based on PrinterName * @param printerName optional Printer Name * @return PrinterJob */ private PrinterJob getPrinterJob (String printerName) { if (printerName != null && printerName.length() > 0) return PrintUtil.getPrinterJob(printerName); return PrintUtil.getPrinterJob(m_printerName); } // getPrinterJob /** * Show Print Dialog and Set Paper.
    * Optionally re-calculate layout. */ public void pageSetupDialog () { if (m_layout == null) layout(); m_layout.pageSetupDialog(getPrinterJob(m_printerName)); IReportEngineEventListener[] listeners = eventListeners.toArray(new IReportEngineEventListener[0]); for(IReportEngineEventListener listener : listeners) { listener.onPageSetupChanged(new ReportEngineEvent(this)); } } // pageSetupDialog /** * Set Printer (name) * @param printerName valid printer name */ public void setPrinterName(String printerName) { if (printerName == null) m_printerName = Ini.getProperty(Ini.P_PRINTER); else m_printerName = printerName; } // setPrinterName /** * Get Printer (name) * @return printer name */ public String getPrinterName() { return m_printerName; } // getPrinterName /** * Create HTML File * @param file file * @param onlyTable if false create complete HTML document * @param language optional language - if null the default language is used to format numbers/dates * @return true if success */ public boolean createHTML (File file, boolean onlyTable, Language language) { return createHTML(file, onlyTable, language, null); } /** * Create HTML File * @param file file * @param onlyTable if false create complete HTML document * @param language optional language - if null the default language is used to format numbers/dates * @param extension optional extension for html output * @return true if success */ public boolean createHTML (File file, boolean onlyTable, Language language, IHTMLExtension extension) { try { Language lang = language; if (lang == null) lang = Language.getLoginLanguage(); Writer fw = new OutputStreamWriter(new FileOutputStream(file, false), Ini.getCharset()); // teo_sarca: save using adempiere charset [ 1658127 ] return createHTML (new BufferedWriter(fw), onlyTable, lang, extension); } catch (FileNotFoundException fnfe) { log.log(Level.SEVERE, "(f) - " + fnfe.toString()); } catch (Exception e) { log.log(Level.SEVERE, "(f)", e); throw new AdempiereException(e); } return false; } // createHTML /** * Write HTML to writer * @param writer writer * @param onlyTable if false create complete HTML document * @param language optional language - if null numbers/dates are not formatted * @return true if success */ public boolean createHTML (Writer writer, boolean onlyTable, Language language) { return createHTML(writer, onlyTable, language, null); } /** * Write HTML to writer with isExport = false * @param writer writer * @param onlyTable if false create complete HTML document * @param language optional language - if null numbers/dates are not formatted * @param extension optional extension for html output * @return true if success */ public boolean createHTML (Writer writer, boolean onlyTable, Language language, IHTMLExtension extension){ return createHTML (writer, onlyTable, language, extension, false); } /** * Write HTML to writer * @param writer writer * @param onlyTable if false create complete HTML document * @param language optional language - if null numbers/dates are not formatted * @param extension optional extension for html output * @param isExport when isExport = true will don't embed resource dependent zk framework * @return true if success */ public boolean createHTML (Writer writer, boolean onlyTable, Language language, IHTMLExtension extension, boolean isExport) { HTMLReportRendererConfiguration config = new HTMLReportRendererConfiguration() .setOutputWriter(writer) .setOnlyTable(onlyTable) .setExport(isExport) .setExtension(extension) .setLanguage(language); new HTMLReportRenderer().renderReport(this, config); return true; } // createHTML /** * Get record identifier string * @param mTable * @param tableName * @param recordID * @return String identifier */ public String getIdentifier(MTable mTable, String tableName, int recordID) { ArrayList list = new ArrayList(); // get translation table - null if not exists MTable mTableTrl = MTable.get(getCtx(), tableName+"_Trl"); String tableNameTrl = ""; // get report language String reportLang = getLanguageID() > 0 ? new MLanguage(getCtx(), getLanguageID(), null).getAD_Language() : Language.getLoginLanguage().getAD_Language(); // use Trl table or base table boolean isTrl = !Env.isBaseLanguage(Language.getLanguage(reportLang), tableName); if(isTrl && mTableTrl != null) tableNameTrl = mTableTrl.getTableName(); else isTrl = false; // load identifier columns for (String idColumnName : mTable.getIdentifierColumns()) { MColumn column = mTable.getColumn(idColumnName); list.add (column); } if(list.size() <= 0) { return String.valueOf(recordID); } StringBuilder displayColumn = new StringBuilder(); String separator = MSysConfig.getValue(MSysConfig.IDENTIFIER_SEPARATOR, "_", Env.getAD_Client_ID(Env.getCtx())); // get record identifier from SQL for(int i = 0; i < list.size(); i++) { MColumn identifierColumn = list.get(i); if(i > 0) displayColumn.append("||'").append(separator).append("'||"); displayColumn.append("COALESCE(") .append(DB.TO_CHAR(addTrlSuffix(identifierColumn, tableName, isTrl)+"."+identifierColumn.getColumnName(), identifierColumn.getAD_Reference_ID(), Env.getAD_Language(Env.getCtx()))) .append(",") .append(DB.TO_CHAR(tableName+"."+identifierColumn.getColumnName(), identifierColumn.getAD_Reference_ID(), Env.getAD_Language(Env.getCtx()))) .append(",'')"); } ArrayList params = new ArrayList(); StringBuilder sql = new StringBuilder("SELECT "); sql.append(displayColumn.toString()); sql.append(" FROM ").append(tableName); if(isTrl) { sql.append(" LEFT JOIN ").append(tableNameTrl).append(" ON ") .append(tableName).append(".").append(tableName).append("_ID = ") .append(tableNameTrl).append(".").append(tableName).append("_ID AND ") .append(tableNameTrl).append(".AD_Language=?"); params.add(reportLang); } sql.append(" WHERE ") .append(tableName).append(".").append(tableName).append("_ID=?"); params.add(recordID); return DB.getSQLValueStringEx(null, sql.toString(), params); } // getIdentifier /** * Add "_Trl" suffix to table name, if the column is translated * @param column * @param tableName * @param isTrl - is translated * @return tableName */ private String addTrlSuffix(MColumn column, String tableName, boolean isTrl) { if(column.isTranslated() && isTrl) return tableName + "_Trl"; else return tableName; } // addTrlSuffix /** * Create delimited text file * @param file file * @param delimiter delimiter, e.g. comma, tab * @param language translation language * @return true if success */ public boolean createCSV (File file, char delimiter, Language language) { try { Writer fw = new OutputStreamWriter(new FileOutputStream(file, false), Ini.getCharset()); // teo_sarca: save using adempiere charset [ 1658127 ] return createCSV (new BufferedWriter(fw), delimiter, language); } catch (FileNotFoundException fnfe) { log.log(Level.SEVERE, "(f) - " + fnfe.toString()); } catch (Exception e) { log.log(Level.SEVERE, "(f)", e); } return false; } // createCSV /** * Write delimited content to writer * @param writer writer * @param delimiter delimiter, e.g. comma, tab * @param language translation language * @return true if success */ public boolean createCSV (Writer writer, char delimiter, Language language) { switch (delimiter) { case ',' -> { CSVReportRendererConfiguration config = new CSVReportRendererConfiguration().setLanguage(language).setOutputWriter(writer); new CSVReportRenderer().renderReport(this, config); } case ';' -> { SSVReportRendererConfiguration config = new SSVReportRendererConfiguration().setLanguage(language).setOutputWriter(writer); new SSVReportRenderer().renderReport(this, config); } case '\t' -> { TabDelimitedReportRendererConfiguration config = new TabDelimitedReportRendererConfiguration().setLanguage(language).setOutputWriter(writer); new TabDelimitedReportRenderer().renderReport(this, config); } default -> throw new IllegalArgumentException("Unexpected value: " + delimiter); } return true; } // createCSV /** * Create XML File * @param file file * @return true if success */ public boolean createXML (File file) { XMLReportRendererConfiguration config = new XMLReportRendererConfiguration().setOutputFile(file); new XMLReportRenderer().renderReport(this, config); return true; } // createXML /** * Write XML to writer * @param writer writer * @return true if success */ public boolean createXML (Writer writer) { XMLReportRendererConfiguration config = new XMLReportRendererConfiguration().setOutputWriter(writer); new XMLReportRenderer().renderReport(this, config); return true; } // createXML /** * Create PDF file (created as temporary file). * @return PDF file */ public File getPDF() { return getPDF (null); } // getPDF /** * Create PDF file. * @param file optional, null to use system generated temporary file * @return PDF file */ public File getPDF (File file) { try { if (file == null) file = (m_pi != null && !Util.isEmpty(m_pi.getPDFFileName(),true)) ? FileUtil.createFile(m_pi.getPDFFileName()) : FileUtil.createTempFile (FileUtil.makePrefix(getName()), ".pdf"); } catch (IOException e) { log.log(Level.SEVERE, "", e); } if (createPDF (file)) return file; return null; } // getPDF /** * Create HTML file (created as temporary file). * @return HTML file */ public File getHTML() { return getHTML(null); } // getHTML /** * Create HTML file. * @param file optional, null to use system generated temporary file * @return HTML file */ public File getHTML(File file) { try { if (file == null) file = FileUtil.createTempFile (FileUtil.makePrefix(getName()), ".html"); } catch (IOException e) { log.log(Level.SEVERE, "", e); } if (createHTML(file, false, Env.getLanguage(getCtx()))) return file; return null; } // getHTML /** * Create CSV file (created as temporary file). * @return CSV file */ public File getCSV() { return getCSV(null); } // getCSV /** * Create CSV file. * @param file optional, null to use system generated temporary file * @return CSV file */ public File getCSV(File file) { try { if (file == null) file = FileUtil.createTempFile (FileUtil.makePrefix(getName()), ".csv"); } catch (IOException e) { log.log(Level.SEVERE, "", e); } if (createCSV(file, ',', Env.getLanguage(getCtx()))) return file; return null; } // getCSV /** * Create XLS file (created as temporary file). * @return XLS file */ public File getXLS() { return getXLS(null); } // getXLS /** * Create XLS file. * @param file optional, null to use system generated temporary file * @return XLS file */ public File getXLS(File file) { try { if (file == null) file = FileUtil.createTempFile (FileUtil.makePrefix(getName()), ".xls"); } catch (IOException e) { log.log(Level.SEVERE, "", e); } try { createXLS(file, Env.getLanguage(getCtx())); return file; } catch (Exception e) { log.log(Level.SEVERE, "", e); return null; } } // getXLS /** * Create XLSX file (created as temporary file). * @return XLSX file */ public File getXLSX() { return getXLSX(null); } // getXLSX /** * Create XLSX file. * @param file optional, null to use system generated temporary file * @return XLSX file */ public File getXLSX(File file) { try { if (file == null) file = FileUtil.createTempFile (FileUtil.makePrefix(getName()), ".xlsx"); } catch (IOException e) { log.log(Level.SEVERE, "", e); } try { createXLSX(file, Env.getLanguage(getCtx())); return file; } catch (Exception e) { log.log(Level.SEVERE, "", e); return null; } } // getXLSX /** * Create PDF File * @param file optional, null to use system generated temporary file * @return true if success */ public boolean createPDF (File file) { String fileName = null; URI uri = null; try { if (file == null) { file = FileUtil.createTempFile ("ReportEngine", ".pdf"); } else { if (file.exists()) { file.delete(); file = new File(file.getAbsolutePath()); } } uri = file.toURI(); fileName = file.getAbsolutePath(); } catch (Exception e) { log.log(Level.SEVERE, "file", e); return false; } if (log.isLoggable(Level.FINE)) log.fine(uri.toString()); try { if (m_printFormat != null && m_printFormat.getJasperProcess_ID() > 0) { ProcessInfo pi = new ProcessInfo ("", m_printFormat.getJasperProcess_ID(), m_printFormat.getAD_Table_ID(), m_info.getRecord_ID()); if (m_printFormat.getLanguage() != null && m_printFormat.getLanguage().getAD_Language() != null) { ProcessInfoParameter reportLanguagePip = new ProcessInfoParameter("AD_Language", m_printFormat.getLanguage().getAD_Language(), null, null, null); pi.setParameter(new ProcessInfoParameter[] {reportLanguagePip}); } pi.setIsBatch(true); pi.setPDFFileName(fileName); pi.setTransientObject(m_printFormat); ServerProcessCtl.process(pi, (m_trxName == null ? null : Trx.get(m_trxName, false)), false); } else { PDFReportRendererConfiguration config = new PDFReportRendererConfiguration().setOutputFile(file); new PDFReportRenderer().renderReport(this, config); } } catch (Exception e) { log.log(Level.SEVERE, "PDF", e); throw new AdempiereException(e); } File file2 = new File(fileName); if (log.isLoggable(Level.INFO)) log.info(file2.getAbsolutePath() + " - " + file2.length()); return file2.exists(); } // createPDF /** * Create PDF as Data array * @return pdf data */ public byte[] createPDFData () { ByteArrayOutputStream os = new ByteArrayOutputStream(); PDFReportRendererConfiguration config = new PDFReportRendererConfiguration().setOutputStream(os); new PDFReportRenderer().renderReport(this, config); return os.toByteArray(); } // createPDFData /** * Create PostScript File * @param file output file * @return true if success */ public boolean createPS (File file) { PSReportRendererConfiguration config = new PSReportRendererConfiguration().setOutputFile(file); new PSReportRenderer().renderReport(this, config); return true; } // createPS /** * Write PostScript to writer * @param os output stream * @return true if success */ public boolean createPS (OutputStream os) { PSReportRendererConfiguration config = new PSReportRendererConfiguration().setOutputStream(os); new PSReportRenderer().renderReport(this, config); return true; } // createPS /** * Create Excel file * @param outFile output file * @param language * @throws Exception if error */ public void createXLS(File outFile, Language language) throws Exception { XLSReportRendererConfiguration config = new XLSReportRendererConfiguration().setOutputFile(outFile).setLanguage(language); new XLSReportRenderer().renderReport(this, config); } /** * Create ExcelX file * @param outFile output file * @param language * @throws Exception if error */ public void createXLSX(File outFile, Language language) throws Exception { XLSXReportRendererConfiguration config = new XLSXReportRendererConfiguration().setOutputFile(outFile).setLanguage(language); new XLSXReportRenderer().renderReport(this, config); } /** * Get Report Engine for process info * @param ctx context * @param pi process info with AD_PInstance_ID * @return report engine or null */ static public ReportEngine get (Properties ctx, ProcessInfo pi) { return get(ctx, pi, 0); } /** * Get Report Engine for process info * @param ctx context * @param pi process info with AD_PInstance_ID * @param windowNo Window No * @return report engine or null */ static public ReportEngine get (Properties ctx, ProcessInfo pi, int windowNo) { int AD_Client_ID = pi.getAD_Client_ID(); // int AD_Table_ID = 0; int AD_ReportView_ID = 0; String TableName = null; int AD_PrintFormat_ID = 0; boolean IsForm = false; int Client_ID = -1; MPInstance instance = null; // Get AD_Table_ID and TableName StringBuilder sql = new StringBuilder("SELECT rv.AD_ReportView_ID,rv.WhereClause,") .append(" t.AD_Table_ID,t.TableName, pf.AD_PrintFormat_ID, pf.IsForm, pf.AD_Client_ID ") .append("FROM AD_PInstance pi") .append(" INNER JOIN AD_Process p ON (pi.AD_Process_ID=p.AD_Process_ID)") .append(" INNER JOIN AD_ReportView rv ON (p.AD_ReportView_ID=rv.AD_ReportView_ID)") .append(" INNER JOIN AD_Table t ON (rv.AD_Table_ID=t.AD_Table_ID)") .append(" LEFT OUTER JOIN AD_PrintFormat pf ON (p.AD_ReportView_ID=pf.AD_ReportView_ID AND pf.AD_Client_ID IN (0,?) AND pf.IsActive='Y') ") .append("WHERE pi.AD_PInstance_ID=? ") // #2 .append("ORDER BY pf.AD_Client_ID DESC, pf.IsDefault DESC"); // own first PreparedStatement pstmt = null; ResultSet rs = null; try { pstmt = DB.prepareStatement(sql.toString(), null); pstmt.setInt(1, AD_Client_ID); pstmt.setInt(2, pi.getAD_PInstance_ID()); rs = pstmt.executeQuery(); // Just get first if (rs.next()) { AD_ReportView_ID = rs.getInt(1); // required // AD_Table_ID = rs.getInt(3); TableName = rs.getString(4); // required for query AD_PrintFormat_ID = rs.getInt(5); // required IsForm = "Y".equals(rs.getString(6)); // required Client_ID = rs.getInt(7); instance = new MPInstance(ctx, pi.getAD_PInstance_ID(), null); if(instance.getAD_PrintFormat_ID() <= 0) instance.setAD_PrintFormat_ID(AD_PrintFormat_ID); else AD_PrintFormat_ID = instance.getAD_PrintFormat_ID(); setDefaultReportTypeToPInstance(ctx, instance, AD_PrintFormat_ID); instance.saveEx(); } } catch (SQLException e1) { log.log(Level.SEVERE, "(1) - " + sql, e1); } finally { DB.close(rs, pstmt); rs = null; pstmt = null; } // Nothing found if (AD_ReportView_ID == 0) { // Check Print format in Report Directly sql = new StringBuilder("SELECT t.AD_Table_ID,t.TableName, pf.AD_PrintFormat_ID, pf.IsForm ") .append("FROM AD_PInstance pi") .append(" INNER JOIN AD_Process p ON (pi.AD_Process_ID=p.AD_Process_ID)") .append(" INNER JOIN AD_PrintFormat pf ON (p.AD_PrintFormat_ID=pf.AD_PrintFormat_ID)") .append(" INNER JOIN AD_Table t ON (pf.AD_Table_ID=t.AD_Table_ID) ") .append("WHERE pi.AD_PInstance_ID=?"); try { pstmt = DB.prepareStatement(sql.toString(), null); pstmt.setInt(1, pi.getAD_PInstance_ID()); rs = pstmt.executeQuery(); if (rs.next()) { AD_Table_ID = rs.getInt(1); TableName = rs.getString(2); // required for query AD_PrintFormat_ID = rs.getInt(3); // required IsForm = "Y".equals(rs.getString(4)); // required Client_ID = AD_Client_ID; instance = new MPInstance(ctx, pi.getAD_PInstance_ID(), null); } } catch (SQLException e1) { log.log(Level.SEVERE, "(2) - " + sql, e1); } finally { DB.close(rs, pstmt); rs = null; pstmt = null; } if (AD_PrintFormat_ID == 0) { log.log(Level.SEVERE, "Report Info NOT found AD_PInstance_ID=" + pi.getAD_PInstance_ID() + ",AD_Client_ID=" + AD_Client_ID); return null; } else if(instance != null) { instance.setAD_PrintFormat_ID(AD_PrintFormat_ID); setDefaultReportTypeToPInstance(ctx, instance, AD_PrintFormat_ID); instance.saveEx(); } } // Create Query from Parameters MQuery query = null; if (IsForm && (pi.getRecord_ID() > 0 || !Util.isEmpty(pi.getRecord_UU())) // Form = one record && !TableName.startsWith("T_") ) // Not temporary table - teo_sarca, BF [ 2828886 ] { if (pi.getRecord_ID() > 0) query = MQuery.getEqualQuery(TableName + "_ID", pi.getRecord_ID()); else query = MQuery.getEqualQuery(PO.getUUIDColumnName(TableName), pi.getRecord_UU()); } else { query = MQuery.get (ctx, pi.getAD_PInstance_ID(), TableName); } // Get Print Format MPrintFormat format = null; Object so = pi.getSerializableObject(); if (so instanceof MPrintFormat) format = (MPrintFormat)so; if (format == null && AD_PrintFormat_ID != 0) { // We have a PrintFormat with the correct Client if (Client_ID == AD_Client_ID) format = MPrintFormat.get (ctx, AD_PrintFormat_ID, false); else format = MPrintFormat.copyToClient (ctx, AD_PrintFormat_ID, AD_Client_ID); } if (format != null && format.getItemCount() == 0) { if (log.isLoggable(Level.INFO)) log.info("No Items - recreating: " + format); format.delete(true); format = null; } // Create Format if (format == null && AD_ReportView_ID != 0) format = MPrintFormat.createFromReportView(ctx, AD_ReportView_ID, pi.getTitle()); if (format == null) return null; // format.setTranslationLanguage(format.getLanguage()); // PrintInfo info = new PrintInfo (pi); info.setAD_Table_ID(AD_Table_ID); return new ReportEngine(ctx, format, query, info, pi.isSummary(), pi.getTransactionName(), windowNo); } // get /** Order = 0 */ public static final int ORDER = 0; /** Shipment = 1 */ public static final int SHIPMENT = 1; /** Invoice = 2 */ public static final int INVOICE = 2; /** Project = 3 */ public static final int PROJECT = 3; /** RfQ = 4 */ public static final int RFQ = 4; /** Remittance = 5 */ public static final int REMITTANCE = 5; /** Check = 6 */ public static final int CHECK = 6; /** Dunning = 7 */ public static final int DUNNING = 7; /** Manufacturing Order = 8 */ public static final int MANUFACTURING_ORDER = 8; /** Distribution Order = 9 */ public static final int DISTRIBUTION_ORDER = 9; /** Physical Inventory = 10 */ public static final int INVENTORY = 10; /** Inventory Move = 11 */ public static final int MOVEMENT = 11; private static final String[] DOC_BASETABLES = new String[] { "C_Order", "M_InOut", "C_Invoice", "C_Project", "C_RfQResponse", "C_PaySelectionCheck", "C_PaySelectionCheck", "C_DunningRunEntry","PP_Order", "DD_Order", "M_Inventory", "M_Movement"}; private static final String[] DOC_IDS = new String[] { "C_Order_ID", "M_InOut_ID", "C_Invoice_ID", "C_Project_ID", "C_RfQResponse_ID", "C_PaySelectionCheck_ID", "C_PaySelectionCheck_ID", "C_DunningRunEntry_ID" , "PP_Order_ID" , "DD_Order_ID", "M_Inventory_ID", "M_Movement_ID" }; private static final int[] DOC_TABLE_ID = new int[] { MOrder.Table_ID, MInOut.Table_ID, MInvoice.Table_ID, MProject.Table_ID, MRfQResponse.Table_ID, MPaySelectionCheck.Table_ID, MPaySelectionCheck.Table_ID, MDunningRunEntry.Table_ID, X_PP_Order.Table_ID, MDDOrder.Table_ID, MInventory.Table_ID, MMovement.Table_ID }; /** * Get Document Print Engine for Document Type. * @param ctx context * @param type document type * @param Record_ID id * @return Report Engine or null */ public static ReportEngine get (Properties ctx, int type, int Record_ID) { return get(ctx, type, Record_ID, null, 0); } /** * Get Document Print Engine for Document Type. * @param ctx context * @param type document type * @param Record_ID id * @return Report Engine or null */ public static ReportEngine get (Properties ctx, int type, int Record_ID, int windowNo) { return get(ctx, type, Record_ID, null, windowNo); } /** * Get Document Print Engine for Document Type. * @param ctx context * @param type document type * @param Record_ID id * @param trxName * @return Report Engine or null */ public static ReportEngine get (Properties ctx, int type, int Record_ID, String trxName) { return get(ctx, type, Record_ID, trxName, 0); } /** * Get Document Print Engine for Document Type. * @param ctx context * @param type document type * @param Record_ID id * @param trxName * @param windowNo * @return Report Engine or null */ public static ReportEngine get(Properties ctx, int type, int Record_ID, String trxName, int windowNo) { if (Record_ID < 1) { log.log(Level.WARNING, "No PrintFormat for Record_ID=" + Record_ID + ", Type=" + type); return null; } // Order - Print Shipment or Invoice if (type == ORDER) { int[] what = getDocumentWhat (Record_ID); if (what != null) { type = what[0]; Record_ID = what[1]; } } // Order int AD_PrintFormat_ID = 0; int C_BPartner_ID = 0; String DocumentNo = null; int copies = 1; // Language MClient client = MClient.get(ctx); Language language = client.getLanguage(); // Get Document Info StringBuilder sql = null; if (type == CHECK) sql = new StringBuilder("SELECT bad.Check_PrintFormat_ID,") // 1 .append(" c.IsMultiLingualDocument,bp.AD_Language,bp.C_BPartner_ID,d.DocumentNo ") // 2..5 .append("FROM C_PaySelectionCheck d") .append(" INNER JOIN C_PaySelection ps ON (d.C_PaySelection_ID=ps.C_PaySelection_ID)") .append(" INNER JOIN C_BankAccountDoc bad ON (ps.C_BankAccount_ID=bad.C_BankAccount_ID AND d.PaymentRule=bad.PaymentRule)") .append(" INNER JOIN AD_Client c ON (d.AD_Client_ID=c.AD_Client_ID)") .append(" INNER JOIN C_BPartner bp ON (d.C_BPartner_ID=bp.C_BPartner_ID) ") .append("WHERE d.C_PaySelectionCheck_ID=?"); // info from BankAccount else if (type == DUNNING) sql = new StringBuilder("SELECT dl.Dunning_PrintFormat_ID,") .append(" c.IsMultiLingualDocument,bp.AD_Language,bp.C_BPartner_ID,dr.DunningDate ") .append("FROM C_DunningRunEntry d") .append(" INNER JOIN AD_Client c ON (d.AD_Client_ID=c.AD_Client_ID)") .append(" INNER JOIN C_BPartner bp ON (d.C_BPartner_ID=bp.C_BPartner_ID)") .append(" INNER JOIN C_DunningRun dr ON (d.C_DunningRun_ID=dr.C_DunningRun_ID)") .append(" INNER JOIN C_DunningLevel dl ON (dl.C_DunningLevel_ID=d.C_DunningLevel_ID) ") .append("WHERE d.C_DunningRunEntry_ID=?"); // info from Dunning else if (type == REMITTANCE) sql = new StringBuilder("SELECT pf.Remittance_PrintFormat_ID,") .append(" c.IsMultiLingualDocument,bp.AD_Language,bp.C_BPartner_ID,d.DocumentNo ") .append("FROM C_PaySelectionCheck d") .append(" INNER JOIN AD_Client c ON (d.AD_Client_ID=c.AD_Client_ID)") .append(" INNER JOIN AD_PrintForm pf ON (c.AD_Client_ID=pf.AD_Client_ID)") .append(" INNER JOIN C_BPartner bp ON (d.C_BPartner_ID=bp.C_BPartner_ID) ") .append("WHERE d.C_PaySelectionCheck_ID=?") // info from PrintForm .append(" AND pf.AD_Org_ID IN (0,d.AD_Org_ID) ORDER BY pf.AD_Org_ID DESC"); else if (type == PROJECT) sql = new StringBuilder("SELECT pf.Project_PrintFormat_ID,") .append(" c.IsMultiLingualDocument,bp.AD_Language,bp.C_BPartner_ID,d.Value ") .append("FROM C_Project d") .append(" INNER JOIN AD_Client c ON (d.AD_Client_ID=c.AD_Client_ID)") .append(" INNER JOIN AD_PrintForm pf ON (c.AD_Client_ID=pf.AD_Client_ID)") .append(" LEFT OUTER JOIN C_BPartner bp ON (d.C_BPartner_ID=bp.C_BPartner_ID) ") .append("WHERE d.C_Project_ID=?") // info from PrintForm .append(" AND pf.AD_Org_ID IN (0,d.AD_Org_ID) ORDER BY pf.AD_Org_ID DESC"); else if (type == MANUFACTURING_ORDER) sql = new StringBuilder("SELECT pf.Manuf_Order_PrintFormat_ID,") .append(" c.IsMultiLingualDocument,bp.AD_Language, 0 , d.DocumentNo ") .append("FROM PP_Order d") .append(" INNER JOIN AD_Client c ON (d.AD_Client_ID=c.AD_Client_ID)") .append(" LEFT OUTER JOIN AD_User u ON (u.AD_User_ID=d.Planner_ID)") .append(" LEFT OUTER JOIN C_BPartner bp ON (u.C_BPartner_ID=bp.C_BPartner_ID) ") .append(" INNER JOIN AD_PrintForm pf ON (c.AD_Client_ID=pf.AD_Client_ID)") .append("WHERE d.PP_Order_ID=?") // info from PrintForm .append(" AND pf.AD_Org_ID IN (0,d.AD_Org_ID) ORDER BY pf.AD_Org_ID DESC"); else if (type == DISTRIBUTION_ORDER) sql = new StringBuilder("SELECT pf.Distrib_Order_PrintFormat_ID,") .append(" c.IsMultiLingualDocument,bp.AD_Language, bp.C_BPartner_ID , d.DocumentNo ") .append("FROM DD_Order d") .append(" INNER JOIN AD_Client c ON (d.AD_Client_ID=c.AD_Client_ID)") .append(" INNER JOIN AD_PrintForm pf ON (c.AD_Client_ID=pf.AD_Client_ID)") .append(" LEFT OUTER JOIN C_BPartner bp ON (d.C_BPartner_ID=bp.C_BPartner_ID) ") .append("WHERE d.DD_Order_ID=?") // info from PrintForm .append(" AND pf.AD_Org_ID IN (0,d.AD_Org_ID) ORDER BY pf.AD_Org_ID DESC"); else if (type == RFQ) sql = new StringBuilder("SELECT COALESCE(t.AD_PrintFormat_ID, pf.AD_PrintFormat_ID),") .append(" c.IsMultiLingualDocument,bp.AD_Language,bp.C_BPartner_ID,rr.Name ") .append("FROM C_RfQResponse rr") .append(" INNER JOIN C_RfQ r ON (rr.C_RfQ_ID=r.C_RfQ_ID)") .append(" INNER JOIN C_RfQ_Topic t ON (r.C_RfQ_Topic_ID=t.C_RfQ_Topic_ID)") .append(" INNER JOIN AD_Client c ON (rr.AD_Client_ID=c.AD_Client_ID)") .append(" INNER JOIN C_BPartner bp ON (rr.C_BPartner_ID=bp.C_BPartner_ID),") .append(" AD_PrintFormat pf ") .append("WHERE pf.AD_Client_ID IN (0,rr.AD_Client_ID)") .append(" AND pf.AD_Table_ID=725 AND pf.IsTableBased='N'") // from RfQ PrintFormat .append(" AND rr.C_RfQResponse_ID=? ") // Info from RfQTopic .append("ORDER BY t.AD_PrintFormat_ID, pf.AD_Client_ID DESC, pf.AD_Org_ID DESC"); // Fix [2574162] Priority to choose invoice print format not working else if (type == ORDER || type == INVOICE) sql = new StringBuilder("SELECT pf.Order_PrintFormat_ID,pf.Shipment_PrintFormat_ID,") // 1..2 // Prio: 1. BPartner 2. DocType, 3. PrintFormat (Org) // see InvoicePrint .append(" COALESCE (bp.Invoice_PrintFormat_ID,dt.AD_PrintFormat_ID,pf.Invoice_PrintFormat_ID),") // 3 .append(" pf.Project_PrintFormat_ID, pf.Remittance_PrintFormat_ID,") // 4..5 .append(" c.IsMultiLingualDocument, bp.AD_Language,") // 6..7 .append(" COALESCE(dt.DocumentCopies,0)+COALESCE(bp.DocumentCopies,1), ") // 8 .append(" dt.AD_PrintFormat_ID,bp.C_BPartner_ID,d.DocumentNo ") // 9..11 .append("FROM " + DOC_BASETABLES[type] + " d") .append(" INNER JOIN AD_Client c ON (d.AD_Client_ID=c.AD_Client_ID)") .append(" INNER JOIN AD_PrintForm pf ON (c.AD_Client_ID=pf.AD_Client_ID)") .append(" INNER JOIN C_BPartner bp ON (d.C_BPartner_ID=bp.C_BPartner_ID)") .append(" LEFT OUTER JOIN C_DocType dt ON ((d.C_DocType_ID>0 AND d.C_DocType_ID=dt.C_DocType_ID) OR (d.C_DocType_ID=0 AND d.C_DocTypeTarget_ID=dt.C_DocType_ID)) ") .append("WHERE d." + DOC_IDS[type] + "=?") // info from PrintForm .append(" AND pf.AD_Org_ID IN (0,d.AD_Org_ID) ") .append("ORDER BY pf.AD_Org_ID DESC"); else if (type == INVENTORY || type == MOVEMENT) sql = new StringBuilder("SELECT COALESCE (dt.AD_PrintFormat_ID, 0), 0,") // 1..2 .append(" NULL, 0 , d.DocumentNo ") // 3..5 .append("FROM " + DOC_BASETABLES[type] + " d") .append(" LEFT OUTER JOIN C_DocType dt ON (d.C_DocType_ID=dt.C_DocType_ID) ") .append("WHERE d." + DOC_IDS[type] + "=?"); // info from PrintForm else // Get PrintFormat from Org or 0 of document client sql = new StringBuilder("SELECT pf.Order_PrintFormat_ID,pf.Shipment_PrintFormat_ID,") // 1..2 // Prio: 1. BPartner 2. DocType, 3. PrintFormat (Org) // see InvoicePrint .append(" COALESCE (bp.Invoice_PrintFormat_ID,dt.AD_PrintFormat_ID,pf.Invoice_PrintFormat_ID),") // 3 .append(" pf.Project_PrintFormat_ID, pf.Remittance_PrintFormat_ID,") // 4..5 .append(" c.IsMultiLingualDocument, bp.AD_Language,") // 6..7 .append(" COALESCE(dt.DocumentCopies,0)+COALESCE(bp.DocumentCopies,1), ") // 8 .append(" dt.AD_PrintFormat_ID,bp.C_BPartner_ID,d.DocumentNo, ") // 9..11 .append(" pf.Manuf_Order_PrintFormat_ID, pf.Distrib_Order_PrintFormat_ID ") // 12..13 .append("FROM " + DOC_BASETABLES[type] + " d") .append(" INNER JOIN AD_Client c ON (d.AD_Client_ID=c.AD_Client_ID)") .append(" INNER JOIN AD_PrintForm pf ON (c.AD_Client_ID=pf.AD_Client_ID)") .append(" INNER JOIN C_BPartner bp ON (d.C_BPartner_ID=bp.C_BPartner_ID)") .append(" LEFT OUTER JOIN C_DocType dt ON (d.C_DocType_ID=dt.C_DocType_ID) ") .append("WHERE d." + DOC_IDS[type] + "=?") // info from PrintForm .append(" AND pf.AD_Org_ID IN (0,d.AD_Org_ID) ") .append("ORDER BY pf.AD_Org_ID DESC"); // PreparedStatement pstmt = null; ResultSet rs = null; try { pstmt = DB.prepareStatement(sql.toString(), trxName); pstmt.setInt(1, Record_ID); rs = pstmt.executeQuery(); if (rs.next()) // first record only { if (type == CHECK || type == DUNNING || type == REMITTANCE || type == PROJECT || type == RFQ || type == MANUFACTURING_ORDER || type == DISTRIBUTION_ORDER || type == INVENTORY || type == MOVEMENT) { AD_PrintFormat_ID = rs.getInt(1); copies = 1; // Set Language when enabled String AD_Language = rs.getString(3); if (AD_Language != null)// && "Y".equals(rs.getString(2))) // IsMultiLingualDocument language = Language.getLanguage(AD_Language); C_BPartner_ID = rs.getInt(4); if (type == DUNNING) { Timestamp ts = rs.getTimestamp(5); DocumentNo = ts.toString(); } else DocumentNo = rs.getString(5); if(AD_PrintFormat_ID == 0 && type == INVENTORY){ MProcess process = MProcess.get(ctx, PROCESS_RPT_M_INVENTORY); AD_PrintFormat_ID = process.getAD_PrintFormat_ID(); } if(AD_PrintFormat_ID == 0 && type == MOVEMENT){ MProcess process = MProcess.get(ctx, PROCESS_RPT_M_MOVEMENT); AD_PrintFormat_ID = process.getAD_PrintFormat_ID(); } } else { // Set PrintFormat AD_PrintFormat_ID = rs.getInt(type+1); if (type != INVOICE && rs.getInt(9) != 0) // C_DocType.AD_PrintFormat_ID AD_PrintFormat_ID = rs.getInt(9); copies = rs.getInt(8); // Set Language when enabled String AD_Language = rs.getString(7); if (AD_Language != null) // && "Y".equals(rs.getString(6))) // IsMultiLingualDocument language = Language.getLanguage(AD_Language); C_BPartner_ID = rs.getInt(10); DocumentNo = rs.getString(11); } } } catch (Exception e) { log.log(Level.SEVERE, "Record_ID=" + Record_ID + ", SQL=" + sql, e); } finally { DB.close(rs, pstmt); rs = null; pstmt = null; } if (AD_PrintFormat_ID == 0) { log.log(Level.SEVERE, "No PrintFormat found for Type=" + type + ", Record_ID=" + Record_ID); return null; } // Get Format & Data MPrintFormat format = MPrintFormat.get (ctx, AD_PrintFormat_ID, false); format.setLanguage(language); // BP Language if Multi-Lingual format.setTranslationLanguage(language); // query MQuery query = new MQuery(format.getAD_Table_ID()); query.addRestriction(DOC_IDS[type], MQuery.EQUAL, Record_ID); // if (DocumentNo == null || DocumentNo.length() == 0) DocumentNo = "DocPrint"; PrintInfo info = new PrintInfo( DocumentNo, DOC_TABLE_ID[type], Record_ID, C_BPartner_ID); info.setCopies(copies); info.setDocumentCopy(false); // true prints "Copy" on second info.setPrinterName(format.getPrinterName()); // Engine ReportEngine re = new ReportEngine(ctx, format, query, info, trxName, windowNo); return re; } // get /** * Determine what Order document to print. * @param C_Order_ID id * @return int Array with [ReportEngine constant for type of print(INVOICE, ORDER, etc), record id] */ private static int[] getDocumentWhat (int C_Order_ID) { int[] what = new int[2]; what[0] = ORDER; what[1] = C_Order_ID; // StringBuilder sql = new StringBuilder("SELECT dt.DocSubTypeSO ") .append("FROM C_DocType dt, C_Order o ") .append("WHERE o.C_DocType_ID=dt.C_DocType_ID") .append(" AND o.C_Order_ID=?"); String DocSubTypeSO = null; PreparedStatement pstmt = null; ResultSet rs = null; try { pstmt = DB.prepareStatement(sql.toString(), null); pstmt.setInt(1, C_Order_ID); rs = pstmt.executeQuery(); if (rs.next()) DocSubTypeSO = rs.getString(1); // @Trifon - Order is not completed(C_DoctType_ID=0) then try with C_DocTypeTarget_ID // [ 2819637 ] Wrong print format on non completed order - https://sourceforge.net/p/adempiere/bugs/1977/ if (DocSubTypeSO == null || "".equals(DocSubTypeSO)) { sql = new StringBuilder("SELECT dt.DocSubTypeSO ") .append("FROM C_DocType dt, C_Order o ") .append("WHERE o.C_DocTypeTarget_ID=dt.C_DocType_ID") .append(" AND o.C_Order_ID=?"); DB.close(rs, pstmt); rs = null; pstmt = null; pstmt = DB.prepareStatement(sql.toString(), null); pstmt.setInt(1, C_Order_ID); rs = pstmt.executeQuery(); if (rs.next()) { DocSubTypeSO = rs.getString(1); } } } catch (SQLException e1) { log.log(Level.SEVERE, "(1) - " + sql, e1); return null; // error } finally { DB.close(rs, pstmt); rs = null; pstmt = null; } if (DocSubTypeSO == null) DocSubTypeSO = ""; // WalkIn Receipt, WalkIn Invoice, if (DocSubTypeSO.equals(MOrder.DocSubTypeSO_POS) || DocSubTypeSO.equals(MOrder.DocSubTypeSO_OnCredit)) what[0] = INVOICE; // WalkIn Pickup, else if (DocSubTypeSO.equals(MOrder.DocSubTypeSO_Warehouse)) what[0] = SHIPMENT; // Offer Binding, Offer Nonbinding, Standard Order else return what; // Get Record_ID of Invoice/Receipt if (what[0] == INVOICE) sql = new StringBuilder("SELECT C_Invoice_ID REC FROM C_Invoice WHERE C_Order_ID=?") // 1 .append(" ORDER BY C_Invoice_ID DESC"); else sql = new StringBuilder("SELECT M_InOut_ID REC FROM M_InOut WHERE C_Order_ID=?") // 1 .append(" ORDER BY M_InOut_ID DESC"); try { pstmt = DB.prepareStatement(sql.toString(), null); pstmt.setInt(1, C_Order_ID); rs = pstmt.executeQuery(); if (rs.next()) { what[1] = rs.getInt(1); } else // No Document Found what[0] = ORDER; } catch (SQLException e2) { log.log(Level.SEVERE, "(2) - " + sql, e2); return null; } finally { DB.close(rs, pstmt); rs = null; pstmt = null; } if (log.isLoggable(Level.FINE)) log.fine("Order => " + what[0] + " ID=" + what[1]); return what; } // getDocumentWhat /** * Print Confirm.
    * Update Date Printed. * @param type report engine document type ({@link #ORDER}, {@link #SHIPMENT}, etc) * @param Record_ID record id */ public static void printConfirm (int type, int Record_ID) { StringBuilder sql = new StringBuilder(); if (type == ORDER || type == SHIPMENT || type == INVOICE) sql.append("UPDATE ").append(DOC_BASETABLES[type]) .append(" SET DatePrinted=getDate(), IsPrinted='Y' WHERE ") .append(DOC_IDS[type]).append("=").append(Record_ID); // if (sql.length() > 0) { int no = DB.executeUpdate(sql.toString(), null); if (no != 1) log.log(Level.SEVERE, "Updated records=" + no + " - should be just one"); } } // printConfirm /** * Set extended where clause * @param whereExtended */ public void setWhereExtended(String whereExtended) { m_whereExtended = whereExtended; } /** * Get extended where clause * @return extended where clause */ public String getWhereExtended() { return m_whereExtended; } /** * Set windowNo of the report to parse the context */ public void setWindowNo(int windowNo) { m_windowNo = windowNo; } /** * Get window no * @return window no */ public int getWindowNo() { return m_windowNo; } /** * Set summary report * @param summary */ public void setSummary(boolean summary) { m_summary = summary; } /** * Is summary report * @return true if it is a summary report */ public boolean isSummary() { return m_summary; } /** * Set language id * @param languageID */ public void setLanguageID(int languageID) { m_language_id = languageID; } /** * Get language id * @return language id */ public int getLanguageID() { return m_language_id; } private String reportType; /** * Set report output type * @param type output type (pdf, html, etc) */ public void setReportType(String type) { reportType = type; } /** * Get report output type * @return report output type (pdf, html, etc) */ public String getReportType() { return reportType; } /** * Determines, if current tab content should be replaced, or a new tab should be opened * @return true if it is to replace content of current active tab */ public boolean isReplaceTabContent() { return m_isReplaceTabContent; } /** * Sets, if current tab content should be replaced, or a new tab should be opened * @param m_isReplaceTabContent */ public void setIsReplaceTabContent(boolean m_isReplaceTabContent) { this.m_isReplaceTabContent = m_isReplaceTabContent; } /** * Get Report Engine Type from Table_ID * @param tableID * @return Report Engine Type * -1 if Report Engine Type was not found */ public static int getReportEngineType(int tableID) { for(int i = 0; i < DOC_TABLE_ID.length; i++) { if(DOC_TABLE_ID[i] == tableID) return i; } return -1; } /** * Update AD_PInstance with default report output type (if it is not set) * @param ctx * @param instance * @param printFormatID */ public static void setDefaultReportTypeToPInstance(Properties ctx, MPInstance instance, int printFormatID) { if(Util.isEmpty(instance.getReportType())) { MPrintFormat pf = new MPrintFormat(ctx, printFormatID, null); String type = pf.isForm() // a42niem - provide explicit default and check on client/org specifics ? MSysConfig.getValue(MSysConfig.ZK_REPORT_FORM_OUTPUT_TYPE,"PDF",Env.getAD_Client_ID(ctx),Env.getAD_Org_ID(ctx)) : MSysConfig.getValue(MSysConfig.ZK_REPORT_TABLE_OUTPUT_TYPE,"PDF",Env.getAD_Client_ID(ctx),Env.getAD_Org_ID(ctx)); instance.setReportType(type); } } private ProcessInfo m_pi = null; /** * @param pi */ public void setProcessInfo(ProcessInfo pi) { m_pi = pi; } /** * @return ProcessInfo */ public ProcessInfo getProcessInfo() { return m_pi; } /** * Evaluate display logic of a print format item * @param printData data for display logic evaluation * @param item print format item * @return true if item has no display logic or display logic evaluate to true */ public static boolean isDisplayPFItem(PrintData printData, MPrintFormatItem item) { if(Util.isEmpty(item.getDisplayLogic())) return true; return Evaluator.evaluateLogic(new PrintDataEvaluatee(null, printData), item.getDisplayLogic()); } } // ReportEngine