feat(clients): fromDate/toDate submittedon_date range filter on GET /clients
Fineract Docker Builds / build (true, docker-compose.yml, mariadb) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MariaDB / test (test-core-1) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MariaDB / test (test-core-2) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MariaDB / test (test-core-3) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MariaDB / test (test-core-4) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MariaDB / test (test-core-5) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - PostgreSQL / test (test-core-1) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - PostgreSQL / test (test-core-2) (push) Canceled after 0s
Fineract Build & Cucumber tests (without E2E tests) / verify (progressive-loan, build-progressive-loan) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 10 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 2 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 3 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 4 of 10) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - PostgreSQL / test (test-core-3) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - PostgreSQL / test (test-core-4) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - PostgreSQL / test (test-core-5) (push) Canceled after 0s
Fineract Build & Cucumber tests (without E2E tests) / verify (main, build-core) (push) Canceled after 0s
Fineract Build & Cucumber tests (without E2E tests) / verify (main, cucumber) (push) Canceled after 0s
Fineract Docker Builds / build (false, docker-compose-postgresql.yml, postgresql) (push) Canceled after 0s
Fineract Documentation build / build (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 1 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 5 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 6 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 7 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 8 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 9 of 10) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MySQL / test (test-core-1) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MySQL / test (test-core-2) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MySQL / test (test-core-3) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MySQL / test (test-core-4) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MySQL / test (test-core-5) (push) Canceled after 0s
Fineract Liquibase Only mode - PostgreSQL / test (push) Canceled after 0s
Fineract Messaging Smoke Tests / Smoke Test with ActiveMQ (push) Canceled after 0s
Fineract Messaging Smoke Tests / Smoke Test with Kafka (push) Canceled after 0s

Backs the Client Approval tab's Today/Yesterday quick filters server-side.
offset/limit/displayName/orderBy/sortOrder/status already existed on this
endpoint; added fromDate/toDate (yyyy-MM-dd, inclusive) alongside them,
filtering on c.submittedon_date, following the same ::date-cast convention
already used by ClientPendingEditReadPlatformServiceImpl for the
equivalent pending-edits filter. Updated the one other caller
(SelfClientsApiResource) to pass null/null.
This commit is contained in:
2026-07-30 10:33:48 +05:30
parent 02541eed6c
commit b1cfa996b4
3 changed files with 24 additions and 6 deletions
@@ -44,6 +44,7 @@ import java.time.LocalDate;
import java.util.Collection;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.apache.fineract.commands.data.AuditData;
import org.apache.fineract.commands.domain.CommandWrapper;
import org.apache.fineract.commands.service.AuditReadPlatformService;
@@ -142,7 +143,8 @@ public class ClientsApiResource {
@Produces({ MediaType.APPLICATION_JSON })
@Operation(summary = "List Clients", description = "The list capability of clients can support pagination and sorting.\n\n"
+ "Example Requests:\n" + "\n" + "clients\n" + "\n" + "clients?fields=displayName,officeName,timeline\n" + "\n"
+ "clients?offset=10&limit=50\n" + "\n" + "clients?orderBy=displayName&sortOrder=DESC")
+ "clients?offset=10&limit=50\n" + "\n" + "clients?orderBy=displayName&sortOrder=DESC\n\n"
+ "clients?fromDate=2026-01-01&toDate=2026-01-31 (submittedon_date range, yyyy-MM-dd, inclusive)")
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = ClientsApiResourceSwagger.GetClientsResponse.class)))
public String retrieveAll(@Context final UriInfo uriInfo,
@QueryParam("officeId") @Parameter(description = "officeId") final Long officeId,
@@ -157,10 +159,15 @@ public class ClientsApiResource {
@QueryParam("orderBy") @Parameter(description = "orderBy") final String orderBy,
@QueryParam("sortOrder") @Parameter(description = "sortOrder") final String sortOrder,
@QueryParam("orphansOnly") @Parameter(description = "orphansOnly") final Boolean orphansOnly,
@QueryParam("legalForm") final Integer legalForm) {
@QueryParam("legalForm") final Integer legalForm,
@QueryParam("fromDate") @Parameter(description = "fromDate") final String fromDate,
@QueryParam("toDate") @Parameter(description = "toDate") final String toDate) {
final LocalDate fromDateParsed = StringUtils.isNotBlank(fromDate) ? LocalDate.parse(fromDate) : null;
final LocalDate toDateParsed = StringUtils.isNotBlank(toDate) ? LocalDate.parse(toDate) : null;
return retrieveAll(uriInfo, officeId, externalId, displayName, firstname, lastname, status, legalForm, hierarchy, offset, limit,
orderBy, sortOrder, orphansOnly, false);
orderBy, sortOrder, orphansOnly, false, fromDateParsed, toDateParsed);
}
@GET
@@ -437,7 +444,7 @@ public class ClientsApiResource {
public String retrieveAll(final UriInfo uriInfo, final Long officeId, final String externalId, final String displayName,
final String firstname, final String lastname, final String status, final Integer legalForm, final String hierarchy,
final Integer offset, final Integer limit, final String orderBy, final String sortOrder, final Boolean orphansOnly,
final boolean isSelfUser) {
final boolean isSelfUser, final LocalDate fromDate, final LocalDate toDate) {
context.authenticatedUser().validateHasReadPermission(ClientApiConstants.CLIENT_RESOURCE_NAME);
sqlValidator.validate(orderBy);
sqlValidator.validate(sortOrder);
@@ -445,7 +452,8 @@ public class ClientsApiResource {
sqlValidator.validate(hierarchy);
final SearchParameters searchParameters = SearchParameters.builder().limit(limit).officeId(officeId).externalId(externalId)
.name(displayName).hierarchy(hierarchy).firstname(firstname).lastname(lastname).status(status).orphansOnly(orphansOnly)
.isSelfUser(isSelfUser).offset(offset).orderBy(orderBy).sortOrder(sortOrder).legalForm(legalForm).build();
.isSelfUser(isSelfUser).offset(offset).orderBy(orderBy).sortOrder(sortOrder).legalForm(legalForm).fromDate(fromDate)
.toDate(toDate).build();
final Page<ClientData> clientData = clientReadPlatformService.retrieveAll(searchParameters);
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters());
return toApiJsonSerializer.serialize(settings, clientData, ClientApiConstants.CLIENT_RESPONSE_DATA_PARAMETERS);
@@ -178,6 +178,16 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
extraCriteria += " and c.status_enum = " + clientStatus.getValue().toString() + " ";
}
if (searchParameters.hasFromDate()) {
paramList.add(searchParameters.getFromDate().toString());
extraCriteria += " and c.submittedon_date >= ?::date ";
}
if (searchParameters.hasToDate()) {
paramList.add(searchParameters.getToDate().toString());
extraCriteria += " and c.submittedon_date <= ?::date ";
}
if (firstname != null) {
paramList.add(firstname);
extraCriteria += " and c.firstname like ? ";
@@ -135,7 +135,7 @@ public class SelfClientsApiResource {
final String hierarchy = null;
final Boolean orphansOnly = null;
return this.clientApiResource.retrieveAll(uriInfo, officeId, externalId, displayName, firstname, lastname, status, legalForm,
hierarchy, offset, limit, orderBy, sortOrder, orphansOnly, true);
hierarchy, offset, limit, orderBy, sortOrder, orphansOnly, true, null, null);
}
@GET