From 9884f92489f089b970236ffd49e0f72953d37a12 Mon Sep 17 00:00:00 2001 From: Scott McGowan Date: Fri, 20 Feb 2026 15:18:20 +0000 Subject: [PATCH 1/8] feat: add support for update report definition endpoints --- CHANGELOG.md | 2 + .../com/smartsheet/api/ReportResources.java | 24 +++ .../api/internal/ReportResourcesImpl.java | 34 +++++ .../models/ReportAggregationCriterion.java | 97 ++++++++++++ .../api/models/ReportColumnIdentifier.java | 140 ++++++++++++++++++ .../api/models/ReportDefinition.java | 124 ++++++++++++++++ .../api/models/ReportFilterCriterion.java | 99 +++++++++++++ .../api/models/ReportFilterExpression.java | 105 +++++++++++++ .../api/models/ReportGroupingCriterion.java | 121 +++++++++++++++ .../api/models/ReportSortingCriterion.java | 97 ++++++++++++ .../models/enums/ReportAggregationType.java | 30 ++++ .../enums/ReportFilterExpressionOperator.java | 25 ++++ .../models/enums/ReportFilterOperator.java | 59 ++++++++ .../models/enums/ReportSystemColumnType.java | 54 +++++++ .../reports/TestUpdateReportDefinition.java | 138 +++++++++++++++++ .../sdktest/users/CommonTestConstants.java | 3 + 16 files changed, 1152 insertions(+) create mode 100644 src/main/java/com/smartsheet/api/models/ReportAggregationCriterion.java create mode 100644 src/main/java/com/smartsheet/api/models/ReportColumnIdentifier.java create mode 100644 src/main/java/com/smartsheet/api/models/ReportDefinition.java create mode 100644 src/main/java/com/smartsheet/api/models/ReportFilterCriterion.java create mode 100644 src/main/java/com/smartsheet/api/models/ReportFilterExpression.java create mode 100644 src/main/java/com/smartsheet/api/models/ReportGroupingCriterion.java create mode 100644 src/main/java/com/smartsheet/api/models/ReportSortingCriterion.java create mode 100644 src/main/java/com/smartsheet/api/models/enums/ReportAggregationType.java create mode 100644 src/main/java/com/smartsheet/api/models/enums/ReportFilterExpressionOperator.java create mode 100644 src/main/java/com/smartsheet/api/models/enums/ReportFilterOperator.java create mode 100644 src/main/java/com/smartsheet/api/models/enums/ReportSystemColumnType.java create mode 100644 src/test/java/com/smartsheet/api/sdktest/reports/TestUpdateReportDefinition.java diff --git a/CHANGELOG.md b/CHANGELOG.md index cf40d3410..45064a264 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). ## [x.x.x] - unreleased +### Added +- Added support for PATCH /reports/{reportId}/definition endpoint, Update Report Definition ## [3.10.0] - 2025-12-04 ### Added diff --git a/src/main/java/com/smartsheet/api/ReportResources.java b/src/main/java/com/smartsheet/api/ReportResources.java index 973ed7039..b5eafadb2 100644 --- a/src/main/java/com/smartsheet/api/ReportResources.java +++ b/src/main/java/com/smartsheet/api/ReportResources.java @@ -19,7 +19,9 @@ import com.smartsheet.api.models.PagedResult; import com.smartsheet.api.models.PaginationParameters; import com.smartsheet.api.models.Report; +import com.smartsheet.api.models.ReportDefinition; import com.smartsheet.api.models.ReportPublish; +import com.smartsheet.api.models.Result; import com.smartsheet.api.models.SheetEmail; import com.smartsheet.api.models.enums.ReportInclusion; @@ -212,6 +214,28 @@ Report getReport( */ ReportPublish updatePublishStatus(long id, ReportPublish reportPublish) throws SmartsheetException; + /** + *

Updates a report's definition (filters, grouping, aggregation, and sorting).

+ * + *

It mirrors to the following Smartsheet REST API method: PATCH /reports/{id}/definition

+ * + *

This endpoint supports partial updates only on root level properties of the report definition, + * such as {@code filters}, {@code groupingCriteria}, and {@code aggregationCriteria}. For example, + * you can update the report's filters without affecting its grouping criteria. However, nested + * properties within these objects, such as a specific filter or grouping criterion, cannot be + * updated individually and require a full replacement of the respective section.

