FR [ 1894573 ] Alert Processor Improvements

This commit is contained in:
teo_sarca 2008-02-15 20:27:59 +00:00
parent 8219afb5ca
commit c39ed6b8d0
10 changed files with 809 additions and 51 deletions

View File

@ -0,0 +1,407 @@
/******************************************************************************
* Product: Adempiere ERP & CRM Smart Business Solution *
* Copyright (C) 2008 SC ARHIPAC SERVICE SRL. 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. *
*****************************************************************************/
package org.adempiere.impexp;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.sql.Timestamp;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.HashMap;
import java.util.Properties;
import java.util.logging.Level;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFDataFormat;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFFooter;
import org.apache.poi.hssf.usermodel.HSSFHeader;
import org.apache.poi.hssf.usermodel.HSSFPrintSetup;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.compiere.Adempiere;
import org.compiere.util.CLogMgt;
import org.compiere.util.CLogger;
import org.compiere.util.DisplayType;
import org.compiere.util.Env;
import org.compiere.util.Ini;
import org.compiere.util.Language;
import org.compiere.util.Util;
/**
* Abstract MS Excel Format (xls) Exporter
* @author Teo Sarca, SC ARHIPAC SERVICE SRL
*/
public abstract class AbstractExcelExporter
{
protected abstract boolean isFunctionRow();
protected abstract int getColumnCount();
protected abstract int getRowCount();
protected abstract void setCurrentRow(int row);
protected abstract boolean isColumnPrinted(int col);
protected abstract String getHeaderName(int col);
protected abstract int getDisplayType(int row, int col);
protected abstract Object getValueAt(int row, int col);
protected abstract boolean isPageBreak(int row, int col);
/** Logger */
protected CLogger log = CLogger.getCLogger(getClass());
//
private HSSFWorkbook m_workbook;
private HSSFDataFormat m_dataFormat;
private HSSFFont m_fontHeader = null;
private HSSFFont m_fontDefault = null;
private Language m_lang = null;
private int m_sheetCount = 0;
/** Styles cache */
private HashMap<String, HSSFCellStyle> m_styles = new HashMap<String, HSSFCellStyle>();
public AbstractExcelExporter() {
m_workbook = new HSSFWorkbook();
m_dataFormat = m_workbook.createDataFormat();
}
protected Properties getCtx() {
return Env.getCtx();
}
private String fixString(String str)
{
// ms excel doesn't support UTF8 charset
return Util.stripDiacritics(str);
}
protected Language getLanguage() {
if (m_lang == null)
m_lang = Env.getLanguage(getCtx());
return m_lang;
}
private HSSFFont getFont(boolean isHeader) {
HSSFFont font = null;
if (isHeader) {
if (m_fontHeader == null) {
m_fontHeader = m_workbook.createFont();
m_fontHeader.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
}
font = m_fontHeader;
}
else if (isFunctionRow()) {
font = m_workbook.createFont();
font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
font.setItalic(true);
}
else {
if (m_fontDefault == null) {
m_fontDefault = m_workbook.createFont();
}
font = m_fontDefault;
}
return font;
}
/**
* Get Excel number format string by given {@link NumberFormat}
* @param df number format
* @param isHighlightNegativeNumbers highlight negative numbers using RED color
* @return number excel format string
*/
private String getFormatString(NumberFormat df, boolean isHighlightNegativeNumbers) {
StringBuffer format = new StringBuffer();
int integerDigitsMin = df.getMinimumIntegerDigits();
int integerDigitsMax = df.getMaximumIntegerDigits();
for (int i = 0; i < integerDigitsMax; i++) {
if (i < integerDigitsMin)
format.insert(0, "0");
else
format.insert(0, "#");
if (i == 2) {
format.insert(0, ",");
}
}
int fractionDigitsMin = df.getMinimumFractionDigits();
int fractionDigitsMax = df.getMaximumFractionDigits();
for (int i = 0; i < fractionDigitsMax; i++) {
if (i == 0)
format.append(".");
if (i < fractionDigitsMin)
format.append("0");
else
format.append("#");
}
if (isHighlightNegativeNumbers) {
String f = format.toString();
format = new StringBuffer(f).append(";[RED]-").append(f);
}
//
if (CLogMgt.isLevelFinest()) log.finest("NumberFormat: "+format);
return format.toString();
}
private HSSFCellStyle getStyle(int row, int col) {
int displayType = getDisplayType(row, col);
String key = "cell-"+col+"-"+displayType;
HSSFCellStyle cs = m_styles.get(key);
if (cs == null) {
boolean isHighlightNegativeNumbers = true;
cs = m_workbook.createCellStyle();
HSSFFont font = getFont(false);
cs.setFont(font);
// Border
cs.setBorderLeft((short)1);
cs.setBorderTop((short)1);
cs.setBorderRight((short)1);
cs.setBorderBottom((short)1);
//
if (DisplayType.isDate(displayType)) {
cs.setDataFormat(m_dataFormat.getFormat("DD.MM.YYYY"));
}
else if (DisplayType.isNumeric(displayType)) {
DecimalFormat df = DisplayType.getNumberFormat(displayType, getLanguage());
String format = getFormatString(df, isHighlightNegativeNumbers);
cs.setDataFormat(m_dataFormat.getFormat(format));
}
m_styles.put(key, cs);
}
return cs;
}
private HSSFCellStyle getHeaderStyle(int col)
{
String key = "header-"+col;
HSSFCellStyle cs_header = m_styles.get(key);
if (cs_header == null) {
HSSFFont font_header = getFont(true);
cs_header = m_workbook.createCellStyle();
cs_header.setFont(font_header);
cs_header.setBorderLeft((short)2);
cs_header.setBorderTop((short)2);
cs_header.setBorderRight((short)2);
cs_header.setBorderBottom((short)2);
cs_header.setDataFormat(HSSFDataFormat.getBuiltinFormat("text"));
cs_header.setWrapText(true);
m_styles.put(key, cs_header);
}
return cs_header;
}
private void fixColumnWidth(HSSFSheet sheet, int lastColumnIndex)
{
/* POI 3.0.1 *
for (short colnum = 0; colnum < lastColumnIndex; colnum++) {
sheet.autoSizeColumn(colnum);
}
/**/
}
private void closeTableSheet(HSSFSheet prevSheet, String prevSheetName, int colCount)
{
if (prevSheet == null)
return;
//
fixColumnWidth(prevSheet, colCount);
prevSheet.createFreezePane(1, 1);
if (!Util.isEmpty(prevSheetName, true) && m_sheetCount > 0) {
int prevSheetIndex = m_sheetCount - 1;
try {
m_workbook.setSheetName(prevSheetIndex, prevSheetName);
}
catch (Exception e) {
log.log(Level.WARNING, "Error setting sheet "+prevSheetIndex+" name to "+prevSheetName, e);
}
}
}
private HSSFSheet createTableSheet()
{
HSSFSheet sheet= m_workbook.createSheet();
sheet.setFitToPage(true);
// Print Setup
HSSFPrintSetup ps = sheet.getPrintSetup();
sheet.setAutobreaks(true);
ps.setFitWidth((short)1);
ps.setNoColor(true);
// Sheet Header
HSSFHeader header = sheet.getHeader();
header.setRight(HSSFHeader.page()+ " / "+HSSFHeader.numPages());
// Sheet Footer
HSSFFooter footer = sheet.getFooter();
footer.setLeft(Adempiere.ADEMPIERE_R);
footer.setCenter(Env.getHeader(getCtx(), 0));
Timestamp now = new Timestamp(System.currentTimeMillis());
footer.setRight(DisplayType.getDateFormat(DisplayType.DateTime, getLanguage()).format(now));
// Table Header
createTableHeader(sheet);
m_sheetCount++;
//
return sheet;
}
private void createTableHeader(HSSFSheet sheet)
{
short colnumMax = 0;
HSSFRow row = sheet.createRow(0);
// for all columns
short colnum = 0;
for (int col = 0; col < getColumnCount(); col++)
{
if (colnum > colnumMax)
colnumMax = colnum;
//
if (isColumnPrinted(col))
{
HSSFCell cell = row.createCell(colnum);
// header row
HSSFCellStyle style = getHeaderStyle(col);
cell.setCellStyle(style);
String str = fixString(getHeaderName(col));
/* POI 3.0.1 *
cell.setCellValue(new HSSFRichTextString(str));
/* POI 2.0 */
cell.setCellValue(str);
/**/
colnum++;
} // printed
} // for all columns
// m_workbook.setRepeatingRowsAndColumns(m_sheetCount, 0, 0, 0, 0);
}
/**
* Export to given stream
* @param out
* @throws Exception
*/
private void export(OutputStream out)
throws Exception
{
HSSFSheet sheet= createTableSheet();
String sheetName = null;
//
short colnumMax = 0;
for (int rownum = 0, xls_rownum = 1; rownum < getRowCount(); rownum++, xls_rownum++)
{
setCurrentRow(rownum);
boolean isPageBreak = false;
HSSFRow row = sheet.createRow(xls_rownum);
// for all columns
short colnum = 0;
for (int col = 0; col < getColumnCount(); col++)
{
if (colnum > colnumMax)
colnumMax = colnum;
//
if (isColumnPrinted(col))
{
HSSFCell cell = row.createCell(colnum);
// line row
Object obj = getValueAt(rownum, col);
int displayType = getDisplayType(rownum, col);
if (obj == null)
;
else if (DisplayType.isDate(displayType)) {
Timestamp value = (Timestamp)obj;
cell.setCellValue(value);
}
else if (DisplayType.isNumeric(displayType)) {
double value = 0;
if (obj instanceof Number) {
value = ((Number)obj).doubleValue();
}
cell.setCellValue(value);
}
else if (DisplayType.YesNo == displayType) {
boolean value = false;
if (obj instanceof Boolean)
value = (Boolean)obj;
else
value = "Y".equals(obj);
cell.setCellValue(value);
}
else {
String value = fixString(obj.toString()); // formatted
/* POI 3.0.1 *
cell.setCellValue(new HSSFRichTextString(value));
/* POI 2.0 */
cell.setCellValue(value);
/**/
}
//
HSSFCellStyle style = getStyle(rownum, col);
cell.setCellStyle(style);
// Page break
if (isPageBreak(rownum, col)) {
isPageBreak = true;
sheetName = fixString(cell.getStringCellValue());
}
//
colnum++;
} // printed
} // for all columns
//
// Page Break
if (isPageBreak) {
closeTableSheet(sheet, sheetName, colnumMax);
sheet = createTableSheet();
xls_rownum = 0;
isPageBreak = false;
}
} // for all rows
closeTableSheet(sheet, sheetName, colnumMax);
//
m_workbook.write(out);
out.close();
//
// Workbook Info
if (CLogMgt.isLevelFine()) {
log.fine("Sheets #"+m_sheetCount);
log.fine("Styles used #"+m_styles.size());
}
}
/**
* Export to file
* @param file
* @param language reporting language
* @throws Exception
*/
public void export(File file, Language language)
throws Exception
{
export(file, language, true);
}
/**
* Export to file
* @param file
* @param language reporting language
* @param autoOpen auto open file after generated
* @throws Exception
*/
public void export(File file, Language language, boolean autoOpen)
throws Exception
{
m_lang = language;
if (file == null)
file = File.createTempFile("Report_", ".xls");
FileOutputStream out = new FileOutputStream(file);
export(out);
if (autoOpen && Ini.isClient())
Env.startBrowser(file.toURI().toString());
}
}

