diff --git a/base/src/org/compiere/model/Query.java b/base/src/org/compiere/model/Query.java
index 563ab2da43..fe809db8cf 100644
--- a/base/src/org/compiere/model/Query.java
+++ b/base/src/org/compiere/model/Query.java
@@ -23,6 +23,7 @@ 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.Collection;
import java.util.Iterator;
@@ -48,6 +49,7 @@ import org.compiere.util.Util;
*
FR [ 2107109 ] Add method Query.setOnlyActiveRecords
* FR [ 2421313 ] Introduce Query.firstOnly convenient method
* FR [ 2546052 ] Introduce Query aggregate methods
+ * FR [ 2726447 ] Query aggregate methods for all return types
* @author Redhuan D. Oon
* FR: [ 2214883 ] Remove SQL code and Replace for Query // introducing SQL String prompt in log.info
* FR: [ 2214883 ] - to introduce .setClient_ID
@@ -308,8 +310,24 @@ public class Query
* @param sqlExpression
* @param sqlFunction
* @return aggregated value
+ * @throws DBException
*/
public BigDecimal aggregate(String sqlExpression, String sqlFunction) throws DBException
+ {
+ return aggregate(sqlExpression, sqlFunction, BigDecimal.class);
+ }
+
+ /**
+ * Aggregate given expression on this criteria
+ * @param
+ * @param sqlExpression
+ * @param sqlFunction
+ * @param returnType
+ * @return aggregated value
+ * @throws DBException
+ */
+ @SuppressWarnings("unchecked")
+ public T aggregate(String sqlExpression, String sqlFunction, Class returnType) throws DBException
{
if (Util.isEmpty(sqlFunction, true))
{
@@ -331,7 +349,9 @@ public class Query
.append(sqlExpression).append(")")
.append(" FROM ").append(table.getTableName());
- BigDecimal value = null;
+ T value = null;
+ T defaultValue = null;
+
String sql = buildSQL(sqlSelect, false);
PreparedStatement pstmt = null;
ResultSet rs = null;
@@ -341,7 +361,34 @@ public class Query
rs = createResultSet(pstmt);
if (rs.next())
{
- value = rs.getBigDecimal(1);
+ if (returnType.isAssignableFrom(BigDecimal.class))
+ {
+ value = (T)rs.getBigDecimal(1);
+ defaultValue = (T)Env.ZERO;
+ }
+ else if (returnType.isAssignableFrom(Double.class))
+ {
+ value = (T)Double.valueOf(rs.getDouble(1));
+ defaultValue = (T)Double.valueOf(0.00);
+ }
+ else if (returnType.isAssignableFrom(Integer.class))
+ {
+ value = (T)Integer.valueOf(rs.getInt(1));
+ defaultValue = (T)Integer.valueOf(0);
+ }
+ else if (returnType.isAssignableFrom(Timestamp.class))
+ {
+ value = (T)rs.getTimestamp(1);
+ }
+ else if (returnType.isAssignableFrom(Boolean.class))
+ {
+ value = (T) Boolean.valueOf("Y".equals(rs.getString(1)));
+ defaultValue = (T) Boolean.FALSE;
+ }
+ else
+ {
+ value = (T)rs.getObject(1);
+ }
}
if (rs.next())
{
@@ -360,7 +407,7 @@ public class Query
//
if (value == null)
{
- value = Env.ZERO;
+ value = defaultValue;
}
return value;
}
diff --git a/extend/src/test/functional/QueryTest.java b/extend/src/test/functional/QueryTest.java
index 9a51197a96..6295d3ec84 100644
--- a/extend/src/test/functional/QueryTest.java
+++ b/extend/src/test/functional/QueryTest.java
@@ -1,8 +1,19 @@
-/**
- *
- */
+/******************************************************************************
+ * 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 test.functional;
+import java.sql.Timestamp;
import java.util.Iterator;
import java.util.List;
@@ -17,7 +28,7 @@ import test.AdempiereTestCase;
/**
* Test {@link org.compiere.model.Query} class
- * @author Teo Sarca, SC ARHIPAC SERVICE SRL
+ * @author Teo Sarca, www.arhipac.ro
*/
public class QueryTest extends AdempiereTestCase
{
@@ -212,6 +223,16 @@ public class QueryTest extends AdempiereTestCase
DB.getSQLValueBDEx(getTrxName(), "SELECT MAX(LineNetAmt) "+sqlFrom),
query.aggregate("LineNetAmt", Query.AGGREGATE_MAX));
//
+ // Test aggregate (String) - FR [ 2726447 ]
+ assertEquals("MAX not match (String)",
+ DB.getSQLValueStringEx(getTrxName(), "SELECT MAX(Description) "+sqlFrom),
+ (String)query.aggregate("Description", Query.AGGREGATE_MAX, String.class));
+ //
+ // Test aggregate (Timestamp) - FR [ 2726447 ]
+ assertEquals("MAX not match (Timestamp)",
+ DB.getSQLValueTSEx(getTrxName(), "SELECT MAX(Updated) "+sqlFrom),
+ (Timestamp)query.aggregate("Updated", Query.AGGREGATE_MAX, Timestamp.class));
+ //
// Test Exception : No Aggregate Function defined
assertExceptionThrown("No Aggregate Function defined", DBException.class, new Runnable(){
public void run()