FR [ 1894573 ] Alert Processor Improvements
This commit is contained in:
parent
8219afb5ca
commit
c39ed6b8d0
|
@ -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());
|
||||
}
|
||||
}
|
|
@ -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) {
|
||||
}
|
||||
}
|
|
@ -19,7 +19,9 @@ package org.compiere.model;
|
|||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Properties;
|
||||
import java.util.TreeSet;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.compiere.util.DB;
|
||||
|
@ -29,6 +31,9 @@ import org.compiere.util.DB;
|
|||
*
|
||||
* @author Jorg Janke
|
||||
* @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
|
||||
{
|
||||
|
@ -195,6 +200,32 @@ public class MAlert extends X_AD_Alert
|
|||
return -1;
|
||||
} // 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
|
||||
* @return info
|
||||
|
|
|
@ -513,7 +513,24 @@ public class MClient extends X_AD_Client
|
|||
* @return true if sent
|
||||
*/
|
||||
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);
|
||||
String toEMail = to.getEMail();
|
||||
|
@ -525,8 +542,7 @@ public class MClient extends X_AD_Client
|
|||
EMail email = createEMail(null, to, subject, message);
|
||||
if (email == null)
|
||||
return false;
|
||||
if (attachment != null)
|
||||
email.addAttachment(attachment);
|
||||
email.addAttachments(attachments);
|
||||
try
|
||||
{
|
||||
return sendEmailNow(null, to, email);
|
||||
|
|
|
@ -40,6 +40,7 @@ public class DefaultContextProvider implements ContextProvider {
|
|||
}
|
||||
|
||||
public void showURL(String url) {
|
||||
/* JAVA5 */
|
||||
if (!Ini.isClient()) return;
|
||||
// OS command
|
||||
String cmd = "rundll32 url.dll,FileProtocolHandler ";
|
||||
|
@ -77,7 +78,15 @@ public class DefaultContextProvider implements ContextProvider {
|
|||
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());
|
||||
}
|
||||
/**/
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -726,6 +726,19 @@ public final class EMail implements Serializable
|
|||
m_attachments.add(file);
|
||||
} // 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
|
||||
* @param url url content to attach
|
||||
|
|
|
@ -209,7 +209,23 @@ public class Util
|
|||
*/
|
||||
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
|
||||
|
||||
/**************************************************************************
|
||||
|
@ -634,4 +650,28 @@ public class Util
|
|||
getIterator (aString, new AttributedCharacterIterator.Attribute[] {TextAttribute.UNDERLINE});
|
||||
} // 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
|
||||
|
|
|
@ -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');
|
|
@ -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');
|
|
@ -16,11 +16,32 @@
|
|||
*****************************************************************************/
|
||||
package org.compiere.server;
|
||||
|
||||
import java.sql.*;
|
||||
import java.util.logging.*;
|
||||
import org.compiere.*;
|
||||
import org.compiere.model.*;
|
||||
import org.compiere.util.*;
|
||||
import java.io.File;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.ResultSetMetaData;
|
||||
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
|
||||
* @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
|
||||
{
|
||||
|
@ -101,11 +125,12 @@ public class AlertProcessor extends AdempiereServer
|
|||
//
|
||||
boolean valid = true;
|
||||
boolean processed = false;
|
||||
ArrayList<File> attachments = new ArrayList<File>();
|
||||
MAlertRule[] rules = alert.getRules(false);
|
||||
for (int i = 0; i < rules.length; i++)
|
||||
{
|
||||
if (i > 0)
|
||||
message.append(Env.NL).append("================================").append(Env.NL);
|
||||
message.append(Env.NL);
|
||||
String trxName = null; // assume r/o
|
||||
|
||||
MAlertRule rule = rules[i];
|
||||
|
@ -147,7 +172,11 @@ public class AlertProcessor extends AdempiereServer
|
|||
|
||||
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)
|
||||
{
|
||||
message.append(text);
|
||||
|
@ -208,51 +237,120 @@ public class AlertProcessor extends AdempiereServer
|
|||
return true;
|
||||
}
|
||||
|
||||
// Send Message
|
||||
int countMail = 0;
|
||||
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++;
|
||||
}
|
||||
}
|
||||
}
|
||||
Collection<Integer> users = alert.getRecipientUsers();
|
||||
int countMail = notifyUsers(users, alert.getAlertSubject(), message.toString(), attachments);
|
||||
|
||||
m_summary.append(alert.getName()).append(" (EMails=").append(countMail).append(") - ");
|
||||
return valid;
|
||||
} // processAlert
|
||||
|
||||
/**
|
||||
* List Sql Select
|
||||
* @param sql sql select
|
||||
* @param trxName transaction
|
||||
* @return list of rows & values
|
||||
* @throws Exception
|
||||
* Notify users
|
||||
* @param users AD_User_ID list
|
||||
* @param subject email subject
|
||||
* @param message email message
|
||||
* @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;
|
||||
ResultSet rs = null;
|
||||
Exception error = null;
|
||||
try
|
||||
{
|
||||
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();
|
||||
while (rs.next ())
|
||||
{
|
||||
|
@ -266,9 +364,6 @@ public class AlertProcessor extends AdempiereServer
|
|||
}
|
||||
if (result.length() == 0)
|
||||
log.fine("No rows selected");
|
||||
rs.close ();
|
||||
pstmt.close ();
|
||||
pstmt = null;
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
|
@ -280,7 +375,8 @@ public class AlertProcessor extends AdempiereServer
|
|||
}
|
||||
finally
|
||||
{
|
||||
DB.close(pstmt);
|
||||
DB.close(rs, pstmt);
|
||||
rs = null; pstmt = null;
|
||||
}
|
||||
|
||||
// Error occured
|
||||
|
@ -289,9 +385,33 @@ public class AlertProcessor extends AdempiereServer
|
|||
+ error.getLocalizedMessage());
|
||||
|
||||
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
|
||||
|
|
Loading…
Reference in New Issue