View File

@ -0,0 +1,116 @@
/******************************************************************************
* Product: Adempiere ERP & CRM Smart Business Solution *
* Copyright (C) 2008 SC ARHIPAC SERVICE SRL. 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. *
*****************************************************************************/
package org.adempiere.impexp;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Properties;
import org.compiere.util.DisplayType;
import org.compiere.util.Msg;
import org.compiere.util.Util;
/**
* Export excel from ArrayList of data
* @author Teo Sarca, SC ARHIPAC SERVICE SRL
*
*/
public class ArrayExcelExporter extends AbstractExcelExporter {
private Properties m_ctx = null;
private ArrayList<ArrayList<Object>> m_data = null;
public ArrayExcelExporter(Properties ctx, ArrayList<ArrayList<Object>> data) {
super();
m_ctx = ctx;
m_data = data;
}
@Override
public Properties getCtx() {
return m_ctx;
}
@Override
protected int getColumnCount() {
return m_data.get(0).size();
}
@Override
protected int getDisplayType(int row, int col) {
ArrayList<Object> dataRow = m_data.get(row+1);
Object value = dataRow.get(col);
if (value == null)
;
else if (value instanceof Timestamp) {
return DisplayType.Date;
// TODO: handle DateTime
}
else if (value instanceof Number) {
if (value instanceof Integer) {
return DisplayType.Integer;
}
else {
return DisplayType.Number;
}
}
else if (value instanceof Boolean) {
return DisplayType.YesNo;
}
else {
return DisplayType.String;
}
return -1;
}
@Override
protected String getHeaderName(int col) {
Object o = m_data.get(0).get(col);
String name = o != null ? o.toString() : null;
String nameTrl = Msg.translate(getLanguage(), name);
if (Util.isEmpty(nameTrl))
nameTrl = name;
return nameTrl;
}
@Override
protected int getRowCount() {
return m_data.size() - 1;
}
@Override
protected Object getValueAt(int row, int col) {
ArrayList<Object> dataRow = m_data.get(row+1);
Object value = dataRow.get(col);
return value;
}
@Override
protected boolean isColumnPrinted(int col) {
return true;
}
@Override
protected boolean isFunctionRow() {
return false;
}
@Override
protected boolean isPageBreak(int row, int col) {
return false;
}
@Override
protected void setCurrentRow(int row) {
}
}

