Skip to content

Commit

Permalink
Add missing values to summary
Browse files Browse the repository at this point in the history
  • Loading branch information
yamelsenih committed May 23, 2024
1 parent 5c815e8 commit dfa9242
Show file tree
Hide file tree
Showing 8 changed files with 146 additions and 70 deletions.
7 changes: 5 additions & 2 deletions src/main/java/org/spin/report_engine/data/Cell.java
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,11 @@ public Cell withValue(Object value) {
}

public String getDisplayValue() {
if(Util.isEmpty(displayValue) && value != null) {
return String.valueOf(value);
if(Util.isEmpty(displayValue)) {
if(value != null) {
return String.valueOf(value);
}
return "";
}
return displayValue;
}
Expand Down
36 changes: 29 additions & 7 deletions src/main/java/org/spin/report_engine/data/ReportInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ public class ReportInfo {
private List<ColumnInfo> columns;
private List<Row> rows;
private List<Row> summaryRows;
private List<Row> groupedRows;
private Row temporaryRow;
private int printFormatId;
private int reportViewId;
Expand All @@ -48,8 +49,9 @@ private ReportInfo(PrintFormat printFormat) {
columns = new ArrayList<>();
rows = new ArrayList<Row>();
summaryRows = new ArrayList<Row>();
groupedRows = new ArrayList<Row>();
summaryHandler = SummaryHandler.newInstance(printFormat.getItems());
level = printFormat.getGroupItems().size() + 1;
level = printFormat.getGroupItems().stream().mapToInt(item -> item.getSortSequence()).sum() + 1;
sortingItems = printFormat.getSortingItems();
}

Expand All @@ -66,6 +68,10 @@ public ReportInfo withLevel(int minimumLevel) {
return this;
}

public List<PrintFormatItem> getSortingItems() {
return sortingItems;
}

public String getName() {
return name;
}
Expand Down Expand Up @@ -128,15 +134,31 @@ public List<Row> getSummaryRows() {
return summaryRows;
}

public List<Row> getGroupedRows() {
return groupedRows;
}

// private Comparator<Row> getSortingValue(List<PrintFormatItem> groupColumns) {
// AtomicReference<Comparator<Row>> comparator = new AtomicReference<>();
// groupColumns.forEach(printFormatItem -> {
// Comparator<Row> groupComparator = (p, o) -> p.getCompareValue(printFormatItem.getPrintFormatItemId()).compareToIgnoreCase(o.getCompareValue(printFormatItem.getPrintFormatItemId()));
// if(comparator.get() == null) {
// comparator.set(groupComparator);
// } else {
// comparator.getAndUpdate(value -> value.thenComparing(groupComparator));
// }
// });
// comparator.getAndUpdate(value -> value.thenComparing(Comparator.comparing(Row::getLevel)));
// return comparator.get();
// }

public ReportInfo completeInfo() {
summaryRows = summaryHandler.getTotalsAsRows()
.stream().sorted(Comparator.comparing(row -> row.getSortingValue(sortingItems)))
.collect(Collectors.toList());;
List<Row> summaryAsRows = summaryHandler.getAsRows();
List<Row> completeRows = Stream.concat(getRows().stream(), summaryAsRows.stream())
.sorted(Comparator.comparing(row -> row.getSortingValue(sortingItems)))
groupedRows = summaryHandler.getAsRows();
List<Row> completeRows = Stream.concat(getRows().stream(), groupedRows.stream())
.sorted(Comparator.comparing(Row::getLevel))
.collect(Collectors.toList());
rows = completeRows;

return this;
}

Expand Down
40 changes: 26 additions & 14 deletions src/main/java/org/spin/report_engine/data/Row.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,12 @@
************************************************************************************/
package org.spin.report_engine.data;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

import org.spin.report_engine.format.PrintFormatItem;

/**
* Row information or representation for Row
* @author Yamel Senih, ysenih@erpya.com, ERPCyA http://www.erpya.com
Expand All @@ -29,11 +28,22 @@ public class Row {
/** Data for Row */
private Map<Integer, Cell> data;
private int level;
private List<Row> children;

public Row() {
data = new HashMap<>();
children = new ArrayList<Row>();
}

public List<Row> getChildren() {
return children;
}

public Row addChildren(Row child) {
children.add(child);
return this;
}

public static Row newInstance() {
return new Row();
}
Expand All @@ -55,22 +65,14 @@ public Map<Integer, Cell> getData() {
public Cell getCell(int printFormatItemId) {
return Optional.ofNullable(data.get(printFormatItemId)).orElse(Cell.newInstance());
}

public String getCompareValue(int itemId) {
return Optional.ofNullable(getCell(itemId).getDisplayValue()).orElse("");
}

public int getLevel() {
return level;
}

public String getSortingValue(List<PrintFormatItem> groupColumns) {
StringBuffer value = new StringBuffer();
groupColumns.forEach(printFormatItem -> {
if(value.length() > 0) {
value.append("|");
}
value.append(Optional.ofNullable(getCell(printFormatItem.getPrintFormatItemId()).getDisplayValue()).orElse(""));
});
value.append(getLevel());
return value.toString();
}

public Row withLevel(int level) {
this.level = level;
Expand All @@ -85,4 +87,14 @@ public void setData(Map<Integer, Cell> data) {
public String toString() {
return "Row [data=" + data + ", level=" + level + "]";
}

@Override
public int hashCode() {
return toString().hashCode();
}

@Override
public boolean equals(Object o) {
return toString().equals(((Row)o).toString());
}
}
66 changes: 36 additions & 30 deletions src/main/java/org/spin/report_engine/data/SummaryHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
package org.spin.report_engine.data;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
Expand All @@ -30,27 +31,30 @@
public class SummaryHandler {
private List<PrintFormatItem> groupedItems;
private List<PrintFormatItem> summarizedItems;
private Map<Integer, Map<String, Map<Integer, SummaryFunction>>> summary;
private Map<Integer, Map<Row, Map<Integer, SummaryFunction>>> summary;
private Map<Integer, Map<String, Map<Integer, SummaryFunction>>> completeSummary;

private SummaryHandler(List<PrintFormatItem> printFormatItems) {
groupedItems = printFormatItems.stream().filter(item -> item.isGroupBy()).collect(Collectors.toList());
groupedItems = printFormatItems.stream().filter(item -> item.isGroupBy()).sorted(Comparator.comparing(PrintFormatItem::getSortSequence)).collect(Collectors.toList());
summarizedItems = printFormatItems.stream().filter(printItem -> {
if(printItem.isHideGrandTotal()) {
return false;
}
return printItem.isAveraged() || printItem.isCounted() || printItem.isMaxCalc() || printItem.isMinCalc() || printItem.isSummarized() || printItem.isVarianceCalc();
}).collect(Collectors.toList());
summary = new HashMap<Integer, Map<String, Map<Integer, SummaryFunction>>>();
summary = new HashMap<Integer, Map<Row, Map<Integer, SummaryFunction>>>();
completeSummary = new HashMap<Integer, Map<String, Map<Integer, SummaryFunction>>>();
}

public SummaryHandler addRow(Row row) {
groupedItems.forEach(groupItem -> {
Map<String, Map<Integer, SummaryFunction>> groupTotals = Optional.ofNullable(summary.get(groupItem.getPrintFormatItemId())).orElse(new HashMap<String, Map<Integer,SummaryFunction>>());
Row keyRow = Row.newInstance().withLevel(groupItem.getSortSequence());
groupedItems.stream().filter(item -> item.getSortSequence() <= groupItem.getSortSequence()).forEach(item ->{
keyRow.withCell(item.getPrintFormatItemId(), row.getCell(item.getPrintFormatItemId()));
});
Map<Row, Map<Integer, SummaryFunction>> groupTotals = Optional.ofNullable(summary.get(groupItem.getPrintFormatItemId())).orElse(new HashMap<Row, Map<Integer, SummaryFunction>>());
Map<String, Map<Integer, SummaryFunction>> totals = Optional.ofNullable(completeSummary.get(groupItem.getPrintFormatItemId())).orElse(new HashMap<String, Map<Integer,SummaryFunction>>());
String groupKey = row.getCell(groupItem.getPrintFormatItemId()).getDisplayValue();
Map<Integer, SummaryFunction> columnTotals = Optional.ofNullable(groupTotals.get(groupKey)).orElse(new HashMap<Integer, SummaryFunction>());
Map<Integer, SummaryFunction> columnTotals = Optional.ofNullable(groupTotals.get(keyRow)).orElse(new HashMap<Integer, SummaryFunction>());
Map<Integer, SummaryFunction> sumTotals = Optional.ofNullable(totals.get(SummaryFunction.getFunctionSymbol(SummaryFunction.F_SUM))).orElse(new HashMap<Integer, SummaryFunction>());
Map<Integer, SummaryFunction> averageTotals = Optional.ofNullable(totals.get(SummaryFunction.getFunctionSymbol(SummaryFunction.F_MEAN))).orElse(new HashMap<Integer, SummaryFunction>());
Map<Integer, SummaryFunction> countTotals = Optional.ofNullable(totals.get(SummaryFunction.getFunctionSymbol(SummaryFunction.F_COUNT))).orElse(new HashMap<Integer, SummaryFunction>());
Expand All @@ -68,7 +72,7 @@ public SummaryHandler addRow(Row row) {
addValue(sumItem.getPrintFormatItemId(), varianceTotals, row.getCell(sumItem.getPrintFormatItemId()));
addValue(sumItem.getPrintFormatItemId(), deviationTotals, row.getCell(sumItem.getPrintFormatItemId()));
});
groupTotals.put(groupKey, columnTotals);
groupTotals.put(keyRow, columnTotals);
totals.put(SummaryFunction.getFunctionSymbol(SummaryFunction.F_SUM), sumTotals);
totals.put(SummaryFunction.getFunctionSymbol(SummaryFunction.F_MEAN), averageTotals);
totals.put(SummaryFunction.getFunctionSymbol(SummaryFunction.F_COUNT), countTotals);
Expand Down Expand Up @@ -100,42 +104,44 @@ public List<PrintFormatItem> getSummarizedItems() {
return summarizedItems;
}

public Map<Integer, Map<String, Map<Integer, SummaryFunction>>> getSummary() {
public Map<Integer, Map<Row, Map<Integer, SummaryFunction>>> getSummary() {
return summary;
}

public List<Row> getAsRows() {
List<Row> rows = new ArrayList<Row>();
groupedItems.forEach(groupItem -> {
Map<String, Map<Integer, SummaryFunction>> groupTotals = Optional.ofNullable(summary.get(groupItem.getPrintFormatItemId())).orElse(new HashMap<String, Map<Integer,SummaryFunction>>());
groupTotals.keySet().forEach(groupValue -> {
Map<Integer, SummaryFunction> summaryValue = groupTotals.get(groupValue);
Row row = Row.newInstance().withLevel(groupItem.getSequence()).withCell(groupItem.getPrintFormatItemId(), Cell.newInstance().withValue(groupValue));
summarizedItems.forEach(sumItem -> {
row.withCell(sumItem.getPrintFormatItemId(), Cell.newInstance().withValue(summaryValue.get(sumItem.getPrintFormatItemId()).getValue(SummaryFunction.F_SUM)));
});
rows.add(row);
});
});
return rows;
}

public List<Row> getTotalsAsRows() {
List<Row> rows = new ArrayList<Row>();
groupedItems.forEach(groupItem -> {
Map<String, Map<Integer, SummaryFunction>> groupTotals = Optional.ofNullable(completeSummary.get(groupItem.getPrintFormatItemId())).orElse(new HashMap<String, Map<Integer,SummaryFunction>>());
groupTotals.keySet().forEach(groupValue -> {
Map<Integer, SummaryFunction> summaryValue = groupTotals.get(groupValue);
Row summaryRow = Row.newInstance().withLevel(0).withCell(groupItem.getPrintFormatItemId(), Cell.newInstance().withValue(groupValue));
Map<Row, Map<Integer, SummaryFunction>> groupTotals = Optional.ofNullable(summary.get(groupItem.getPrintFormatItemId())).orElse(new HashMap<Row, Map<Integer,SummaryFunction>>());
groupTotals.keySet().forEach(groupValueRow -> {
// System.err.println(groupValueRow);
Map<Integer, SummaryFunction> summaryValue = groupTotals.get(groupValueRow);
// Row row = Row.newInstance().withLevel(groupItem.getSortSequence()).withCell(groupItem.getPrintFormatItemId(), Cell.newInstance().withValue(groupValueRow));
summarizedItems.forEach(sumItem -> {
SummaryFunction function = summaryValue.get(sumItem.getPrintFormatItemId());
summaryRow.withCell(sumItem.getPrintFormatItemId(), Cell.newInstance().withValue(function.getValue(SummaryFunction.F_SUM)).withFunction(function));
groupValueRow.withCell(sumItem.getPrintFormatItemId(), Cell.newInstance().withValue(function.getValue(SummaryFunction.F_SUM)).withFunction(function));
});
rows.add(summaryRow);
rows.add(groupValueRow);
});
});
return rows;
}

// public List<Row> getTotalsAsRows() {
// List<Row> rows = new ArrayList<Row>();
// groupedItems.forEach(groupItem -> {
// Map<String, Map<Integer, SummaryFunction>> groupTotals = Optional.ofNullable(completeSummary.get(groupItem.getPrintFormatItemId())).orElse(new HashMap<String, Map<Integer,SummaryFunction>>());
// groupTotals.keySet().forEach(groupValue -> {
// Map<Integer, SummaryFunction> summaryValue = groupTotals.get(groupValue);
// Row summaryRow = Row.newInstance().withLevel(0).withCell(groupItem.getPrintFormatItemId(), Cell.newInstance().withValue(groupValue));
// summarizedItems.forEach(sumItem -> {
// SummaryFunction function = summaryValue.get(sumItem.getPrintFormatItemId());
// summaryRow.withCell(sumItem.getPrintFormatItemId(), Cell.newInstance().withValue(function.getValue(SummaryFunction.F_SUM)).withFunction(function));
// });
// rows.add(summaryRow);
// });
// });
// return rows;
// }

@Override
public String toString() {
Expand Down
41 changes: 28 additions & 13 deletions src/main/java/org/spin/report_engine/format/PrintFormat.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.adempiere.core.domains.models.I_AD_PrintFormatItem;
import org.adempiere.core.domains.models.I_AD_ReportView;
Expand Down Expand Up @@ -47,6 +48,7 @@ public class PrintFormat {
private boolean isSummary;
private List<ReportView> reportViews;
private List<PrintFormatItem> items;
private List<PrintFormatColumn> columnsDefinition;
private int aliasNumber;

private PrintFormat(MPrintFormat printFormat) {
Expand All @@ -57,6 +59,7 @@ private PrintFormat(MPrintFormat printFormat) {
reportView = ReportView.newInstance(new MReportView(Env.getCtx(), printFormat.getAD_ReportView_ID(), null));
}
tableId = printFormat.getAD_Table_ID();
MTable table = MTable.get(printFormat.getCtx(), tableId);
tableName = MTable.getTableName(printFormat.getCtx(), printFormat.getAD_Table_ID());
isSummary = printFormat.isSummary();
// Get Views
Expand All @@ -72,6 +75,23 @@ private PrintFormat(MPrintFormat printFormat) {
.setOrderBy(I_AD_PrintFormatItem.COLUMNNAME_SeqNo)
.getIDsAsList()
.forEach(printFormatItemId -> items.add(PrintFormatItem.newInstance(new MPrintFormatItem(Env.getCtx(), printFormatItemId, null))));
columnsDefinition = table.getColumnsAsList()
.stream()
.filter(column -> !hasPrintFormatItem(column.getAD_Column_ID()))
.map(column -> {
String columnName = column.getColumnName();
if(!Util.isEmpty(column.getColumnSQL())) {
columnName = "(" + column.getColumnSQL() + ")";
return PrintFormatColumn.newInstance(column).withColumnNameAlias(columnName);
} else {
columnName = getQueryColumnName(column.getColumnName());
return PrintFormatColumn.newInstance(column).withColumnNameAlias(columnName);
}
}).collect(Collectors.toList());
}

private boolean hasPrintFormatItem(int columnId) {
return items.stream().filter(item -> item.getColumnId() == columnId).count() > 0;
}

public static PrintFormat newInstance(MPrintFormat printFormat) {
Expand Down Expand Up @@ -122,25 +142,17 @@ public List<PrintFormatItem> getSortingItems() {
return items.stream().filter(item -> item.isGroupBy() || item.isOrderBy()).sorted(Comparator.comparing(PrintFormatItem::getSortSequence)).collect(Collectors.toList());
}

public List<PrintFormatColumn> getColumnsDefinition() {
return columnsDefinition;
}

public QueryDefinition getQuery() {
clearTableAlias();
StringBuffer query = new StringBuffer();
StringBuffer orderBy = new StringBuffer();
StringBuffer tableReferences = new StringBuffer();
Language language = Language.getLoginLanguage();
List<PrintFormatColumn> columns = new ArrayList<PrintFormatColumn>();
// Add all columns
// TODO: Add all from columns instead, now is from print format but is nice to have it from columns of table
getItems().stream().filter(item -> item.getColumnId() > 0).forEach(item -> {
String columnName = null;
if(item.isVirtualColumn()) {
columnName = "(" + item.getColumnSql() + ")";
columns.add(PrintFormatColumn.newInstance(item).withColumnNameAlias(item.getColumnName()));
} else {
columnName = getQueryColumnName(item.getColumnName());
columns.add(PrintFormatColumn.newInstance(item).withColumnNameAlias(columnName));
}
});
getItems().stream()
.filter(item -> item.isActive() && item.isPrinted())
.sorted(Comparator.comparing(PrintFormatItem::getSequence))
Expand All @@ -156,10 +168,12 @@ public QueryDefinition getQuery() {
query.append(columnName);
query.append(" AS ").append(item.getColumnName());
alias = item.getColumnName();
columns.add(PrintFormatColumn.newInstance(item).withColumnNameAlias(item.getColumnName()));
} else {
columnName = getQueryColumnName(item.getColumnName());
query.append(columnName);
alias = columnName;
columns.add(PrintFormatColumn.newInstance(item).withColumnNameAlias(columnName));
}
// Process Display Value
if(item.getReferenceId() == DisplayType.TableDir
Expand Down Expand Up @@ -311,7 +325,8 @@ public QueryDefinition getQuery() {
return QueryDefinition.newInstance()
.withQuery(query.toString())
.withOrderBy(orderBy.toString())
.withColumns(columns);
.withColumns(Stream.concat(columns.stream(),
getColumnsDefinition().stream()).collect(Collectors.toList()));
}

private String getQueryColumnName(String columnName) {
Expand Down
Loading

0 comments on commit dfa9242

Please sign in to comment.