+ * + * @param id the ID of the report + * @param definition the ReportDefinition object containing the updated definition + * @throws IllegalArgumentException if any argument is null + * @throws InvalidRequestException if there is any problem with the REST API request + * @throws AuthorizationException if there is any problem with the REST API authorization (access token) + * @throws ResourceNotFoundException if the resource cannot be found + * @throws ServiceUnavailableException if the REST API service is not available (possibly due to rate limiting) + * @throws SmartsheetException if there is any other error during the operation + */ + void updateReportDefinition(long id, ReportDefinition definition) throws SmartsheetException; + /** *

Creates an object of ShareResources.

* diff --git a/src/main/java/com/smartsheet/api/internal/ReportResourcesImpl.java b/src/main/java/com/smartsheet/api/internal/ReportResourcesImpl.java index 1951411c1..aed4a39a4 100644 --- a/src/main/java/com/smartsheet/api/internal/ReportResourcesImpl.java +++ b/src/main/java/com/smartsheet/api/internal/ReportResourcesImpl.java @@ -27,7 +27,9 @@ import com.smartsheet.api.models.PagedResult; import com.smartsheet.api.models.PaginationParameters; import com.smartsheet.api.models.Report; +import com.smartsheet.api.models.ReportDefinition; import com.smartsheet.api.models.ReportPublish; +import com.smartsheet.api.models.Result; import com.smartsheet.api.models.SheetEmail; import com.smartsheet.api.models.enums.ReportInclusion; @@ -305,6 +307,38 @@ public ReportPublish updatePublishStatus(long id, ReportPublish reportPublish) t return this.updateResource(REPORTS_PATH + id + "/publish", ReportPublish.class, reportPublish); } + /** + * Updates a report's definition (filters, grouping, aggregation, and sorting). + *

+ * It mirrors to the following Smartsheet REST API method: PATCH /reports/{id}/definition + *

+ * This endpoint supports partial updates only on root level properties of the report definition, + * such as filters, groupingCriteria, and aggregationCriteria. For example, you can update the + * report's filters without affecting its grouping criteria. However, nested properties within + * these objects, such as a specific filter or grouping criterion, cannot be updated individually + * and require a full replacement of the respective section. + *

+ * Exceptions: + * - InvalidRequestException : if there is any problem with the REST API request + * - AuthorizationException : if there is any problem with the REST API authorization(access token) + * - ResourceNotFoundException : if the resource can not be found + * - ServiceUnavailableException : if the REST API service is not available (possibly due to rate limiting) + * - SmartsheetRestException : if there is any other REST API related error occurred during the operation + * - SmartsheetException : if there is any other error occurred during the operation + * + * @param id the ID of the report + * @param definition the ReportDefinition object containing the updated definition + * @throws IllegalArgumentException if any argument is null + * @throws InvalidRequestException if there is any problem with the REST API request + * @throws AuthorizationException if there is any problem with the REST API authorization (access token) + * @throws ResourceNotFoundException if the resource cannot be found + * @throws ServiceUnavailableException if the REST API service is not available (possibly due to rate limiting) + * @throws SmartsheetException if there is any other error during the operation + */ + public void updateReportDefinition(long id, ReportDefinition definition) throws SmartsheetException { + this.patchResource(REPORTS_PATH + id + "/definition", Result.class, definition); + } + /** *

Creates an object of ShareResources.

* diff --git a/src/main/java/com/smartsheet/api/models/ReportAggregationCriterion.java b/src/main/java/com/smartsheet/api/models/ReportAggregationCriterion.java new file mode 100644 index 000000000..45011e8c8 --- /dev/null +++ b/src/main/java/com/smartsheet/api/models/ReportAggregationCriterion.java @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2025 Smartsheet + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.smartsheet.api.models; + +import com.smartsheet.api.models.enums.ReportAggregationType; + +/** + * Represents an aggregation criterion for a report. + */ +public class ReportAggregationCriterion { + + /** + * The column to aggregate. + */ + private ReportColumnIdentifier column; + + /** + * Type of aggregation. + */ + private ReportAggregationType aggregationType; + + /** + * Indicates whether the group is expanded in the UI (default: true). + */ + private Boolean isExpanded; + + /** + * Gets the column to aggregate. + * + * @return the column + */ + public ReportColumnIdentifier getColumn() { + return column; + } + + /** + * Sets the column to aggregate. + * + * @param column the column + */ + public ReportAggregationCriterion setColumn(ReportColumnIdentifier column) { + this.column = column; + return this; + } + + /** + * Gets the type of aggregation. + * + * @return the aggregation type + */ + public ReportAggregationType getAggregationType() { + return aggregationType; + } + + /** + * Sets the type of aggregation. + * + * @param aggregationType the aggregation type + */ + public ReportAggregationCriterion setAggregationType(ReportAggregationType aggregationType) { + this.aggregationType = aggregationType; + return this; + } + + /** + * Gets whether the group is expanded in the UI. + * + * @return true if expanded, false otherwise + */ + public Boolean getIsExpanded() { + return isExpanded; + } + + /** + * Sets whether the group is expanded in the UI. + * + * @param isExpanded true if expanded, false otherwise + */ + public ReportAggregationCriterion setIsExpanded(Boolean isExpanded) { + this.isExpanded = isExpanded; + return this; + } +} diff --git a/src/main/java/com/smartsheet/api/models/ReportColumnIdentifier.java b/src/main/java/com/smartsheet/api/models/ReportColumnIdentifier.java new file mode 100644 index 000000000..7cda2b623 --- /dev/null +++ b/src/main/java/com/smartsheet/api/models/ReportColumnIdentifier.java @@ -0,0 +1,140 @@ +/* + * Copyright (C) 2025 Smartsheet + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.smartsheet.api.models; + +import com.smartsheet.api.models.enums.ColumnType; +import com.smartsheet.api.models.enums.ReportSystemColumnType; + +/** + * Object used to match a sheet column for a report. + *

+ * One of [{@code type}, {@code systemColumnType}] or [{@code primary=true}] is required. + *

+ * {@code systemColumnType} should be specified if you want to match a system column. Use {@code primary=true} + * to match primary columns. When matching primary columns, {@code title} can be used to customize the primary + * column name in the rendered report. + *

+ * Note: Columns in the report are matched by the combination of {@code title} and {@code type} + * (and {@code systemColumnType} if specified). + *

+ * Note: {@code symbol} is not used for matching and as a result {@code CHECKBOX} or {@code PICKLIST} + * columns with different symbols (from different sheets) can be combined into the same column in the report. + * You cannot combine {@code CHECKBOX} with {@code PICKLIST} into the same column in the report because they + * are different types. + */ +public class ReportColumnIdentifier { + + /** + * Column title to be matched from the source sheets. + *

+ * Note: If {@code primary} is true, then this property can be used to customize the primary column title. + */ + private String title; + + /** + * Column type to be matched from the source sheets. + */ + private ColumnType type; + + /** + * System column type to be matched from the source sheets. + */ + private ReportSystemColumnType systemColumnType; + + /** + * Indicates if the matched column is primary (default: false). + */ + private Boolean primary; + + /** + * Gets the column title. + * + * @return the title + */ + public String getTitle() { + return title; + } + + /** + * Sets the column title. + *

+ * If primary is true, this can be used to customize the primary column title in the report. + * + * @param title the title + */ + public ReportColumnIdentifier setTitle(String title) { + this.title = title; + return this; + } + + /** + * Gets the column type. + * + * @return the type + */ + public ColumnType getType() { + return type; + } + + /** + * Sets the column type. + * + * @param type the type + */ + public ReportColumnIdentifier setType(ColumnType type) { + this.type = type; + return this; + } + + /** + * Gets the system column type. + * + * @return the system column type + */ + public ReportSystemColumnType getSystemColumnType() { + return systemColumnType; + } + + /** + * Sets the system column type. + * + * @param systemColumnType the system column type + */ + public ReportColumnIdentifier setSystemColumnType(ReportSystemColumnType systemColumnType) { + this.systemColumnType = systemColumnType; + return this; + } + + /** + * Gets whether this identifies the primary column. + * + * @return true if this is the primary column, false otherwise + */ + public Boolean getPrimary() { + return primary; + } + + /** + * Sets whether this identifies the primary column. + * + * @param primary true if this is the primary column, false otherwise + */ + public ReportColumnIdentifier setPrimary(Boolean primary) { + this.primary = primary; + return this; + } +} diff --git a/src/main/java/com/smartsheet/api/models/ReportDefinition.java b/src/main/java/com/smartsheet/api/models/ReportDefinition.java new file mode 100644 index 000000000..c6cd8e134 --- /dev/null +++ b/src/main/java/com/smartsheet/api/models/ReportDefinition.java @@ -0,0 +1,124 @@ +/* + * Copyright (C) 2025 Smartsheet + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.smartsheet.api.models; + +import java.util.List; + +/** + * The report definition contains filters, grouping and sorting properties of the report. + *

+ * Note: When groupingCriteria is defined the primary column of the report will move to the + * index 0 when it is first rendered by the app. + */ +public class ReportDefinition { + + /** + * Represents the filter expression for the report. + */ + private ReportFilterExpression filters; + + /** + * Represents the list of report grouping criteria. + */ + private List groupingCriteria; + + /** + * Represents the list of report aggregation criteria. + */ + private List aggregationCriteria; + + /** + * Represents the list of report sorting criteria. + */ + private List sortingCriteria; + + /** + * Gets the filter expression. + * + * @return the filters + */ + public ReportFilterExpression getFilters() { + return filters; + } + + /** + * Sets the filter expression. + * + * @param filters the filter expression + */ + public ReportDefinition setFilters(ReportFilterExpression filters) { + this.filters = filters; + return this; + } + + /** + * Gets the list of report grouping criteria. + * + * @return the grouping criteria + */ + public List getGroupingCriteria() { + return groupingCriteria; + } + + /** + * Sets the list of report grouping criteria. + * + * @param groupingCriteria the grouping criteria + */ + public ReportDefinition setGroupingCriteria(List groupingCriteria) { + this.groupingCriteria = groupingCriteria; + return this; + } + + /** + * Gets the list of report aggregation criteria. + * + * @return the aggregation criteria + */ + public List getAggregationCriteria() { + return aggregationCriteria; + } + + /** + * Sets the list of report aggregation criteria. + * + * @param aggregationCriteria the aggregation criteria + */ + public ReportDefinition setAggregationCriteria(List aggregationCriteria) { + this.aggregationCriteria = aggregationCriteria; + return this; + } + + /** + * Gets the list of report sorting criteria. + * + * @return the sorting criteria + */ + public List getSortingCriteria() { + return sortingCriteria; + } + + /** + * Sets the list of report sorting criteria. + * + * @param sortingCriteria the sorting criteria + */ + public ReportDefinition setSortingCriteria(List sortingCriteria) { + this.sortingCriteria = sortingCriteria; + return this; + } +} diff --git a/src/main/java/com/smartsheet/api/models/ReportFilterCriterion.java b/src/main/java/com/smartsheet/api/models/ReportFilterCriterion.java new file mode 100644 index 000000000..864b73d90 --- /dev/null +++ b/src/main/java/com/smartsheet/api/models/ReportFilterCriterion.java @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2025 Smartsheet + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.smartsheet.api.models; + +import com.smartsheet.api.models.enums.ReportFilterOperator; + +import java.util.List; + +/** + * Represents a single filter criterion. + */ +public class ReportFilterCriterion { + + /** + * The column to filter on. + */ + private ReportColumnIdentifier column; + + /** + * The condition operator. + */ + private ReportFilterOperator operator; + + /** + * List of filter values. + */ + private List values; + + /** + * Gets the column identifier. + * + * @return the column + */ + public ReportColumnIdentifier getColumn() { + return column; + } + + /** + * Sets the column identifier. + * + * @param column the column + */ + public ReportFilterCriterion setColumn(ReportColumnIdentifier column) { + this.column = column; + return this; + } + + /** + * Gets the condition operator. + * + * @return the operator + */ + public ReportFilterOperator getOperator() { + return operator; + } + + /** + * Sets the condition operator. + * + * @param operator the operator + */ + public ReportFilterCriterion setOperator(ReportFilterOperator operator) { + this.operator = operator; + return this; + } + + /** + * Gets the filter values. + * + * @return the values + */ + public List getValues() { + return values; + } + + /** + * Sets the filter values. + * + * @param values the values + */ + public ReportFilterCriterion setValues(List values) { + this.values = values; + return this; + } +} diff --git a/src/main/java/com/smartsheet/api/models/ReportFilterExpression.java b/src/main/java/com/smartsheet/api/models/ReportFilterExpression.java new file mode 100644 index 000000000..42056f775 --- /dev/null +++ b/src/main/java/com/smartsheet/api/models/ReportFilterExpression.java @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2025 Smartsheet + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.smartsheet.api.models; + +import com.smartsheet.api.models.enums.ReportFilterExpressionOperator; + +import java.util.List; + +/** + * Report filter expression. It is a recursive object that allows at most 3 levels. + *

+ * At least one of {@code criteria} or {@code nestedCriteria} has to be provided in addition to {@code operator}. + *

+ * Example: A filter that matches rows where (Price > 11 AND Primary CONTAINS "PROJ-1") OR (Quantity < 12 AND "Sold Out" IS_CHECKED) + */ +public class ReportFilterExpression { + + /** + * The boolean operator that will be applied to the list of criteria and nestedCriteria. + */ + private ReportFilterExpressionOperator operator; + + /** + * A recursive list of report filter expressions. Each item will be joined to the filter + * expression with the AND/OR operator defined on this level. + */ + private List nestedCriteria; + + /** + * Criteria objects specifying custom criteria against which to match cell values. Each item + * will be joined to the filter expression with the AND/OR operator defined on this level. + */ + private List criteria; + + /** + * Gets the boolean operator. + * + * @return the operator + */ + public ReportFilterExpressionOperator getOperator() { + return operator; + } + + /** + * Sets the boolean operator. + * + * @param operator the operator + */ + public ReportFilterExpression setOperator(ReportFilterExpressionOperator operator) { + this.operator = operator; + return this; + } + + /** + * Gets the nested criteria list. + * + * @return the nested criteria + */ + public List getNestedCriteria() { + return nestedCriteria; + } + + /** + * Sets the nested criteria list. + * + * @param nestedCriteria the nested criteria + */ + public ReportFilterExpression setNestedCriteria(List nestedCriteria) { + this.nestedCriteria = nestedCriteria; + return this; + } + + /** + * Gets the criteria list. + * + * @return the criteria + */ + public List getCriteria() { + return criteria; + } + + /** + * Sets the criteria list. + * + * @param criteria the criteria + */ + public ReportFilterExpression setCriteria(List criteria) { + this.criteria = criteria; + return this; + } +} diff --git a/src/main/java/com/smartsheet/api/models/ReportGroupingCriterion.java b/src/main/java/com/smartsheet/api/models/ReportGroupingCriterion.java new file mode 100644 index 000000000..229b798e6 --- /dev/null +++ b/src/main/java/com/smartsheet/api/models/ReportGroupingCriterion.java @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2025 Smartsheet + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.smartsheet.api.models; + +import com.smartsheet.api.models.enums.SortDirection; + +/** + * Represents a grouping criterion for a report. + */ +public class ReportGroupingCriterion { + + /** + * Grouping criteria id (read-only). + */ + private String id; + + /** + * The column to group by. + */ + private ReportColumnIdentifier column; + + /** + * Sorting direction within the group. + */ + private SortDirection sortingDirection; + + /** + * Indicates whether the group is expanded in the UI (default: true). + */ + private Boolean isExpanded; + + /** + * Gets the grouping criteria id. + * + * @return the id + */ + public String getId() { + return id; + } + + /** + * Sets the grouping criteria id. + * + * @param id the grouping criteria id + */ + public ReportGroupingCriterion setId(String id) { + this.id = id; + return this; + } + + /** + * Gets the column to group by. + * + * @return the column + */ + public ReportColumnIdentifier getColumn() { + return column; + } + + /** + * Sets the column to group by. + * + * @param column the column + */ + public ReportGroupingCriterion setColumn(ReportColumnIdentifier column) { + this.column = column; + return this; + } + + /** + * Gets the sorting direction within the group. + * + * @return the sorting direction + */ + public SortDirection getSortingDirection() { + return sortingDirection; + } + + /** + * Sets the sorting direction within the group. + * + * @param sortingDirection the sorting direction + */ + public ReportGroupingCriterion setSortingDirection(SortDirection sortingDirection) { + this.sortingDirection = sortingDirection; + return this; + } + + /** + * Gets whether the group is expanded in the UI. + * + * @return true if expanded, false otherwise + */ + public Boolean getIsExpanded() { + return isExpanded; + } + + /** + * Sets whether the group is expanded in the UI. + * + * @param isExpanded true if expanded, false otherwise + */ + public ReportGroupingCriterion setIsExpanded(Boolean isExpanded) { + this.isExpanded = isExpanded; + return this; + } +} diff --git a/src/main/java/com/smartsheet/api/models/ReportSortingCriterion.java b/src/main/java/com/smartsheet/api/models/ReportSortingCriterion.java new file mode 100644 index 000000000..39caebb90 --- /dev/null +++ b/src/main/java/com/smartsheet/api/models/ReportSortingCriterion.java @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2025 Smartsheet + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.smartsheet.api.models; + +import com.smartsheet.api.models.enums.SortDirection; + +/** + * Represents a sorting criterion for a report. + */ +public class ReportSortingCriterion { + + /** + * The column to sort by. + */ + private ReportColumnIdentifier column; + + /** + * Sorting direction. + */ + private SortDirection sortingDirection; + + /** + * Force null values to the bottom of the sorted list (default: true). + */ + private Boolean forceNullsToBottom; + + /** + * Gets the column to sort by. + * + * @return the column + */ + public ReportColumnIdentifier getColumn() { + return column; + } + + /** + * Sets the column to sort by. + * + * @param column the column + */ + public ReportSortingCriterion setColumn(ReportColumnIdentifier column) { + this.column = column; + return this; + } + + /** + * Gets the sorting direction. + * + * @return the sorting direction + */ + public SortDirection getSortingDirection() { + return sortingDirection; + } + + /** + * Sets the sorting direction. + * + * @param sortingDirection the sorting direction + */ + public ReportSortingCriterion setSortingDirection(SortDirection sortingDirection) { + this.sortingDirection = sortingDirection; + return this; + } + + /** + * Gets whether to force null values to the bottom. + * + * @return true if nulls forced to bottom, false otherwise + */ + public Boolean getForceNullsToBottom() { + return forceNullsToBottom; + } + + /** + * Sets whether to force null values to the bottom. + * + * @param forceNullsToBottom true to force nulls to bottom, false otherwise + */ + public ReportSortingCriterion setForceNullsToBottom(Boolean forceNullsToBottom) { + this.forceNullsToBottom = forceNullsToBottom; + return this; + } +} diff --git a/src/main/java/com/smartsheet/api/models/enums/ReportAggregationType.java b/src/main/java/com/smartsheet/api/models/enums/ReportAggregationType.java new file mode 100644 index 000000000..61c256145 --- /dev/null +++ b/src/main/java/com/smartsheet/api/models/enums/ReportAggregationType.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2025 Smartsheet + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.smartsheet.api.models.enums; + +/** + * Represents the type of aggregation that can be applied to report data. + */ +public enum ReportAggregationType { + SUM, + AVG, + MIN, + MAX, + COUNT, + FIRST, + LAST +} \ No newline at end of file diff --git a/src/main/java/com/smartsheet/api/models/enums/ReportFilterExpressionOperator.java b/src/main/java/com/smartsheet/api/models/enums/ReportFilterExpressionOperator.java new file mode 100644 index 000000000..776811b92 --- /dev/null +++ b/src/main/java/com/smartsheet/api/models/enums/ReportFilterExpressionOperator.java @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2025 Smartsheet + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.smartsheet.api.models.enums; + +/** + * Represents the boolean operator for combining filter criteria. + */ +public enum ReportFilterExpressionOperator { + AND, + OR +} diff --git a/src/main/java/com/smartsheet/api/models/enums/ReportFilterOperator.java b/src/main/java/com/smartsheet/api/models/enums/ReportFilterOperator.java new file mode 100644 index 000000000..a5fc80da9 --- /dev/null +++ b/src/main/java/com/smartsheet/api/models/enums/ReportFilterOperator.java @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2025 Smartsheet + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.smartsheet.api.models.enums; + +/** + * Represents the condition operator for report filter criteria. + */ +public enum ReportFilterOperator { + EQUAL, + NOT_EQUAL, + GREATER_THAN, + LESS_THAN, + CONTAINS, + BETWEEN, + TODAY, + PAST, + FUTURE, + LAST_N_DAYS, + NEXT_N_DAYS, + IS_BLANK, + IS_NOT_BLANK, + IS_NUMBER, + IS_NOT_NUMBER, + IS_DATE, + IS_NOT_DATE, + IS_CHECKED, + IS_UNCHECKED, + IS_ONE_OF, + IS_NOT_ONE_OF, + LESS_THAN_OR_EQUAL, + GREATER_THAN_OR_EQUAL, + DOES_NOT_CONTAIN, + NOT_BETWEEN, + NOT_TODAY, + NOT_PAST, + NOT_FUTURE, + NOT_LAST_N_DAYS, + NOT_NEXT_N_DAYS, + HAS_ANY_OF, + HAS_NONE_OF, + HAS_ALL_OF, + NOT_ALL_OF, + MULTI_IS_EQUAL, + MULTI_IS_NOT_EQUAL +} diff --git a/src/main/java/com/smartsheet/api/models/enums/ReportSystemColumnType.java b/src/main/java/com/smartsheet/api/models/enums/ReportSystemColumnType.java new file mode 100644 index 000000000..49fa3a69a --- /dev/null +++ b/src/main/java/com/smartsheet/api/models/enums/ReportSystemColumnType.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2025 Smartsheet + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.smartsheet.api.models.enums; + +/** + * Represents the system column types. + * + * @see Column Types Help + */ +public enum ReportSystemColumnType { + /** + * Represents the AUTO_NUMBER system column type. + */ + AUTO_NUMBER, + + /** + * Represents the MODIFIED_DATE system column type. + */ + MODIFIED_DATE, + + /** + * Represents the MODIFIED_BY system column type. + */ + MODIFIED_BY, + + /** + * Represents the CREATED_DATE system column type. + */ + CREATED_DATE, + + /** + * Represents the CREATED_BY system column type. + */ + CREATED_BY, + + /** + * Represents the SHEET_NAME system column type (available for reports only). + */ + SHEET_NAME, +} diff --git a/src/test/java/com/smartsheet/api/sdktest/reports/TestUpdateReportDefinition.java b/src/test/java/com/smartsheet/api/sdktest/reports/TestUpdateReportDefinition.java new file mode 100644 index 000000000..6545cc847 --- /dev/null +++ b/src/test/java/com/smartsheet/api/sdktest/reports/TestUpdateReportDefinition.java @@ -0,0 +1,138 @@ +package com.smartsheet.api.sdktest.reports; + +import com.github.tomakehurst.wiremock.http.RequestMethod; +import com.github.tomakehurst.wiremock.verification.LoggedRequest; +import com.smartsheet.api.Smartsheet; +import com.smartsheet.api.SmartsheetException; +import com.smartsheet.api.WiremockClient; +import com.smartsheet.api.WiremockClientWrapper; +import com.smartsheet.api.internal.json.JSONSerializerException; +import com.smartsheet.api.internal.json.JacksonJsonSerializer; +import com.smartsheet.api.internal.json.JsonSerializer; +import com.smartsheet.api.models.ReportColumnIdentifier; +import com.smartsheet.api.models.ReportDefinition; +import com.smartsheet.api.models.ReportFilterCriterion; +import com.smartsheet.api.models.ReportFilterExpression; +import com.smartsheet.api.models.enums.ColumnType; +import com.smartsheet.api.models.enums.ReportFilterExpressionOperator; +import com.smartsheet.api.models.enums.ReportFilterOperator; +import com.smartsheet.api.sdktest.users.Utils; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.net.URI; +import java.util.ArrayList; +import java.util.UUID; + +import static com.smartsheet.api.sdktest.users.CommonTestConstants.TEST_REPORT_ID; +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; + +public class TestUpdateReportDefinition { + + private ReportDefinition testReportDefinition; + private String testReportDefinitionJson; + + @BeforeEach + void setUp() throws JSONSerializerException { + testReportDefinition = new ReportDefinition(); + testReportDefinition.setFilters( + new ReportFilterExpression() + .setOperator(ReportFilterExpressionOperator.AND) + .setCriteria(new ArrayList<>() {{ + add( + new ReportFilterCriterion() + .setOperator(ReportFilterOperator.EQUAL) + .setColumn( + new ReportColumnIdentifier() + .setPrimary(true) + .setTitle("Primary") + .setType(ColumnType.TEXT_NUMBER) + ) + + ); + }}) + ); + + testReportDefinitionJson = "{\"filters\":" + +"{\"operator\":\"AND\"," + +"\"criteria\":[{\"column\":" + +"{\"title\":\"Primary\",\"type\":\"TEXT_NUMBER\",\"primary\":true}," + +"\"operator\":\"EQUAL\"}]}}"; + } + + @Test + void testUpdateReportDefinitionGeneratedUrlIsCorrect() throws SmartsheetException { + String requestId = UUID.randomUUID().toString(); + WiremockClientWrapper wrapper = Utils.createWiremockSmartsheetClient( + "/reports/update-report-definition/all-response-body-properties", + requestId + ); + Smartsheet smartsheet = wrapper.getSmartsheet(); + WiremockClient wiremockClient = wrapper.getWiremockClient(); + + smartsheet.reportResources().updateReportDefinition(TEST_REPORT_ID, testReportDefinition); + LoggedRequest wiremockRequest = wiremockClient.findWiremockRequest(requestId); + String path = URI.create(wiremockRequest.getUrl()).getPath(); + + assertThat(path).isEqualTo("/2.0/reports/" + TEST_REPORT_ID + "/definition"); + assertThat(wiremockRequest.getMethod()).isEqualTo(RequestMethod.PATCH); + + String requestBody = wiremockRequest.getBodyAsString(); + assertThat(requestBody).isEqualTo(testReportDefinitionJson); + } + + @Test + void testUpdateReportDefinitionAllResponseBodyProperties() { + String requestId = UUID.randomUUID().toString(); + WiremockClientWrapper wrapper = Utils.createWiremockSmartsheetClient( + "/reports/update-report-definition/all-response-body-properties", + requestId + ); + Smartsheet smartsheet = wrapper.getSmartsheet(); + + Assertions.assertDoesNotThrow(() -> { + smartsheet.reportResources().updateReportDefinition(TEST_REPORT_ID, testReportDefinition); + }); + } + + @Test + void testUpdateReportDefinitionInvalidArgument() { + String requestId = UUID.randomUUID().toString(); + WiremockClientWrapper wrapper = Utils.createWiremockSmartsheetClient( + "/reports/update-report-definition/all-response-body-properties", + requestId + ); + Smartsheet smartsheet = wrapper.getSmartsheet(); + + Assertions.assertThrows(IllegalArgumentException.class, () -> { + smartsheet.reportResources().updateReportDefinition(TEST_REPORT_ID, null); + }); + } + + @Test + void testUpdateReportDefinitionError500Response() { + String requestId = UUID.randomUUID().toString(); + WiremockClientWrapper wrapper = Utils.createWiremockSmartsheetClient("/errors/500-response", requestId); + Smartsheet smartsheet = wrapper.getSmartsheet(); + + SmartsheetException exception = Assertions.assertThrows(SmartsheetException.class, () -> { + smartsheet.reportResources().updateReportDefinition(TEST_REPORT_ID, testReportDefinition); + }); + + assertThat(exception.getMessage()).isEqualTo("Internal Server Error"); + } + + @Test + void testUpdateReportDefinitionError400Response() { + String requestId = UUID.randomUUID().toString(); + WiremockClientWrapper wrapper = Utils.createWiremockSmartsheetClient("/errors/400-response", requestId); + Smartsheet smartsheet = wrapper.getSmartsheet(); + + SmartsheetException exception = Assertions.assertThrows(SmartsheetException.class, () -> { + smartsheet.reportResources().updateReportDefinition(TEST_REPORT_ID, testReportDefinition); + }); + + assertThat(exception.getMessage()).isEqualTo("Malformed Request"); + } +} diff --git a/src/test/java/com/smartsheet/api/sdktest/users/CommonTestConstants.java b/src/test/java/com/smartsheet/api/sdktest/users/CommonTestConstants.java index 400d31b63..c889cb9b6 100644 --- a/src/test/java/com/smartsheet/api/sdktest/users/CommonTestConstants.java +++ b/src/test/java/com/smartsheet/api/sdktest/users/CommonTestConstants.java @@ -19,4 +19,7 @@ public class CommonTestConstants { public static final long TEST_USER_ID = 1234567890L; public static final long TEST_PLAN_ID = 1234567890123456L; + public static final long TEST_SHEET_ID = 9876543210L; + public static final long TEST_WORKSPACE_ID = 1122334455L; + public static final long TEST_REPORT_ID = 2233445566L; } From 5abfb502f13244024ebbe77fc91dd51f09a21f5d Mon Sep 17 00:00:00 2001 From: Scott McGowan Date: Fri, 20 Feb 2026 15:31:50 +0000 Subject: [PATCH 2/8] feat: add support for update report definition endpoints fix linter issues --- .../com/smartsheet/api/ReportResources.java | 1 - .../api/models/ReportFilterExpression.java | 3 +- .../models/enums/ReportAggregationType.java | 2 +- .../reports/TestUpdateReportDefinition.java | 57 ++++++++++++------- 4 files changed, 38 insertions(+), 25 deletions(-) diff --git a/src/main/java/com/smartsheet/api/ReportResources.java b/src/main/java/com/smartsheet/api/ReportResources.java index b5eafadb2..8f673ae03 100644 --- a/src/main/java/com/smartsheet/api/ReportResources.java +++ b/src/main/java/com/smartsheet/api/ReportResources.java @@ -21,7 +21,6 @@ import com.smartsheet.api.models.Report; import com.smartsheet.api.models.ReportDefinition; import com.smartsheet.api.models.ReportPublish; -import com.smartsheet.api.models.Result; import com.smartsheet.api.models.SheetEmail; import com.smartsheet.api.models.enums.ReportInclusion; diff --git a/src/main/java/com/smartsheet/api/models/ReportFilterExpression.java b/src/main/java/com/smartsheet/api/models/ReportFilterExpression.java index 42056f775..9d38673e0 100644 --- a/src/main/java/com/smartsheet/api/models/ReportFilterExpression.java +++ b/src/main/java/com/smartsheet/api/models/ReportFilterExpression.java @@ -25,7 +25,8 @@ *