View File

@ -19,7 +19,9 @@ package org.compiere.model;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.Properties; import java.util.Properties;
import java.util.TreeSet;
import java.util.logging.Level; import java.util.logging.Level;
import org.compiere.util.DB; import org.compiere.util.DB;
@ -29,6 +31,9 @@ import org.compiere.util.DB;
* *
* @author Jorg Janke * @author Jorg Janke
* @version $Id: MAlert.java,v 1.3 2006/07/30 00:51:05 jjanke Exp $ * @version $Id: MAlert.java,v 1.3 2006/07/30 00:51:05 jjanke Exp $
*
* @author Teo Sarca, SC ARHIPAC SERVICE SRL
* <li>FR [ 1894573 ] Alert Processor Improvements
*/ */
public class MAlert extends X_AD_Alert public class MAlert extends X_AD_Alert
{ {
@ -195,6 +200,32 @@ public class MAlert extends X_AD_Alert
return -1; return -1;
} // getFirstAD_User_ID } // getFirstAD_User_ID
/**
* @return unique list of recipient users
*/
public Collection<Integer> getRecipientUsers() {
MAlertRecipient[] recipients = getRecipients(false);
TreeSet<Integer> users = new TreeSet<Integer>();
for (int i = 0; i < recipients.length; i++)
{
MAlertRecipient recipient = recipients[i];
if (recipient.getAD_User_ID() >= 0) // System == 0
users.add(recipient.getAD_User_ID());
if (recipient.getAD_Role_ID() >= 0) // SystemAdministrator == 0
{
MUserRoles[] urs = MUserRoles.getOfRole(getCtx(), recipient.getAD_Role_ID());
for (int j = 0; j < urs.length; j++)
{
MUserRoles ur = urs[j];
if (!ur.isActive())
continue;
users.add(ur.getAD_User_ID());
}
}
}
return users;
}
/** /**
* String Representation * String Representation
* @return info * @return info

View File

@ -513,8 +513,25 @@ public class MClient extends X_AD_Client
* @return true if sent * @return true if sent
*/ */
public boolean sendEMail (int AD_User_ID, public boolean sendEMail (int AD_User_ID,
String subject, String message, File attachment) String subject, String message, File attachment)
{ {
Collection<File> attachments = new ArrayList<File>();
if (attachment != null)
attachments.add(attachment);
return sendEMailAttachments(AD_User_ID, subject, message, attachments);
}
/**
* Send EMail from Request User - with trace
* @param AD_User_ID recipient
* @param subject subject
* @param message message
* @param attachment optional collection of attachments
* @return true if sent
*/
public boolean sendEMailAttachments (int AD_User_ID,
String subject, String message, Collection<File> attachments)
{
MUser to = MUser.get(getCtx(), AD_User_ID); MUser to = MUser.get(getCtx(), AD_User_ID);
String toEMail = to.getEMail(); String toEMail = to.getEMail();
if (toEMail == null || toEMail.length() == 0) if (toEMail == null || toEMail.length() == 0)
@ -525,8 +542,7 @@ public class MClient extends X_AD_Client
EMail email = createEMail(null, to, subject, message); EMail email = createEMail(null, to, subject, message);
if (email == null) if (email == null)
return false; return false;
if (attachment != null) email.addAttachments(attachments);
email.addAttachment(attachment);
try try
{ {
return sendEmailNow(null, to, email); return sendEmailNow(null, to, email);

View File

@ -40,6 +40,7 @@ public class DefaultContextProvider implements ContextProvider {
} }
public void showURL(String url) { public void showURL(String url) {
/* JAVA5 */
if (!Ini.isClient()) return; if (!Ini.isClient()) return;
// OS command // OS command
String cmd = "rundll32 url.dll,FileProtocolHandler "; String cmd = "rundll32 url.dll,FileProtocolHandler ";
@ -77,7 +78,15 @@ public class DefaultContextProvider implements ContextProvider {
s_log.severe(execute + " - " + e); s_log.severe(execute + " - " + e);
} }
} }
/* JAVA6 *
try {
java.net.URI uri = new java.net.URI(url);
java.awt.Desktop.getDesktop().browse(uri);
}
catch (Exception e) {
s_log.warning(e.getLocalizedMessage());
}
/**/
} }
} }

