FINERACT-2246: New command processing - document management
This commit is contained in:
committed by
Aleksandar Vidakovic
parent
8a61e30a45
commit
2ff0c62f40
+8
@@ -19,7 +19,13 @@
|
||||
package org.apache.fineract.infrastructure.bulkimport.data;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Data
|
||||
public final class ImportData {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@@ -27,6 +33,8 @@ public final class ImportData {
|
||||
@SuppressWarnings("unused")
|
||||
private Long documentId;
|
||||
@SuppressWarnings("unused")
|
||||
private Integer entityType;
|
||||
@SuppressWarnings("unused")
|
||||
private String name;
|
||||
@SuppressWarnings("unused")
|
||||
private LocalDate importTime;
|
||||
|
||||
+1
-6
@@ -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 {
|
||||
@@ -33,8 +31,5 @@ public interface BulkImportWorkbookService {
|
||||
|
||||
Collection<ImportData> getImports(GlobalEntityType type);
|
||||
|
||||
DocumentData getOutputTemplateLocation(String importDocumentId);
|
||||
|
||||
Response getOutputTemplate(String importDocumentId);
|
||||
|
||||
ImportData getImport(Long id);
|
||||
}
|
||||
|
||||
+1
@@ -364,6 +364,7 @@ public class FineractProperties {
|
||||
private List<String> regexWhitelist;
|
||||
private boolean mimeWhitelistEnabled;
|
||||
private List<String> mimeWhitelist;
|
||||
private Integer defaultBufferSize;
|
||||
private FineractContentFilesystemProperties filesystem;
|
||||
private FineractContentS3Properties s3;
|
||||
}
|
||||
|
||||
+23
-23
@@ -16,36 +16,36 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.infrastructure.documentmanagement.domain;
|
||||
package org.apache.fineract.infrastructure.documentmanagement.adapter;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.util.Optional;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
public enum StorageType {
|
||||
// NOTE: this is a trick to decouple the entity image IDs from the image service
|
||||
@Deprecated
|
||||
public interface EntityImageIdAdapter {
|
||||
|
||||
FILE_SYSTEM(1), //
|
||||
S3(2); //
|
||||
boolean accept(String entityType);
|
||||
|
||||
private final Integer value;
|
||||
Optional<ImageIdResult> get(Long entityId);
|
||||
|
||||
StorageType(final Integer value) {
|
||||
this.value = value;
|
||||
}
|
||||
Optional<ImageIdResult> set(Long entityId, Long imageId);
|
||||
|
||||
public Integer getValue() {
|
||||
return this.value;
|
||||
}
|
||||
@Builder
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
class ImageIdResult implements Serializable {
|
||||
|
||||
private static final Map<Integer, StorageType> intToEnumMap = new HashMap<>();
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
static {
|
||||
for (final StorageType type : StorageType.values()) {
|
||||
intToEnumMap.put(type.value, type);
|
||||
}
|
||||
}
|
||||
|
||||
public static StorageType fromInt(final int i) {
|
||||
final StorageType type = intToEnumMap.get(Integer.valueOf(i));
|
||||
return type;
|
||||
private Long id;
|
||||
private String displayName;
|
||||
}
|
||||
}
|
||||
-51
@@ -1,51 +0,0 @@
|
||||
/**
|
||||
* 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.data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.fineract.infrastructure.documentmanagement.domain.StorageType;
|
||||
|
||||
/**
|
||||
* Immutable data object representing a user document being managed on the platform.
|
||||
*/
|
||||
@Getter
|
||||
@RequiredArgsConstructor
|
||||
public class DocumentData implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final Long id;
|
||||
private final String parentEntityType;
|
||||
private final Long parentEntityId;
|
||||
private final String name;
|
||||
private final String fileName;
|
||||
private final Long size;
|
||||
private final String type;
|
||||
private final String location;
|
||||
private final String description;
|
||||
private final Integer storageType;
|
||||
|
||||
public StorageType storageType() {
|
||||
return StorageType.fromInt(this.storageType);
|
||||
}
|
||||
}
|
||||
-61
@@ -1,61 +0,0 @@
|
||||
/**
|
||||
* 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.domain;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Table;
|
||||
import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
|
||||
|
||||
@Entity
|
||||
@Table(name = "m_image")
|
||||
public final class Image extends AbstractPersistableCustom<Long> {
|
||||
|
||||
@Column(name = "location", length = 500)
|
||||
private String location;
|
||||
|
||||
@Column(name = "storage_type_enum")
|
||||
private Integer storageType;
|
||||
|
||||
public Image(final String location, final StorageType storageType) {
|
||||
this.location = location;
|
||||
this.storageType = storageType.getValue();
|
||||
}
|
||||
|
||||
Image() {
|
||||
|
||||
}
|
||||
|
||||
public String getLocation() {
|
||||
return this.location;
|
||||
}
|
||||
|
||||
public Integer getStorageType() {
|
||||
return this.storageType;
|
||||
}
|
||||
|
||||
public void setLocation(final String location) {
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
public void setStorageType(final Integer storageType) {
|
||||
this.storageType = storageType;
|
||||
}
|
||||
|
||||
}
|
||||
-1
@@ -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());
|
||||
}
|
||||
|
||||
|
||||
+2
-9
@@ -22,7 +22,6 @@ import jakarta.persistence.Column;
|
||||
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;
|
||||
@@ -33,7 +32,6 @@ import org.apache.commons.lang3.StringUtils;
|
||||
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
|
||||
@@ -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) {
|
||||
|
||||
@@ -262,8 +259,4 @@ public class Staff extends AbstractPersistableCustom<Long> {
|
||||
return this.office;
|
||||
}
|
||||
|
||||
public void setImage(Image image) {
|
||||
this.image = image;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
/**
|
||||
* 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 static java.util.Objects.nonNull;
|
||||
|
||||
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;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
@Component
|
||||
@Deprecated
|
||||
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
|
||||
@Transactional(readOnly = true)
|
||||
public Optional<ImageIdResult> get(Long entityId) {
|
||||
return repository.findById(entityId).filter(client -> nonNull(client.getImageId()))
|
||||
.map(client -> ImageIdResult.builder().id(client.getImageId()).displayName(client.getDisplayName()).build());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public Optional<ImageIdResult> set(Long entityId, Long imageId) {
|
||||
final var result = get(entityId);
|
||||
|
||||
if (imageId == null) {
|
||||
repository.removeImageId(entityId);
|
||||
} else {
|
||||
repository.updateByIdAndImageId(entityId, imageId);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
+2
-16
@@ -27,7 +27,6 @@ import jakarta.persistence.JoinTable;
|
||||
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;
|
||||
@@ -46,7 +45,6 @@ import org.apache.fineract.infrastructure.core.domain.AbstractAuditableWithUTCDa
|
||||
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;
|
||||
@@ -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;
|
||||
|
||||
@@ -494,10 +488,6 @@ public class Client extends AbstractAuditableWithUTCDateTimeCustom<Long> {
|
||||
return this.office.getId();
|
||||
}
|
||||
|
||||
public void setImage(final Image image) {
|
||||
this.image = image;
|
||||
}
|
||||
|
||||
public String mobileNo() {
|
||||
return this.mobileNo;
|
||||
}
|
||||
@@ -510,10 +500,6 @@ public class Client extends AbstractAuditableWithUTCDateTimeCustom<Long> {
|
||||
this.mobileNo = mobileNo;
|
||||
}
|
||||
|
||||
public boolean isNotStaff() {
|
||||
return !isStaff();
|
||||
}
|
||||
|
||||
public boolean isStaff() {
|
||||
return this.isStaff;
|
||||
}
|
||||
|
||||
+8
@@ -22,6 +22,7 @@ import org.apache.fineract.infrastructure.core.domain.ExternalId;
|
||||
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;
|
||||
|
||||
@@ -46,4 +47,11 @@ public interface ClientRepository extends JpaRepository<Client, Long>, JpaSpecif
|
||||
@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);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
/**
|
||||
* 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.util;
|
||||
|
||||
import jakarta.ws.rs.container.AsyncResponse;
|
||||
import jakarta.ws.rs.core.HttpHeaders;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
import jakarta.ws.rs.core.StreamingOutput;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
@Slf4j
|
||||
public final class StreamResponseUtil {
|
||||
|
||||
public static String DISPOSITION_TYPE_ATTACHMENT = "attachment";
|
||||
public static String DISPOSITION_TYPE_INLINE = "inline";
|
||||
|
||||
private static final ExecutorService executor = Executors.newCachedThreadPool();
|
||||
|
||||
private StreamResponseUtil() {}
|
||||
|
||||
public static Response ok(final StreamResponseData content) {
|
||||
final var stream = new StreamingOutput() {
|
||||
|
||||
@Override
|
||||
public void write(OutputStream out) throws IOException {
|
||||
IOUtils.copy(content.getStream(), out);
|
||||
}
|
||||
};
|
||||
|
||||
if (StringUtils.isEmpty(content.getDispositionType())) {
|
||||
return Response.ok(stream, content.getType()).build();
|
||||
} else {
|
||||
return Response.ok(stream, content.getType()).header(HttpHeaders.CONTENT_DISPOSITION,
|
||||
String.format("%s; filename=\"%s\"", content.getDispositionType(), content.getFileName())).build();
|
||||
}
|
||||
}
|
||||
|
||||
public static Future<?> ok(final AsyncResponse asyncResponse, final StreamResponseData content) {
|
||||
return executor.submit(() -> {
|
||||
if (StringUtils.isEmpty(content.getDispositionType())) {
|
||||
asyncResponse.resume(Response.ok(content.getStream(), content.getType()).build());
|
||||
} else {
|
||||
asyncResponse.resume(Response.ok(content.getStream(), content.getType()).header(HttpHeaders.CONTENT_DISPOSITION,
|
||||
String.format("%s; filename=\"%s\"", content.getDispositionType(), content.getFileName())).build());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Builder
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public static final class StreamResponseData {
|
||||
|
||||
private InputStream stream;
|
||||
private String type;
|
||||
private String fileName;
|
||||
private String dispositionType;
|
||||
private Long size;
|
||||
}
|
||||
}
|
||||
-1
@@ -34,7 +34,6 @@
|
||||
<!-- Core Module Entities -->
|
||||
<class>org.apache.fineract.useradministration.domain.Role</class>
|
||||
<class>org.apache.fineract.portfolio.fund.domain.Fund</class>
|
||||
<class>org.apache.fineract.infrastructure.documentmanagement.domain.Image</class>
|
||||
<class>org.apache.fineract.organisation.workingdays.domain.WorkingDays</class>
|
||||
<class>org.apache.fineract.useradministration.domain.Permission</class>
|
||||
<class>org.apache.fineract.useradministration.domain.AppUserClientMapping</class>
|
||||
|
||||
Reference in New Issue
Block a user