mirror of
https://github.com/Kingsrook/qqq.git
synced 2025-07-18 05:01:07 +00:00
CE-881 - Initial test updates for this story (saved reports, excel pivots)
This commit is contained in:
@ -36,6 +36,7 @@ import com.kingsrook.qqq.backend.core.exceptions.QException;
|
|||||||
import com.kingsrook.qqq.backend.core.exceptions.QUserFacingException;
|
import com.kingsrook.qqq.backend.core.exceptions.QUserFacingException;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.reporting.ExportInput;
|
import com.kingsrook.qqq.backend.core.model.actions.reporting.ExportInput;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.reporting.ExportOutput;
|
import com.kingsrook.qqq.backend.core.model.actions.reporting.ExportOutput;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.actions.reporting.ReportDestination;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.reporting.ReportFormat;
|
import com.kingsrook.qqq.backend.core.model.actions.reporting.ReportFormat;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QQueryFilter;
|
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QQueryFilter;
|
||||||
import com.kingsrook.qqq.backend.core.model.data.QRecord;
|
import com.kingsrook.qqq.backend.core.model.data.QRecord;
|
||||||
@ -43,6 +44,7 @@ import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
|||||||
import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldMetaData;
|
import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldMetaData;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldType;
|
import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldType;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData;
|
import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData;
|
||||||
|
import com.kingsrook.qqq.backend.core.utils.LocalMacDevUtils;
|
||||||
import com.kingsrook.qqq.backend.core.utils.TestUtils;
|
import com.kingsrook.qqq.backend.core.utils.TestUtils;
|
||||||
import org.apache.commons.csv.CSVFormat;
|
import org.apache.commons.csv.CSVFormat;
|
||||||
import org.apache.commons.csv.CSVParser;
|
import org.apache.commons.csv.CSVParser;
|
||||||
@ -118,6 +120,26 @@ class ExportActionTest extends BaseTest
|
|||||||
runReport(recordCount, filename, ReportFormat.XLSX, true);
|
runReport(recordCount, filename, ReportFormat.XLSX, true);
|
||||||
|
|
||||||
File file = new File(filename);
|
File file = new File(filename);
|
||||||
|
LocalMacDevUtils.openFile(file.getAbsolutePath());
|
||||||
|
|
||||||
|
assertTrue(file.delete());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@Test
|
||||||
|
public void testExcelPOI() throws Exception
|
||||||
|
{
|
||||||
|
int recordCount = 1000;
|
||||||
|
String filename = "/tmp/ReportActionTest-POI.xlsx";
|
||||||
|
|
||||||
|
runReport(recordCount, filename, ReportFormat.XLSX, true);
|
||||||
|
|
||||||
|
File file = new File(filename);
|
||||||
|
LocalMacDevUtils.openFile(file.getAbsolutePath());
|
||||||
|
|
||||||
assertTrue(file.delete());
|
assertTrue(file.delete());
|
||||||
}
|
}
|
||||||
@ -147,9 +169,10 @@ class ExportActionTest extends BaseTest
|
|||||||
ExportInput exportInput = new ExportInput();
|
ExportInput exportInput = new ExportInput();
|
||||||
exportInput.setTableName(TestUtils.TABLE_NAME_ORDER);
|
exportInput.setTableName(TestUtils.TABLE_NAME_ORDER);
|
||||||
|
|
||||||
exportInput.setReportFormat(ReportFormat.CSV);
|
|
||||||
ByteArrayOutputStream reportOutputStream = new ByteArrayOutputStream();
|
ByteArrayOutputStream reportOutputStream = new ByteArrayOutputStream();
|
||||||
exportInput.setReportOutputStream(reportOutputStream);
|
exportInput.setReportDestination(new ReportDestination()
|
||||||
|
.withReportFormat(ReportFormat.CSV)
|
||||||
|
.withReportOutputStream(reportOutputStream));
|
||||||
exportInput.setQueryFilter(new QQueryFilter());
|
exportInput.setQueryFilter(new QQueryFilter());
|
||||||
exportInput.setFieldNames(List.of("id", "orderNo", "storeId", "orderLine.id", "orderLine.sku", "orderLine.quantity"));
|
exportInput.setFieldNames(List.of("id", "orderNo", "storeId", "orderLine.id", "orderLine.sku", "orderLine.quantity"));
|
||||||
// exportInput.setFieldNames(List.of("id", "orderNo", "storeId"));
|
// exportInput.setFieldNames(List.of("id", "orderNo", "storeId"));
|
||||||
@ -197,8 +220,7 @@ class ExportActionTest extends BaseTest
|
|||||||
exportInput.setTableName("person");
|
exportInput.setTableName("person");
|
||||||
QTableMetaData table = exportInput.getTable();
|
QTableMetaData table = exportInput.getTable();
|
||||||
|
|
||||||
exportInput.setReportFormat(reportFormat);
|
exportInput.setReportDestination(new ReportDestination().withReportFormat(reportFormat).withReportOutputStream(outputStream));
|
||||||
exportInput.setReportOutputStream(outputStream);
|
|
||||||
exportInput.setQueryFilter(new QQueryFilter());
|
exportInput.setQueryFilter(new QQueryFilter());
|
||||||
exportInput.setLimit(recordCount);
|
exportInput.setLimit(recordCount);
|
||||||
|
|
||||||
@ -243,7 +265,7 @@ class ExportActionTest extends BaseTest
|
|||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// use xlsx, which has a max-rows limit, to verify that code runs, but doesn't throw when there aren't too many rows //
|
// use xlsx, which has a max-rows limit, to verify that code runs, but doesn't throw when there aren't too many rows //
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
exportInput.setReportFormat(ReportFormat.XLSX);
|
exportInput.setReportDestination(new ReportDestination().withReportFormat(ReportFormat.XLSX));
|
||||||
|
|
||||||
new ExportAction().preExecute(exportInput);
|
new ExportAction().preExecute(exportInput);
|
||||||
|
|
||||||
@ -278,7 +300,7 @@ class ExportActionTest extends BaseTest
|
|||||||
////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////
|
||||||
// use xlsx, which has a max-cols limit, to verify that code. //
|
// use xlsx, which has a max-cols limit, to verify that code. //
|
||||||
////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////
|
||||||
exportInput.setReportFormat(ReportFormat.XLSX);
|
exportInput.setReportDestination(new ReportDestination().withReportFormat(ReportFormat.XLSX));
|
||||||
|
|
||||||
assertThrows(QUserFacingException.class, () ->
|
assertThrows(QUserFacingException.class, () ->
|
||||||
{
|
{
|
||||||
|
@ -23,19 +23,27 @@ package com.kingsrook.qqq.backend.core.actions.reporting;
|
|||||||
|
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.FileInputStream;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.time.Month;
|
import java.time.Month;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import com.kingsrook.qqq.backend.core.BaseTest;
|
import com.kingsrook.qqq.backend.core.BaseTest;
|
||||||
import com.kingsrook.qqq.backend.core.context.QContext;
|
import com.kingsrook.qqq.backend.core.context.QContext;
|
||||||
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.actions.reporting.ReportDestination;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.reporting.ReportFormat;
|
import com.kingsrook.qqq.backend.core.model.actions.reporting.ReportFormat;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.reporting.ReportInput;
|
import com.kingsrook.qqq.backend.core.model.actions.reporting.ReportInput;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.actions.reporting.pivottable.PivotTableDefinition;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.actions.reporting.pivottable.PivotTableFunction;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.actions.reporting.pivottable.PivotTableGroupBy;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.actions.reporting.pivottable.PivotTableValue;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QCriteriaOperator;
|
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QCriteriaOperator;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QFilterCriteria;
|
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QFilterCriteria;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QFilterOrderBy;
|
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QFilterOrderBy;
|
||||||
@ -51,7 +59,14 @@ import com.kingsrook.qqq.backend.core.model.metadata.reporting.QReportView;
|
|||||||
import com.kingsrook.qqq.backend.core.model.metadata.reporting.ReportType;
|
import com.kingsrook.qqq.backend.core.model.metadata.reporting.ReportType;
|
||||||
import com.kingsrook.qqq.backend.core.modules.backend.implementations.memory.MemoryRecordStore;
|
import com.kingsrook.qqq.backend.core.modules.backend.implementations.memory.MemoryRecordStore;
|
||||||
import com.kingsrook.qqq.backend.core.testutils.PersonQRecord;
|
import com.kingsrook.qqq.backend.core.testutils.PersonQRecord;
|
||||||
|
import com.kingsrook.qqq.backend.core.utils.LocalMacDevUtils;
|
||||||
import com.kingsrook.qqq.backend.core.utils.TestUtils;
|
import com.kingsrook.qqq.backend.core.utils.TestUtils;
|
||||||
|
import org.apache.poi.ss.usermodel.Cell;
|
||||||
|
import org.apache.poi.ss.usermodel.Row;
|
||||||
|
import org.apache.poi.ss.usermodel.Sheet;
|
||||||
|
import org.apache.poi.xssf.usermodel.XSSFPivotTable;
|
||||||
|
import org.apache.poi.xssf.usermodel.XSSFSheet;
|
||||||
|
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||||
import org.junit.jupiter.api.AfterEach;
|
import org.junit.jupiter.api.AfterEach;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
@ -85,10 +100,10 @@ public class GenerateReportActionTest extends BaseTest
|
|||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
@Test
|
@Test
|
||||||
void testPivot1() throws QException
|
void testSummary1() throws QException
|
||||||
{
|
{
|
||||||
QInstance qInstance = QContext.getQInstance();
|
QInstance qInstance = QContext.getQInstance();
|
||||||
qInstance.addReport(definePersonShoesPivotReport(true));
|
qInstance.addReport(definePersonShoesSummaryReport(true));
|
||||||
insertPersonRecords(qInstance);
|
insertPersonRecords(qInstance);
|
||||||
runReport(qInstance, Map.of("startDate", LocalDate.of(1980, Month.JANUARY, 1), "endDate", LocalDate.of(1980, Month.DECEMBER, 31)));
|
runReport(qInstance, Map.of("startDate", LocalDate.of(1980, Month.JANUARY, 1), "endDate", LocalDate.of(1980, Month.DECEMBER, 31)));
|
||||||
|
|
||||||
@ -140,10 +155,10 @@ public class GenerateReportActionTest extends BaseTest
|
|||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
@Test
|
@Test
|
||||||
void testPivot2() throws QException
|
void testSummary2() throws QException
|
||||||
{
|
{
|
||||||
QInstance qInstance = QContext.getQInstance();
|
QInstance qInstance = QContext.getQInstance();
|
||||||
QReportMetaData report = definePersonShoesPivotReport(false);
|
QReportMetaData report = definePersonShoesSummaryReport(false);
|
||||||
|
|
||||||
//////////////////////////////////////////////
|
//////////////////////////////////////////////
|
||||||
// change from the default to sort reversed //
|
// change from the default to sort reversed //
|
||||||
@ -172,10 +187,10 @@ public class GenerateReportActionTest extends BaseTest
|
|||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
@Test
|
@Test
|
||||||
void testPivot3() throws QException
|
void testSummary3() throws QException
|
||||||
{
|
{
|
||||||
QInstance qInstance = QContext.getQInstance();
|
QInstance qInstance = QContext.getQInstance();
|
||||||
QReportMetaData report = definePersonShoesPivotReport(false);
|
QReportMetaData report = definePersonShoesSummaryReport(false);
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// remove the filters, change to sort by personCount (to get some ties), then sumPrice desc //
|
// remove the filters, change to sort by personCount (to get some ties), then sumPrice desc //
|
||||||
@ -224,16 +239,16 @@ public class GenerateReportActionTest extends BaseTest
|
|||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
@Test
|
@Test
|
||||||
void testPivot4() throws QException
|
void testSummary4() throws QException
|
||||||
{
|
{
|
||||||
QInstance qInstance = QContext.getQInstance();
|
QInstance qInstance = QContext.getQInstance();
|
||||||
QReportMetaData report = definePersonShoesPivotReport(false);
|
QReportMetaData report = definePersonShoesSummaryReport(false);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// remove the filter, change to have 2 pivot columns - homeStateId and lastName - we should get no roll-up like this. //
|
// remove the filter, change to have 2 pivot columns - homeStateId and lastName - we should get no roll-up like this. //
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
report.getDataSources().get(0).getQueryFilter().setCriteria(null);
|
report.getDataSources().get(0).getQueryFilter().setCriteria(null);
|
||||||
report.getViews().get(0).setPivotFields(List.of(
|
report.getViews().get(0).setSummaryFields(List.of(
|
||||||
"homeStateId",
|
"homeStateId",
|
||||||
"lastName"
|
"lastName"
|
||||||
));
|
));
|
||||||
@ -282,16 +297,16 @@ public class GenerateReportActionTest extends BaseTest
|
|||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
@Test
|
@Test
|
||||||
void testPivot5() throws QException
|
void testSummary5() throws QException
|
||||||
{
|
{
|
||||||
QInstance qInstance = QContext.getQInstance();
|
QInstance qInstance = QContext.getQInstance();
|
||||||
QReportMetaData report = definePersonShoesPivotReport(false);
|
QReportMetaData report = definePersonShoesSummaryReport(false);
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
// remove the filter, and just pivot on homeStateId - should aggregate differently //
|
// remove the filter, and just pivot on homeStateId - should aggregate differently //
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
report.getDataSources().get(0).getQueryFilter().setCriteria(null);
|
report.getDataSources().get(0).getQueryFilter().setCriteria(null);
|
||||||
report.getViews().get(0).setPivotFields(List.of("homeStateId"));
|
report.getViews().get(0).setSummaryFields(List.of("homeStateId"));
|
||||||
qInstance.addReport(report);
|
qInstance.addReport(report);
|
||||||
insertPersonRecords(qInstance);
|
insertPersonRecords(qInstance);
|
||||||
runReport(qInstance, Map.of("startDate", LocalDate.now(), "endDate", LocalDate.now()));
|
runReport(qInstance, Map.of("startDate", LocalDate.now(), "endDate", LocalDate.now()));
|
||||||
@ -322,13 +337,12 @@ public class GenerateReportActionTest extends BaseTest
|
|||||||
try(FileOutputStream fileOutputStream = new FileOutputStream(name))
|
try(FileOutputStream fileOutputStream = new FileOutputStream(name))
|
||||||
{
|
{
|
||||||
QInstance qInstance = QContext.getQInstance();
|
QInstance qInstance = QContext.getQInstance();
|
||||||
qInstance.addReport(definePersonShoesPivotReport(true));
|
qInstance.addReport(definePersonShoesSummaryReport(true));
|
||||||
insertPersonRecords(qInstance);
|
insertPersonRecords(qInstance);
|
||||||
|
|
||||||
ReportInput reportInput = new ReportInput();
|
ReportInput reportInput = new ReportInput();
|
||||||
reportInput.setReportName(REPORT_NAME);
|
reportInput.setReportName(REPORT_NAME);
|
||||||
reportInput.setReportFormat(ReportFormat.CSV);
|
reportInput.setReportDestination(new ReportDestination().withReportFormat(ReportFormat.CSV).withReportOutputStream(fileOutputStream));
|
||||||
reportInput.setReportOutputStream(fileOutputStream);
|
|
||||||
reportInput.setInputValues(Map.of("startDate", LocalDate.of(1970, Month.MAY, 15), "endDate", LocalDate.now()));
|
reportInput.setInputValues(Map.of("startDate", LocalDate.of(1970, Month.MAY, 15), "endDate", LocalDate.now()));
|
||||||
new GenerateReportAction().execute(reportInput);
|
new GenerateReportAction().execute(reportInput);
|
||||||
System.out.println("Wrote File: " + name);
|
System.out.println("Wrote File: " + name);
|
||||||
@ -341,27 +355,122 @@ public class GenerateReportActionTest extends BaseTest
|
|||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
@Test
|
@Test
|
||||||
void runToXlsx() throws Exception
|
void runSummaryToXlsx() throws Exception
|
||||||
{
|
{
|
||||||
String name = "/tmp/report.xlsx";
|
ReportFormat format = ReportFormat.XLSX;
|
||||||
|
String name = "/tmp/report-" + format + ".xlsx";
|
||||||
try(FileOutputStream fileOutputStream = new FileOutputStream(name))
|
try(FileOutputStream fileOutputStream = new FileOutputStream(name))
|
||||||
{
|
{
|
||||||
QInstance qInstance = QContext.getQInstance();
|
QInstance qInstance = QContext.getQInstance();
|
||||||
qInstance.addReport(definePersonShoesPivotReport(true));
|
qInstance.addReport(definePersonShoesSummaryReport(true));
|
||||||
insertPersonRecords(qInstance);
|
insertPersonRecords(qInstance);
|
||||||
|
|
||||||
ReportInput reportInput = new ReportInput();
|
ReportInput reportInput = new ReportInput();
|
||||||
reportInput.setReportName(REPORT_NAME);
|
reportInput.setReportName(REPORT_NAME);
|
||||||
reportInput.setReportFormat(ReportFormat.XLSX);
|
reportInput.setReportDestination(new ReportDestination().withReportFormat(format).withReportOutputStream(fileOutputStream));
|
||||||
reportInput.setReportOutputStream(fileOutputStream);
|
|
||||||
reportInput.setInputValues(Map.of("startDate", LocalDate.of(1970, Month.MAY, 15), "endDate", LocalDate.now()));
|
reportInput.setInputValues(Map.of("startDate", LocalDate.of(1970, Month.MAY, 15), "endDate", LocalDate.now()));
|
||||||
new GenerateReportAction().execute(reportInput);
|
new GenerateReportAction().execute(reportInput);
|
||||||
System.out.println("Wrote File: " + name);
|
System.out.println("Wrote File: " + name);
|
||||||
|
|
||||||
|
LocalMacDevUtils.openFile(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@Test
|
||||||
|
void runTableToXlsx() throws Exception
|
||||||
|
{
|
||||||
|
ReportFormat format = ReportFormat.XLSX;
|
||||||
|
String name = "/tmp/report-" + format + ".xlsx";
|
||||||
|
try(FileOutputStream fileOutputStream = new FileOutputStream(name))
|
||||||
|
{
|
||||||
|
QInstance qInstance = QContext.getQInstance();
|
||||||
|
qInstance.addReport(defineTableOnlyReport());
|
||||||
|
insertPersonRecords(qInstance);
|
||||||
|
|
||||||
|
ReportInput reportInput = new ReportInput();
|
||||||
|
reportInput.setReportName(REPORT_NAME);
|
||||||
|
reportInput.setReportDestination(new ReportDestination().withReportFormat(format).withReportOutputStream(fileOutputStream));
|
||||||
|
reportInput.setInputValues(Map.of("startDate", LocalDate.of(1970, Month.MAY, 15), "endDate", LocalDate.now()));
|
||||||
|
new GenerateReportAction().execute(reportInput);
|
||||||
|
System.out.println("Wrote File: " + name);
|
||||||
|
|
||||||
|
LocalMacDevUtils.openFile(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@Test
|
||||||
|
void runPivotToXlsx() throws Exception
|
||||||
|
{
|
||||||
|
String name = "/tmp/pivot-test.xlsx";
|
||||||
|
try(FileOutputStream fileOutputStream = new FileOutputStream(name))
|
||||||
|
{
|
||||||
|
QInstance qInstance = QContext.getQInstance();
|
||||||
|
qInstance.addReport(definePivotReport());
|
||||||
|
insertPersonRecords(qInstance);
|
||||||
|
|
||||||
|
ReportInput reportInput = new ReportInput();
|
||||||
|
reportInput.setReportName(REPORT_NAME);
|
||||||
|
reportInput.setReportDestination(new ReportDestination().withReportFormat(ReportFormat.XLSX).withReportOutputStream(fileOutputStream));
|
||||||
|
reportInput.setInputValues(Map.of("startDate", LocalDate.of(1970, Month.MAY, 15), "endDate", LocalDate.now()));
|
||||||
|
new GenerateReportAction().execute(reportInput);
|
||||||
|
System.out.println("Wrote File: " + name);
|
||||||
|
|
||||||
|
// LocalMacDevUtils.mayOpenFiles = true;
|
||||||
|
LocalMacDevUtils.openFile(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////
|
||||||
|
// read the file we wrote, and assert about its contents //
|
||||||
|
///////////////////////////////////////////////////////////
|
||||||
|
FileInputStream file = new FileInputStream(name);
|
||||||
|
XSSFWorkbook workbook = new XSSFWorkbook(file);
|
||||||
|
|
||||||
|
XSSFSheet sheet = workbook.getSheetAt(1);
|
||||||
|
List<XSSFPivotTable> pivotTables = sheet.getPivotTables();
|
||||||
|
XSSFPivotTable xssfPivotTable = pivotTables.get(0);
|
||||||
|
List<Integer> rowLabelColumns = xssfPivotTable.getRowLabelColumns();
|
||||||
|
List<Integer> colLabelColumns = xssfPivotTable.getColLabelColumns();
|
||||||
|
Sheet dataSheet = xssfPivotTable.getDataSheet();
|
||||||
|
Sheet parentSheet = xssfPivotTable.getParentSheet();
|
||||||
|
System.out.println();
|
||||||
|
|
||||||
|
Map<Integer, List<Object>> data = new HashMap<>();
|
||||||
|
int i = 0;
|
||||||
|
for(Row row : sheet)
|
||||||
|
{
|
||||||
|
data.put(i, new ArrayList<>());
|
||||||
|
|
||||||
|
for(Cell cell : row)
|
||||||
|
{
|
||||||
|
data.get(i).add(switch(cell.getCellType())
|
||||||
|
{
|
||||||
|
case _NONE -> "<_NONE>";
|
||||||
|
case NUMERIC -> cell.getNumericCellValue();
|
||||||
|
case STRING -> cell.getStringCellValue();
|
||||||
|
case FORMULA -> cell.getCellFormula();
|
||||||
|
case BLANK -> "<BLANK>";
|
||||||
|
case BOOLEAN -> cell.getBooleanCellValue();
|
||||||
|
case ERROR -> cell.getErrorCellValue();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
@ -369,8 +478,7 @@ public class GenerateReportActionTest extends BaseTest
|
|||||||
{
|
{
|
||||||
ReportInput reportInput = new ReportInput();
|
ReportInput reportInput = new ReportInput();
|
||||||
reportInput.setReportName(REPORT_NAME);
|
reportInput.setReportName(REPORT_NAME);
|
||||||
reportInput.setReportFormat(ReportFormat.LIST_OF_MAPS);
|
reportInput.setReportDestination(new ReportDestination().withReportFormat(ReportFormat.LIST_OF_MAPS).withReportOutputStream(new ByteArrayOutputStream()));
|
||||||
reportInput.setReportOutputStream(new ByteArrayOutputStream());
|
|
||||||
reportInput.setInputValues(inputValues);
|
reportInput.setInputValues(inputValues);
|
||||||
new GenerateReportAction().execute(reportInput);
|
new GenerateReportAction().execute(reportInput);
|
||||||
}
|
}
|
||||||
@ -383,12 +491,12 @@ public class GenerateReportActionTest extends BaseTest
|
|||||||
private void insertPersonRecords(QInstance qInstance) throws QException
|
private void insertPersonRecords(QInstance qInstance) throws QException
|
||||||
{
|
{
|
||||||
TestUtils.insertRecords(qInstance, qInstance.getTable(TestUtils.TABLE_NAME_PERSON_MEMORY), List.of(
|
TestUtils.insertRecords(qInstance, qInstance.getTable(TestUtils.TABLE_NAME_PERSON_MEMORY), List.of(
|
||||||
new PersonQRecord().withLastName("Jonson").withBirthDate(LocalDate.of(1980, Month.JANUARY, 31)).withNoOfShoes(null).withHomeStateId(1).withPrice(null).withCost(new BigDecimal("0.50")), // wrong last initial
|
new PersonQRecord().withFirstName("Darin").withLastName("Jonson").withBirthDate(LocalDate.of(1980, Month.JANUARY, 31)).withNoOfShoes(null).withHomeStateId(1).withPrice(null).withCost(new BigDecimal("0.50")), // wrong last initial
|
||||||
new PersonQRecord().withLastName("Jones").withBirthDate(LocalDate.of(1980, Month.JANUARY, 31)).withNoOfShoes(3).withHomeStateId(1).withPrice(new BigDecimal("1.00")).withCost(new BigDecimal("0.50")), // wrong last initial
|
new PersonQRecord().withFirstName("Darin").withLastName("Jones").withBirthDate(LocalDate.of(1980, Month.JANUARY, 31)).withNoOfShoes(3).withHomeStateId(1).withPrice(new BigDecimal("1.00")).withCost(new BigDecimal("0.50")), // wrong last initial
|
||||||
new PersonQRecord().withLastName("Kelly").withBirthDate(LocalDate.of(1979, Month.DECEMBER, 30)).withNoOfShoes(4).withHomeStateId(1).withPrice(new BigDecimal("1.20")).withCost(new BigDecimal("0.50")), // bad birthdate
|
new PersonQRecord().withFirstName("Darin").withLastName("Kelly").withBirthDate(LocalDate.of(1979, Month.DECEMBER, 30)).withNoOfShoes(4).withHomeStateId(1).withPrice(new BigDecimal("1.20")).withCost(new BigDecimal("0.50")), // bad birthdate
|
||||||
new PersonQRecord().withLastName("Keller").withBirthDate(LocalDate.of(1980, Month.JANUARY, 7)).withNoOfShoes(5).withHomeStateId(1).withPrice(new BigDecimal("2.40")).withCost(new BigDecimal("3.50")),
|
new PersonQRecord().withFirstName("Trevor").withLastName("Keller").withBirthDate(LocalDate.of(1980, Month.JANUARY, 7)).withNoOfShoes(5).withHomeStateId(1).withPrice(new BigDecimal("2.40")).withCost(new BigDecimal("3.50")),
|
||||||
new PersonQRecord().withLastName("Kelkhoff").withBirthDate(LocalDate.of(1980, Month.FEBRUARY, 15)).withNoOfShoes(6).withHomeStateId(1).withPrice(new BigDecimal("3.60")).withCost(new BigDecimal("3.50")),
|
new PersonQRecord().withFirstName("Trevor").withLastName("Kelkhoff").withBirthDate(LocalDate.of(1980, Month.FEBRUARY, 15)).withNoOfShoes(6).withHomeStateId(1).withPrice(new BigDecimal("3.60")).withCost(new BigDecimal("3.50")),
|
||||||
new PersonQRecord().withLastName("Kelkhoff").withBirthDate(LocalDate.of(1980, Month.MARCH, 20)).withNoOfShoes(7).withHomeStateId(2).withPrice(new BigDecimal("4.80")).withCost(new BigDecimal("3.50"))
|
new PersonQRecord().withFirstName("Kelly").withLastName("Kelkhoff").withBirthDate(LocalDate.of(1980, Month.MARCH, 20)).withNoOfShoes(7).withHomeStateId(2).withPrice(new BigDecimal("4.80")).withCost(new BigDecimal("3.50"))
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -397,7 +505,7 @@ public class GenerateReportActionTest extends BaseTest
|
|||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public static QReportMetaData definePersonShoesPivotReport(boolean includeTotalRow)
|
public static QReportMetaData definePersonShoesSummaryReport(boolean includeTotalRow)
|
||||||
{
|
{
|
||||||
return new QReportMetaData()
|
return new QReportMetaData()
|
||||||
.withName(REPORT_NAME)
|
.withName(REPORT_NAME)
|
||||||
@ -420,7 +528,7 @@ public class GenerateReportActionTest extends BaseTest
|
|||||||
.withLabel("pivot")
|
.withLabel("pivot")
|
||||||
.withDataSourceName("persons")
|
.withDataSourceName("persons")
|
||||||
.withType(ReportType.SUMMARY)
|
.withType(ReportType.SUMMARY)
|
||||||
.withPivotFields(List.of("lastName"))
|
.withSummaryFields(List.of("lastName"))
|
||||||
.withIncludeTotalRow(includeTotalRow)
|
.withIncludeTotalRow(includeTotalRow)
|
||||||
.withTitleFormat("Number of shoes - people born between %s and %s - pivot on LastName, sort by Quantity, Revenue DESC")
|
.withTitleFormat("Number of shoes - people born between %s and %s - pivot on LastName, sort by Quantity, Revenue DESC")
|
||||||
.withTitleFields(List.of("${input.startDate}", "${input.endDate}"))
|
.withTitleFields(List.of("${input.startDate}", "${input.endDate}"))
|
||||||
@ -452,33 +560,8 @@ public class GenerateReportActionTest extends BaseTest
|
|||||||
@Test
|
@Test
|
||||||
void testTableOnlyReport() throws QException
|
void testTableOnlyReport() throws QException
|
||||||
{
|
{
|
||||||
QInstance qInstance = QContext.getQInstance();
|
QInstance qInstance = QContext.getQInstance();
|
||||||
QReportMetaData report = new QReportMetaData()
|
QReportMetaData report = defineTableOnlyReport();
|
||||||
.withName(REPORT_NAME)
|
|
||||||
.withDataSources(List.of(
|
|
||||||
new QReportDataSource()
|
|
||||||
.withName("persons")
|
|
||||||
.withSourceTable(TestUtils.TABLE_NAME_PERSON_MEMORY)
|
|
||||||
.withQueryFilter(new QQueryFilter()
|
|
||||||
.withCriteria(new QFilterCriteria("birthDate", QCriteriaOperator.GREATER_THAN, List.of("${input.startDate}")))
|
|
||||||
)
|
|
||||||
))
|
|
||||||
.withInputFields(List.of(
|
|
||||||
new QFieldMetaData("startDate", QFieldType.DATE_TIME)
|
|
||||||
))
|
|
||||||
.withViews(List.of(
|
|
||||||
new QReportView()
|
|
||||||
.withName("table1")
|
|
||||||
.withLabel("table1")
|
|
||||||
.withDataSourceName("persons")
|
|
||||||
.withType(ReportType.TABLE)
|
|
||||||
.withColumns(List.of(
|
|
||||||
new QReportField().withName("id"),
|
|
||||||
new QReportField().withName("firstName"),
|
|
||||||
new QReportField().withName("lastName")
|
|
||||||
))
|
|
||||||
));
|
|
||||||
|
|
||||||
qInstance.addReport(report);
|
qInstance.addReport(report);
|
||||||
|
|
||||||
insertPersonRecords(qInstance);
|
insertPersonRecords(qInstance);
|
||||||
@ -493,6 +576,86 @@ public class GenerateReportActionTest extends BaseTest
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
private static QReportMetaData defineTableOnlyReport()
|
||||||
|
{
|
||||||
|
QReportMetaData report = new QReportMetaData()
|
||||||
|
.withName(REPORT_NAME)
|
||||||
|
.withDataSources(List.of(
|
||||||
|
new QReportDataSource()
|
||||||
|
.withName("persons")
|
||||||
|
.withSourceTable(TestUtils.TABLE_NAME_PERSON_MEMORY)
|
||||||
|
.withQueryFilter(new QQueryFilter()
|
||||||
|
.withCriteria(new QFilterCriteria("birthDate", QCriteriaOperator.GREATER_THAN, List.of("${input.startDate}"))))))
|
||||||
|
|
||||||
|
.withInputFields(List.of(
|
||||||
|
new QFieldMetaData("startDate", QFieldType.DATE_TIME)))
|
||||||
|
|
||||||
|
.withViews(List.of(
|
||||||
|
new QReportView()
|
||||||
|
.withName("table1")
|
||||||
|
.withLabel("table1")
|
||||||
|
.withDataSourceName("persons")
|
||||||
|
.withType(ReportType.TABLE)
|
||||||
|
.withColumns(List.of(
|
||||||
|
new QReportField().withName("id"),
|
||||||
|
new QReportField().withName("firstName"),
|
||||||
|
new QReportField().withName("lastName")))));
|
||||||
|
|
||||||
|
return report;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
private static QReportMetaData definePivotReport()
|
||||||
|
{
|
||||||
|
QReportMetaData report = new QReportMetaData()
|
||||||
|
.withName(REPORT_NAME)
|
||||||
|
.withDataSources(List.of(
|
||||||
|
new QReportDataSource()
|
||||||
|
.withName("persons")
|
||||||
|
.withSourceTable(TestUtils.TABLE_NAME_PERSON_MEMORY)
|
||||||
|
.withQueryFilter(new QQueryFilter()
|
||||||
|
.withCriteria(new QFilterCriteria("birthDate", QCriteriaOperator.GREATER_THAN, List.of("${input.startDate}"))))))
|
||||||
|
|
||||||
|
.withInputFields(List.of(
|
||||||
|
new QFieldMetaData("startDate", QFieldType.DATE_TIME)))
|
||||||
|
|
||||||
|
.withViews(List.of(
|
||||||
|
|
||||||
|
new QReportView()
|
||||||
|
.withName("table1")
|
||||||
|
.withLabel("table1")
|
||||||
|
.withDataSourceName("persons")
|
||||||
|
.withType(ReportType.TABLE)
|
||||||
|
.withColumns(List.of(
|
||||||
|
new QReportField().withName("id"),
|
||||||
|
new QReportField().withName("firstName"),
|
||||||
|
new QReportField().withName("lastName"))),
|
||||||
|
|
||||||
|
new QReportView()
|
||||||
|
.withName("pivotTable1")
|
||||||
|
.withLabel("My Pivot Table")
|
||||||
|
|
||||||
|
.withType(ReportType.PIVOT)
|
||||||
|
.withPivotTableSourceViewName("table1")
|
||||||
|
.withPivotTableDefinition(new PivotTableDefinition()
|
||||||
|
.withRow(new PivotTableGroupBy().withFieldName("firstName"))
|
||||||
|
.withRow(new PivotTableGroupBy().withFieldName("lastName"))
|
||||||
|
// .withColumn(new PivotTableGroupBy().withFieldName("firstName"))
|
||||||
|
.withValue(new PivotTableValue().withFunction(PivotTableFunction.COUNT).withFieldName("id")))
|
||||||
|
));
|
||||||
|
|
||||||
|
return report;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
@ -566,8 +729,7 @@ public class GenerateReportActionTest extends BaseTest
|
|||||||
|
|
||||||
ReportInput reportInput = new ReportInput();
|
ReportInput reportInput = new ReportInput();
|
||||||
reportInput.setReportName(TestUtils.REPORT_NAME_PERSON_SIMPLE);
|
reportInput.setReportName(TestUtils.REPORT_NAME_PERSON_SIMPLE);
|
||||||
reportInput.setReportFormat(ReportFormat.LIST_OF_MAPS);
|
reportInput.setReportDestination(new ReportDestination().withReportFormat(ReportFormat.LIST_OF_MAPS).withReportOutputStream(new ByteArrayOutputStream()));
|
||||||
reportInput.setReportOutputStream(new ByteArrayOutputStream());
|
|
||||||
new GenerateReportAction().execute(reportInput);
|
new GenerateReportAction().execute(reportInput);
|
||||||
|
|
||||||
List<Map<String, String>> list = ListOfMapsExportStreamer.getList("Simple Report");
|
List<Map<String, String>> list = ListOfMapsExportStreamer.getList("Simple Report");
|
||||||
|
@ -35,6 +35,7 @@ import com.kingsrook.qqq.backend.core.model.actions.templates.RenderTemplateInpu
|
|||||||
import com.kingsrook.qqq.backend.core.model.actions.templates.RenderTemplateOutput;
|
import com.kingsrook.qqq.backend.core.model.actions.templates.RenderTemplateOutput;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
||||||
import com.kingsrook.qqq.backend.core.model.templates.TemplateType;
|
import com.kingsrook.qqq.backend.core.model.templates.TemplateType;
|
||||||
|
import com.kingsrook.qqq.backend.core.utils.LocalMacDevUtils;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
|
||||||
@ -107,8 +108,8 @@ class ConvertHtmlToPdfActionTest extends BaseTest
|
|||||||
/////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////
|
||||||
// for local dev on a mac, turn this on to auto-open the generated PDF //
|
// for local dev on a mac, turn this on to auto-open the generated PDF //
|
||||||
/////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////
|
||||||
// todo not commit
|
// LocalMacDevUtils.mayOpenFiles = true;
|
||||||
// Runtime.getRuntime().exec(new String[] { "/usr/bin/open", "/tmp/file.pdf" });
|
LocalMacDevUtils.openFile("/tmp/file.pdf");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -34,6 +34,7 @@ import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData;
|
|||||||
import com.kingsrook.qqq.backend.core.utils.TestUtils;
|
import com.kingsrook.qqq.backend.core.utils.TestUtils;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||||
|
|
||||||
@ -156,4 +157,47 @@ class DynamicDefaultValueBehaviorTest extends BaseTest
|
|||||||
assertNull(record.getValue("firstName"));
|
assertNull(record.getValue("firstName"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@Test
|
||||||
|
void testUserId()
|
||||||
|
{
|
||||||
|
QInstance qInstance = QContext.getQInstance();
|
||||||
|
QTableMetaData table = qInstance.getTable(TestUtils.TABLE_NAME_PERSON_MEMORY);
|
||||||
|
table.getField("firstName").withBehavior(DynamicDefaultValueBehavior.USER_ID);
|
||||||
|
|
||||||
|
{
|
||||||
|
////////////////////////////////
|
||||||
|
// set it (if null) on insert //
|
||||||
|
////////////////////////////////
|
||||||
|
QRecord record = new QRecord().withValue("id", 1);
|
||||||
|
ValueBehaviorApplier.applyFieldBehaviors(ValueBehaviorApplier.Action.INSERT, qInstance, table, List.of(record), null);
|
||||||
|
assertEquals(QContext.getQSession().getUser().getIdReference(), record.getValue("firstName"));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
////////////////////////////////
|
||||||
|
// set it (if null) on update //
|
||||||
|
////////////////////////////////
|
||||||
|
QRecord record = new QRecord().withValue("id", 1);
|
||||||
|
ValueBehaviorApplier.applyFieldBehaviors(ValueBehaviorApplier.Action.UPDATE, qInstance, table, List.of(record), null);
|
||||||
|
assertEquals(QContext.getQSession().getUser().getIdReference(), record.getValue("firstName"));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// only set it if it wasn't previously set (both insert & update) //
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
QRecord record = new QRecord().withValue("id", 1).withValue("firstName", "Bob");
|
||||||
|
ValueBehaviorApplier.applyFieldBehaviors(ValueBehaviorApplier.Action.INSERT, qInstance, table, List.of(record), null);
|
||||||
|
assertEquals("Bob", record.getValue("firstName"));
|
||||||
|
|
||||||
|
ValueBehaviorApplier.applyFieldBehaviors(ValueBehaviorApplier.Action.UPDATE, qInstance, table, List.of(record), null);
|
||||||
|
assertEquals("Bob", record.getValue("firstName"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,7 @@ class BasicRunReportProcessTest extends BaseTest
|
|||||||
void testRunReport() throws QException
|
void testRunReport() throws QException
|
||||||
{
|
{
|
||||||
QInstance instance = TestUtils.defineInstance();
|
QInstance instance = TestUtils.defineInstance();
|
||||||
QReportMetaData report = GenerateReportActionTest.definePersonShoesPivotReport(true);
|
QReportMetaData report = GenerateReportActionTest.definePersonShoesSummaryReport(true);
|
||||||
QProcessMetaData runReportProcess = BasicRunReportProcess.defineProcessMetaData();
|
QProcessMetaData runReportProcess = BasicRunReportProcess.defineProcessMetaData();
|
||||||
|
|
||||||
instance.addReport(report);
|
instance.addReport(report);
|
||||||
|
@ -40,6 +40,14 @@ public class PersonQRecord extends QRecord
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public PersonQRecord withFirstName(String firstName)
|
||||||
|
{
|
||||||
|
setValue("firstName", firstName);
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public PersonQRecord withBirthDate(LocalDate birthDate)
|
public PersonQRecord withBirthDate(LocalDate birthDate)
|
||||||
{
|
{
|
||||||
setValue("birthDate", birthDate);
|
setValue("birthDate", birthDate);
|
||||||
|
Reference in New Issue
Block a user