View File

@ -725,6 +725,19 @@ public final class EMail implements Serializable
m_attachments = new ArrayList<Object>(); m_attachments = new ArrayList<Object>();
m_attachments.add(file); m_attachments.add(file);
} // addAttachment } // addAttachment
/**
* Add a collection of attachments
* @param files collection of files
*/
public void addAttachments(Collection<File> files)
{
if (files == null || files.size() == 0)
return;
for (File f : files) {
addAttachment(f);
}
}
/** /**
* Add url based file Attachment * Add url based file Attachment

View File

@ -209,7 +209,23 @@ public class Util
*/ */
public static boolean isEmpty (String str) public static boolean isEmpty (String str)
{ {
return (str == null || str.length() == 0); return isEmpty(str, false);
} // isEmpty
/**
* Is String Empty
* @param str string
* @param trimWhitespaces trim whitespaces
* @return true if >= 1 char
*/
public static boolean isEmpty (String str, boolean trimWhitespaces)
{
if (str == null)
return true;
if (trimWhitespaces)
return str.trim().length() == 0;
else
return str.length() == 0;
} // isEmpty } // isEmpty
/************************************************************************** /**************************************************************************
@ -634,4 +650,28 @@ public class Util
getIterator (aString, new AttributedCharacterIterator.Attribute[] {TextAttribute.UNDERLINE}); getIterator (aString, new AttributedCharacterIterator.Attribute[] {TextAttribute.UNDERLINE});
} // main } // main
/**
* String diacritics from given string
* @param s original string
* @return string without diacritics
*/
public static String stripDiacritics(String s) {
/* JAVA5 behaviour */
return s;
/* JAVA6 behaviour *
if (s == null) {
return s;
}
String normStr = java.text.Normalizer.normalize(s, java.text.Normalizer.Form.NFD);
StringBuffer sb = new StringBuffer();
for (int i = 0; i < normStr.length(); i++) {
char ch = normStr.charAt(i);
if (ch < 255)
sb.append(ch);
}
return sb.toString();
/* */
}
} // Util } // Util

