Merge pull request #42 from Kitzanos/fature/GEPAFINBE-44
GEPAFINBE-44 (Beneficiario must be able to download Call Documents)
This commit is contained in:
@@ -201,5 +201,7 @@ public class GepafinConstant {
|
|||||||
public static final String DELEGATION_DELETE_SUCCESS = "delegation.delete.success";
|
public static final String DELEGATION_DELETE_SUCCESS = "delegation.delete.success";
|
||||||
public static final String USER_NOT_AUTHORIZED_TO_CREATE_APPLICATION = "user.not.authorized.create.application";
|
public static final String USER_NOT_AUTHORIZED_TO_CREATE_APPLICATION = "user.not.authorized.create.application";
|
||||||
public static final String APPLICATION_SUBMITTED_CANNOT_CHANGE = "application.submitted.cannot.change";
|
public static final String APPLICATION_SUBMITTED_CANNOT_CHANGE = "application.submitted.cannot.change";
|
||||||
|
public static final String CALL_DOCUMENTS_FETCH_SUCCESS_MSG = "call.documents.fetch.success";
|
||||||
|
public static final String CALL_DOCUMENTS_NOT_FOUND_MSG = "call.documents.not.found";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
package net.gepafin.tendermanagement.dao;
|
package net.gepafin.tendermanagement.dao;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
@@ -8,13 +12,21 @@ import java.util.ArrayList;
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.zip.ZipEntry;
|
||||||
|
import java.util.zip.ZipOutputStream;
|
||||||
|
|
||||||
import net.gepafin.tendermanagement.enums.DocumentSourceTypeEnum;
|
import net.gepafin.tendermanagement.enums.DocumentSourceTypeEnum;
|
||||||
import net.gepafin.tendermanagement.model.response.*;
|
import net.gepafin.tendermanagement.model.response.*;
|
||||||
import net.gepafin.tendermanagement.service.*;
|
import net.gepafin.tendermanagement.service.*;
|
||||||
import net.gepafin.tendermanagement.util.DateTimeUtil;
|
import net.gepafin.tendermanagement.util.DateTimeUtil;
|
||||||
import net.gepafin.tendermanagement.util.Utils;
|
import net.gepafin.tendermanagement.util.Utils;
|
||||||
|
import org.h2.util.IOUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.http.HttpHeaders;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
@@ -85,6 +97,10 @@ public class CallDao {
|
|||||||
private FlowDao flowDao;
|
private FlowDao flowDao;
|
||||||
@Autowired
|
@Autowired
|
||||||
private FormDao formDao;
|
private FormDao formDao;
|
||||||
|
@Value("${aws.s3.url.folder}")
|
||||||
|
private String s3Folder;
|
||||||
|
@Autowired
|
||||||
|
private AmazonS3Service amazonS3Service;
|
||||||
|
|
||||||
public CallResponse createCallStep1(CreateCallRequestStep1 createCallRequest, Long userId) {
|
public CallResponse createCallStep1(CreateCallRequestStep1 createCallRequest, Long userId) {
|
||||||
UserEntity userEntity = userService.validateUser(userId);
|
UserEntity userEntity = userService.validateUser(userId);
|
||||||
@@ -101,6 +117,35 @@ public class CallDao {
|
|||||||
return createCallResponseBean;
|
return createCallResponseBean;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
public byte[] downloadCallDocumentsAsZip(Long callId) {
|
||||||
|
List<DocumentEntity> documents = documentRepository.findBySourceIdAndSourceAndTypeAndIsDeletedFalse(callId, DocumentSourceTypeEnum.CALL.getValue(),DocumentTypeEnum.DOCUMENT.getValue());
|
||||||
|
if (documents.isEmpty()) {
|
||||||
|
throw new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.DOCUMENT_NOT_FOUND));
|
||||||
|
}
|
||||||
|
|
||||||
|
try (ByteArrayOutputStream zipOutputStream = new ByteArrayOutputStream();
|
||||||
|
ZipOutputStream zos = new ZipOutputStream(zipOutputStream)) {
|
||||||
|
|
||||||
|
for (DocumentEntity document : documents) {
|
||||||
|
try (InputStream fileInputStream = amazonS3Service.getFile(s3Folder, document.getFileName())) {
|
||||||
|
ZipEntry zipEntry = new ZipEntry(document.getFileName());
|
||||||
|
zos.putNextEntry(zipEntry);
|
||||||
|
IOUtils.copy(fileInputStream, zos);
|
||||||
|
zos.closeEntry();
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException("Error downloading or adding document to ZIP: " + document.getFileName(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
zos.finish();
|
||||||
|
return zipOutputStream.toByteArray();
|
||||||
|
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException("Error while creating ZIP file", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public CallEntity convertToCallEntity(CreateCallRequestStep1 createCallRequest) {
|
public CallEntity convertToCallEntity(CreateCallRequestStep1 createCallRequest) {
|
||||||
CallEntity callEntity = new CallEntity();
|
CallEntity callEntity = new CallEntity();
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ public interface DocumentRepository extends JpaRepository<DocumentEntity, Long>
|
|||||||
Optional<DocumentEntity> findByIdAndSourceIdAndIsDeletedFalse(Long id, Long sourceId);
|
Optional<DocumentEntity> findByIdAndSourceIdAndIsDeletedFalse(Long id, Long sourceId);
|
||||||
|
|
||||||
List<DocumentEntity> findBySource(String source);
|
List<DocumentEntity> findBySource(String source);
|
||||||
|
List<DocumentEntity> findBySourceIdAndSourceAndTypeAndIsDeletedFalse(Long sourceId, String source, String type);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,5 +32,5 @@ public interface CallService {
|
|||||||
CallEntity validateCall(Long callId);
|
CallEntity validateCall(Long callId);
|
||||||
|
|
||||||
CallEntity validatePublishedCall(Long callId);
|
CallEntity validatePublishedCall(Long callId);
|
||||||
|
byte[] downloadCallDocumentsAsZip(Long callId);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -92,4 +92,9 @@ public class CallServiceImpl implements CallService {
|
|||||||
public CallEntity validatePublishedCall(Long callId) {
|
public CallEntity validatePublishedCall(Long callId) {
|
||||||
return callDao.validatePublishedCall(callId);
|
return callDao.validatePublishedCall(callId);
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
|
@Transactional(readOnly = true)
|
||||||
|
public byte[] downloadCallDocumentsAsZip(Long callId) {
|
||||||
|
return callDao.downloadCallDocumentsAsZip(callId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -134,4 +134,19 @@ public interface CallApi {
|
|||||||
public ResponseEntity<Response<CallResponse>> updateCallStatus(HttpServletRequest request,
|
public ResponseEntity<Response<CallResponse>> updateCallStatus(HttpServletRequest request,
|
||||||
@Parameter(description = "The call id", required = true) @PathVariable("callId") Long callId,
|
@Parameter(description = "The call id", required = true) @PathVariable("callId") Long callId,
|
||||||
@Parameter(description = "status", required = true)@RequestParam(value = "status", required = true) CallStatusEnum status);
|
@Parameter(description = "status", required = true)@RequestParam(value = "status", required = true) CallStatusEnum status);
|
||||||
|
|
||||||
|
@Operation(summary = "Api to download call documents as a ZIP file",
|
||||||
|
responses = {
|
||||||
|
@ApiResponse(responseCode = "200", description = "OK"),
|
||||||
|
@ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
|
||||||
|
@ExampleObject(value = ErrorConstants.NOTFOUND_ERROR_EXAMPLE)})),
|
||||||
|
@ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
|
||||||
|
@ExampleObject(value = ErrorConstants.UNAUTHORIZED_ERROR_EXAMPLE)})),
|
||||||
|
@ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
|
||||||
|
@ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE)}))
|
||||||
|
})
|
||||||
|
@GetMapping(value = "/{callId}/documents/zip")
|
||||||
|
ResponseEntity<byte[]> downloadCallDocumentsAsZip(HttpServletRequest httpServletRequest,
|
||||||
|
@Parameter(description = "The call ID", required = true) @PathVariable("callId") Long callId);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,9 @@ import java.util.List;
|
|||||||
|
|
||||||
import net.gepafin.tendermanagement.enums.CallStatusEnum;
|
import net.gepafin.tendermanagement.enums.CallStatusEnum;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
@@ -84,4 +86,22 @@ public class CallApiController implements CallApi {
|
|||||||
CallResponse updateCall = callService.updateCallStatus(request, callId, status);
|
CallResponse updateCall = callService.updateCallStatus(request, callId, status);
|
||||||
return ResponseEntity.ok(new Response<>(updateCall, Status.SUCCESS, Translator.toLocale(GepafinConstant.UPDATE_CALL_STATUS_SUCCESS_MSG)));
|
return ResponseEntity.ok(new Response<>(updateCall, Status.SUCCESS, Translator.toLocale(GepafinConstant.UPDATE_CALL_STATUS_SUCCESS_MSG)));
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
|
public ResponseEntity<byte[]> downloadCallDocumentsAsZip(HttpServletRequest request, Long callId) {
|
||||||
|
byte[] zipFile = callService.downloadCallDocumentsAsZip(callId);
|
||||||
|
|
||||||
|
HttpHeaders headers = new HttpHeaders();
|
||||||
|
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
|
||||||
|
headers.setContentDispositionFormData("attachment", "documents.zip");
|
||||||
|
|
||||||
|
if (zipFile == null || zipFile.length == 0) {
|
||||||
|
String notFoundMessage = Translator.toLocale(GepafinConstant.CALL_DOCUMENTS_NOT_FOUND_MSG);
|
||||||
|
return ResponseEntity.status(HttpStatus.NOT_FOUND)
|
||||||
|
.body(notFoundMessage.getBytes());
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ResponseEntity<>(zipFile, headers, HttpStatus.OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -226,5 +226,8 @@ user.company.relation.not.found=User with the specified company relation not fou
|
|||||||
delegation.delete.success=Delegation deleted successfully.
|
delegation.delete.success=Delegation deleted successfully.
|
||||||
user.not.authorized.create.application=User must be a legal representative or have delegation.
|
user.not.authorized.create.application=User must be a legal representative or have delegation.
|
||||||
application.submitted.cannot.change=The submitted application cannot be changed.
|
application.submitted.cannot.change=The submitted application cannot be changed.
|
||||||
|
# Call Document Messages
|
||||||
|
call.documents.fetch.success=Documents fetched successfully.
|
||||||
|
call.documents.not.found=No documents found for the specified call.
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -222,5 +222,8 @@ delegation.delete.success=Delega eliminata con successo.
|
|||||||
user.not.authorized.create.application=L'utente deve essere un rappresentante legale o avere una delega.
|
user.not.authorized.create.application=L'utente deve essere un rappresentante legale o avere una delega.
|
||||||
application.submitted.cannot.change=La domanda inviata non può essere modificata.
|
application.submitted.cannot.change=La domanda inviata non può essere modificata.
|
||||||
|
|
||||||
|
# Call Document Messages
|
||||||
|
call.documents.fetch.success=Documenti recuperati con successo.
|
||||||
|
call.documents.not.found=Nessun documento trovato per la chiamata specificata.
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user