diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/savedreports/ReportColumn.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/savedreports/ReportColumn.java
new file mode 100644
index 00000000..44518fe2
--- /dev/null
+++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/savedreports/ReportColumn.java
@@ -0,0 +1,98 @@
+/*
+ * QQQ - Low-code Application Framework for Engineers.
+ * Copyright (C) 2021-2024. Kingsrook, LLC
+ * 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
+ * contact@kingsrook.com
+ * https://github.com/Kingsrook/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package com.kingsrook.qqq.backend.core.model.savedreports;
+
+
+import java.io.Serializable;
+
+
+/*******************************************************************************
+ ** single entry in ReportColumns object - as part of SavedReport
+ *******************************************************************************/
+public class ReportColumn implements Serializable
+{
+ private String name;
+ private Boolean isVisible;
+
+
+
+ /*******************************************************************************
+ ** Getter for name
+ *******************************************************************************/
+ public String getName()
+ {
+ return (this.name);
+ }
+
+
+
+ /*******************************************************************************
+ ** Setter for name
+ *******************************************************************************/
+ public void setName(String name)
+ {
+ this.name = name;
+ }
+
+
+
+ /*******************************************************************************
+ ** Fluent setter for name
+ *******************************************************************************/
+ public ReportColumn withName(String name)
+ {
+ this.name = name;
+ return (this);
+ }
+
+
+
+ /*******************************************************************************
+ ** Getter for isVisible
+ *******************************************************************************/
+ public Boolean getIsVisible()
+ {
+ return (this.isVisible);
+ }
+
+
+
+ /*******************************************************************************
+ ** Setter for isVisible
+ *******************************************************************************/
+ public void setIsVisible(Boolean isVisible)
+ {
+ this.isVisible = isVisible;
+ }
+
+
+
+ /*******************************************************************************
+ ** Fluent setter for isVisible
+ *******************************************************************************/
+ public ReportColumn withIsVisible(Boolean isVisible)
+ {
+ this.isVisible = isVisible;
+ return (this);
+ }
+
+}
diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/savedreports/ReportColumns.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/savedreports/ReportColumns.java
new file mode 100644
index 00000000..3d05c9d9
--- /dev/null
+++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/savedreports/ReportColumns.java
@@ -0,0 +1,95 @@
+/*
+ * QQQ - Low-code Application Framework for Engineers.
+ * Copyright (C) 2021-2024. Kingsrook, LLC
+ * 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
+ * contact@kingsrook.com
+ * https://github.com/Kingsrook/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package com.kingsrook.qqq.backend.core.model.savedreports;
+
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+
+/*******************************************************************************
+ ** type of object expected to be in the SavedReport columnsJSON field
+ *******************************************************************************/
+public class ReportColumns implements Serializable
+{
+ private List columns;
+
+
+ /*******************************************************************************
+ ** Getter for columns
+ *******************************************************************************/
+ public List getColumns()
+ {
+ return (this.columns);
+ }
+
+
+
+ /*******************************************************************************
+ ** Setter for columns
+ *******************************************************************************/
+ public void setColumns(List columns)
+ {
+ this.columns = columns;
+ }
+
+
+
+ /*******************************************************************************
+ ** Fluent setter for columns
+ *******************************************************************************/
+ public ReportColumns withColumns(List columns)
+ {
+ this.columns = columns;
+ return (this);
+ }
+
+
+ /*******************************************************************************
+ ** Fluent setter to add 1 column
+ *******************************************************************************/
+ public ReportColumns withColumn(ReportColumn column)
+ {
+ if(this.columns == null)
+ {
+ this.columns = new ArrayList<>();
+ }
+ this.columns.add(column);
+ return (this);
+ }
+
+
+ /*******************************************************************************
+ ** Fluent setter to add 1 column w/ just a name
+ *******************************************************************************/
+ public ReportColumns withColumn(String name)
+ {
+ if(this.columns == null)
+ {
+ this.columns = new ArrayList<>();
+ }
+ this.columns.add(new ReportColumn().withName(name));
+ return (this);
+ }
+
+}
diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/processes/implementations/savedreports/SavedReportToReportMetaDataAdapter.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/processes/implementations/savedreports/SavedReportToReportMetaDataAdapter.java
index 431349ef..751f20d7 100644
--- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/processes/implementations/savedreports/SavedReportToReportMetaDataAdapter.java
+++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/processes/implementations/savedreports/SavedReportToReportMetaDataAdapter.java
@@ -25,9 +25,8 @@ package com.kingsrook.qqq.backend.core.processes.implementations.savedreports;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
-import java.util.Map;
import java.util.Set;
-import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.DeserializationFeature;
import com.kingsrook.qqq.backend.core.context.QContext;
import com.kingsrook.qqq.backend.core.exceptions.QException;
import com.kingsrook.qqq.backend.core.logging.QLogger;
@@ -43,12 +42,15 @@ 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.tables.ExposedJoin;
import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData;
+import com.kingsrook.qqq.backend.core.model.savedreports.ReportColumn;
+import com.kingsrook.qqq.backend.core.model.savedreports.ReportColumns;
import com.kingsrook.qqq.backend.core.model.savedreports.SavedReport;
import com.kingsrook.qqq.backend.core.utils.CollectionUtils;
import com.kingsrook.qqq.backend.core.utils.JsonUtils;
import com.kingsrook.qqq.backend.core.utils.StringUtils;
import com.kingsrook.qqq.backend.core.utils.ValueUtils;
import com.kingsrook.qqq.backend.core.utils.collections.ListBuilder;
+import org.apache.commons.lang.BooleanUtils;
import static com.kingsrook.qqq.backend.core.logging.LogUtils.logPair;
@@ -73,16 +75,15 @@ public class SavedReportToReportMetaDataAdapter
QReportMetaData reportMetaData = new QReportMetaData();
reportMetaData.setLabel(savedReport.getLabel());
- ////////////////////////////
- // set up the data-source //
- ////////////////////////////
+ /////////////////////////////////////////////////////
+ // set up the data-source - e.g., table and filter //
+ /////////////////////////////////////////////////////
QReportDataSource dataSource = new QReportDataSource();
reportMetaData.setDataSources(List.of(dataSource));
dataSource.setName("main");
QTableMetaData table = qInstance.getTable(savedReport.getTableName());
dataSource.setSourceTable(savedReport.getTableName());
-
dataSource.setQueryFilter(JsonUtils.toObject(savedReport.getQueryFilterJson(), QQueryFilter.class));
//////////////////////////
@@ -96,69 +97,41 @@ public class SavedReportToReportMetaDataAdapter
view.setLabel(savedReport.getLabel()); // todo eh?
view.setIncludeHeaderRow(true);
- // don't need:
- // view.setOrderByFields(); - only used for summary reports
- // view.setTitleFormat(); - not using at this time
- // view.setTitleFields(); - not using at this time
- // view.setRecordTransformStep();
- // view.setViewCustomizer();
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////
- // columns in the saved-report look like a JSON object, w/ a key "columns", which is an array of objects //
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////
- Set neededJoinTables = new HashSet<>();
+ ////////////////////////////////////////////////////////////////////////////////////////////////
+ // columns in the saved-report should look like a serialized version of ReportColumns object //
+ // map them to a list of QReportField objects //
+ // also keep track of what joinTables we find that we need to select //
+ ////////////////////////////////////////////////////////////////////////////////////////////////
+ ReportColumns columnsObject = JsonUtils.toObject(savedReport.getColumnsJson(), ReportColumns.class, om -> om.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES));
List reportColumns = new ArrayList<>();
view.setColumns(reportColumns);
- Map columnsObject = JsonUtils.toObject(savedReport.getColumnsJson(), new TypeReference<>() {});
- List