View File

@ -0,0 +1,3 @@
-- FR [ 1894573 ] Alert Processor Improvements
insert into AD_SysConfig (AD_SYSCONFIG_ID,AD_CLIENT_ID,AD_ORG_ID,CREATED,UPDATED,CREATEDBY,UPDATEDBY,ISACTIVE,NAME,VALUE,DESCRIPTION,ENTITYTYPE,CONFIGURATIONLEVEL)
values (50014,0,0,to_date('15-02-2008','DD-MM-RRRR'),to_date('15-02-2008','DD-MM-RRRR'),0,0,'Y','ALERT_SEND_ATTACHMENT_AS_XLS','Y','Send alert results as Excel attachments','D','C');

View File

@ -0,0 +1,3 @@
-- FR [ 1894573 ] Alert Processor Improvements
insert into AD_SysConfig (AD_SYSCONFIG_ID,AD_CLIENT_ID,AD_ORG_ID,CREATED,UPDATED,CREATEDBY,UPDATEDBY,ISACTIVE,NAME,VALUE,DESCRIPTION,ENTITYTYPE,CONFIGURATIONLEVEL)
values (50014,0,0,TO_TIMESTAMP('2008-02-15 00:00:00','YYYY-MM-DD HH24:MI:SS'),TO_TIMESTAMP('2008-02-15 00:00:00','YYYY-MM-DD HH24:MI:SS'),0,0,'Y','ALERT_SEND_ATTACHMENT_AS_XLS','Y','Send alert results as Excel attachments','D','C');

