Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions config/docker/env/fineract-common.env
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ FINERACT_MANAGEMENT_ENDPOINT_WEB_EXPOSURE_INCLUDE=health,info,prometheus
FINERACT_MANAGEMENT_METRICS_TAGS_APPLICATION=fineract
FINERACT_REMOTE_JOB_MESSAGE_HANDLER_SPRING_EVENTS_ENABLED=true
FINERACT_INSECURE_HTTP_CLIENT=true
FINERACT_CONTENT_FILESYSTEM_ROOT_FOLDER=/tmp
SPRING_PROFILES_ACTIVE=test,diagnostics
OTEL_SERVICE_NAME=fineract
JAVA_TOOL_OPTIONS="-Xmx1G -XX:MinRAMPercentage=25 -XX:MaxRAMPercentage=80 -XX:TieredStopAtLevel=1 -XX:+UseContainerSupport -XX:+UseStringDeduplication --add-exports=java.naming/com.sun.jndi.ldap=ALL-UNNAMED --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.invoke=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add-opens=java.base/java.security=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.management/javax.management=ALL-UNNAMED --add-opens=java.naming/javax.naming=ALL-UNNAMED"
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@
import feign.RequestLine;
import feign.Response;
import java.util.List;
import org.apache.fineract.client.models.DeleteEntityTypeEntityIdDocumentsResponse;
import org.apache.fineract.client.models.DocumentCreateResponse;
import org.apache.fineract.client.models.DocumentData;
import org.apache.fineract.client.models.PostEntityTypeEntityIdDocumentsResponse;
import org.apache.fineract.client.models.PutEntityTypeEntityIdDocumentsResponse;
import org.apache.fineract.client.models.DocumentDeleteResponse;
import org.apache.fineract.client.models.DocumentUpdateResponse;

