Skip to content
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
24 changes: 24 additions & 0 deletions src/main/java/com/smartsheet/api/ReportResources.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
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.SheetEmail;
import com.smartsheet.api.models.enums.ReportInclusion;
Expand Down Expand Up @@ -212,6 +213,29 @@ Report getReport(
*/
ReportPublish updatePublishStatus(long id, ReportPublish reportPublish) throws SmartsheetException;

/**
* <p>Updates a report's definition (filters, grouping, summarize, and sorting).</p>
*
* <p>It mirrors to the following Smartsheet REST API method: PUT /reports/{id}/definition</p>
*
* <p>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,
* 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.
* </p>
*
* @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;

/**
* <p>Creates an object of ShareResources.</p>
*
Expand Down
52 changes: 52 additions & 0 deletions src/main/java/com/smartsheet/api/internal/AbstractResources.java
Original file line number Diff line number Diff line change
Expand Up @@ -756,6 +756,58 @@ protected <T, S> List<S> postAndReceiveList(String path, T objectToPost, Class<S
return obj;
}

/**
* Update a resource using Smartsheet REST API with PUT method.
* <p>
* 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 <T> 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> T putResource(String path, Class<T> 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.
* <p>
Expand Down
36 changes: 36 additions & 0 deletions src/main/java/com/smartsheet/api/internal/ReportResourcesImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -53,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/";

/**
Expand Down Expand Up @@ -305,6 +308,39 @@ 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, summarizing, and sorting).
* <p>
* It mirrors to the following Smartsheet REST API method: PUT /reports/{id}/definition
* <p>
* 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.
* <p>
* 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 {
String path = REPORTS_PATH + id + "/definition";
this.putResource(path, Result.class, definition);
}

/**
* <p>Creates an object of ShareResources.</p>
*
Expand Down
140 changes: 140 additions & 0 deletions src/main/java/com/smartsheet/api/models/ReportColumnIdentifier.java
Original file line number Diff line number Diff line change
@@ -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.
* <p>
* One of [{@code type}, {@code systemColumnType}] or [{@code primary=true}] is required.
* <p>
* {@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.
* <p>
* <b>Note:</b> Columns in the report are matched by the combination of {@code title} and {@code type}
* (and {@code systemColumnType} if specified).
* <p>
* <b>Note:</b> {@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.
* <p>
* 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.
* <p>
* 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;
}
}
Loading
Loading