package org.adempiere.webui.apps;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.logging.Level;
import org.adempiere.webui.component.Button;
import org.adempiere.webui.component.Panel;
import org.adempiere.webui.component.Window;
import org.adempiere.webui.desktop.IDesktop;
import org.adempiere.webui.process.WProcessInfo;
import org.adempiere.webui.session.SessionManager;
import org.adempiere.webui.window.FDialog;
import org.adempiere.webui.window.SimplePDFViewer;
import org.compiere.apps.ProcessCtl;
import org.compiere.print.ReportEngine;
import org.compiere.process.ProcessInfo;
import org.compiere.process.ProcessInfoUtil;
import org.compiere.util.CLogger;
import org.compiere.util.DB;
import org.compiere.util.Env;
import org.compiere.util.Msg;
import org.zkoss.zk.au.out.AuEcho;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zk.ui.util.Clients;
import org.zkoss.zkex.zul.Borderlayout;
import org.zkoss.zkex.zul.Center;
import org.zkoss.zkex.zul.North;
import org.zkoss.zkex.zul.South;
import org.zkoss.zul.Div;
import org.zkoss.zul.Hbox;
import org.zkoss.zul.Html;
import com.lowagie.text.Document;
import com.lowagie.text.pdf.PdfContentByte;
import com.lowagie.text.pdf.PdfImportedPage;
import com.lowagie.text.pdf.PdfReader;
import com.lowagie.text.pdf.PdfWriter;
/******************************************************************************
* Product: Adempiere ERP & CRM Smart Business Solution *
* Copyright (C) 2007 Low Heng Sin *
* 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. *
*****************************************************************************/
/**
* Dialog to Start process or report.
* Displays information about the process
* and lets the user decide to start it
* and displays results (optionally print them).
* Calls ProcessCtl to execute.
* @author Low Heng Sin
* @author arboleda - globalqss
* - Implement ShowHelp option on processes and reports
*/
public class ProcessDialog extends Window implements EventListener//, ASyncProcess
{
/**
* generate serial version ID
*/
private static final long serialVersionUID = 5545731871518761455L;
private static final String MESSAGE_DIV_STYLE = "max-height: 150pt; overflow: auto";
private Div messageDiv;
private Center center;
private North north;
/**
* Dialog to start a process/report
* @param ctx
* @param parent
* @param title
* @param aProcess
* @param WindowNo
* @param AD_Process_ID
* @param tableId
* @param recordId
* @param autoStart
*/
public ProcessDialog (int AD_Process_ID, boolean isSOTrx)
{
log.info("Process=" + AD_Process_ID );
m_ctx = Env.getCtx();
m_WindowNo = SessionManager.getAppDesktop().registerWindow(this);
this.setAttribute(IDesktop.WINDOWNO_ATTRIBUTE, m_WindowNo);
m_AD_Process_ID = AD_Process_ID;
Env.setContext(Env.getCtx(), m_WindowNo, "IsSOTrx", isSOTrx ? "Y" : "N");
try
{
initComponents();
init();
}
catch(Exception ex)
{
log.log(Level.SEVERE, "", ex);
}
} // ProcessDialog
private void initComponents() {
this.setStyle("position: absolute; width: 100%; height: 100%");
Borderlayout layout = new Borderlayout();
layout.setStyle("position: absolute; width: 100%; height: 100%; border: none;");
messageDiv = new Div();
message = new Html();
messageDiv.appendChild(message);
messageDiv.setStyle(MESSAGE_DIV_STYLE);
north = new North();
north.appendChild(messageDiv);
layout.appendChild(north);
north.setAutoscroll(true);
north.setStyle("border: none;");
centerPanel = new Panel();
center = new Center();
layout.appendChild(center);
center.appendChild(centerPanel);
center.setFlex(true);
center.setAutoscroll(true);
center.setStyle("border: none");
Div div = new Div();
div.setAlign("center");
Hbox hbox = new Hbox();
String label = Msg.getMsg(Env.getCtx(), "Start");
bOK = new Button(label.replaceAll("&", ""));
bOK.setImage("/images/Ok16.png");
bOK.setId("Ok");
bOK.addEventListener(Events.ON_CLICK, this);
bOK.setSclass("action-button");
hbox.appendChild(bOK);
label = Msg.getMsg(Env.getCtx(), "Cancel");
Button btn = new Button(label.replaceAll("&", ""));
btn.setImage("/images/Cancel16.png");
btn.setId("Cancel");
btn.addEventListener(Events.ON_CLICK, this);
btn.setSclass("action-button");
hbox.appendChild(btn);
div.appendChild(hbox);
div.setStyle("padding: 10px");
South south = new South();
layout.appendChild(south);
south.appendChild(div);
this.appendChild(layout);
}
private int m_WindowNo;
private Properties m_ctx;
private int m_AD_Process_ID;
private String m_Name = null;
private boolean m_IsReport = false;
private int[] m_ids = null;
private StringBuffer m_messageText = new StringBuffer();
private String m_ShowHelp = null; // Determine if a Help Process Window is shown
private Panel centerPanel = null;
private Html message = null;
private Button bOK = null;
private boolean valid = true;
/** Logger */
private static CLogger log = CLogger.getCLogger(ProcessDialog.class);
//
private ProcessParameterPanel parameterPanel = null;
private ProcessInfo m_pi = null;
private boolean m_isLocked = false;
private String initialMessage;
private BusyDialog progressWindow;
/**
* Set Visible
* (set focus to OK if visible)
* @param visible true if visible
*/
public boolean setVisible (boolean visible)
{
return super.setVisible(visible);
} // setVisible
/**
* Dispose
*/
public void dispose()
{
SessionManager.getAppDesktop().closeWindow(m_WindowNo);
valid = false;
}// dispose
/**
* Dynamic Init
* @return true, if there is something to process (start from menu)
*/
public boolean init()
{
log.config("");
//
boolean trl = !Env.isBaseLanguage(m_ctx, "AD_Process");
String sql = "SELECT Name, Description, Help, IsReport, ShowHelp "
+ "FROM AD_Process "
+ "WHERE AD_Process_ID=?";
if (trl)
sql = "SELECT t.Name, t.Description, t.Help, p.IsReport, p.ShowHelp "
+ "FROM AD_Process p, AD_Process_Trl t "
+ "WHERE p.AD_Process_ID=t.AD_Process_ID"
+ " AND p.AD_Process_ID=? AND t.AD_Language=?";
PreparedStatement pstmt = null;
ResultSet rs = null;
try
{
pstmt = DB.prepareStatement(sql, null);
pstmt.setInt(1, m_AD_Process_ID);
if (trl)
pstmt.setString(2, Env.getAD_Language(m_ctx));
rs = pstmt.executeQuery();
if (rs.next())
{
m_Name = rs.getString(1);
m_IsReport = rs.getString(4).equals("Y");
m_ShowHelp = rs.getString(5);
//
m_messageText.append("<b>");
String s = rs.getString(2); // Description
if (rs.wasNull())
m_messageText.append(Msg.getMsg(m_ctx, "StartProcess?"));
else
m_messageText.append(s);
m_messageText.append("</b>");
s = rs.getString(3); // Help
if (!rs.wasNull())
m_messageText.append("<p>").append(s).append("</p>");
}
}
catch (SQLException e)
{
log.log(Level.SEVERE, sql, e);
return false;
}
finally
{
DB.close(rs, pstmt);
}
if (m_Name == null)
return false;
//
this.setTitle(m_Name);
initialMessage = m_messageText.toString();
message.setContent(initialMessage);
bOK.setLabel(Msg.getMsg(Env.getCtx(), "Start"));
// Move from APanel.actionButton
m_pi = new WProcessInfo(m_Name, m_AD_Process_ID);
m_pi.setAD_User_ID (Env.getAD_User_ID(Env.getCtx()));
m_pi.setAD_Client_ID(Env.getAD_Client_ID(Env.getCtx()));
parameterPanel = new ProcessParameterPanel(m_WindowNo, m_pi, "70%");
centerPanel.getChildren().clear();
if ( parameterPanel.init() ) {
centerPanel.appendChild(parameterPanel);
} else {
if (m_ShowHelp != null && m_ShowHelp.equals("N")) {
startProcess();
}
}
// Check if the process is a silent one
if(m_ShowHelp != null && m_ShowHelp.equals("S"))
{
startProcess();
}
return true;
} // init
public void startProcess()
{
m_pi.setPrintPreview(true);
this.lockUI(m_pi);
Clients.response(new AuEcho(this, "runProcess", null));
}
public void runProcess() {
try {
ProcessCtl.process(null, m_WindowNo, parameterPanel, m_pi, null);
} finally {
unlockUI(m_pi);
}
}
public void onEvent(Event event) {
Component component = event.getTarget();
if (component instanceof Button) {
Button element = (Button)component;
if ("Ok".equalsIgnoreCase(element.getId())) {
if (!parameterPanel.validateParameters())
return;
if (element.getLabel().length() > 0)
this.startProcess();
else
this.dispose();
} else if ("Cancel".equalsIgnoreCase(element.getId())) {
this.dispose();
}
}
}
public void lockUI(ProcessInfo pi) {
if (m_isLocked) return;
m_isLocked = true;
showBusyDialog();
}
private void showBusyDialog() {
progressWindow = new BusyDialog();
progressWindow.setPage(this.getPage());
progressWindow.doHighlighted();
}
public void unlockUI(ProcessInfo pi) {
if (!m_isLocked) return;
m_isLocked = false;
hideBusyDialog();
updateUI(pi);
}
private void hideBusyDialog() {
if (progressWindow != null) {
progressWindow.dispose();
progressWindow = null;
}
}
private void updateUI(ProcessInfo pi) {
ProcessInfoUtil.setLogFromDB(pi);
m_messageText.append("<p><font color=\"").append(pi.isError() ? "#FF0000" : "#0000FF").append("\">** ")
.append(pi.getSummary())
.append("</font></p>");
m_messageText.append(pi.getLogInfo(true));
message.setContent(m_messageText.toString());
bOK.setLabel("");
m_ids = pi.getIDs();
//move message div to center to give more space to display potentially very long log info
centerPanel.detach();
messageDiv.detach();
messageDiv.setStyle("");
north.setVisible(false);
center.appendChild(messageDiv);
invalidate();
Clients.response(new AuEcho(this, "onAfterProcess", null));
}
public void onAfterProcess()
{
//
afterProcessTask();
// Close automatically
if (m_IsReport && !m_pi.isError())
this.dispose();
// If the process is a silent one and no errors occured, close the dialog
if(m_ShowHelp != null && m_ShowHelp.equals("S"))
this.dispose();
}
/**************************************************************************
* Optional Processing Task
*/
private void afterProcessTask()
{
// something to do?
if (m_ids != null && m_ids.length > 0)
{
log.config("");
// Print invoices
if (m_AD_Process_ID == 119)
printInvoices();
else if (m_AD_Process_ID == 118)
printShipments();
}
} // afterProcessTask
/**************************************************************************
* Print Shipments
*/
private void printShipments()
{
if (m_ids == null)
return;
if (!FDialog.ask(m_WindowNo, this, "PrintShipments"))
return;
m_messageText.append("<p>").append(Msg.getMsg(Env.getCtx(), "PrintShipments")).append("</p>");
message.setContent(m_messageText.toString());
showBusyDialog();
Clients.response(new AuEcho(this, "onPrintShipments", null));
} // printInvoices
public void onPrintShipments()
{
// Loop through all items
List<File> pdfList = new ArrayList<File>();
for (int i = 0; i < m_ids.length; i++)
{
int M_InOut_ID = m_ids[i];
ReportEngine re = ReportEngine.get (Env.getCtx(), ReportEngine.SHIPMENT, M_InOut_ID);
pdfList.add(re.getPDF());
}
if (pdfList.size() > 1) {
try {
File outFile = File.createTempFile("PrintShipments", ".pdf");
Document document = null;
PdfWriter copy = null;
for (File f : pdfList)
{
String fileName = f.getAbsolutePath();
PdfReader reader = new PdfReader(fileName);
reader.consolidateNamedDestinations();
if (document == null)
{
document = new Document(reader.getPageSizeWithRotation(1));
copy = PdfWriter.getInstance(document, new FileOutputStream(outFile));
document.open();
}
int pages = reader.getNumberOfPages();
PdfContentByte cb = copy.getDirectContent();
for (int i = 1; i <= pages; i++) {
document.newPage();
PdfImportedPage page = copy.getImportedPage(reader, i);
cb.addTemplate(page, 0, 0);
}
}
document.close();
hideBusyDialog();
Window win = new SimplePDFViewer(this.getTitle(), new FileInputStream(outFile));
SessionManager.getAppDesktop().showWindow(win, "center");
} catch (Exception e) {
log.log(Level.SEVERE, e.getLocalizedMessage(), e);
}
} else if (pdfList.size() > 0) {
hideBusyDialog();
try {
Window win = new SimplePDFViewer(this.getTitle(), new FileInputStream(pdfList.get(0)));
SessionManager.getAppDesktop().showWindow(win, "center");
} catch (Exception e)
{
log.log(Level.SEVERE, e.getLocalizedMessage(), e);
}
}
}
/**
* Print Invoices
*/
private void printInvoices()
{
if (m_ids == null)
return;
if (!FDialog.ask(m_WindowNo, this, "PrintInvoices"))
return;
m_messageText.append("<p>").append(Msg.getMsg(Env.getCtx(), "PrintInvoices")).append("</p>");
message.setContent(m_messageText.toString());
showBusyDialog();
Clients.response(new AuEcho(this, "onPrintInvoices", null));
} // printInvoices
public void onPrintInvoices()
{
// Loop through all items
List<File> pdfList = new ArrayList<File>();
for (int i = 0; i < m_ids.length; i++)
{
int C_Invoice_ID = m_ids[i];
ReportEngine re = ReportEngine.get (Env.getCtx(), ReportEngine.INVOICE, C_Invoice_ID);
pdfList.add(re.getPDF());
}
if (pdfList.size() > 1) {
try {
File outFile = File.createTempFile("PrintInvoices", ".pdf");
Document document = null;
PdfWriter copy = null;
for (File f : pdfList)
{
PdfReader reader = new PdfReader(f.getAbsolutePath());
if (document == null)
{
document = new Document(reader.getPageSizeWithRotation(1));
copy = PdfWriter.getInstance(document, new FileOutputStream(outFile));
document.open();
}
PdfContentByte cb = copy.getDirectContent(); // Holds the PDF
int pages = reader.getNumberOfPages();
for (int i = 1; i <= pages; i++) {
document.newPage();
PdfImportedPage page = copy.getImportedPage(reader, i);
cb.addTemplate(page, 0, 0);
}
}
document.close();
hideBusyDialog();
Window win = new SimplePDFViewer(this.getTitle(), new FileInputStream(outFile));
SessionManager.getAppDesktop().showWindow(win, "center");
} catch (Exception e) {
log.log(Level.SEVERE, e.getLocalizedMessage(), e);
}
} else if (pdfList.size() > 0) {
try {
Window win = new SimplePDFViewer(this.getTitle(), new FileInputStream(pdfList.get(0)));
SessionManager.getAppDesktop().showWindow(win, "center");
} catch (Exception e)
{
log.log(Level.SEVERE, e.getLocalizedMessage(), e);
}
}
}
public boolean isValid() {
return valid;
}
public void executeASync(ProcessInfo pi) {
}
public boolean isUILocked() {
return m_isLocked;
}
} // ProcessDialog