Skip to content

Commit

Permalink
Add support to:
Browse files Browse the repository at this point in the history
- Parameters based on custom definition
- Parameter Translation Tab
- Sequence for dashboard allocation
- SQL Column for where clause
- Util class for chart load
  • Loading branch information
yamelsenih committed Apr 21, 2023
1 parent 7a57cfd commit 89f4f15
Show file tree
Hide file tree
Showing 10 changed files with 6,160 additions and 13 deletions.
12 changes: 6 additions & 6 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,12 @@ publishing {
publications {
mavenJava(MavenPublication) {
groupId 'io.github.adempiere'
artifactId 'adempiere-template-project'
artifactId 'adempiere-dashboard-improvements'
version
from components.java
pom {
name = 'ADempiere Template Project'
description = 'Fill it with project description'
name = 'ADempiere Dashboard Improvements'
description = 'This project allows improve the dashboard use for ADempiere for new UI'
url = 'http://adempiere.io/'
licenses {
license {
Expand All @@ -89,9 +89,9 @@ publishing {
}
}
scm {
connection = 'scm:git:git://github.com/adempiere/adempiere-template-project.git'
developerConnection = 'scm:git:ssh://github.com/adempiere/adempiere-template-project.git'
url = 'http://github.com/adempiere/adempiere-template-project'
connection = 'scm:git:git://github.com/adempiere/adempiere-dashboard-improvements.git'
developerConnection = 'scm:git:ssh://github.com/adempiere/adempiere-dashboard-improvements.git'
url = 'http://github.com/adempiere/adempiere-dashboard-improvements'
}
}
}
Expand Down
221 changes: 221 additions & 0 deletions src/main/java/org/spin/eca50/controller/ChartBuilder.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
/*************************************************************************************
* Product: Adempiere ERP & CRM Smart Business Solution *
* This program is free software; you can redistribute it and/or modify it *
* under the terms version 2 or later 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. *
* For the text or an alternative of this public license, you may reach us *
* Copyright (C) 2012-2023 E.R.P. Consultores y Asociados, S.A. All Rights Reserved. *
* Contributor(s): Yamel Senih www.erpya.com *
*************************************************************************************/
package org.spin.eca50.controller;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

import org.adempiere.exceptions.AdempiereException;
import org.compiere.model.MChart;
import org.compiere.model.MChartDatasource;
import org.compiere.model.MRole;
import org.compiere.model.Query;
import org.compiere.util.DB;
import org.compiere.util.Env;
import org.compiere.util.TimeUtil;
import org.compiere.util.Util;
import org.spin.eca50.data.ChartDataValue;
import org.spin.eca50.data.ChartSeriesValue;
import org.spin.eca50.data.ChartValue;
import org.spin.eca50.util.ChartQueryDefinition;

/**
* A class as controller for Chart Service
* @author Yamel Senih at www.erpya.com
*
*/
public class ChartBuilder {

/**
* Get Data Source Query
* @param chartDatasourceId
* @param isTimeSeries
* @param timeUnit
* @param timeScope
* @param customParameters
* @return
*/
private static ChartQueryDefinition getDataSourceQuery(int chartDatasourceId, boolean isTimeSeries, String timeUnit, int timeScope, Map<String, Object> customParameters) {
if(chartDatasourceId <= 0) {
throw new AdempiereException("@AD_ChartDatasource_ID@ @NotFound@");
}
MChartDatasource datasource = new MChartDatasource(Env.getCtx(), chartDatasourceId, null);
String value = datasource.getValueColumn();
String dateColumn = datasource.getDateColumn();
String seriesColumn = datasource.getSeriesColumn();
String name = datasource.getName();
String where = datasource.getWhereClause();
String fromClause = datasource.getFromClause();
String category;
String unit = "D";
if (!isTimeSeries) {
category = datasource.getCategoryColumn();
} else {
if (timeUnit.equals(MChart.TIMEUNIT_Week)) {
unit = "W";
} else if (timeUnit.equals(MChart.TIMEUNIT_Month)) {
unit = "MM";
} else if (timeUnit.equals(MChart.TIMEUNIT_Quarter)) {
unit = "Q";
} else if (timeUnit.equals(MChart.TIMEUNIT_Year)) {
unit = "Y";
}
category = " TRUNC(" + dateColumn + ", '" + unit + "') ";
}

String series = DB.TO_STRING(name);
boolean hasSeries = false;
if (seriesColumn != null) {
series = seriesColumn;
hasSeries = true;
}
//
if (!Util.isEmpty(where)) {
where = Env.parseContext(Env.getCtx(), 0, where, true);
}

List<Object> parameters = new ArrayList<Object>();
StringBuffer sql = new StringBuffer("SELECT " + value + ", " + category + ", " + series);
sql.append(" FROM ").append(fromClause);
StringBuffer whereClause = new StringBuffer();
if (!Util.isEmpty(where)) {
whereClause.append(where);
}

Timestamp currentDate = Env.getContextAsDate(Env.getCtx(), "#Date");
Timestamp startDate = null;
Timestamp endDate = null;

int scope = timeScope;
int offset = datasource.getTimeOffset();

if (isTimeSeries && scope != 0) {
offset += -scope;
startDate = TimeUtil.getDay(TimeUtil.addDuration(currentDate, timeUnit, offset));
endDate = TimeUtil.getDay(TimeUtil.addDuration(currentDate, timeUnit, scope));
}

if (startDate != null && endDate != null) {
if(whereClause.length() > 0) {
whereClause.append(" AND ");
}
whereClause.append(category).append(" >= ? ").append("AND ").append(category).append(" <= ? ");
parameters.add(startDate);
parameters.add(endDate);
}
// Add custom parameters
if(customParameters != null && customParameters.size() > 0) {
customParameters.entrySet().forEach(parameter -> {
if(whereClause.length() > 0) {
whereClause.append(" AND ");
}
whereClause.append(parameter.getKey());
parameters.add(parameter.getValue());
});
}
// Add where clause
if(whereClause.length() > 0) {
sql.append(" WHERE ").append(whereClause);
}
MRole role = MRole.getDefault(Env.getCtx(), false);
sql = new StringBuffer(role.addAccessSQL(sql.toString(), null, true, false));

if (hasSeries) {
sql.append(" GROUP BY " + series + ", " + category + " ORDER BY " + series + ", " + category);
} else {
sql.append(" GROUP BY " + category + " ORDER BY " + category);
}
return new ChartQueryDefinition(name, sql.toString(), parameters);
}

/**
* Get Chart data
* This method allows run all data sources and get data
* @param chartId
* @param customParameters
* @return
*/
public static ChartValue getChartData(int chartId, Map<String, Object> customParameters) {
if(chartId <= 0) {
throw new AdempiereException("@AD_Chart_ID@ @NotFound@");
}
MChart chart = new MChart(Env.getCtx(), chartId, null);
ChartValue metrics = new ChartValue(chart.getName());
List<ChartQueryDefinition> dataSources = new ArrayList<ChartQueryDefinition>();
new Query(Env.getCtx(), MChartDatasource.Table_Name, MChart.COLUMNNAME_AD_Chart_ID + " = ?", null)
.setParameters(chart.getAD_Chart_ID())
.setOnlyActiveRecords(true)
.getIDsAsList().forEach(chartDataSourceId -> {
dataSources.add(getDataSourceQuery(chartId, chart.isTimeSeries(), chart.getTimeUnit(), chart.getTimeScope(), customParameters));
});
// Run queries
if(dataSources.size() > 0) {
dataSources.forEach(dataSource -> {
ChartSeriesValue series = new ChartSeriesValue(dataSource.getName());
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
pstmt = DB.prepareStatement(dataSource.getQuery(), null);
if(dataSource.getParameters().size() > 0) {
AtomicInteger position = new AtomicInteger(1);
for(Object parameter : dataSource.getParameters()) {
pstmt.setObject(position.getAndIncrement(), parameter);
}
}
rs = pstmt.executeQuery();
while(rs.next()) {
String key = rs.getString(2);
String seriesName = rs.getString(3);
if (seriesName != null) {
series.setName(seriesName);
}
if(chart.isTimeSeries()) {
// TODO: Define it with dates
}
ChartDataValue data = new ChartDataValue(key, rs.getBigDecimal(1));
series.addData(data);
}
metrics.addSerie(series);
} catch (Exception e) {
throw new AdempiereException(e);
} finally {
DB.close(rs, pstmt);
rs = null; pstmt = null;
}

});
}
//
return metrics;
}

public static void main(String[] args) {
org.compiere.Adempiere.startup(true);
Env.setContext(Env.getCtx(), "#Date", new Timestamp(System.currentTimeMillis()));
Env.setContext(Env.getCtx(), "#AD_Client_ID", 1000000);
Env.setContext(Env.getCtx(), "#AD_Role_ID", 1000000);
Map<String, Object> customParameters = new HashMap<String, Object>();
customParameters.put("i.DateInvoiced <= ?", new Timestamp(System.currentTimeMillis()));
ChartValue data = getChartData(1000000, customParameters);
System.out.println(data);
}
}
42 changes: 42 additions & 0 deletions src/main/java/org/spin/eca50/data/ChartDataValue.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*************************************************************************************
* Product: Adempiere ERP & CRM Smart Business Solution *
* This program is free software; you can redistribute it and/or modify it *
* under the terms version 2 or later 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. *
* For the text or an alternative of this public license, you may reach us *
* Copyright (C) 2012-2023 E.R.P. Consultores y Asociados, S.A. All Rights Reserved. *
* Contributor(s): Yamel Senih www.erpya.com *
*************************************************************************************/
package org.spin.eca50.data;

import java.math.BigDecimal;

/**
* Stub for chart data values
* @author Yamel Senih at www.erpya.com
*
*/
public final class ChartDataValue {

private String name;
private BigDecimal amount;

public ChartDataValue(String name, BigDecimal amount) {
this.name = name;
this.amount = amount;
}

public String getName() {
return name;
}

public BigDecimal getAmount() {
return amount;
}
}
55 changes: 55 additions & 0 deletions src/main/java/org/spin/eca50/data/ChartSeriesValue.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*************************************************************************************
* Product: Adempiere ERP & CRM Smart Business Solution *
* This program is free software; you can redistribute it and/or modify it *
* under the terms version 2 or later 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. *
* For the text or an alternative of this public license, you may reach us *
* Copyright (C) 2012-2023 E.R.P. Consultores y Asociados, S.A. All Rights Reserved. *
* Contributor(s): Yamel Senih www.erpya.com *
*************************************************************************************/
package org.spin.eca50.data;

import java.util.ArrayList;
import java.util.List;

/**
* Stub for chart series
* @author Yamel Senih at www.erpya.com
*
*/
public final class ChartSeriesValue {

private String name;
private List<ChartDataValue> dataSet;

public ChartSeriesValue(String name) {
this.name = name;
this.dataSet = new ArrayList<ChartDataValue>();
}

public ChartSeriesValue addData(ChartDataValue data) {
if(data != null) {
dataSet.add(data);
}
return this;
}

public ChartSeriesValue setName(String name) {
this.name = name;
return this;
}

public String getName() {
return name;
}

public List<ChartDataValue> getDataSet() {
return dataSet;
}
}
Loading

0 comments on commit 89f4f15

Please sign in to comment.