feat(current-accounts): add document upload/list/download/delete endpoints
/v1/currentaccounts/{id}/documents had no handler at all -- the
account's own /v1/currentaccounts resource matches the request path
first and has no documents method, so it never fell through to the
generic /v1/{entityType}/{entityId}/documents resource that every
other entity type relies on. Current accounts got a 404 on every
Documents-tab request.
Delegates straight to the existing DocumentApiResource so current
accounts get identical behaviour to clients, loans, etc.
This commit is contained in:
+69
@@ -18,6 +18,11 @@
|
||||
*/
|
||||
package org.apache.fineract.portfolio.savings.api;
|
||||
|
||||
import static org.apache.fineract.infrastructure.documentmanagement.api.DocumentApiConstants.DOCUMENT_API_PARAM_DESCRIPTION;
|
||||
import static org.apache.fineract.infrastructure.documentmanagement.api.DocumentApiConstants.DOCUMENT_API_PARAM_FILE;
|
||||
import static org.apache.fineract.infrastructure.documentmanagement.api.DocumentApiConstants.DOCUMENT_API_PARAM_NAME;
|
||||
import static org.springframework.http.HttpHeaders.CONTENT_LENGTH;
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
||||
@@ -26,6 +31,7 @@ import jakarta.ws.rs.Consumes;
|
||||
import jakarta.ws.rs.DELETE;
|
||||
import jakarta.ws.rs.DefaultValue;
|
||||
import jakarta.ws.rs.GET;
|
||||
import jakarta.ws.rs.HeaderParam;
|
||||
import jakarta.ws.rs.POST;
|
||||
import jakarta.ws.rs.PUT;
|
||||
import jakarta.ws.rs.Path;
|
||||
@@ -34,9 +40,11 @@ import jakarta.ws.rs.Produces;
|
||||
import jakarta.ws.rs.QueryParam;
|
||||
import jakarta.ws.rs.core.Context;
|
||||
import jakarta.ws.rs.core.MediaType;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
import jakarta.ws.rs.core.UriInfo;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import java.io.InputStream;
|
||||
import java.time.LocalDate;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
@@ -50,6 +58,10 @@ import org.apache.fineract.infrastructure.core.exception.UnrecognizedQueryParamE
|
||||
import org.apache.fineract.infrastructure.core.serialization.ApiRequestJsonSerializationSettings;
|
||||
import org.apache.fineract.infrastructure.core.serialization.DefaultToApiJsonSerializer;
|
||||
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
|
||||
import org.apache.fineract.infrastructure.documentmanagement.api.DocumentApiResource;
|
||||
import org.apache.fineract.infrastructure.documentmanagement.data.DocumentCreateResponse;
|
||||
import org.apache.fineract.infrastructure.documentmanagement.data.DocumentData;
|
||||
import org.apache.fineract.infrastructure.documentmanagement.data.DocumentDeleteResponse;
|
||||
import org.apache.fineract.infrastructure.security.exception.NoAuthorizationException;
|
||||
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
|
||||
import org.apache.fineract.infrastructure.security.service.SqlValidator;
|
||||
@@ -63,6 +75,9 @@ import org.apache.fineract.commands.service.PortfolioCommandSourceWritePlatformS
|
||||
import org.apache.fineract.portfolio.currentaccount.service.CurrentAccountEditWritePlatformService;
|
||||
import org.apache.fineract.portfolio.currentaccount.service.CurrentAccountWritePlatformService;
|
||||
import org.apache.fineract.portfolio.savings.service.CurrentAccountTemplateReadPlatformService;
|
||||
import org.glassfish.jersey.media.multipart.FormDataBodyPart;
|
||||
import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
|
||||
import org.glassfish.jersey.media.multipart.FormDataParam;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Path("/v1/currentaccounts")
|
||||
@@ -84,6 +99,10 @@ public class CurrentAccountsApiResource {
|
||||
private final CurrentAccountEditWritePlatformService currentAccountEditWritePlatformService;
|
||||
private final FromJsonHelper fromApiJsonHelper;
|
||||
private final DefaultToApiJsonSerializer<CurrentAccountPendingEditData> pendingEditApiJsonSerializer;
|
||||
private final DocumentApiResource documentApiResource;
|
||||
|
||||
/** Matches the {@code entityType} current-account document requests are stored/looked up under. */
|
||||
private static final String DOCUMENT_ENTITY_TYPE = "currentaccounts";
|
||||
|
||||
@GET
|
||||
@Path("template")
|
||||
@@ -337,4 +356,54 @@ public class CurrentAccountsApiResource {
|
||||
return this.toApiJsonSerializer.serialize(result);
|
||||
}
|
||||
|
||||
// ── Documents ────────────────────────────────────────────────────────────
|
||||
// The generic /v1/{entityType}/{entityId}/documents resource (DocumentApiResource) never gets a
|
||||
// chance to handle current-account requests: this class's own literal /v1/currentaccounts path
|
||||
// is matched first for anything under {accountId}, and it has no "documents" method, so the
|
||||
// request dead-ends in a 404 instead of falling through. These delegate straight to the same
|
||||
// DocumentApiResource so current accounts get identical document-management behaviour.
|
||||
|
||||
@GET
|
||||
@Path("{accountId}/documents")
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
@Operation(summary = "List documents attached to a current account")
|
||||
@ApiResponse(responseCode = "200", description = "OK")
|
||||
public List<DocumentData> retrieveDocuments(@PathParam("accountId") final Long accountId) {
|
||||
return documentApiResource.retrieveAllDocuments(DOCUMENT_ENTITY_TYPE, accountId);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("{accountId}/documents/{documentId}/attachment")
|
||||
@Produces({ MediaType.APPLICATION_OCTET_STREAM })
|
||||
@Operation(summary = "Download a document attached to a current account")
|
||||
@ApiResponse(responseCode = "200", description = "Not Shown: The corresponding Binary file")
|
||||
public Response downloadDocument(@PathParam("accountId") final Long accountId, @PathParam("documentId") final Long documentId) {
|
||||
return documentApiResource.downloadFile(DOCUMENT_ENTITY_TYPE, accountId, documentId);
|
||||
}
|
||||
|
||||
@POST
|
||||
@Path("{accountId}/documents")
|
||||
@Consumes({ MediaType.MULTIPART_FORM_DATA })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
@Operation(summary = "Attach a document to a current account")
|
||||
@ApiResponse(responseCode = "200", description = "Not Shown (multi-part form data)")
|
||||
public DocumentCreateResponse createDocument(@PathParam("accountId") final Long accountId,
|
||||
@HeaderParam(CONTENT_LENGTH) final Long fileSize, @FormDataParam(DOCUMENT_API_PARAM_FILE) final InputStream inputStream,
|
||||
@FormDataParam(DOCUMENT_API_PARAM_FILE) final FormDataContentDisposition fileDetails,
|
||||
@FormDataParam(DOCUMENT_API_PARAM_FILE) final FormDataBodyPart filePart,
|
||||
@FormDataParam(DOCUMENT_API_PARAM_NAME) final String name,
|
||||
@FormDataParam(DOCUMENT_API_PARAM_DESCRIPTION) final String description) {
|
||||
return documentApiResource.createDocument(DOCUMENT_ENTITY_TYPE, accountId, fileSize, inputStream, fileDetails, filePart, name,
|
||||
description);
|
||||
}
|
||||
|
||||
@DELETE
|
||||
@Path("{accountId}/documents/{documentId}")
|
||||
@Operation(summary = "Remove a document attached to a current account")
|
||||
@ApiResponse(responseCode = "200", description = "OK")
|
||||
public DocumentDeleteResponse deleteDocument(@PathParam("accountId") final Long accountId,
|
||||
@PathParam("documentId") final Long documentId) {
|
||||
return documentApiResource.deleteDocument(DOCUMENT_ENTITY_TYPE, accountId, documentId);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user