From 840673e4e5ff178b34c9bce7b2ddfeb4bb9d4300 Mon Sep 17 00:00:00 2001 From: Carlos Ruiz Date: Fri, 13 Oct 2017 17:40:12 +0200 Subject: [PATCH 1/4] IDEMPIERE-2877 Adapt jasper reporting to latest (actually using deprecated methods) / thanks to Tiago Ceridorio (tifece) for the patch --- org.adempiere.ui.zk/META-INF/MANIFEST.MF | 1 + .../adempiere/webui/window/ZkJRViewer.java | 172 +++++++++++------- .../webui/window/ZkJRViewerProvider.java | 23 ++- 3 files changed, 131 insertions(+), 65 deletions(-) diff --git a/org.adempiere.ui.zk/META-INF/MANIFEST.MF b/org.adempiere.ui.zk/META-INF/MANIFEST.MF index 199ef6947b..827c76b5d7 100644 --- a/org.adempiere.ui.zk/META-INF/MANIFEST.MF +++ b/org.adempiere.ui.zk/META-INF/MANIFEST.MF @@ -17,6 +17,7 @@ Import-Package: javax.activation, net.sf.jasperreports.engine, net.sf.jasperreports.engine.export, net.sf.jasperreports.engine.util, + net.sf.jasperreports.export, org.adempiere.report.jasper, org.apache.commons.codec.binary, org.apache.ecs, diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/ZkJRViewer.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/ZkJRViewer.java index 5cca8ff1bd..5793692408 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/ZkJRViewer.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/ZkJRViewer.java @@ -3,24 +3,10 @@ package org.adempiere.webui.window; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; +import java.util.ArrayList; import java.util.logging.Level; import javax.activation.FileDataSource; -import javax.servlet.http.HttpServletRequest; - -import net.sf.jasperreports.engine.DefaultJasperReportsContext; -import net.sf.jasperreports.engine.JRException; -import net.sf.jasperreports.engine.JRExporterParameter; -import net.sf.jasperreports.engine.JasperPrint; -import net.sf.jasperreports.engine.JasperReport; -import net.sf.jasperreports.engine.export.JRCsvExporter; -import net.sf.jasperreports.engine.export.JRCsvExporterParameter; -import net.sf.jasperreports.engine.export.JRHtmlExporter; -import net.sf.jasperreports.engine.export.JRHtmlExporterParameter; -import net.sf.jasperreports.engine.export.JRPdfExporter; -import net.sf.jasperreports.engine.export.JRXlsExporter; -import net.sf.jasperreports.engine.export.JRXlsExporterParameter; -import net.sf.jasperreports.engine.util.LocalJasperReportsContext; import org.adempiere.exceptions.AdempiereException; import org.adempiere.webui.LayoutUtils; @@ -44,7 +30,6 @@ import org.compiere.util.Msg; import org.compiere.util.Util; import org.zkoss.util.media.AMedia; import org.zkoss.zk.ui.Component; -import org.zkoss.zk.ui.Executions; import org.zkoss.zk.ui.Page; import org.zkoss.zk.ui.event.Event; import org.zkoss.zk.ui.event.EventListener; @@ -59,13 +44,32 @@ import org.zkoss.zul.Separator; import org.zkoss.zul.Tab; import org.zkoss.zul.Toolbar; +import net.sf.jasperreports.engine.DefaultJasperReportsContext; +import net.sf.jasperreports.engine.JRException; +import net.sf.jasperreports.engine.JasperPrint; +import net.sf.jasperreports.engine.JasperReport; +import net.sf.jasperreports.engine.export.HtmlExporter; +import net.sf.jasperreports.engine.export.JRCsvExporter; +import net.sf.jasperreports.engine.export.JRPdfExporter; +import net.sf.jasperreports.engine.export.JRXlsExporter; +import net.sf.jasperreports.engine.util.LocalJasperReportsContext; +import net.sf.jasperreports.export.SimpleCsvExporterConfiguration; +import net.sf.jasperreports.export.SimpleExporterInput; +import net.sf.jasperreports.export.SimpleHtmlExporterOutput; +import net.sf.jasperreports.export.SimpleHtmlReportConfiguration; +import net.sf.jasperreports.export.SimpleOutputStreamExporterOutput; +import net.sf.jasperreports.export.SimpleWriterExporterOutput; +import net.sf.jasperreports.export.SimpleXlsReportConfiguration; + public class ZkJRViewer extends Window implements EventListener, ITabOnCloseHandler { /** - * + * */ private static final long serialVersionUID = -7047317766671393738L; private JasperPrint jasperPrint; + private java.util.List jasperPrintList; + private boolean isList; private Listbox previewType = new Listbox(); private Iframe iframe; private AMedia media; @@ -74,19 +78,31 @@ public class ZkJRViewer extends Window implements EventListener, ITabOnCl private File attachment = null; /** Logger */ private static CLogger log = CLogger.getCLogger(ZkJRViewer.class); - + /** Window No */ private int m_WindowNo = -1; private long prevKeyEventTime = 0; private KeyEvent prevKeyEvent; private String m_title; // local title - embedded windows clear the title - + public ZkJRViewer(JasperPrint jasperPrint, String title) { super(); this.setTitle(title); m_title = title; this.jasperPrint = jasperPrint; + this.isList = false; + m_WindowNo = SessionManager.getAppDesktop().registerWindow(this); + setAttribute(IDesktop.WINDOWNO_ATTRIBUTE, m_WindowNo); + init(); + } + + public ZkJRViewer(java.util.List jasperPrintList, String title) { + super(); + this.setTitle(title); + m_title = title; + this.jasperPrintList = jasperPrintList; + this.isList = true; m_WindowNo = SessionManager.getAppDesktop().registerWindow(this); setAttribute(IDesktop.WINDOWNO_ATTRIBUTE, m_WindowNo); init(); @@ -123,11 +139,11 @@ public class ZkJRViewer extends Window implements EventListener, ITabOnCl previewType.setMold("select"); attachment = null; // Added by Martin Augustine - Ntier software Services 09/10/2013 - if (isCanExport) { + if (isCanExport && !isList) { previewType.appendItem("PDF", "PDF"); previewType.appendItem("HTML", "HTML"); previewType.appendItem("Excel", "XLS"); - previewType.appendItem("CSV", "CSV"); + previewType.appendItem("CSV", "CSV"); previewType.appendItem("SSV", "SSV"); if ("PDF".equals(defaultType)) { previewType.setSelectedIndex(0); @@ -177,7 +193,7 @@ public class ZkJRViewer extends Window implements EventListener, ITabOnCl layout.appendChild(north); north.appendChild(toolbar); ZKUpdateUtil.setVflex(north, "min"); - + Center center = new Center(); layout.appendChild(center); iframe = new Iframe(); @@ -192,12 +208,12 @@ public class ZkJRViewer extends Window implements EventListener, ITabOnCl } catch (Exception e) { log.log(Level.SEVERE, e.getLocalizedMessage(), e); throw new AdempiereException("Failed to render report.", e); - } + } center.appendChild(iframe); this.setBorder("normal"); } - + private String makePrefix(String name) { StringBuilder prefix = new StringBuilder(); char[] nameArray = name.toCharArray(); @@ -206,7 +222,7 @@ public class ZkJRViewer extends Window implements EventListener, ITabOnCl prefix.append(ch); } else { prefix.append("_"); - } + } } return prefix.toString(); } @@ -216,7 +232,7 @@ public class ZkJRViewer extends Window implements EventListener, ITabOnCl */ public void actionPerformed (Event e) { - + if (e.getTarget() == previewType) cmd_render(); else if (e.getTarget() == bSendMail) // Added by Martin Augustine - Ntier software services 09/10/2013 @@ -225,7 +241,7 @@ public class ZkJRViewer extends Window implements EventListener, ITabOnCl private void cmd_render() { try { - renderReport(); + renderReport(); } catch (Exception e) { throw new AdempiereException("Failed to render report", e); } @@ -253,7 +269,7 @@ public class ZkJRViewer extends Window implements EventListener, ITabOnCl } // cmd_sendMail - public void onEvent(Event event) throws Exception { + public void onEvent(Event event) throws Exception { if (event.getName().equals(Events.ON_CLICK) || event.getName().equals(Events.ON_SELECT)) { actionPerformed(event); } else if (event.getName().equals(Events.ON_CTRL_KEY)) { @@ -291,15 +307,15 @@ public class ZkJRViewer extends Window implements EventListener, ITabOnCl private void renderReport() throws Exception { String reportType; ClassLoader cl = Thread.currentThread().getContextClassLoader(); - try { + try { Thread.currentThread().setContextClassLoader(JasperReport.class.getClassLoader()); Listitem selected = previewType.getSelectedItem(); reportType=selected.getValue(); - if ( "PDF".equals( reportType ) ) + if ( "PDF".equals( reportType ) ) { attachment = getPDF(); media = new AMedia(m_title + ".pdf", "pdf", "application/pdf", attachment, true); - + } else if ("HTML".equals(reportType)) { String path = System.getProperty("java.io.tmpdir"); String prefix = makePrefix(jasperPrint.getName()); @@ -308,16 +324,19 @@ public class ZkJRViewer extends Window implements EventListener, ITabOnCl log.log(Level.FINE, "Path="+path + " Prefix="+prefix); } File file = File.createTempFile(prefix, ".html", new File(path)); - - JRHtmlExporter exporter = new JRHtmlExporter(); - exporter.setParameter(JRExporterParameter.JASPER_PRINT,jasperPrint); - exporter.setParameter(JRExporterParameter.OUTPUT_FILE, file); - // Make images available for the HTML output - exporter.setParameter(JRHtmlExporterParameter.IS_OUTPUT_IMAGES_TO_DIR, Boolean.TRUE); - exporter.setParameter(JRHtmlExporterParameter.IMAGES_DIR_NAME, Executions.getCurrent().getDesktop().getSession().getWebApp().getRealPath("/images/report/")); - HttpServletRequest request = (HttpServletRequest)Executions.getCurrent().getNativeRequest(); - exporter.setParameter(JRHtmlExporterParameter.IMAGES_URI, request.getContextPath()+"/images/report/"); - exporter.exportReport(); + + HtmlExporter exporter = new HtmlExporter(); + SimpleHtmlReportConfiguration htmlConfig = new SimpleHtmlReportConfiguration(); + htmlConfig.setEmbedImage(true); + htmlConfig.setAccessibleHtml(true); + if (!isList){ + jasperPrintList = new ArrayList<>(); + jasperPrintList.add(jasperPrint); + } + exporter.setExporterInput(SimpleExporterInput.getInstance(jasperPrintList)); + exporter.setExporterOutput(new SimpleHtmlExporterOutput(file)); + exporter.setConfiguration(htmlConfig); + exporter.exportReport(); media = new AMedia(m_title, "html", "text/html", file, false); } else if ("XLS".equals(reportType)) { String path = System.getProperty("java.io.tmpdir"); @@ -326,17 +345,24 @@ public class ZkJRViewer extends Window implements EventListener, ITabOnCl { log.log(Level.FINE, "Path="+path + " Prefix="+prefix); } - File file = File.createTempFile(prefix, ".xls", new File(path)); + File file = File.createTempFile(prefix, ".xls", new File(path)); FileOutputStream fos = new FileOutputStream(file); - + // coding For Excel: JRXlsExporter exporterXLS = new JRXlsExporter(); - exporterXLS.setParameter(JRXlsExporterParameter.JASPER_PRINT, jasperPrint); - exporterXLS.setParameter(JRXlsExporterParameter.OUTPUT_STREAM, fos); - exporterXLS.setParameter(JRXlsExporterParameter.IS_ONE_PAGE_PER_SHEET, Boolean.FALSE); - exporterXLS.exportReport(); - media = new AMedia(m_title + ".xls", "xls", "application/vnd.ms-excel", file, true); - + SimpleXlsReportConfiguration xlsConfig = new SimpleXlsReportConfiguration(); + xlsConfig.setOnePagePerSheet(false); + + if (!isList){ + jasperPrintList = new ArrayList<>(); + jasperPrintList.add(jasperPrint); + } + exporterXLS.setExporterInput(SimpleExporterInput.getInstance(jasperPrintList)); + exporterXLS.setExporterOutput(new SimpleOutputStreamExporterOutput(fos)); + exporterXLS.setConfiguration(xlsConfig); + exporterXLS.exportReport(); + media = new AMedia(m_title + ".xls", "xls", "application/vnd.ms-excel", file, true); + }else if ("CSV".equals(reportType)) { String path = System.getProperty("java.io.tmpdir"); String prefix = makePrefix(jasperPrint.getName()); @@ -347,11 +373,15 @@ public class ZkJRViewer extends Window implements EventListener, ITabOnCl File file = File.createTempFile(prefix, ".csv", new File(path)); FileOutputStream fos = new FileOutputStream(file); JRCsvExporter exporter= new JRCsvExporter(); - exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint); - exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, fos); + if (!isList){ + jasperPrintList = new ArrayList<>(); + jasperPrintList.add(jasperPrint); + } + exporter.setExporterInput(SimpleExporterInput.getInstance(jasperPrintList)); + exporter.setExporterOutput(new SimpleWriterExporterOutput(fos)); exporter.exportReport(); - - media = new AMedia(m_title + ".csv", "csv", "application/csv", file, true); + + media = new AMedia(m_title + ".csv", "csv", "application/csv", file, true); }else if ("SSV".equals(reportType)) { String path = System.getProperty("java.io.tmpdir"); @@ -363,24 +393,36 @@ public class ZkJRViewer extends Window implements EventListener, ITabOnCl File file = File.createTempFile(prefix, ".ssv", new File(path)); FileOutputStream fos = new FileOutputStream(file); JRCsvExporter exporter= new JRCsvExporter(); - exporter.setParameter(JRCsvExporterParameter.FIELD_DELIMITER, ";"); - exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint); - exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, fos); + SimpleCsvExporterConfiguration csvConfig = new SimpleCsvExporterConfiguration(); + csvConfig.setFieldDelimiter(";"); + if (!isList){ + jasperPrintList = new ArrayList<>(); + jasperPrintList.add(jasperPrint); + } + exporter.setExporterInput(SimpleExporterInput.getInstance(jasperPrintList)); + exporter.setExporterOutput(new SimpleWriterExporterOutput(fos)); + exporter.setConfiguration(csvConfig); exporter.exportReport(); - - media = new AMedia(m_title, "ssv", "application/ssv", file, true); + + media = new AMedia(m_title, "ssv", "application/ssv", file, true); } } finally { Thread.currentThread().setContextClassLoader(cl); } iframe.setSrc(null); - Events.echoEvent("onRenderReport", this, null); + Events.echoEvent("onRenderReport", this, null); } - + private File getPDF() throws IOException, JRException { String path = System.getProperty("java.io.tmpdir"); - String prefix = makePrefix(jasperPrint.getName()); + + String prefix = null; + if (isList) + prefix = makePrefix(jasperPrintList.get(0).getName())+"_List"; + else + prefix = makePrefix(jasperPrint.getName()); + if (log.isLoggable(Level.FINE)) { log.log(Level.FINE, "Path="+path + " Prefix="+prefix); @@ -389,8 +431,12 @@ public class ZkJRViewer extends Window implements EventListener, ITabOnCl LocalJasperReportsContext context = new LocalJasperReportsContext(DefaultJasperReportsContext.getInstance()); context.setClassLoader(JRPdfExporter.class.getClassLoader()); JRPdfExporter exporter = new JRPdfExporter(context); - exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint); - exporter.setParameter(JRExporterParameter.OUTPUT_FILE_NAME, file.getAbsolutePath()); + if (!isList){ + jasperPrintList = new ArrayList<>(); + jasperPrintList.add(jasperPrint); + } + exporter.setExporterInput(SimpleExporterInput.getInstance(jasperPrintList)); + exporter.setExporterOutput(new SimpleOutputStreamExporterOutput(file)); exporter.exportReport(); return file; } diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/ZkJRViewerProvider.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/ZkJRViewerProvider.java index 42ffaaa0f0..cbc685323e 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/ZkJRViewerProvider.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/ZkJRViewerProvider.java @@ -3,6 +3,8 @@ package org.adempiere.webui.window; import net.sf.jasperreports.engine.JRException; import net.sf.jasperreports.engine.JasperPrint; +import java.util.List; + import org.adempiere.report.jasper.JRViewerProvider; import org.adempiere.webui.apps.AEnv; import org.adempiere.webui.component.Window; @@ -14,11 +16,28 @@ public class ZkJRViewerProvider implements JRViewerProvider { public void openViewer(final JasperPrint jasperPrint, final String title) throws JRException { Runnable runnable = new Runnable() { - + @Override public void run() { Window viewer = new ZkJRViewer(jasperPrint, title); - + + viewer.setAttribute(Window.MODE_KEY, Window.MODE_EMBEDDED); + viewer.setAttribute(Window.INSERT_POSITION_KEY, Window.INSERT_NEXT); + viewer.setAttribute(WindowContainer.DEFER_SET_SELECTED_TAB, Boolean.TRUE); + SessionManager.getAppDesktop().showWindow(viewer); + } + }; + AEnv.executeAsyncDesktopTask(runnable); + } + + public void openViewer(final List jasperPrintList, final String title) + throws JRException { + Runnable runnable = new Runnable() { + + @Override + public void run() { + Window viewer = new ZkJRViewer(jasperPrintList, title); + viewer.setAttribute(Window.MODE_KEY, Window.MODE_EMBEDDED); viewer.setAttribute(Window.INSERT_POSITION_KEY, Window.INSERT_NEXT); viewer.setAttribute(WindowContainer.DEFER_SET_SELECTED_TAB, Boolean.TRUE); From 4e1f52c9cad901be067ab1a3ddcc40b1be562b5e Mon Sep 17 00:00:00 2001 From: Carlos Ruiz Date: Fri, 13 Oct 2017 20:50:46 +0200 Subject: [PATCH 2/4] IDEMPIERE-3520 Ability to merge several jasper reports in one run --- .../report/jasper/JRViewerProviderList.java | 11 +++ .../report/jasper/ReportStarter.java | 97 +++++++++++-------- .../OSGI-INF/jrviewerprovider.xml | 1 + .../adempiere/webui/window/ZkJRViewer.java | 26 ++++- .../webui/window/ZkJRViewerProvider.java | 9 +- 5 files changed, 93 insertions(+), 51 deletions(-) create mode 100644 org.adempiere.report.jasper/src/org/adempiere/report/jasper/JRViewerProviderList.java diff --git a/org.adempiere.report.jasper/src/org/adempiere/report/jasper/JRViewerProviderList.java b/org.adempiere.report.jasper/src/org/adempiere/report/jasper/JRViewerProviderList.java new file mode 100644 index 0000000000..5718a81331 --- /dev/null +++ b/org.adempiere.report.jasper/src/org/adempiere/report/jasper/JRViewerProviderList.java @@ -0,0 +1,11 @@ +package org.adempiere.report.jasper; + +import java.util.List; + +import net.sf.jasperreports.engine.JRException; +import net.sf.jasperreports.engine.JasperPrint; + +public interface JRViewerProviderList { + + public void openViewer(List jasperPrintList, String title) throws JRException; +} diff --git a/org.adempiere.report.jasper/src/org/adempiere/report/jasper/ReportStarter.java b/org.adempiere.report.jasper/src/org/adempiere/report/jasper/ReportStarter.java index 670166f218..4c4de4e595 100644 --- a/org.adempiere.report.jasper/src/org/adempiere/report/jasper/ReportStarter.java +++ b/org.adempiere.report.jasper/src/org/adempiere/report/jasper/ReportStarter.java @@ -35,6 +35,7 @@ import java.sql.SQLException; import java.sql.Timestamp; import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Properties; @@ -46,6 +47,34 @@ import javax.print.attribute.PrintRequestAttributeSet; import javax.print.attribute.standard.Copies; import javax.print.attribute.standard.JobName; +import org.adempiere.base.Service; +import org.adempiere.exceptions.AdempiereException; +import org.adempiere.exceptions.DBException; +import org.adempiere.util.IProcessUI; +import org.compiere.model.MAttachment; +import org.compiere.model.MAttachmentEntry; +import org.compiere.model.MProcess; +import org.compiere.model.MQuery; +import org.compiere.model.MSysConfig; +import org.compiere.model.MTable; +import org.compiere.model.PrintInfo; +import org.compiere.model.X_AD_PInstance_Para; +import org.compiere.print.MPrintFormat; +import org.compiere.print.PrintUtil; +import org.compiere.print.ServerReportCtl; +import org.compiere.process.ClientProcess; +import org.compiere.process.ProcessCall; +import org.compiere.process.ProcessInfo; +import org.compiere.process.ProcessInfoParameter; +import org.compiere.util.CLogger; +import org.compiere.util.DB; +import org.compiere.util.Env; +import org.compiere.util.Ini; +import org.compiere.util.Language; +import org.compiere.util.Trx; +import org.compiere.util.Util; +import org.compiere.utils.DigestOfFile; + import net.sf.jasperreports.engine.DefaultJasperReportsContext; import net.sf.jasperreports.engine.JRException; import net.sf.jasperreports.engine.JRParameter; @@ -87,34 +116,6 @@ import net.sf.jasperreports.export.SimpleWriterExporterOutput; import net.sf.jasperreports.export.SimpleXlsExporterConfiguration; import net.sf.jasperreports.export.SimpleXmlExporterOutput; -import org.adempiere.base.Service; -import org.adempiere.exceptions.AdempiereException; -import org.adempiere.exceptions.DBException; -import org.adempiere.util.IProcessUI; -import org.compiere.model.MAttachment; -import org.compiere.model.MAttachmentEntry; -import org.compiere.model.MProcess; -import org.compiere.model.MQuery; -import org.compiere.model.MSysConfig; -import org.compiere.model.MTable; -import org.compiere.model.PrintInfo; -import org.compiere.model.X_AD_PInstance_Para; -import org.compiere.print.MPrintFormat; -import org.compiere.print.PrintUtil; -import org.compiere.print.ServerReportCtl; -import org.compiere.process.ClientProcess; -import org.compiere.process.ProcessCall; -import org.compiere.process.ProcessInfo; -import org.compiere.process.ProcessInfoParameter; -import org.compiere.util.CLogger; -import org.compiere.util.DB; -import org.compiere.util.Env; -import org.compiere.util.Ini; -import org.compiere.util.Language; -import org.compiere.util.Trx; -import org.compiere.util.Util; -import org.compiere.utils.DigestOfFile; - /** * @author rlemeill * Originally coming from an application note from compiere.co.uk @@ -185,8 +186,7 @@ public class ReportStarter implements ProcessCall, ClientProcess log.warning("404 not found: Report cannot be found on server "+ e.getMessage()); return null; } catch (IOException e) { - log.severe("I/O error when trying to download (sub)report from server "+ e.getMessage()); - return null; + throw new AdempiereException("I/O error when trying to download (sub)report from server "+ e.getLocalizedMessage()); } } @@ -285,8 +285,7 @@ public class ReportStarter implements ProcessCall, ClientProcess } catch (Exception e) { - log.severe("Unknown exception: "+ e.getMessage()); - return null; + throw new AdempiereException("Unknown exception: "+ e.getLocalizedMessage()); } return reportFile; } @@ -311,8 +310,7 @@ public class ReportStarter implements ProcessCall, ClientProcess String hash = new String(baos.toByteArray()); return hash; } catch (IOException e) { - log.severe("I/O error when trying to download (sub)report from server "+ e.getMessage()); - return null; + throw new AdempiereException("I/O error when trying to download (sub)report from server "+ e.getLocalizedMessage()); } } @@ -379,7 +377,12 @@ public class ReportStarter implements ProcessCall, ClientProcess return false; } - String reportPath = reportData.getReportFilePath(); + List jasperPrintList = new ArrayList(); + String reportFilePath = reportData.getReportFilePath(); + String[] reportPathList = reportFilePath.split(";"); + for (int idx = 0; idx < reportPathList.length; idx++) { + + String reportPath = reportPathList[idx]; if (Util.isEmpty(reportPath, true)) { reportResult(AD_PInstance_ID, "Can not find report", trxName); @@ -702,9 +705,20 @@ public class ReportStarter implements ProcessCall, ClientProcess } } } else { - if (log.isLoggable(Level.INFO)) log.info( "ReportStarter.startProcess run report -"+jasperPrint.getName()); - JRViewerProvider viewerLauncher = Service.locator().locate(JRViewerProvider.class).getService(); - viewerLauncher.openViewer(jasperPrint, pi.getTitle()); + if (reportPathList.length == 1) { + if (log.isLoggable(Level.INFO)) log.info( "ReportStarter.startProcess run report -"+jasperPrint.getName()); + JRViewerProvider viewerLauncher = Service.locator().locate(JRViewerProvider.class).getService(); + viewerLauncher.openViewer(jasperPrint, pi.getTitle()); + } else { + jasperPrintList.add(jasperPrint); + if (idx+1 == reportPathList.length) { + JRViewerProviderList viewerLauncher = Service.locator().locate(JRViewerProviderList.class).getService(); + if (viewerLauncher == null) { + throw new AdempiereException("Can not find a viewer provider for multiple jaspers"); + } + viewerLauncher.openViewer(jasperPrintList, pi.getTitle()); + } + } } } else @@ -786,7 +800,7 @@ public class ReportStarter implements ProcessCall, ClientProcess } } } catch (JRException e) { - log.severe("ReportStarter.startProcess: Can not run report - "+ e.getMessage()); + throw new AdempiereException(e.getLocalizedMessage() + (e.getCause() != null ? " -> " + e.getCause().getLocalizedMessage() : "")); } finally { if (conn != null) { try { @@ -797,6 +811,8 @@ public class ReportStarter implements ProcessCall, ClientProcess } } + } // for reportPathList + if (onrows != null && onrows instanceof Integer) { nrows = (Integer) onrows; processInfo.setRowCount(nrows); @@ -1275,7 +1291,6 @@ public class ReportStarter implements ProcessCall, ClientProcess } catch (SQLException e) { -// log.severe("Execption; sql = "+sql+"; e.getMessage() = " +e.getMessage()); throw new DBException(e, sql); } finally @@ -1373,8 +1388,6 @@ public class ReportStarter implements ProcessCall, ClientProcess catch (SQLException e) { throw new DBException(e, sql); -// log.severe("sql = "+sql+"; e.getMessage() = "+ e.getMessage()); -// return null; } finally { diff --git a/org.adempiere.ui.zk/OSGI-INF/jrviewerprovider.xml b/org.adempiere.ui.zk/OSGI-INF/jrviewerprovider.xml index 802836a337..267f7c129a 100644 --- a/org.adempiere.ui.zk/OSGI-INF/jrviewerprovider.xml +++ b/org.adempiere.ui.zk/OSGI-INF/jrviewerprovider.xml @@ -3,5 +3,6 @@ + diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/ZkJRViewer.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/ZkJRViewer.java index 5793692408..e7f6876717 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/ZkJRViewer.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/ZkJRViewer.java @@ -139,7 +139,7 @@ public class ZkJRViewer extends Window implements EventListener, ITabOnCl previewType.setMold("select"); attachment = null; // Added by Martin Augustine - Ntier software Services 09/10/2013 - if (isCanExport && !isList) { + if (isCanExport) { previewType.appendItem("PDF", "PDF"); previewType.appendItem("HTML", "HTML"); previewType.appendItem("Excel", "XLS"); @@ -318,7 +318,11 @@ public class ZkJRViewer extends Window implements EventListener, ITabOnCl } else if ("HTML".equals(reportType)) { String path = System.getProperty("java.io.tmpdir"); - String prefix = makePrefix(jasperPrint.getName()); + String prefix = null; + if (isList) + prefix = makePrefix(jasperPrintList.get(0).getName())+"_List"; + else + prefix = makePrefix(jasperPrint.getName()); if (log.isLoggable(Level.FINE)) { log.log(Level.FINE, "Path="+path + " Prefix="+prefix); @@ -340,7 +344,11 @@ public class ZkJRViewer extends Window implements EventListener, ITabOnCl media = new AMedia(m_title, "html", "text/html", file, false); } else if ("XLS".equals(reportType)) { String path = System.getProperty("java.io.tmpdir"); - String prefix = makePrefix(jasperPrint.getName()); + String prefix = null; + if (isList) + prefix = makePrefix(jasperPrintList.get(0).getName())+"_List"; + else + prefix = makePrefix(jasperPrint.getName()); if (log.isLoggable(Level.FINE)) { log.log(Level.FINE, "Path="+path + " Prefix="+prefix); @@ -365,7 +373,11 @@ public class ZkJRViewer extends Window implements EventListener, ITabOnCl }else if ("CSV".equals(reportType)) { String path = System.getProperty("java.io.tmpdir"); - String prefix = makePrefix(jasperPrint.getName()); + String prefix = null; + if (isList) + prefix = makePrefix(jasperPrintList.get(0).getName())+"_List"; + else + prefix = makePrefix(jasperPrint.getName()); if (log.isLoggable(Level.FINE)) { log.log(Level.FINE, "Path="+path + " Prefix="+prefix); @@ -385,7 +397,11 @@ public class ZkJRViewer extends Window implements EventListener, ITabOnCl }else if ("SSV".equals(reportType)) { String path = System.getProperty("java.io.tmpdir"); - String prefix = makePrefix(jasperPrint.getName()); + String prefix = null; + if (isList) + prefix = makePrefix(jasperPrintList.get(0).getName())+"_List"; + else + prefix = makePrefix(jasperPrint.getName()); if (log.isLoggable(Level.FINE)) { log.log(Level.FINE, "Path="+path + " Prefix="+prefix); diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/ZkJRViewerProvider.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/ZkJRViewerProvider.java index cbc685323e..61d66795e2 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/ZkJRViewerProvider.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/ZkJRViewerProvider.java @@ -1,17 +1,18 @@ package org.adempiere.webui.window; -import net.sf.jasperreports.engine.JRException; -import net.sf.jasperreports.engine.JasperPrint; - import java.util.List; import org.adempiere.report.jasper.JRViewerProvider; +import org.adempiere.report.jasper.JRViewerProviderList; import org.adempiere.webui.apps.AEnv; import org.adempiere.webui.component.Window; import org.adempiere.webui.part.WindowContainer; import org.adempiere.webui.session.SessionManager; -public class ZkJRViewerProvider implements JRViewerProvider { +import net.sf.jasperreports.engine.JRException; +import net.sf.jasperreports.engine.JasperPrint; + +public class ZkJRViewerProvider implements JRViewerProvider, JRViewerProviderList { public void openViewer(final JasperPrint jasperPrint, final String title) throws JRException { From 1616e7a95b3fee93240842f5e9b5bc8a8194a021 Mon Sep 17 00:00:00 2001 From: Carlos Ruiz Date: Tue, 17 Oct 2017 18:29:34 +0200 Subject: [PATCH 3/4] IDEMPIERE-1546 There is no OSGi interface for a PaymentExport / thanks to Markus Bozem --- .../src/org/adempiere/base/Core.java | 35 ++++ .../base/DefaultPaymentExporterFactory.java | 58 +++++++ .../base/IPaymentExporterFactory.java | 29 ++++ .../compiere/model/MPaySelectionCheck.java | 152 +++++++++++++----- .../compiere/util/GenericPaymentExport.java | 41 ++++- .../src/org/compiere/util/PaymentExport.java | 73 ++++++++- .../src/org/compiere/apps/form/VPayPrint.java | 92 ++++++++--- .../adempiere/webui/apps/form/WPayPrint.java | 100 +++++++++--- .../src/org/compiere/apps/form/PayPrint.java | 73 ++++++++- 9 files changed, 555 insertions(+), 98 deletions(-) create mode 100644 org.adempiere.base/src/org/adempiere/base/DefaultPaymentExporterFactory.java create mode 100644 org.adempiere.base/src/org/adempiere/base/IPaymentExporterFactory.java diff --git a/org.adempiere.base/src/org/adempiere/base/Core.java b/org.adempiere.base/src/org/adempiere/base/Core.java index c84d24890d..59c5a90c8e 100644 --- a/org.adempiere.base/src/org/adempiere/base/Core.java +++ b/org.adempiere.base/src/org/adempiere/base/Core.java @@ -45,6 +45,7 @@ import org.compiere.model.PaymentProcessor; import org.compiere.model.StandardTaxProvider; import org.compiere.process.ProcessCall; import org.compiere.util.CLogger; +import org.compiere.util.PaymentExport; import org.compiere.util.ReplenishInterface; import org.osgi.framework.FrameworkUtil; @@ -415,4 +416,38 @@ public class Core { return engine; } + + /** + * get PaymentExporter instance + * + * @param className + * @return instance of the PaymentExporterInterface or null + */ + public static PaymentExport getPaymentExporter (String className){ + if (className == null || className.length() == 0) { + s_log.log(Level.SEVERE, "No PaymentExporter class name"); + return null; + } + + PaymentExport myPaymentExporter = null; + + List factoryList = + Service.locator().list(IPaymentExporterFactory.class).getServices(); + if (factoryList != null) { + for(IPaymentExporterFactory factory : factoryList) { + PaymentExport exporter = factory.newPaymentExporterInstance(className); + if (exporter != null) { + myPaymentExporter = exporter; + break; + } + } + } + + if (myPaymentExporter == null) { + s_log.log(Level.CONFIG, className + " not found in service/extension registry and classpath"); + return null; + } + + return myPaymentExporter; + } } diff --git a/org.adempiere.base/src/org/adempiere/base/DefaultPaymentExporterFactory.java b/org.adempiere.base/src/org/adempiere/base/DefaultPaymentExporterFactory.java new file mode 100644 index 0000000000..797a98a602 --- /dev/null +++ b/org.adempiere.base/src/org/adempiere/base/DefaultPaymentExporterFactory.java @@ -0,0 +1,58 @@ +/****************************************************************************** + * Product: iDempiere Business Suite ERP/CRM/SCM * + * Copyright (C) 2017 Markus Bozem * + * 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. * * + *****************************************************************************/ +package org.adempiere.base; + +import java.util.logging.Level; + +import org.adempiere.base.equinox.EquinoxExtensionLocator; +import org.compiere.util.CLogger; +import org.compiere.util.PaymentExport; + +/** + * @author mbozem + * + */ +public class DefaultPaymentExporterFactory implements IPaymentExporterFactory { + + private final static CLogger s_log = CLogger.getCLogger(DefaultPaymentExporterFactory.class); + + /** + * default constructor + */ + public DefaultPaymentExporterFactory() { + } + + @Override + public PaymentExport newPaymentExporterInstance(String className) { + PaymentExport myExporter = null; + myExporter = EquinoxExtensionLocator.instance().locate(PaymentExport.class, className, null).getExtension(); + if (myExporter == null) { + //fall back to dynamic java class loadup + try { + Class peClass = Class.forName(className); + if (peClass != null) + myExporter = (PaymentExport)peClass.newInstance(); + } catch (Error e1) { // NoClassDefFound + s_log.log(Level.SEVERE, className + " - Error=" + e1.getMessage()); + return null; + } catch (Exception e2) { + s_log.log(Level.SEVERE, className, e2); + return null; + } + } + + return myExporter; + } + +} diff --git a/org.adempiere.base/src/org/adempiere/base/IPaymentExporterFactory.java b/org.adempiere.base/src/org/adempiere/base/IPaymentExporterFactory.java new file mode 100644 index 0000000000..3397bf572a --- /dev/null +++ b/org.adempiere.base/src/org/adempiere/base/IPaymentExporterFactory.java @@ -0,0 +1,29 @@ +/****************************************************************************** + * Product: iDempiere Business Suite ERP/CRM/SCM * + * Copyright (C) 2017 Markus Bozem * + * 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. * * + *****************************************************************************/ +package org.adempiere.base; + +import org.compiere.util.PaymentExport; + +/** + * PaymentExporter factory interface. + * @author mbozem + */ +public interface IPaymentExporterFactory { + + /** + * @param className + * @return payment exporter instance + */ + public PaymentExport newPaymentExporterInstance(String className); +} diff --git a/org.adempiere.base/src/org/compiere/model/MPaySelectionCheck.java b/org.adempiere.base/src/org/compiere/model/MPaySelectionCheck.java index 7e4f67739b..5f4970e443 100644 --- a/org.adempiere.base/src/org/compiere/model/MPaySelectionCheck.java +++ b/org.adempiere.base/src/org/compiere/model/MPaySelectionCheck.java @@ -20,11 +20,14 @@ import java.math.BigDecimal; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; +import java.sql.Timestamp; import java.util.ArrayList; +import java.util.Date; import java.util.Properties; import java.util.logging.Level; import org.adempiere.exceptions.AdempiereException; +import org.compiere.acct.Doc; import org.compiere.process.DocAction; import org.compiere.util.CLogger; import org.compiere.util.DB; @@ -43,7 +46,7 @@ public class MPaySelectionCheck extends X_C_PaySelectionCheck /** * */ - private static final long serialVersionUID = -5752888482207479355L; + private static final long serialVersionUID = 2130445794890189020L; /** * Get Check for Payment @@ -385,60 +388,127 @@ public class MPaySelectionCheck extends X_C_PaySelectionCheck * Create Payments the first time * @param checks checks * @param batch batch + * @param createDeposit create deposit batch * @return last Document number or 0 if nothing printed */ - public static int confirmPrint (MPaySelectionCheck[] checks, MPaymentBatch batch) + public static int confirmPrint (MPaySelectionCheck[] checks, MPaymentBatch batch, boolean createDepositBatch) { boolean localTrx = false; String trxName = null; - if (checks.length > 0) - trxName = checks[0].get_TrxName(); - Trx trx = null; - if (trxName == null) { - localTrx = true; - trxName = Trx.createTrxName("ConfirmPrintMulti"); - trx = Trx.get(trxName, true); - trx.setDisplayName(MPaySelectionCheck.class.getName()+"_confirmPrints"); - } int lastDocumentNo = 0; - try { - for (int i = 0; i < checks.length; i++) + + if (checks.length > 0) + { + trxName = checks[0].get_TrxName(); + Properties ctx = checks[0].getCtx(); + int c_BankAccount_ID = checks[0].getC_PaySelection().getC_BankAccount_ID() ; + String paymentRule = checks[0].getPaymentRule() ; + Boolean isDebit ; + if (MInvoice.PAYMENTRULE_DirectDeposit.compareTo(paymentRule) == 0 + || MInvoice.PAYMENTRULE_Check.compareTo(paymentRule) == 0 + || MInvoice.PAYMENTRULE_OnCredit.compareTo(paymentRule) == 0) { - MPaySelectionCheck check = checks[i]; - if (localTrx) - check.set_TrxName(trxName); - confirmPrint(check, batch); - - // Get Check Document No - try - { - int no = Integer.parseInt(check.getDocumentNo()); - if (lastDocumentNo < no) - lastDocumentNo = no; - } - catch (NumberFormatException ex) - { - s_log.log(Level.SEVERE, "DocumentNo=" + check.getDocumentNo(), ex); - } - } // all checks - } catch (Exception e) { - if (localTrx && trx != null) { - trx.rollback(); - trx.close(); - trx = null; + isDebit = false ; } - throw new AdempiereException(e); - } finally { - if (localTrx && trx != null) { - trx.commit(); - trx.close(); + else if (MInvoice.PAYMENTRULE_DirectDebit.compareTo(paymentRule) == 0) + { + isDebit = true ; + } + else + { + isDebit = false ; + createDepositBatch = false ; + } + Trx trx = null; + if (trxName == null) { + localTrx = true; + trxName = Trx.createTrxName("ConfirmPrintMulti"); + trx = Trx.get(trxName, true); + } + + try { + MDepositBatch depositBatch = null; + if (createDepositBatch) + { + depositBatch = new MDepositBatch(ctx, 0, trxName) ; + depositBatch.setC_BankAccount_ID(c_BankAccount_ID); + if (isDebit) + { + depositBatch.setC_DocType_ID(MDocType.getDocType(Doc.DOCTYPE_ARReceipt)); + } + else + { + depositBatch.setC_DocType_ID(MDocType.getDocType(Doc.DOCTYPE_APPayment)); + } + depositBatch.setDateDeposit(new Timestamp((new Date()).getTime())); + depositBatch.setDateDoc(new Timestamp((new Date()).getTime())); + depositBatch.saveEx(); + } + + for (int i = 0; i < checks.length; i++) + { + MPaySelectionCheck check = checks[i]; + if (localTrx) + check.set_TrxName(trxName); + confirmPrint(check, batch); + if (createDepositBatch) + { + MDepositBatchLine depositBatchLine = new MDepositBatchLine(depositBatch) ; + depositBatchLine.setC_Payment_ID(check.getC_Payment_ID()); + depositBatchLine.setProcessed(true); + depositBatchLine.saveEx(); + } + // Get Check Document No + try + { + int no = Integer.parseInt(check.getDocumentNo()); + if (lastDocumentNo < no) + lastDocumentNo = no; + } + catch (NumberFormatException ex) + { + s_log.log(Level.SEVERE, "DocumentNo=" + check.getDocumentNo(), ex); + } + } // all checks + + if (createDepositBatch) + { + + depositBatch.setProcessed(true); + depositBatch.saveEx(); + } + + } catch (Exception e) { + if (localTrx && trx != null) { + trx.rollback(); + trx.close(); + trx = null; + } + throw new AdempiereException(e); + } finally { + if (localTrx && trx != null) { + trx.commit(); + trx.close(); + } } } - if (s_log.isLoggable(Level.FINE)) s_log.fine("Last Document No = " + lastDocumentNo); return lastDocumentNo; } // confirmPrint + /************************************************************************** + * Confirm Print. + * Create Payments the first time + * @param checks checks + * @param batch batch + * @return last Document number or 0 if nothing printed + */ + + public static int confirmPrint (MPaySelectionCheck[] checks, MPaymentBatch batch) + { + return confirmPrint (checks,batch,false) ; + } // confirmPrint + /** Logger */ static private CLogger s_log = CLogger.getCLogger (MPaySelectionCheck.class); diff --git a/org.adempiere.base/src/org/compiere/util/GenericPaymentExport.java b/org.adempiere.base/src/org/compiere/util/GenericPaymentExport.java index ca0cdef7b6..dc986342c9 100644 --- a/org.adempiere.base/src/org/compiere/util/GenericPaymentExport.java +++ b/org.adempiere.base/src/org/compiere/util/GenericPaymentExport.java @@ -21,6 +21,7 @@ import java.io.FileWriter; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; +import java.text.SimpleDateFormat; import java.util.logging.Level; import org.compiere.model.MCurrency; @@ -67,11 +68,13 @@ public class GenericPaymentExport implements PaymentExport /************************************************************************** * Export to File * @param checks array of checks + * @param depositBatch book the payments as single position + * @param paymentRule selected payment rule * @param file file to export checks * @return number of lines */ - public int exportToFile (MPaySelectionCheck[] checks, File file, StringBuffer err) - { + public int exportToFile(MPaySelectionCheck[] checks, boolean depositBatch, String paymentRule, File file, + StringBuffer err) { if (checks == null || checks.length == 0) return 0; // Must be a file @@ -115,6 +118,7 @@ public class GenericPaymentExport implements PaymentExport .append(x).append("PayDate").append(x).append(",") .append(x).append("Currency").append(x).append(",") .append(x).append("PayAmount").append(x).append(",") + .append(x).append("DepositBatch").append(x).append(",") .append(x).append("Comment").append(x) .append(Env.NL); fw.write(line.toString()); @@ -154,6 +158,7 @@ public class GenericPaymentExport implements PaymentExport .append(mpp.getParent().getPayDate()).append(",") // PayDate .append(x).append(MCurrency.getISO_Code(Env.getCtx(), mpp.getParent().getC_Currency_ID())).append(x).append(",") // Currency .append(mpp.getPayAmt()).append(",") // PayAmount + .append(x).append(depositBatch).append(x).append(",") .append(x).append(comment.toString()).append(x) // Comment .append(Env.NL); fw.write(line.toString()); @@ -249,5 +254,35 @@ public class GenericPaymentExport implements PaymentExport return bp; } // getBPartnerInfo + @Override + public String getFilenamePrefix() { + String creationDate = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(System.currentTimeMillis()) ; + return "payments-" + creationDate ; + } + + @Override + public String getFilenameSuffix() { + return ".csv"; + } + + @Override + public String getContentType() { + return "text/csv"; + } + + @Override + public boolean supportsDepositBatch() { + return true; + } + + @Override + public boolean supportsSeparateBooking() { + return true; + } + + @Override + public boolean getDefaultDepositBatch() { + return false; + } -} // PaymentExport +} // PaymentExporterInterface diff --git a/org.adempiere.base/src/org/compiere/util/PaymentExport.java b/org.adempiere.base/src/org/compiere/util/PaymentExport.java index 85500b465a..0b516ccde2 100644 --- a/org.adempiere.base/src/org/compiere/util/PaymentExport.java +++ b/org.adempiere.base/src/org/compiere/util/PaymentExport.java @@ -24,6 +24,10 @@ import org.compiere.model.MPaySelectionCheck; * Custom Payment Export Interface * * @author Carlos Ruiz - GlobalQSS + * + * Contributors: + * Markus Bozem - IDEMPIERE-1546 / IDEMPIERE-3286 + * * @version PaymentExport.java */ public interface PaymentExport @@ -34,7 +38,74 @@ public interface PaymentExport * @param checks array of checks * @param file file to export checks * @return number of lines + * + * This method is preserved for backward compatibility (old non-OSGi way via fragment), + * new interfaces can leave this method unimplemented and must implement the other methods */ - public int exportToFile (MPaySelectionCheck[] checks, File file, StringBuffer err); + public default int exportToFile (MPaySelectionCheck[] checks, File file, StringBuffer err) { + return exportToFile (checks, false, (String)null, file, err); + } + + /************************************************************************** + * Export to file + * @param checks array of checks + * @param depositBatch create deposit batch + * @param file file to export checks + * @return number of lines + */ + public default int exportToFile (MPaySelectionCheck[] checks, boolean depositBatch, String paymentRule, File file, StringBuffer err) { + return exportToFile (checks, file, err); + } + + /** + * Get the filename prefix from plugin + * e.g. "SEPA-Credit-Transfer-" + * @return prefix for filename + */ + public default String getFilenamePrefix() { + return "paymentExport"; + } + + /** + * Get the filename suffix from plugin + * e.g. ".xml" + * @return suffix for filename + */ + public default String getFilenameSuffix() { + return ".txt"; + } + + /** + * Get the content type from plugin + * e.g. "text/xml" or "text/csv" + * @return content type delivered to browser + */ + public default String getContentType() { + return "text/plain"; + } + + /** + * Plugin supports deposit batch + * @return true if supported + */ + public default boolean supportsDepositBatch() { + return false; + } + + /** + * Plugin supports booking payments separate on bank statement (no deposit batch) + * @return true if supported + */ + public default boolean supportsSeparateBooking() { + return false; + } + + /** + * Default if supportsDepositBatch is true and supportsSeparateBooking is true + * @return true if deposit batch should be selected on default, false if deposit batch should not be selected + */ + public default boolean getDefaultDepositBatch() { + return false; + } } // PaymentExport diff --git a/org.adempiere.ui.swing/src/org/compiere/apps/form/VPayPrint.java b/org.adempiere.ui.swing/src/org/compiere/apps/form/VPayPrint.java index 07fd91d750..1b506efcd2 100644 --- a/org.adempiere.ui.swing/src/org/compiere/apps/form/VPayPrint.java +++ b/org.adempiere.ui.swing/src/org/compiere/apps/form/VPayPrint.java @@ -46,6 +46,7 @@ import static org.compiere.model.SystemIDs.*; import org.compiere.plaf.CompiereColor; import org.compiere.print.ReportCtl; import org.compiere.print.ReportEngine; +import org.compiere.swing.CCheckBox; import org.compiere.swing.CComboBox; import org.compiere.swing.CLabel; import org.compiere.swing.CPanel; @@ -54,7 +55,6 @@ import org.compiere.util.DisplayType; import org.compiere.util.Env; import org.compiere.util.Ini; import org.compiere.util.Msg; -import org.compiere.util.PaymentExport; import org.compiere.util.ValueNamePair; /** @@ -65,6 +65,7 @@ import org.compiere.util.ValueNamePair; * * Contributors: * Carlos Ruiz - GlobalQSS - FR 3132033 - Make payment export class configurable per bank + * Markus Bozem: IDEMPIERE-1546 / IDEMPIERE-3286 */ public class VPayPrint extends PayPrint implements FormPanel, ActionListener, VetoableChangeListener { @@ -120,7 +121,10 @@ public class VPayPrint extends PayPrint implements FormPanel, ActionListener, Ve private VNumber fBalance = new VNumber(); private CLabel lCurrency = new CLabel(); private CLabel fCurrency = new CLabel(); - + private CLabel lDepositBatch = new CLabel(); + private CCheckBox fDepositBatch = new CCheckBox(); + private CLabel lSumPayments = new CLabel(); + private VNumber fSumPayments = new VNumber(); /** * Static Init * @throws Exception @@ -133,6 +137,8 @@ public class VPayPrint extends PayPrint implements FormPanel, ActionListener, Ve southLayout.setAlignment(FlowLayout.RIGHT); centerPanel.setLayout(centerLayout); // + bPrint.setEnabled(false); + bExport.setEnabled(false); bPrint.addActionListener(this); bExport.addActionListener(this); bCancel.addActionListener(this); @@ -156,6 +162,10 @@ public class VPayPrint extends PayPrint implements FormPanel, ActionListener, Ve fBalance.setReadWrite(false); fBalance.setDisplayType(DisplayType.Amount); lCurrency.setText(Msg.translate(Env.getCtx(), "C_Currency_ID")); + lDepositBatch.setText(Msg.translate(Env.getCtx(), "C_DepositBatch_ID")); + lSumPayments.setText(Msg.getMsg(Env.getCtx(), "Sum")); + fSumPayments.setReadWrite(false); + fSumPayments.setDisplayType(DisplayType.Amount); // southPanel.add(bCancel, null); southPanel.add(bExport, null); @@ -190,6 +200,15 @@ public class VPayPrint extends PayPrint implements FormPanel, ActionListener, Ve ,GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(0, 12, 12, 5), 0, 0)); centerPanel.add(fCurrency, new GridBagConstraints(3, 2, 1, 1, 0.0, 0.0 ,GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 12, 12), 0, 0)); + + centerPanel.add(lDepositBatch, new GridBagConstraints(0, 4, 1, 1, 0.0, 0.0 + ,GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(0, 12, 5, 5), 0, 0)); + centerPanel.add(fDepositBatch, new GridBagConstraints(1, 4, 1, 1, 0.0, 0.0 + ,GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 5, 12), 0, 0)); + centerPanel.add(lSumPayments, new GridBagConstraints(2, 4, 1, 1, 0.0, 0.0 + ,GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(0, 12, 5, 5), 0, 0)); + centerPanel.add(fSumPayments, new GridBagConstraints(3, 4, 1, 1, 0.0, 0.0 + ,GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 5, 12), 0, 0)); } // VPayPrint /** @@ -311,6 +330,9 @@ public class VPayPrint extends PayPrint implements FormPanel, ActionListener, Ve if(noPayments != null) fNoPayments.setText(noPayments); + if(sumPayments != null) + fSumPayments.setValue(sumPayments); + bProcess.setEnabled(PaymentRule.equals("T")); if(documentNo != null) @@ -318,9 +340,44 @@ public class VPayPrint extends PayPrint implements FormPanel, ActionListener, Ve if(msg != null && msg.length() > 0) ADialog.error(m_WindowNo, panel, msg); + + getPluginFeatures(); } // loadPaymentRuleInfo - + protected void getPluginFeatures() + { + if (m_C_PaySelection_ID!=0) + { + if (loadPaymentExportClass (null)>=0) + { + bExport.setEnabled(true); + + fDepositBatch.setValue(m_PaymentExport.getDefaultDepositBatch()); + if (m_PaymentExport.supportsDepositBatch() && m_PaymentExport.supportsSeparateBooking()) + { + fDepositBatch.setReadWrite(true); + } + else + { + fDepositBatch.setReadWrite(false); + } + } + else + { + bExport.setEnabled(false); + } + if (printFormatId!=null && printFormatId!=0) + { + bPrint.setEnabled(true); + } + else + { + bPrint.setEnabled(false); + } + } + + } // getPluginFeatures + /************************************************************************** * Export payments to file */ @@ -339,7 +396,8 @@ public class VPayPrint extends PayPrint implements FormPanel, ActionListener, Ve fc.setDialogTitle(Msg.getMsg(Env.getCtx(), "Export")); fc.setFileSelectionMode(JFileChooser.FILES_ONLY); fc.setMultiSelectionEnabled(false); - fc.setSelectedFile(new java.io.File("paymentExport.txt")); + String filename = m_PaymentExport.getFilenamePrefix() + m_PaymentExport.getFilenameSuffix(); + fc.setSelectedFile(new java.io.File(filename)); if (fc.showSaveDialog(panel) != JFileChooser.APPROVE_OPTION) return; @@ -349,26 +407,14 @@ public class VPayPrint extends PayPrint implements FormPanel, ActionListener, Ve if (m_PaymentExportClass == null || m_PaymentExportClass.trim().length() == 0) { m_PaymentExportClass = "org.compiere.util.GenericPaymentExport"; } - // Get Payment Export Class - PaymentExport custom = null; - try + + no = loadPaymentExportClass(err) ; + + if (no >= 0) { - Class clazz = Class.forName(m_PaymentExportClass); - custom = (PaymentExport)clazz.newInstance(); - no = custom.exportToFile(m_checks, fc.getSelectedFile(), err); - } - catch (ClassNotFoundException e) - { - no = -1; - err.append("No custom PaymentExport class " + m_PaymentExportClass + " - " + e.toString()); - log.log(Level.SEVERE, err.toString(), e); - } - catch (Exception e) - { - no = -1; - err.append("Error in " + m_PaymentExportClass + " check log, " + e.toString()); - log.log(Level.SEVERE, err.toString(), e); + no = m_PaymentExport.exportToFile(m_checks,(Boolean) fDepositBatch.getValue(),PaymentRule, fc.getSelectedFile(), err); } + if (no >= 0) { ADialog.info(m_WindowNo, panel, "Saved", fc.getSelectedFile().getAbsolutePath() + "\n" @@ -377,7 +423,7 @@ public class VPayPrint extends PayPrint implements FormPanel, ActionListener, Ve if (ADialog.ask(m_WindowNo, panel, "VPayPrintSuccess?")) { // int lastDocumentNo = - MPaySelectionCheck.confirmPrint (m_checks, m_batch); + MPaySelectionCheck.confirmPrint (m_checks, m_batch, (Boolean) fDepositBatch.getValue()); // document No not updated } } else { diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WPayPrint.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WPayPrint.java index 8ebc830ea7..692eda2558 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WPayPrint.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WPayPrint.java @@ -39,6 +39,7 @@ import org.adempiere.webui.component.Rows; import org.adempiere.webui.component.Window; import org.adempiere.webui.editor.WNumberEditor; import org.adempiere.webui.editor.WSearchEditor; +import org.adempiere.webui.editor.WYesNoEditor; import org.adempiere.webui.event.ValueChangeEvent; import org.adempiere.webui.event.ValueChangeListener; import org.adempiere.webui.panel.ADForm; @@ -61,7 +62,6 @@ import org.compiere.util.DB; import org.compiere.util.DisplayType; import org.compiere.util.Env; import org.compiere.util.Msg; -import org.compiere.util.PaymentExport; import org.compiere.util.ValueNamePair; import org.zkoss.zk.ui.event.Event; import org.zkoss.zk.ui.event.EventListener; @@ -80,6 +80,7 @@ import com.itextpdf.text.pdf.PdfReader; * * Contributors: * Carlos Ruiz - GlobalQSS - FR 3132033 - Make payment export class configurable per bank + * Markus Bozem: IDEMPIERE-1546 / IDEMPIERE-3286 */ public class WPayPrint extends PayPrint implements IFormController, EventListener, ValueChangeListener { @@ -136,7 +137,12 @@ public class WPayPrint extends PayPrint implements IFormController, EventListene protected WNumberEditor fBalance = new WNumberEditor(); protected Label lCurrency = new Label(); protected Label fCurrency = new Label(); + protected Label lDepositBatch = new Label(); + protected WYesNoEditor fDepositBatch = new WYesNoEditor("", "", "Book as one post", false, false, true) ; + protected Label lSumPayments = new Label(); + protected WNumberEditor fSumPayments = new WNumberEditor(); + /** * Static Init * @throws Exception @@ -168,6 +174,10 @@ public class WPayPrint extends PayPrint implements IFormController, EventListene fBalance.setReadWrite(false); fBalance.getComponent().setIntegral(false); lCurrency.setText(Msg.translate(Env.getCtx(), "C_Currency_ID")); + lDepositBatch.setText(Msg.translate(Env.getCtx(), "C_DepositBatch_ID")); + lSumPayments.setText(Msg.getMsg(Env.getCtx(), "Sum")); + fSumPayments.setReadWrite(false); + fSumPayments.getComponent().setIntegral(false); // southPanel.addButton(bExport); southPanel.addButton(bPrint); @@ -195,8 +205,18 @@ public class WPayPrint extends PayPrint implements IFormController, EventListene row.appendChild(fDocumentNo.getComponent()); row.appendChild(lNoPayments.rightAlign()); row.appendChild(fNoPayments); + + row = rows.newRow(); + row.appendChild(lDepositBatch.rightAlign()) ; + row.appendChild(fDepositBatch.getComponent()) ; + row.appendChild(lSumPayments.rightAlign()) ; + row.appendChild(fSumPayments.getComponent()) ; southPanel.getButton(ConfirmPanel.A_OK).setVisible(false); + bExport.setDisabled(true); + bPrint.setDisabled(true); + fDepositBatch.setReadWrite(false); + fDocumentNo.setReadWrite(false); } // VPayPrint /** @@ -318,6 +338,9 @@ public class WPayPrint extends PayPrint implements IFormController, EventListene if(noPayments != null) fNoPayments.setText(noPayments); + + if(sumPayments != null) + fSumPayments.setValue(sumPayments); bProcess.setEnabled(PaymentRule.equals("T")); @@ -326,9 +349,45 @@ public class WPayPrint extends PayPrint implements IFormController, EventListene if(msg != null && msg.length() > 0) FDialog.error(m_WindowNo, form, msg); + + getPluginFeatures(); } // loadPaymentRuleInfo + protected void getPluginFeatures() + { + if (m_C_PaySelection_ID!=0) + { + if (loadPaymentExportClass (null)>=0) + { + bExport.setDisabled(false); + + fDepositBatch.setValue(m_PaymentExport.getDefaultDepositBatch()); + if (m_PaymentExport.supportsDepositBatch() && m_PaymentExport.supportsSeparateBooking()) + { + fDepositBatch.setReadWrite(true); + } + else + { + fDepositBatch.setReadWrite(false); + } + } + else + { + bExport.setDisabled(true); + } + if (printFormatId!=null && printFormatId!=0) + { + bPrint.setEnabled(true); + } + else + { + bPrint.setEnabled(false); + } + } + } // getPluginFeatures + + /************************************************************************** * Export payments to file */ @@ -343,37 +402,28 @@ public class WPayPrint extends PayPrint implements IFormController, EventListene try { - // Get File Info - File tempFile = File.createTempFile("paymentExport", ".txt"); - - // Create File int no = 0; StringBuffer err = new StringBuffer(""); if (m_PaymentExportClass == null || m_PaymentExportClass.trim().length() == 0) { m_PaymentExportClass = "org.compiere.util.GenericPaymentExport"; } - // Get Payment Export Class - PaymentExport custom = null; - try + + File tempFile = null; + String filenameForDownload = ""; + + no = loadPaymentExportClass(err) ; + + if (no >= 0) { - Class clazz = Class.forName(m_PaymentExportClass); - custom = (PaymentExport)clazz.newInstance(); - no = custom.exportToFile(m_checks, tempFile, err); - } - catch (ClassNotFoundException e) - { - no = -1; - err.append("No custom PaymentExport class " + m_PaymentExportClass + " - " + e.toString()); - log.log(Level.SEVERE, err.toString(), e); - } - catch (Exception e) - { - no = -1; - err.append("Error in " + m_PaymentExportClass + " check log, " + e.toString()); - log.log(Level.SEVERE, err.toString(), e); + // Get File Info + tempFile = File.createTempFile(m_PaymentExport.getFilenamePrefix(), m_PaymentExport.getFilenameSuffix()); + filenameForDownload = m_PaymentExport.getFilenamePrefix() + m_PaymentExport.getFilenameSuffix(); + + no = m_PaymentExport.exportToFile(m_checks,(Boolean) fDepositBatch.getValue(),PaymentRule, tempFile, err); } + if (no >= 0) { - Filedownload.save(new FileInputStream(tempFile), "plain/text", "paymentExport.txt"); + Filedownload.save(new FileInputStream(tempFile), m_PaymentExport.getContentType(), filenameForDownload); FDialog.info(m_WindowNo, form, "Saved", Msg.getMsg(Env.getCtx(), "NoOfLines") + "=" + no); @@ -384,7 +434,7 @@ public class WPayPrint extends PayPrint implements IFormController, EventListene { if (result) { - MPaySelectionCheck.confirmPrint (m_checks, m_batch); + MPaySelectionCheck.confirmPrint (m_checks, m_batch, (Boolean) fDepositBatch.getValue()); // document No not updated } diff --git a/org.adempiere.ui/src/org/compiere/apps/form/PayPrint.java b/org.adempiere.ui/src/org/compiere/apps/form/PayPrint.java index 37817a3bb0..7dd2c792eb 100644 --- a/org.adempiere.ui/src/org/compiere/apps/form/PayPrint.java +++ b/org.adempiere.ui/src/org/compiere/apps/form/PayPrint.java @@ -13,7 +13,8 @@ * * * Contributors: * * Carlos Ruiz - GlobalQSS: * - * FR 3132033 - Make payment export class configurable per bank * + * FR 3132033 - Make payment export class configurable per bank + * Markus Bozem: IDEMPIERE-1546 / IDEMPIERE-3286 * *****************************************************************************/ package org.compiere.apps.form; @@ -24,8 +25,11 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; +import java.util.List; import java.util.logging.Level; +import org.adempiere.base.IPaymentExporterFactory; +import org.adempiere.base.Service; import org.compiere.model.MLookupFactory; import org.compiere.model.MLookupInfo; import org.compiere.model.MPaySelectionCheck; @@ -34,6 +38,7 @@ import org.compiere.util.CLogger; import org.compiere.util.DB; import org.compiere.util.Env; import org.compiere.util.Language; +import org.compiere.util.PaymentExport; import org.compiere.util.ValueNamePair; public class PayPrint { @@ -57,6 +62,7 @@ public class PayPrint { public String bank; public String currency; public BigDecimal balance; + protected PaymentExport m_PaymentExport; /** * PaySelect changed - load Bank @@ -157,7 +163,8 @@ public class PayPrint { public String noPayments; public Integer documentNo; - + public Double sumPayments; + public Integer printFormatId; /** * PaymentRule changed - load DocumentNo, NoPayments, @@ -167,19 +174,23 @@ public class PayPrint { { String msg = null; - String sql = "SELECT COUNT(*) " + String sql = "SELECT COUNT(*),SUM(payamt) " + "FROM C_PaySelectionCheck " - + "WHERE C_PaySelection_ID=?"; + + "WHERE C_PaySelection_ID=? AND PaymentRule=?"; PreparedStatement pstmt = null; ResultSet rs = null; try { pstmt = DB.prepareStatement(sql, null); pstmt.setInt(1, C_PaySelection_ID); + pstmt.setString(2, PaymentRule); rs = pstmt.executeQuery(); // if (rs.next()) + { noPayments = String.valueOf(rs.getInt(1)); + sumPayments = rs.getDouble(2); + } } catch (SQLException e) { @@ -192,8 +203,11 @@ public class PayPrint { pstmt = null; } + printFormatId = null; + documentNo = null; + // DocumentNo - sql = "SELECT CurrentNext " + sql = "SELECT CurrentNext, Check_PrintFormat_ID " + "FROM C_BankAccountDoc " + "WHERE C_BankAccount_ID=? AND PaymentRule=? AND IsActive='Y'"; try @@ -204,7 +218,10 @@ public class PayPrint { rs = pstmt.executeQuery(); // if (rs.next()) + { documentNo = new Integer(rs.getInt(1)); + printFormatId = new Integer(rs.getInt(2)); + } else { log.log(Level.SEVERE, "VPayPrint.loadPaymentRuleInfo - No active BankAccountDoc for C_BankAccount_ID=" @@ -225,4 +242,50 @@ public class PayPrint { return msg; } // loadPaymentRuleInfo + + protected int loadPaymentExportClass (StringBuffer err) + { + m_PaymentExport = null ; + + if (m_PaymentExportClass == null || m_PaymentExportClass.trim().length() == 0) { + m_PaymentExportClass = "org.compiere.util.GenericPaymentExport"; + } + try + { + List factories = Service.locator().list(IPaymentExporterFactory.class).getServices(); + if (factories != null && !factories.isEmpty()) { + for(IPaymentExporterFactory factory : factories) { + m_PaymentExport = factory.newPaymentExporterInstance(m_PaymentExportClass); + if (m_PaymentExport != null) + break; + } + } + + if (m_PaymentExport == null) + { + Class clazz = Class.forName (m_PaymentExportClass); + m_PaymentExport = (PaymentExport)clazz.newInstance(); + } + + } + catch (ClassNotFoundException e) + { + if (err!=null) + { + err.append("No custom PaymentExport class " + m_PaymentExportClass + " - " + e.toString()); + log.log(Level.SEVERE, err.toString(), e); + } + return -1; + } + catch (Exception e) + { + if (err!=null) + { + err.append("Error in " + m_PaymentExportClass + " check log, " + e.toString()); + log.log(Level.SEVERE, err.toString(), e); + } + return -1; + } + return 0 ; + } // loadPaymentExportClass } From 0a930345baa60e7620f964e849f183b7ff7f6ac5 Mon Sep 17 00:00:00 2001 From: Orlando Curieles Date: Tue, 17 Oct 2017 19:06:59 +0200 Subject: [PATCH 4/4] IDEMPIERE-3521 InfoWindow problem on other SQL when make a register count --- .../WEB-INF/src/org/adempiere/webui/info/InfoWindow.java | 4 ++++ .../WEB-INF/src/org/adempiere/webui/panel/InfoPanel.java | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/info/InfoWindow.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/info/InfoWindow.java index 9d919319a7..21d14192a8 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/info/InfoWindow.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/info/InfoWindow.java @@ -1705,6 +1705,10 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL } countSql = MRole.getDefault().addAccessSQL (countSql, getTableName(), MRole.SQL_FULLYQUALIFIED, MRole.SQL_RO); + // Fix GroupBy On InfoWindow + String otherClause = infoWindow.getOtherClause(); + if (otherClause !=null) + countSql = countSql+" "+otherClause; countSql = "SELECT COUNT(*) FROM ( " + countSql + " ) a"; diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/InfoPanel.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/InfoPanel.java index 6ceedc67f7..376011e0d4 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/InfoPanel.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/InfoPanel.java @@ -1065,6 +1065,10 @@ public abstract class InfoPanel extends Window implements EventListener, countSql = countSql.trim(); countSql = countSql.substring(0, countSql.length() - 5); } + String otherClause = infoWindow.getOtherClause(); // Fix otherClause on count + if (otherClause != null) + countSql = countSql+" "+otherClause; + countSql = MRole.getDefault().addAccessSQL (countSql, getTableName(), MRole.SQL_FULLYQUALIFIED, MRole.SQL_RO); if (log.isLoggable(Level.FINER))