View File

@ -16,11 +16,32 @@
*****************************************************************************/ *****************************************************************************/
package org.compiere.server; package org.compiere.server;
import java.sql.*; import java.io.File;
import java.util.logging.*; import java.sql.PreparedStatement;
import org.compiere.*; import java.sql.ResultSet;
import org.compiere.model.*; import java.sql.ResultSetMetaData;
import org.compiere.util.*; import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Collection;
import java.util.logging.Level;
import org.adempiere.impexp.ArrayExcelExporter;
import org.compiere.Adempiere;
import org.compiere.model.MAlert;
import org.compiere.model.MAlertProcessor;
import org.compiere.model.MAlertProcessorLog;
import org.compiere.model.MAlertRule;
import org.compiere.model.MClient;
import org.compiere.model.MRole;
import org.compiere.model.MSysConfig;
import org.compiere.model.MUser;
import org.compiere.util.CLogger;
import org.compiere.util.DB;
import org.compiere.util.Env;
import org.compiere.util.Msg;
import org.compiere.util.TimeUtil;
import org.compiere.util.Trx;
import org.compiere.util.ValueNamePair;
/** /**
@ -28,6 +49,9 @@ import org.compiere.util.*;
* *
* @author Jorg Janke * @author Jorg Janke
* @version $Id: AlertProcessor.java,v 1.4 2006/07/30 00:53:33 jjanke Exp $ * @version $Id: AlertProcessor.java,v 1.4 2006/07/30 00:53:33 jjanke Exp $
*
* @author Teo Sarca, SC ARHIPAC SERVICE SRL
* <li>FR [ 1894573 ] Alert Processor Improvements
*/ */
public class AlertProcessor extends AdempiereServer public class AlertProcessor extends AdempiereServer
{ {
@ -101,11 +125,12 @@ public class AlertProcessor extends AdempiereServer
// //
boolean valid = true; boolean valid = true;
boolean processed = false; boolean processed = false;
ArrayList<File> attachments = new ArrayList<File>();
MAlertRule[] rules = alert.getRules(false); MAlertRule[] rules = alert.getRules(false);
for (int i = 0; i < rules.length; i++) for (int i = 0; i < rules.length; i++)
{ {
if (i > 0) if (i > 0)
message.append(Env.NL).append("================================").append(Env.NL); message.append(Env.NL);
String trxName = null; // assume r/o String trxName = null; // assume r/o
MAlertRule rule = rules[i]; MAlertRule rule = rules[i];
@ -147,7 +172,11 @@ public class AlertProcessor extends AdempiereServer
try try
{ {
String text = listSqlSelect(sql, trxName); String text = null;
if (MSysConfig.getBooleanValue("ALERT_SEND_ATTACHMENT_AS_XLS", true, Env.getAD_Client_ID(getCtx())))
text = getExcelReport(rule, sql, trxName, attachments);
else
text = getPlainTextReport(rule, sql, trxName, attachments);
if (text != null && text.length() > 0) if (text != null && text.length() > 0)
{ {
message.append(text); message.append(text);
@ -208,51 +237,120 @@ public class AlertProcessor extends AdempiereServer
return true; return true;
} }
// Send Message Collection<Integer> users = alert.getRecipientUsers();
int countMail = 0; int countMail = notifyUsers(users, alert.getAlertSubject(), message.toString(), attachments);
MAlertRecipient[] recipients = alert.getRecipients(false);
for (int i = 0; i < recipients.length; i++)
{
MAlertRecipient recipient = recipients[i];
if (recipient.getAD_User_ID() >= 0) // System == 0
if (m_client.sendEMail(recipient.getAD_User_ID(),
alert.getAlertSubject(), message.toString(), null))
countMail++;
if (recipient.getAD_Role_ID() >= 0) // SystemAdministrator == 0
{
MUserRoles[] urs = MUserRoles.getOfRole(getCtx(), recipient.getAD_Role_ID());
for (int j = 0; j < urs.length; j++)
{
MUserRoles ur = urs[j];
if (!ur.isActive())
continue;
if (m_client.sendEMail (ur.getAD_User_ID(),
alert.getAlertSubject(), message.toString(), null))
countMail++;
}
}
}
m_summary.append(alert.getName()).append(" (EMails=").append(countMail).append(") - "); m_summary.append(alert.getName()).append(" (EMails=").append(countMail).append(") - ");
return valid; return valid;
} // processAlert } // processAlert
/** /**
* List Sql Select * Notify users
* @param sql sql select * @param users AD_User_ID list
* @param trxName transaction * @param subject email subject
* @return list of rows & values * @param message email message
* @throws Exception * @param attachments
* @return how many email were sent
*/ */
private String listSqlSelect (String sql, String trxName) throws Exception private int notifyUsers(Collection<Integer> users, String subject, String message, Collection<File> attachments)
{ {
StringBuffer result = new StringBuffer(); int countMail = 0;
for (int user_id : users) {
MUser user = MUser.get(getCtx(), user_id);
if (user.isNotificationEMail()) {
if (m_client.sendEMailAttachments (user_id, subject, message, attachments))
{
countMail++;
}
}
if (user.isNotificationNote()) {
// TODO: implement
}
}
return countMail;
}
/**
* Get Alert Data
* @param sql
* @param trxName
* @return data
* @throws Exception
*/
private ArrayList<ArrayList<Object>> getData (String sql, String trxName) throws Exception
{
ArrayList<ArrayList<Object>> data = new ArrayList<ArrayList<Object>>();
PreparedStatement pstmt = null; PreparedStatement pstmt = null;
ResultSet rs = null;
Exception error = null; Exception error = null;
try try
{ {
pstmt = DB.prepareStatement (sql, trxName); pstmt = DB.prepareStatement (sql, trxName);
ResultSet rs = pstmt.executeQuery (); rs = pstmt.executeQuery ();
ResultSetMetaData meta = rs.getMetaData();
boolean isFirstRow = true;
while (rs.next ())
{
ArrayList<Object> header = (isFirstRow ? new ArrayList<Object>() : null);
ArrayList<Object> row = new ArrayList<Object>();
for (int col = 1; col <= meta.getColumnCount(); col++)
{
if (isFirstRow) {
String columnName = meta.getColumnLabel(col);
header.add(columnName);
}
Object o = rs.getObject(col);
row.add(o);
} // for all columns
if (isFirstRow)
data.add(header);
data.add(row);
isFirstRow = false;
}
}
catch (Throwable e)
{
log.log(Level.SEVERE, sql, e);
if (e instanceof Exception)
error = (Exception)e;
else
error = new Exception(e.getMessage(), e);
}
finally
{
DB.close(rs, pstmt);
rs = null; pstmt = null;
}
// Error occured
if (error != null)
throw new Exception ("(" + sql + ") " + Env.NL
+ error.getLocalizedMessage());
return data;
} // getData
/**
* Get Plain Text Report (old functionality)
* @param rule (ignored)
* @param sql sql select
* @param trxName transaction
* @param attachments (ignored)
* @return list of rows & values
* @throws Exception
* @deprecated
*/
private String getPlainTextReport(MAlertRule rule, String sql, String trxName, Collection<File> attachments)
throws Exception
{
StringBuffer result = new StringBuffer();
PreparedStatement pstmt = null;
ResultSet rs = null;
Exception error = null;
try
{
pstmt = DB.prepareStatement (sql, trxName);
rs = pstmt.executeQuery ();
ResultSetMetaData meta = rs.getMetaData(); ResultSetMetaData meta = rs.getMetaData();
while (rs.next ()) while (rs.next ())
{ {
@ -266,9 +364,6 @@ public class AlertProcessor extends AdempiereServer
} }
if (result.length() == 0) if (result.length() == 0)
log.fine("No rows selected"); log.fine("No rows selected");
rs.close ();
pstmt.close ();
pstmt = null;
} }
catch (Throwable e) catch (Throwable e)
{ {
@ -280,7 +375,8 @@ public class AlertProcessor extends AdempiereServer
} }
finally finally
{ {
DB.close(pstmt); DB.close(rs, pstmt);
rs = null; pstmt = null;
} }
// Error occured // Error occured
@ -289,9 +385,33 @@ public class AlertProcessor extends AdempiereServer
+ error.getLocalizedMessage()); + error.getLocalizedMessage());
return result.toString(); return result.toString();
} // listSqlSelect }
/**
* Get Excel Report
* @param rule
* @param sql
* @param trxName
* @param attachments
* @return summary message to be added into mail content
* @throws Exception
*/
private String getExcelReport(MAlertRule rule, String sql, String trxName, Collection<File> attachments)
throws Exception
{
ArrayList<ArrayList<Object>> data = getData(sql, trxName);
if (data.size() <= 1)
return null;
// File
String filePrefix = "Alert_"; // TODO: add AD_AlertRule.FileName (maybe)
File file = File.createTempFile(filePrefix, ".xls");
//
ArrayExcelExporter exporter = new ArrayExcelExporter(getCtx(), data);
exporter.export(file, null, false);
attachments.add(file);
String msg = rule.getName() + " (@SeeAttachment@ "+file.getName()+")"+Env.NL;
return Msg.parseTranslation(Env.getCtx(), msg);
}
/** /**
* Get Server Info * Get Server Info