/**
* This class was originally generated by <a href="https://openapi-generator.tech">OpenAPI Generator</a>, but then had
Expand All @@ -44,7 +44,7 @@ public interface DocumentsApiFixed {
* @return PostEntityTypeEntityIdDocumentsResponse
*/
@RequestLine("POST /v1/{entityType}/{entityId}/documents")
PostEntityTypeEntityIdDocumentsResponse createDocument(@Param("entityType") String entityType, @Param("entityId") Long entityId,
DocumentCreateResponse createDocument(@Param("entityType") String entityType, @Param("entityId") Long entityId,
org.apache.fineract.client.feign.FineractMultipartEncoder.MultipartData multipartData);

/**
Expand All @@ -59,7 +59,7 @@ PostEntityTypeEntityIdDocumentsResponse createDocument(@Param("entityType") Stri
* @return DeleteEntityTypeEntityIdDocumentsResponse
*/
@RequestLine("DELETE /v1/{entityType}/{entityId}/documents/{documentId}")
DeleteEntityTypeEntityIdDocumentsResponse deleteDocument(@Param("entityType") String entityType, @Param("entityId") Long entityId,
DocumentDeleteResponse deleteDocument(@Param("entityType") String entityType, @Param("entityId") Long entityId,
@Param("documentId") Long documentId);

/**
Expand Down Expand Up @@ -114,6 +114,6 @@ DocumentData getDocument(@Param("entityType") String entityType, @Param("entityI
* @return PutEntityTypeEntityIdDocumentsResponse
*/
@RequestLine("PUT /v1/{entityType}/{entityId}/documents/{documentId}")
PutEntityTypeEntityIdDocumentsResponse updateDocument(@Param("entityType") String entityType, @Param("entityId") Long entityId,
DocumentUpdateResponse updateDocument(@Param("entityType") String entityType, @Param("entityId") Long entityId,
@Param("documentId") Long documentId, org.apache.fineract.client.feign.FineractMultipartEncoder.MultipartData multipartData);
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@
import java.util.concurrent.TimeUnit;
import org.apache.fineract.client.feign.FineractFeignClientConfig;
import org.apache.fineract.client.feign.services.DocumentsApiFixed;
import org.apache.fineract.client.models.DeleteEntityTypeEntityIdDocumentsResponse;
import org.apache.fineract.client.models.DocumentData;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
Expand Down Expand Up @@ -149,7 +148,7 @@ void testDeleteDocument() {
.willReturn(aResponse().withStatus(200).withHeader("Content-Type", "application/json").withBody(responseBody)));

DocumentsApiFixed api = config.createClient(DocumentsApiFixed.class);
DeleteEntityTypeEntityIdDocumentsResponse response = api.deleteDocument("clients", 123L, 456L);
var response = api.deleteDocument("clients", 123L, 456L);

assertThat(response).isNotNull();
assertThat(response.getResourceId()).isEqualTo(456L);
Expand All @@ -162,7 +161,7 @@ void testDeleteDocumentForLoan() {
.willReturn(aResponse().withStatus(200).withHeader("Content-Type", "application/json").withBody(responseBody)));

DocumentsApiFixed api = config.createClient(DocumentsApiFixed.class);
DeleteEntityTypeEntityIdDocumentsResponse response = api.deleteDocument("loans", 789L, 999L);
var response = api.deleteDocument("loans", 789L, 999L);

assertThat(response).isNotNull();
assertThat(response.getResourceId()).isEqualTo(999L);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@

import java.util.List;
import okhttp3.ResponseBody;
import org.apache.fineract.client.models.DeleteEntityTypeEntityIdDocumentsResponse;
import org.apache.fineract.client.models.DocumentCreateResponse;
import org.apache.fineract.client.models.DocumentData;
import org.apache.fineract.client.models.PostEntityTypeEntityIdDocumentsResponse;
import org.apache.fineract.client.models.PutEntityTypeEntityIdDocumentsResponse;
import org.apache.fineract.client.models.DocumentDeleteResponse;
import org.apache.fineract.client.models.DocumentUpdateResponse;
import retrofit2.Call;
import retrofit2.http.DELETE;
import retrofit2.http.GET;
Expand Down Expand Up @@ -54,7 +54,7 @@ public interface DocumentsApiFixed {
*/
@retrofit2.http.Multipart
@POST("v1/{entityType}/{entityId}/documents")
Call<PostEntityTypeEntityIdDocumentsResponse> createDocument(@retrofit2.http.Path("entityType") String entityType,
Call<DocumentCreateResponse> createDocument(@retrofit2.http.Path("entityType") String entityType,
@retrofit2.http.Path("entityId") Long entityId, @retrofit2.http.Part okhttp3.MultipartBody.Part file,
@retrofit2.http.Part("name") String name, @retrofit2.http.Part("description") String description);

Expand All @@ -70,7 +70,7 @@ Call<PostEntityTypeEntityIdDocumentsResponse> createDocument(@retrofit2.http.Pat
* @return Call&lt;DeleteEntityTypeEntityIdDocumentsResponse&gt;
*/
@DELETE("v1/{entityType}/{entityId}/documents/{documentId}")
Call<DeleteEntityTypeEntityIdDocumentsResponse> deleteDocument(@retrofit2.http.Path("entityType") String entityType,
Call<DocumentDeleteResponse> deleteDocument(@retrofit2.http.Path("entityType") String entityType,
@retrofit2.http.Path("entityId") Long entityId, @retrofit2.http.Path("documentId") Long documentId);

/**
Expand Down Expand Up @@ -139,7 +139,7 @@ Call<List<DocumentData>> retrieveAllDocuments(@retrofit2.http.Path("entityType")
*/
@retrofit2.http.Multipart
@PUT("v1/{entityType}/{entityId}/documents/{documentId}")
Call<PutEntityTypeEntityIdDocumentsResponse> updateDocument(@retrofit2.http.Path("entityType") String entityType,
Call<DocumentUpdateResponse> updateDocument(@retrofit2.http.Path("entityType") String entityType,
@retrofit2.http.Path("entityId") Long entityId, @retrofit2.http.Path("documentId") Long documentId,
@retrofit2.http.Part okhttp3.MultipartBody.Part file, @retrofit2.http.Part("name") String name,
@retrofit2.http.Part("description") String description);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,16 @@ void onStartup() {
@Retry(name = "commandAuditFallback", fallbackMethod = "fatal")
@SuppressWarnings("UnusedMethod")
private void fallback(Command<?> command, Throwable t) throws Exception {
if (Boolean.TRUE.equals(properties.getFileDeadLetterQueueEnabled())) {
fallback(command, null, t);
} else {
fatal(command, t);
}
}

@Retry(name = "commandAuditFallback", fallbackMethod = "fatal")
@SuppressWarnings("UnusedMethod")
private void fallback(Command<?> command, Object response, Throwable t) throws Exception {
if (Boolean.TRUE.equals(properties.getFileDeadLetterQueueEnabled())) {
setError(command, t);
write(command);
Expand All @@ -149,6 +159,11 @@ private void fallback(Command<?> command, Throwable t) throws Exception {

@SuppressWarnings("UnusedMethod")
private void fatal(Command<?> command, Throwable t) {
fatal(command, null, t);
}

@SuppressWarnings("UnusedMethod")
private void fatal(Command<?> command, Object response, Throwable t) {
// note: last line of defense; if this fails then all is lost
setError(command, t);
log.error("Command audit error: {}", command, t);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,10 @@
*/
package org.apache.fineract.infrastructure.bulkimport.service;

import jakarta.ws.rs.core.Response;
import java.io.InputStream;
import java.util.Collection;
import org.apache.fineract.infrastructure.bulkimport.data.GlobalEntityType;
import org.apache.fineract.infrastructure.bulkimport.data.ImportData;
import org.apache.fineract.infrastructure.documentmanagement.data.DocumentData;
import org.glassfish.jersey.media.multipart.FormDataContentDisposition;

public interface BulkImportWorkbookService {
Expand All @@ -32,9 +30,4 @@ Long importWorkbook(String entityType, InputStream inputStream, FormDataContentD
String dateFormat);

Collection<ImportData> getImports(GlobalEntityType type);

DocumentData getOutputTemplateLocation(String importDocumentId);

Response getOutputTemplate(String importDocumentId);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 org.apache.fineract.infrastructure.documentmanagement.adapter;

import java.io.Serial;
import java.io.Serializable;
import java.util.Optional;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

// NOTE: this is a trick to decouple the entity image IDs from the image service
@Deprecated
public interface EntityImageIdAdapter {

boolean accept(String entityType);

Optional<ImageIdResult> get(Long entityId);

default void set(Long entityId) {
set(entityId, null);
}

void set(Long entityId, Long imageId);

@Builder
@Data
@NoArgsConstructor
@AllArgsConstructor
class ImageIdResult implements Serializable {

@Serial
private static final long serialVersionUID = 1L;

private Long id;
private String displayName;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ public class CurrencyUpdateCommandHandler implements CommandHandler<CurrencyUpda
@Transactional
@Override
public CurrencyUpdateResponse handle(final Command<CurrencyUpdateRequest> command) {
// NOTE: fallback method needs to be in the same class
return writePlatformService.updateAllowedCurrencies(command.getPayload());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
import jakarta.persistence.Entity;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToOne;
import jakarta.persistence.Table;
import jakarta.persistence.UniqueConstraint;
import java.time.LocalDate;
Expand All @@ -33,7 +32,6 @@
import org.apache.fineract.infrastructure.core.api.JsonCommand;
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
import org.apache.fineract.infrastructure.documentmanagement.domain.Image;
import org.apache.fineract.organisation.office.domain.Office;

@Getter
Expand Down Expand Up @@ -81,9 +79,8 @@ public class Staff extends AbstractPersistableCustom<Long> {
@JoinColumn(name = "organisational_role_parent_staff_id")
private Staff organisationalRoleParentStaff;

@OneToOne(optional = true)
@JoinColumn(name = "image_id")
private Image image;
@Column(name = "image_id")
private Long imageId;

public static Staff fromJson(final Office staffOffice, final JsonCommand command) {

Expand Down Expand Up @@ -262,8 +259,4 @@ public Office office() {
return this.office;
}

public void setImage(Image image) {
this.image = image;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 org.apache.fineract.portfolio.client.adapter;

import java.util.Optional;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.infrastructure.documentmanagement.adapter.EntityImageIdAdapter;
import org.apache.fineract.portfolio.client.domain.ClientRepository;
import org.springframework.stereotype.Component;

@Slf4j
@RequiredArgsConstructor
@Component
@Deprecated
final class ClientImageIdAdapter implements EntityImageIdAdapter {

private static final String ENTITY_TYPE = "clients";

private final ClientRepository repository;

@Override
public boolean accept(String entityType) {
return ENTITY_TYPE.equalsIgnoreCase(entityType);
}

@Override
public Optional<ImageIdResult> get(Long entityId) {
return repository.findById(entityId)
.map(client -> ImageIdResult.builder().id(client.getImageId()).displayName(client.getDisplayName()).build());
}

@Override
public void set(Long entityId, Long imageId) {
if (imageId == null) {
repository.removeImageId(entityId);
} else {
repository.updateByIdAndImageId(entityId, imageId);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
import jakarta.persistence.ManyToMany;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany;
import jakarta.persistence.OneToOne;
import jakarta.persistence.Table;
import jakarta.persistence.UniqueConstraint;
import java.time.LocalDate;
Expand All @@ -46,7 +45,6 @@
import org.apache.fineract.infrastructure.core.domain.ExternalId;
import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
import org.apache.fineract.infrastructure.core.service.DateUtils;
import org.apache.fineract.infrastructure.documentmanagement.domain.Image;
import org.apache.fineract.infrastructure.security.service.RandomPasswordGenerator;
import org.apache.fineract.organisation.office.domain.Office;
import org.apache.fineract.organisation.staff.domain.Staff;
Expand All @@ -72,13 +70,9 @@ public class Client extends AbstractAuditableWithUTCDateTimeCustom<Long> {
@JoinColumn(name = "transfer_to_office_id")
private Office transferToOffice;

@OneToOne(optional = true)
@JoinColumn(name = "image_id")
private Image image;
@Column(name = "image_id")
private Long imageId;

/**
* A value from {@link ClientStatus}.
*/
@Column(name = "status_enum", nullable = false)
private Integer status;

Expand Down Expand Up @@ -494,10 +488,6 @@ public Long officeId() {
return this.office.getId();
}

public void setImage(final Image image) {
this.image = image;
}

public String mobileNo() {
return this.mobileNo;
}
Expand All @@ -510,10 +500,6 @@ public void setMobileNo(final String mobileNo) {
this.mobileNo = mobileNo;
}

public boolean isNotStaff() {
return !isStaff();
}

public boolean isStaff() {
return this.isStaff;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import org.apache.fineract.portfolio.client.domain.search.SearchingClientRepository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

Expand All @@ -46,4 +47,11 @@ Client fetchByClientIdAndHierarchy(@Param("clientId") Long clientId, @Param("off
@Query("SELECT c.id FROM Client c WHERE c.externalId = :externalId")
Long findIdByExternalId(@Param("externalId") ExternalId externalId);

@Modifying
@Query("UPDATE Client client SET client.imageId = :imageId WHERE client.id = :clientId")
void updateByIdAndImageId(@Param("clientId") Long staffId, @Param("imageId") Long imageId);

@Modifying
@Query("UPDATE Client client SET client.imageId = null WHERE client.id = :clientId")
void removeImageId(@Param("clientId") Long clientId);
}
Loading
Loading