* At least one of {@code criteria} or {@code nestedCriteria} has to be provided in addition to {@code operator}. *

- * Example: A filter that matches rows where (Price > 11 AND Primary CONTAINS "PROJ-1") OR (Quantity < 12 AND "Sold Out" IS_CHECKED) + * Example: A filter that matches rows where + * (Price greater than 11 AND Primary CONTAINS "PROJ-1") OR (Quantity less than 12 AND "Sold Out" IS_CHECKED) */ public class ReportFilterExpression { diff --git a/src/main/java/com/smartsheet/api/models/enums/ReportAggregationType.java b/src/main/java/com/smartsheet/api/models/enums/ReportAggregationType.java index 61c256145..7598fe639 100644 --- a/src/main/java/com/smartsheet/api/models/enums/ReportAggregationType.java +++ b/src/main/java/com/smartsheet/api/models/enums/ReportAggregationType.java @@ -27,4 +27,4 @@ public enum ReportAggregationType { COUNT, FIRST, LAST -} \ No newline at end of file +} diff --git a/src/test/java/com/smartsheet/api/sdktest/reports/TestUpdateReportDefinition.java b/src/test/java/com/smartsheet/api/sdktest/reports/TestUpdateReportDefinition.java index 6545cc847..87b0aedf3 100644 --- a/src/test/java/com/smartsheet/api/sdktest/reports/TestUpdateReportDefinition.java +++ b/src/test/java/com/smartsheet/api/sdktest/reports/TestUpdateReportDefinition.java @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2025 Smartsheet + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.smartsheet.api.sdktest.reports; import com.github.tomakehurst.wiremock.http.RequestMethod; @@ -7,8 +23,6 @@ import com.smartsheet.api.WiremockClient; import com.smartsheet.api.WiremockClientWrapper; import com.smartsheet.api.internal.json.JSONSerializerException; -import com.smartsheet.api.internal.json.JacksonJsonSerializer; -import com.smartsheet.api.internal.json.JsonSerializer; import com.smartsheet.api.models.ReportColumnIdentifier; import com.smartsheet.api.models.ReportDefinition; import com.smartsheet.api.models.ReportFilterCriterion; @@ -37,28 +51,27 @@ public class TestUpdateReportDefinition { void setUp() throws JSONSerializerException { testReportDefinition = new ReportDefinition(); testReportDefinition.setFilters( - new ReportFilterExpression() - .setOperator(ReportFilterExpressionOperator.AND) - .setCriteria(new ArrayList<>() {{ - add( - new ReportFilterCriterion() - .setOperator(ReportFilterOperator.EQUAL) - .setColumn( - new ReportColumnIdentifier() - .setPrimary(true) - .setTitle("Primary") - .setType(ColumnType.TEXT_NUMBER) - ) - - ); - }}) + new ReportFilterExpression() + .setOperator(ReportFilterExpressionOperator.AND) + .setCriteria(new ArrayList<>() {{ + add( + new ReportFilterCriterion() + .setOperator(ReportFilterOperator.EQUAL) + .setColumn( + new ReportColumnIdentifier() + .setPrimary(true) + .setTitle("Primary") + .setType(ColumnType.TEXT_NUMBER) + ) + ); + }}) ); - testReportDefinitionJson = "{\"filters\":" - +"{\"operator\":\"AND\"," - +"\"criteria\":[{\"column\":" - +"{\"title\":\"Primary\",\"type\":\"TEXT_NUMBER\",\"primary\":true}," - +"\"operator\":\"EQUAL\"}]}}"; + testReportDefinitionJson = "{\"filters\":" + + "{\"operator\":\"AND\"," + + "\"criteria\":[{\"column\":" + + "{\"title\":\"Primary\",\"type\":\"TEXT_NUMBER\",\"primary\":true}," + + "\"operator\":\"EQUAL\"}]}}"; } @Test From 200f8cb5fe9af9073d97334d1c7385137d7b5ade Mon Sep 17 00:00:00 2001 From: Scott McGowan Date: Tue, 24 Feb 2026 11:59:13 +0000 Subject: [PATCH 3/8] feat: add support for update report definition endpoint remove read-only param as not in use --- .../api/models/ReportGroupingCriterion.java | 24 ------------------- 1 file changed, 24 deletions(-) diff --git a/src/main/java/com/smartsheet/api/models/ReportGroupingCriterion.java b/src/main/java/com/smartsheet/api/models/ReportGroupingCriterion.java index 229b798e6..dcb88e48f 100644 --- a/src/main/java/com/smartsheet/api/models/ReportGroupingCriterion.java +++ b/src/main/java/com/smartsheet/api/models/ReportGroupingCriterion.java @@ -23,11 +23,6 @@ */ public class ReportGroupingCriterion { - /** - * Grouping criteria id (read-only). - */ - private String id; - /** * The column to group by. */ @@ -43,25 +38,6 @@ public class ReportGroupingCriterion { */ private Boolean isExpanded; - /** - * Gets the grouping criteria id. - * - * @return the id - */ - public String getId() { - return id; - } - - /** - * Sets the grouping criteria id. - * - * @param id the grouping criteria id - */ - public ReportGroupingCriterion setId(String id) { - this.id = id; - return this; - } - /** * Gets the column to group by. * From c3ae057251dfe46bf6018faaa5543071da1c34e6 Mon Sep 17 00:00:00 2001 From: Scott McGowan Date: Tue, 10 Mar 2026 14:10:06 +0000 Subject: [PATCH 4/8] feat: add support for add report columns remove invalid options --- .../api/models/ReportSortingCriterion.java | 24 ------------------- .../models/enums/ReportSystemColumnType.java | 4 ---- 2 files changed, 28 deletions(-) diff --git a/src/main/java/com/smartsheet/api/models/ReportSortingCriterion.java b/src/main/java/com/smartsheet/api/models/ReportSortingCriterion.java index 39caebb90..e13041be9 100644 --- a/src/main/java/com/smartsheet/api/models/ReportSortingCriterion.java +++ b/src/main/java/com/smartsheet/api/models/ReportSortingCriterion.java @@ -33,11 +33,6 @@ public class ReportSortingCriterion { */ private SortDirection sortingDirection; - /** - * Force null values to the bottom of the sorted list (default: true). - */ - private Boolean forceNullsToBottom; - /** * Gets the column to sort by. * @@ -75,23 +70,4 @@ public ReportSortingCriterion setSortingDirection(SortDirection sortingDirection this.sortingDirection = sortingDirection; return this; } - - /** - * Gets whether to force null values to the bottom. - * - * @return true if nulls forced to bottom, false otherwise - */ - public Boolean getForceNullsToBottom() { - return forceNullsToBottom; - } - - /** - * Sets whether to force null values to the bottom. - * - * @param forceNullsToBottom true to force nulls to bottom, false otherwise - */ - public ReportSortingCriterion setForceNullsToBottom(Boolean forceNullsToBottom) { - this.forceNullsToBottom = forceNullsToBottom; - return this; - } } diff --git a/src/main/java/com/smartsheet/api/models/enums/ReportSystemColumnType.java b/src/main/java/com/smartsheet/api/models/enums/ReportSystemColumnType.java index 49fa3a69a..834b3a7c6 100644 --- a/src/main/java/com/smartsheet/api/models/enums/ReportSystemColumnType.java +++ b/src/main/java/com/smartsheet/api/models/enums/ReportSystemColumnType.java @@ -22,10 +22,6 @@ * @see Column Types Help */ public enum ReportSystemColumnType { - /** - * Represents the AUTO_NUMBER system column type. - */ - AUTO_NUMBER, /** * Represents the MODIFIED_DATE system column type. From e496e0b1229ea8bccb0c6d6bf0c68e9396d9f1be Mon Sep 17 00:00:00 2001 From: Scott McGowan Date: Wed, 11 Mar 2026 16:44:31 +0000 Subject: [PATCH 5/8] feat: add support for add report columns add update filters query param support --- .../java/com/smartsheet/api/ReportResources.java | 7 +++++-- .../api/internal/ReportResourcesImpl.java | 12 ++++++++++-- .../sdktest/reports/TestUpdateReportDefinition.java | 13 ++++++++----- 3 files changed, 23 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/smartsheet/api/ReportResources.java b/src/main/java/com/smartsheet/api/ReportResources.java index 8f673ae03..e62a8f657 100644 --- a/src/main/java/com/smartsheet/api/ReportResources.java +++ b/src/main/java/com/smartsheet/api/ReportResources.java @@ -222,10 +222,13 @@ Report getReport( * such as {@code filters}, {@code groupingCriteria}, and {@code aggregationCriteria}. For example, * you can update the report's filters without affecting its grouping criteria. However, nested * properties within these objects, such as a specific filter or grouping criterion, cannot be - * updated individually and require a full replacement of the respective section.

+ * updated individually and require a full replacement of the respective section. + * In order for `filters` to be updated, `updateFilters` must be set to `true`. + *

* * @param id the ID of the report * @param definition the ReportDefinition object containing the updated definition + * @param updateFilters Whether the `filters` property should be updated. * @throws IllegalArgumentException if any argument is null * @throws InvalidRequestException if there is any problem with the REST API request * @throws AuthorizationException if there is any problem with the REST API authorization (access token) @@ -233,7 +236,7 @@ Report getReport( * @throws ServiceUnavailableException if the REST API service is not available (possibly due to rate limiting) * @throws SmartsheetException if there is any other error during the operation */ - void updateReportDefinition(long id, ReportDefinition definition) throws SmartsheetException; + void updateReportDefinition(long id, ReportDefinition definition, Boolean updateFilters) throws SmartsheetException; /** *

Creates an object of ShareResources.

diff --git a/src/main/java/com/smartsheet/api/internal/ReportResourcesImpl.java b/src/main/java/com/smartsheet/api/internal/ReportResourcesImpl.java index aed4a39a4..44c1bbce8 100644 --- a/src/main/java/com/smartsheet/api/internal/ReportResourcesImpl.java +++ b/src/main/java/com/smartsheet/api/internal/ReportResourcesImpl.java @@ -55,6 +55,7 @@ public class ReportResourcesImpl extends AbstractResources implements ReportReso */ private ShareResources shares; + private static final String QUERY_PARAM_UPDATE_FILTERS = "updateFilters"; private static final String REPORTS_PATH = "reports/"; /** @@ -317,6 +318,7 @@ public ReportPublish updatePublishStatus(long id, ReportPublish reportPublish) t * report's filters without affecting its grouping criteria. However, nested properties within * these objects, such as a specific filter or grouping criterion, cannot be updated individually * and require a full replacement of the respective section. + * In order for `filters` to be updated, `updateFilters` must be set to `true`. *

* Exceptions: * - InvalidRequestException : if there is any problem with the REST API request @@ -335,8 +337,14 @@ public ReportPublish updatePublishStatus(long id, ReportPublish reportPublish) t * @throws ServiceUnavailableException if the REST API service is not available (possibly due to rate limiting) * @throws SmartsheetException if there is any other error during the operation */ - public void updateReportDefinition(long id, ReportDefinition definition) throws SmartsheetException { - this.patchResource(REPORTS_PATH + id + "/definition", Result.class, definition); + public void updateReportDefinition(long id, ReportDefinition definition, Boolean updateFilters) throws SmartsheetException { + String path = REPORTS_PATH + id + "/definition"; + + Map queryParameters = new HashMap<>(); + queryParameters.put(QUERY_PARAM_UPDATE_FILTERS, updateFilters); + path += QueryUtil.generateUrl(null, queryParameters); + + this.patchResource(path, Result.class, definition); } /** diff --git a/src/test/java/com/smartsheet/api/sdktest/reports/TestUpdateReportDefinition.java b/src/test/java/com/smartsheet/api/sdktest/reports/TestUpdateReportDefinition.java index 87b0aedf3..76b3bf00b 100644 --- a/src/test/java/com/smartsheet/api/sdktest/reports/TestUpdateReportDefinition.java +++ b/src/test/java/com/smartsheet/api/sdktest/reports/TestUpdateReportDefinition.java @@ -84,10 +84,13 @@ void testUpdateReportDefinitionGeneratedUrlIsCorrect() throws SmartsheetExceptio Smartsheet smartsheet = wrapper.getSmartsheet(); WiremockClient wiremockClient = wrapper.getWiremockClient(); - smartsheet.reportResources().updateReportDefinition(TEST_REPORT_ID, testReportDefinition); + smartsheet.reportResources().updateReportDefinition(TEST_REPORT_ID, testReportDefinition, true); LoggedRequest wiremockRequest = wiremockClient.findWiremockRequest(requestId); String path = URI.create(wiremockRequest.getUrl()).getPath(); + String queryParams = URI.create(wiremockRequest.getUrl()).getQuery(); + assertThat(queryParams).isEqualTo("updateFilters=true"); + assertThat(path).isEqualTo("/2.0/reports/" + TEST_REPORT_ID + "/definition"); assertThat(wiremockRequest.getMethod()).isEqualTo(RequestMethod.PATCH); @@ -105,7 +108,7 @@ void testUpdateReportDefinitionAllResponseBodyProperties() { Smartsheet smartsheet = wrapper.getSmartsheet(); Assertions.assertDoesNotThrow(() -> { - smartsheet.reportResources().updateReportDefinition(TEST_REPORT_ID, testReportDefinition); + smartsheet.reportResources().updateReportDefinition(TEST_REPORT_ID, testReportDefinition, true); }); } @@ -119,7 +122,7 @@ void testUpdateReportDefinitionInvalidArgument() { Smartsheet smartsheet = wrapper.getSmartsheet(); Assertions.assertThrows(IllegalArgumentException.class, () -> { - smartsheet.reportResources().updateReportDefinition(TEST_REPORT_ID, null); + smartsheet.reportResources().updateReportDefinition(TEST_REPORT_ID, null, true); }); } @@ -130,7 +133,7 @@ void testUpdateReportDefinitionError500Response() { Smartsheet smartsheet = wrapper.getSmartsheet(); SmartsheetException exception = Assertions.assertThrows(SmartsheetException.class, () -> { - smartsheet.reportResources().updateReportDefinition(TEST_REPORT_ID, testReportDefinition); + smartsheet.reportResources().updateReportDefinition(TEST_REPORT_ID, testReportDefinition, true); }); assertThat(exception.getMessage()).isEqualTo("Internal Server Error"); @@ -143,7 +146,7 @@ void testUpdateReportDefinitionError400Response() { Smartsheet smartsheet = wrapper.getSmartsheet(); SmartsheetException exception = Assertions.assertThrows(SmartsheetException.class, () -> { - smartsheet.reportResources().updateReportDefinition(TEST_REPORT_ID, testReportDefinition); + smartsheet.reportResources().updateReportDefinition(TEST_REPORT_ID, testReportDefinition, true); }); assertThat(exception.getMessage()).isEqualTo("Malformed Request"); From 54d5dd41612acdd0afa68d4cdafbc118aedda05d Mon Sep 17 00:00:00 2001 From: Scott McGowan Date: Fri, 13 Mar 2026 15:26:12 +0000 Subject: [PATCH 6/8] feat: update report definition response body update change aggregationCriteria to summarizingCriteria to match spec add returns report definition --- .../com/smartsheet/api/ReportResources.java | 11 +++++----- .../api/internal/ReportResourcesImpl.java | 12 +++++++---- .../api/models/ReportDefinition.java | 20 +++++++++---------- ...n.java => ReportSummarizingCriterion.java} | 16 +++++++-------- .../reports/TestUpdateReportDefinition.java | 19 ++++++++++++------ 5 files changed, 45 insertions(+), 33 deletions(-) rename src/main/java/com/smartsheet/api/models/{ReportAggregationCriterion.java => ReportSummarizingCriterion.java} (84%) diff --git a/src/main/java/com/smartsheet/api/ReportResources.java b/src/main/java/com/smartsheet/api/ReportResources.java index e62a8f657..b64d0772e 100644 --- a/src/main/java/com/smartsheet/api/ReportResources.java +++ b/src/main/java/com/smartsheet/api/ReportResources.java @@ -214,21 +214,22 @@ Report getReport( ReportPublish updatePublishStatus(long id, ReportPublish reportPublish) throws SmartsheetException; /** - *

Updates a report's definition (filters, grouping, aggregation, and sorting).

+ *

Updates a report's definition (filters, grouping, summarize, and sorting).

* *

It mirrors to the following Smartsheet REST API method: PATCH /reports/{id}/definition

* *

This endpoint supports partial updates only on root level properties of the report definition, - * such as {@code filters}, {@code groupingCriteria}, and {@code aggregationCriteria}. For example, + * such as {@code filters}, {@code groupingCriteria}, and {@code summarizingCriteria}. For example, * you can update the report's filters without affecting its grouping criteria. However, nested * properties within these objects, such as a specific filter or grouping criterion, cannot be * updated individually and require a full replacement of the respective section. * In order for `filters` to be updated, `updateFilters` must be set to `true`. *

* - * @param id the ID of the report - * @param definition the ReportDefinition object containing the updated definition + * @param id the ID of the report + * @param definition the ReportDefinition object containing the updated definition * @param updateFilters Whether the `filters` property should be updated. + * @return The updated ReportDefinition * @throws IllegalArgumentException if any argument is null * @throws InvalidRequestException if there is any problem with the REST API request * @throws AuthorizationException if there is any problem with the REST API authorization (access token) @@ -236,7 +237,7 @@ Report getReport( * @throws ServiceUnavailableException if the REST API service is not available (possibly due to rate limiting) * @throws SmartsheetException if there is any other error during the operation */ - void updateReportDefinition(long id, ReportDefinition definition, Boolean updateFilters) throws SmartsheetException; + ReportDefinition updateReportDefinition(long id, ReportDefinition definition, Boolean updateFilters) throws SmartsheetException; /** *

Creates an object of ShareResources.

diff --git a/src/main/java/com/smartsheet/api/internal/ReportResourcesImpl.java b/src/main/java/com/smartsheet/api/internal/ReportResourcesImpl.java index 44c1bbce8..9b90107f4 100644 --- a/src/main/java/com/smartsheet/api/internal/ReportResourcesImpl.java +++ b/src/main/java/com/smartsheet/api/internal/ReportResourcesImpl.java @@ -309,12 +309,12 @@ public ReportPublish updatePublishStatus(long id, ReportPublish reportPublish) t } /** - * Updates a report's definition (filters, grouping, aggregation, and sorting). + * Updates a report's definition (filters, grouping, summarizing, and sorting). *

* It mirrors to the following Smartsheet REST API method: PATCH /reports/{id}/definition *

* This endpoint supports partial updates only on root level properties of the report definition, - * such as filters, groupingCriteria, and aggregationCriteria. For example, you can update the + * such as filters, groupingCriteria, and summarizingCriteria. For example, you can update the * report's filters without affecting its grouping criteria. However, nested properties within * these objects, such as a specific filter or grouping criterion, cannot be updated individually * and require a full replacement of the respective section. @@ -330,6 +330,7 @@ public ReportPublish updatePublishStatus(long id, ReportPublish reportPublish) t * * @param id the ID of the report * @param definition the ReportDefinition object containing the updated definition + * @return The updated ReportDefinition * @throws IllegalArgumentException if any argument is null * @throws InvalidRequestException if there is any problem with the REST API request * @throws AuthorizationException if there is any problem with the REST API authorization (access token) @@ -337,14 +338,15 @@ public ReportPublish updatePublishStatus(long id, ReportPublish reportPublish) t * @throws ServiceUnavailableException if the REST API service is not available (possibly due to rate limiting) * @throws SmartsheetException if there is any other error during the operation */ - public void updateReportDefinition(long id, ReportDefinition definition, Boolean updateFilters) throws SmartsheetException { + public ReportDefinition updateReportDefinition(long id, ReportDefinition definition, Boolean updateFilters) throws SmartsheetException { String path = REPORTS_PATH + id + "/definition"; Map queryParameters = new HashMap<>(); queryParameters.put(QUERY_PARAM_UPDATE_FILTERS, updateFilters); path += QueryUtil.generateUrl(null, queryParameters); - this.patchResource(path, Result.class, definition); + ReportDefinitionResult response = this.patchResource(path, ReportDefinitionResult.class, definition); + return response.getResult(); } /** @@ -355,4 +357,6 @@ public void updateReportDefinition(long id, ReportDefinition definition, Boolean public ShareResources shareResources() { return this.shares; } + + private static class ReportDefinitionResult extends Result {} } diff --git a/src/main/java/com/smartsheet/api/models/ReportDefinition.java b/src/main/java/com/smartsheet/api/models/ReportDefinition.java index c6cd8e134..43344b1bd 100644 --- a/src/main/java/com/smartsheet/api/models/ReportDefinition.java +++ b/src/main/java/com/smartsheet/api/models/ReportDefinition.java @@ -37,9 +37,9 @@ public class ReportDefinition { private List groupingCriteria; /** - * Represents the list of report aggregation criteria. + * Represents the list of report summarizing criteria. */ - private List aggregationCriteria; + private List summarizingCriteria; /** * Represents the list of report sorting criteria. @@ -85,21 +85,21 @@ public ReportDefinition setGroupingCriteria(List groupi } /** - * Gets the list of report aggregation criteria. + * Gets the list of report summarizing criteria. * - * @return the aggregation criteria + * @return the summarizing criteria */ - public List getAggregationCriteria() { - return aggregationCriteria; + public List getSummarizingCriteria() { + return summarizingCriteria; } /** - * Sets the list of report aggregation criteria. + * Sets the list of report summarizing criteria. * - * @param aggregationCriteria the aggregation criteria + * @param summarizingCriteria the summarizing criteria */ - public ReportDefinition setAggregationCriteria(List aggregationCriteria) { - this.aggregationCriteria = aggregationCriteria; + public ReportDefinition setSummarizingCriteria(List summarizingCriteria) { + this.summarizingCriteria = summarizingCriteria; return this; } diff --git a/src/main/java/com/smartsheet/api/models/ReportAggregationCriterion.java b/src/main/java/com/smartsheet/api/models/ReportSummarizingCriterion.java similarity index 84% rename from src/main/java/com/smartsheet/api/models/ReportAggregationCriterion.java rename to src/main/java/com/smartsheet/api/models/ReportSummarizingCriterion.java index 45011e8c8..35f921abf 100644 --- a/src/main/java/com/smartsheet/api/models/ReportAggregationCriterion.java +++ b/src/main/java/com/smartsheet/api/models/ReportSummarizingCriterion.java @@ -19,12 +19,12 @@ import com.smartsheet.api.models.enums.ReportAggregationType; /** - * Represents an aggregation criterion for a report. + * Represents an summarizing criterion for a report. */ -public class ReportAggregationCriterion { +public class ReportSummarizingCriterion { /** - * The column to aggregate. + * The column to summarize. */ private ReportColumnIdentifier column; @@ -39,7 +39,7 @@ public class ReportAggregationCriterion { private Boolean isExpanded; /** - * Gets the column to aggregate. + * Gets the column to summarize. * * @return the column */ @@ -48,11 +48,11 @@ public ReportColumnIdentifier getColumn() { } /** - * Sets the column to aggregate. + * Sets the column to summarize. * * @param column the column */ - public ReportAggregationCriterion setColumn(ReportColumnIdentifier column) { + public ReportSummarizingCriterion setColumn(ReportColumnIdentifier column) { this.column = column; return this; } @@ -71,7 +71,7 @@ public ReportAggregationType getAggregationType() { * * @param aggregationType the aggregation type */ - public ReportAggregationCriterion setAggregationType(ReportAggregationType aggregationType) { + public ReportSummarizingCriterion setAggregationType(ReportAggregationType aggregationType) { this.aggregationType = aggregationType; return this; } @@ -90,7 +90,7 @@ public Boolean getIsExpanded() { * * @param isExpanded true if expanded, false otherwise */ - public ReportAggregationCriterion setIsExpanded(Boolean isExpanded) { + public ReportSummarizingCriterion setIsExpanded(Boolean isExpanded) { this.isExpanded = isExpanded; return this; } diff --git a/src/test/java/com/smartsheet/api/sdktest/reports/TestUpdateReportDefinition.java b/src/test/java/com/smartsheet/api/sdktest/reports/TestUpdateReportDefinition.java index 76b3bf00b..000c2a4cc 100644 --- a/src/test/java/com/smartsheet/api/sdktest/reports/TestUpdateReportDefinition.java +++ b/src/test/java/com/smartsheet/api/sdktest/reports/TestUpdateReportDefinition.java @@ -16,6 +16,7 @@ package com.smartsheet.api.sdktest.reports; +import com.github.tomakehurst.wiremock.http.QueryParameter; import com.github.tomakehurst.wiremock.http.RequestMethod; import com.github.tomakehurst.wiremock.verification.LoggedRequest; import com.smartsheet.api.Smartsheet; @@ -37,6 +38,8 @@ import java.net.URI; import java.util.ArrayList; +import java.util.List; +import java.util.Map; import java.util.UUID; import static com.smartsheet.api.sdktest.users.CommonTestConstants.TEST_REPORT_ID; @@ -88,8 +91,8 @@ void testUpdateReportDefinitionGeneratedUrlIsCorrect() throws SmartsheetExceptio LoggedRequest wiremockRequest = wiremockClient.findWiremockRequest(requestId); String path = URI.create(wiremockRequest.getUrl()).getPath(); - String queryParams = URI.create(wiremockRequest.getUrl()).getQuery(); - assertThat(queryParams).isEqualTo("updateFilters=true"); + Map receivedQueryParams = wiremockRequest.getQueryParams(); + assertThat(receivedQueryParams.get("updateFilters").getValues()).isEqualTo(List.of("true")); assertThat(path).isEqualTo("/2.0/reports/" + TEST_REPORT_ID + "/definition"); assertThat(wiremockRequest.getMethod()).isEqualTo(RequestMethod.PATCH); @@ -99,7 +102,7 @@ void testUpdateReportDefinitionGeneratedUrlIsCorrect() throws SmartsheetExceptio } @Test - void testUpdateReportDefinitionAllResponseBodyProperties() { + void testUpdateReportDefinitionAllResponseBodyProperties() throws SmartsheetException { String requestId = UUID.randomUUID().toString(); WiremockClientWrapper wrapper = Utils.createWiremockSmartsheetClient( "/reports/update-report-definition/all-response-body-properties", @@ -107,9 +110,13 @@ void testUpdateReportDefinitionAllResponseBodyProperties() { ); Smartsheet smartsheet = wrapper.getSmartsheet(); - Assertions.assertDoesNotThrow(() -> { - smartsheet.reportResources().updateReportDefinition(TEST_REPORT_ID, testReportDefinition, true); - }); + ReportDefinition response = smartsheet.reportResources().updateReportDefinition(TEST_REPORT_ID, testReportDefinition, true); + + assertThat(response).isNotNull(); + assertThat(response.getFilters()).isNotNull(); + assertThat(response.getSummarizingCriteria()).isNotNull(); + assertThat(response.getGroupingCriteria()).isNotNull(); + assertThat(response.getSortingCriteria()).isNotNull(); } @Test From 18491de0818ec4e79cd2699767dea29e4b239268 Mon Sep 17 00:00:00 2001 From: Scott McGowan Date: Tue, 17 Mar 2026 11:56:51 +0000 Subject: [PATCH 7/8] feat: update report definition response changed to PUT from PATCH no longer returning changed definition no longer needs query param --- .../com/smartsheet/api/ReportResources.java | 5 +- .../api/internal/AbstractResources.java | 52 +++++++++++++++++++ .../api/internal/ReportResourcesImpl.java | 16 ++---- .../reports/TestUpdateReportDefinition.java | 30 ++++------- 4 files changed, 65 insertions(+), 38 deletions(-) diff --git a/src/main/java/com/smartsheet/api/ReportResources.java b/src/main/java/com/smartsheet/api/ReportResources.java index b64d0772e..5392c8e15 100644 --- a/src/main/java/com/smartsheet/api/ReportResources.java +++ b/src/main/java/com/smartsheet/api/ReportResources.java @@ -223,13 +223,10 @@ Report getReport( * you can update the report's filters without affecting its grouping criteria. However, nested * properties within these objects, such as a specific filter or grouping criterion, cannot be * updated individually and require a full replacement of the respective section. - * In order for `filters` to be updated, `updateFilters` must be set to `true`. *

* * @param id the ID of the report * @param definition the ReportDefinition object containing the updated definition - * @param updateFilters Whether the `filters` property should be updated. - * @return The updated ReportDefinition * @throws IllegalArgumentException if any argument is null * @throws InvalidRequestException if there is any problem with the REST API request * @throws AuthorizationException if there is any problem with the REST API authorization (access token) @@ -237,7 +234,7 @@ Report getReport( * @throws ServiceUnavailableException if the REST API service is not available (possibly due to rate limiting) * @throws SmartsheetException if there is any other error during the operation */ - ReportDefinition updateReportDefinition(long id, ReportDefinition definition, Boolean updateFilters) throws SmartsheetException; + void updateReportDefinition(long id, ReportDefinition definition) throws SmartsheetException; /** *

Creates an object of ShareResources.

diff --git a/src/main/java/com/smartsheet/api/internal/AbstractResources.java b/src/main/java/com/smartsheet/api/internal/AbstractResources.java index a884fcf77..0afc4f474 100644 --- a/src/main/java/com/smartsheet/api/internal/AbstractResources.java +++ b/src/main/java/com/smartsheet/api/internal/AbstractResources.java @@ -756,6 +756,58 @@ protected List postAndReceiveList(String path, T objectToPost, Class + * Exceptions: + * IllegalArgumentException : if any argument is null, or path is empty string + * InvalidRequestException : if there is any problem with the REST API request + * AuthorizationException : if there is any problem with the REST API authorization(access token) + * ResourceNotFoundException : if the resource can not be found + * ServiceUnavailableException : if the REST API service is not available (possibly due to rate limiting) + * SmartsheetRestException : if there is any other REST API related error occurred during the operation + * SmartsheetException : if there is any other error occurred during the operation + * + * @param the generic type + * @param path the relative path of the resource + * @param objectClass the resource object class + * @param object the object to patch + * @return the updated resource + * @throws SmartsheetException the smartsheet exception + */ + protected T putResource(String path, Class objectClass, Object object) throws SmartsheetException { + Util.throwIfNull(path, object); + Util.throwIfEmpty(path); + + HttpRequest request; + request = createHttpRequest(smartsheet.getBaseURI().resolve(path), HttpMethod.PUT); + + ByteArrayOutputStream objectBytesStream = new ByteArrayOutputStream(); + this.smartsheet.getJsonSerializer().serialize(object, objectBytesStream); + HttpEntity entity = new HttpEntity(); + entity.setContentType(JSON_CONTENT_TYPE); + entity.setContent(new ByteArrayInputStream(objectBytesStream.toByteArray())); + entity.setContentLength(objectBytesStream.size()); + request.setEntity(entity); + + T obj = null; + try { + HttpResponse response = this.smartsheet.getHttpClient().request(request); + if (response.getStatusCode() == 200) { + obj = this.smartsheet.getJsonSerializer().deserialize(objectClass, + response.getEntity().getContent()); + } else { + handleError(response); + } + } catch (IOException e) { + throw new RuntimeException(e); + } finally { + smartsheet.getHttpClient().releaseConnection(); + } + + return obj; + } + /** * Partially update a resource using Smartsheet REST API with PATCH method. *

diff --git a/src/main/java/com/smartsheet/api/internal/ReportResourcesImpl.java b/src/main/java/com/smartsheet/api/internal/ReportResourcesImpl.java index 9b90107f4..7938bd775 100644 --- a/src/main/java/com/smartsheet/api/internal/ReportResourcesImpl.java +++ b/src/main/java/com/smartsheet/api/internal/ReportResourcesImpl.java @@ -311,14 +311,13 @@ public ReportPublish updatePublishStatus(long id, ReportPublish reportPublish) t /** * Updates a report's definition (filters, grouping, summarizing, and sorting). *

- * It mirrors to the following Smartsheet REST API method: PATCH /reports/{id}/definition + * It mirrors to the following Smartsheet REST API method: PUT /reports/{id}/definition *

* This endpoint supports partial updates only on root level properties of the report definition, * such as filters, groupingCriteria, and summarizingCriteria. For example, you can update the * report's filters without affecting its grouping criteria. However, nested properties within * these objects, such as a specific filter or grouping criterion, cannot be updated individually * and require a full replacement of the respective section. - * In order for `filters` to be updated, `updateFilters` must be set to `true`. *

* Exceptions: * - InvalidRequestException : if there is any problem with the REST API request @@ -330,7 +329,6 @@ public ReportPublish updatePublishStatus(long id, ReportPublish reportPublish) t * * @param id the ID of the report * @param definition the ReportDefinition object containing the updated definition - * @return The updated ReportDefinition * @throws IllegalArgumentException if any argument is null * @throws InvalidRequestException if there is any problem with the REST API request * @throws AuthorizationException if there is any problem with the REST API authorization (access token) @@ -338,15 +336,9 @@ public ReportPublish updatePublishStatus(long id, ReportPublish reportPublish) t * @throws ServiceUnavailableException if the REST API service is not available (possibly due to rate limiting) * @throws SmartsheetException if there is any other error during the operation */ - public ReportDefinition updateReportDefinition(long id, ReportDefinition definition, Boolean updateFilters) throws SmartsheetException { + public void updateReportDefinition(long id, ReportDefinition definition) throws SmartsheetException { String path = REPORTS_PATH + id + "/definition"; - - Map queryParameters = new HashMap<>(); - queryParameters.put(QUERY_PARAM_UPDATE_FILTERS, updateFilters); - path += QueryUtil.generateUrl(null, queryParameters); - - ReportDefinitionResult response = this.patchResource(path, ReportDefinitionResult.class, definition); - return response.getResult(); + this.putResource(path, Result.class, definition); } /** @@ -357,6 +349,4 @@ public ReportDefinition updateReportDefinition(long id, ReportDefinition definit public ShareResources shareResources() { return this.shares; } - - private static class ReportDefinitionResult extends Result {} } diff --git a/src/test/java/com/smartsheet/api/sdktest/reports/TestUpdateReportDefinition.java b/src/test/java/com/smartsheet/api/sdktest/reports/TestUpdateReportDefinition.java index 000c2a4cc..02e3ee26f 100644 --- a/src/test/java/com/smartsheet/api/sdktest/reports/TestUpdateReportDefinition.java +++ b/src/test/java/com/smartsheet/api/sdktest/reports/TestUpdateReportDefinition.java @@ -16,14 +16,12 @@ package com.smartsheet.api.sdktest.reports; -import com.github.tomakehurst.wiremock.http.QueryParameter; import com.github.tomakehurst.wiremock.http.RequestMethod; import com.github.tomakehurst.wiremock.verification.LoggedRequest; import com.smartsheet.api.Smartsheet; import com.smartsheet.api.SmartsheetException; import com.smartsheet.api.WiremockClient; import com.smartsheet.api.WiremockClientWrapper; -import com.smartsheet.api.internal.json.JSONSerializerException; import com.smartsheet.api.models.ReportColumnIdentifier; import com.smartsheet.api.models.ReportDefinition; import com.smartsheet.api.models.ReportFilterCriterion; @@ -38,12 +36,11 @@ import java.net.URI; import java.util.ArrayList; -import java.util.List; -import java.util.Map; import java.util.UUID; import static com.smartsheet.api.sdktest.users.CommonTestConstants.TEST_REPORT_ID; import static org.assertj.core.api.AssertionsForClassTypes.assertThat; +import static org.assertj.core.api.AssertionsForClassTypes.assertThatNoException; public class TestUpdateReportDefinition { @@ -51,7 +48,7 @@ public class TestUpdateReportDefinition { private String testReportDefinitionJson; @BeforeEach - void setUp() throws JSONSerializerException { + void setUp() { testReportDefinition = new ReportDefinition(); testReportDefinition.setFilters( new ReportFilterExpression() @@ -87,22 +84,19 @@ void testUpdateReportDefinitionGeneratedUrlIsCorrect() throws SmartsheetExceptio Smartsheet smartsheet = wrapper.getSmartsheet(); WiremockClient wiremockClient = wrapper.getWiremockClient(); - smartsheet.reportResources().updateReportDefinition(TEST_REPORT_ID, testReportDefinition, true); + smartsheet.reportResources().updateReportDefinition(TEST_REPORT_ID, testReportDefinition); LoggedRequest wiremockRequest = wiremockClient.findWiremockRequest(requestId); String path = URI.create(wiremockRequest.getUrl()).getPath(); - Map receivedQueryParams = wiremockRequest.getQueryParams(); - assertThat(receivedQueryParams.get("updateFilters").getValues()).isEqualTo(List.of("true")); - assertThat(path).isEqualTo("/2.0/reports/" + TEST_REPORT_ID + "/definition"); - assertThat(wiremockRequest.getMethod()).isEqualTo(RequestMethod.PATCH); + assertThat(wiremockRequest.getMethod()).isEqualTo(RequestMethod.PUT); String requestBody = wiremockRequest.getBodyAsString(); assertThat(requestBody).isEqualTo(testReportDefinitionJson); } @Test - void testUpdateReportDefinitionAllResponseBodyProperties() throws SmartsheetException { + void testUpdateReportDefinitionAllResponseBodyProperties() { String requestId = UUID.randomUUID().toString(); WiremockClientWrapper wrapper = Utils.createWiremockSmartsheetClient( "/reports/update-report-definition/all-response-body-properties", @@ -110,13 +104,7 @@ void testUpdateReportDefinitionAllResponseBodyProperties() throws SmartsheetExce ); Smartsheet smartsheet = wrapper.getSmartsheet(); - ReportDefinition response = smartsheet.reportResources().updateReportDefinition(TEST_REPORT_ID, testReportDefinition, true); - - assertThat(response).isNotNull(); - assertThat(response.getFilters()).isNotNull(); - assertThat(response.getSummarizingCriteria()).isNotNull(); - assertThat(response.getGroupingCriteria()).isNotNull(); - assertThat(response.getSortingCriteria()).isNotNull(); + assertThatNoException().isThrownBy(() -> smartsheet.reportResources().updateReportDefinition(TEST_REPORT_ID, testReportDefinition)); } @Test @@ -129,7 +117,7 @@ void testUpdateReportDefinitionInvalidArgument() { Smartsheet smartsheet = wrapper.getSmartsheet(); Assertions.assertThrows(IllegalArgumentException.class, () -> { - smartsheet.reportResources().updateReportDefinition(TEST_REPORT_ID, null, true); + smartsheet.reportResources().updateReportDefinition(TEST_REPORT_ID, null); }); } @@ -140,7 +128,7 @@ void testUpdateReportDefinitionError500Response() { Smartsheet smartsheet = wrapper.getSmartsheet(); SmartsheetException exception = Assertions.assertThrows(SmartsheetException.class, () -> { - smartsheet.reportResources().updateReportDefinition(TEST_REPORT_ID, testReportDefinition, true); + smartsheet.reportResources().updateReportDefinition(TEST_REPORT_ID, testReportDefinition); }); assertThat(exception.getMessage()).isEqualTo("Internal Server Error"); @@ -153,7 +141,7 @@ void testUpdateReportDefinitionError400Response() { Smartsheet smartsheet = wrapper.getSmartsheet(); SmartsheetException exception = Assertions.assertThrows(SmartsheetException.class, () -> { - smartsheet.reportResources().updateReportDefinition(TEST_REPORT_ID, testReportDefinition, true); + smartsheet.reportResources().updateReportDefinition(TEST_REPORT_ID, testReportDefinition); }); assertThat(exception.getMessage()).isEqualTo("Malformed Request"); From 7757db47deee260bbf9f4deba4a98ab380c47362 Mon Sep 17 00:00:00 2001 From: Scott McGowan Date: Thu, 19 Mar 2026 15:14:19 +0000 Subject: [PATCH 8/8] chore: update documentation --- src/main/java/com/smartsheet/api/ReportResources.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/smartsheet/api/ReportResources.java b/src/main/java/com/smartsheet/api/ReportResources.java index 5392c8e15..707976b39 100644 --- a/src/main/java/com/smartsheet/api/ReportResources.java +++ b/src/main/java/com/smartsheet/api/ReportResources.java @@ -216,7 +216,7 @@ Report getReport( /** *

Updates a report's definition (filters, grouping, summarize, and sorting).

* - *

It mirrors to the following Smartsheet REST API method: PATCH /reports/{id}/definition

+ *

It mirrors to the following Smartsheet REST API method: PUT /reports/{id}/definition

* *

This endpoint supports partial updates only on root level properties of the report definition, * such as {@code filters}, {@code groupingCriteria}, and {@code summarizingCriteria}. For example,