Merge pull request #95 from Kitzanos/feature/GEPAFINBE-81
GEPFINBE-81 (Pre Instructor can download all the File inserted by beneficiary in a ZIp)
This commit is contained in:
@@ -290,6 +290,7 @@ public class GepafinConstant {
|
|||||||
public static final String REMINDER_EMAIL_SENT_SUCCESS_MSG = "reminder.email.sent.success.msg";
|
public static final String REMINDER_EMAIL_SENT_SUCCESS_MSG = "reminder.email.sent.success.msg";
|
||||||
public static final String ENCRYPT_INIT_VECTOR = "IG8*(*@&)*#biVVD";
|
public static final String ENCRYPT_INIT_VECTOR = "IG8*(*@&)*#biVVD";
|
||||||
public static final String ENCRYPT_KEY = "U2VjdXJlRW5jcnlwdEtleQ==";
|
public static final String ENCRYPT_KEY = "U2VjdXJlRW5jcnlwdEtleQ==";
|
||||||
|
public static final String APPLICATION_DOCUMENTS_NOT_FOUND_MSG = "application.documents.not.found";
|
||||||
public static final String DUPLICATE_BENEFICIARY_CALL = "beneficiary.call.duplicate";
|
public static final String DUPLICATE_BENEFICIARY_CALL = "beneficiary.call.duplicate";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,12 +4,7 @@ import net.gepafin.tendermanagement.config.Translator;
|
|||||||
import net.gepafin.tendermanagement.constants.GepafinConstant;
|
import net.gepafin.tendermanagement.constants.GepafinConstant;
|
||||||
import net.gepafin.tendermanagement.entities.*;
|
import net.gepafin.tendermanagement.entities.*;
|
||||||
import net.gepafin.tendermanagement.entities.SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum;
|
import net.gepafin.tendermanagement.entities.SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum;
|
||||||
import net.gepafin.tendermanagement.enums.ApplicationSignedDocumentStatusEnum;
|
import net.gepafin.tendermanagement.enums.*;
|
||||||
import net.gepafin.tendermanagement.enums.ApplicationStatusTypeEnum;
|
|
||||||
import net.gepafin.tendermanagement.enums.DocOtherSourceTypeEnum;
|
|
||||||
import net.gepafin.tendermanagement.enums.DocumentSourceTypeEnum;
|
|
||||||
import net.gepafin.tendermanagement.enums.RoleStatusEnum;
|
|
||||||
import net.gepafin.tendermanagement.enums.UserCompanyDelegationStatusEnum;
|
|
||||||
import net.gepafin.tendermanagement.model.request.ApplicationFormFieldRequestBean;
|
import net.gepafin.tendermanagement.model.request.ApplicationFormFieldRequestBean;
|
||||||
import net.gepafin.tendermanagement.model.request.ApplicationRequest;
|
import net.gepafin.tendermanagement.model.request.ApplicationRequest;
|
||||||
import net.gepafin.tendermanagement.model.request.ApplicationRequestBean;
|
import net.gepafin.tendermanagement.model.request.ApplicationRequestBean;
|
||||||
@@ -31,6 +26,7 @@ import net.gepafin.tendermanagement.web.rest.api.errors.CustomValidationExceptio
|
|||||||
import net.gepafin.tendermanagement.web.rest.api.errors.ResourceNotFoundException;
|
import net.gepafin.tendermanagement.web.rest.api.errors.ResourceNotFoundException;
|
||||||
import net.gepafin.tendermanagement.web.rest.api.errors.Status;
|
import net.gepafin.tendermanagement.web.rest.api.errors.Status;
|
||||||
|
|
||||||
|
import org.h2.util.IOUtils;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@@ -42,10 +38,15 @@ import org.springframework.web.multipart.MultipartFile;
|
|||||||
import jakarta.persistence.criteria.Predicate;
|
import jakarta.persistence.criteria.Predicate;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.text.MessageFormat;
|
import java.text.MessageFormat;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.zip.ZipEntry;
|
||||||
|
import java.util.zip.ZipOutputStream;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
public class ApplicationDao {
|
public class ApplicationDao {
|
||||||
@@ -57,7 +58,8 @@ public class ApplicationDao {
|
|||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private ApplicationRepository applicationRepository;
|
private ApplicationRepository applicationRepository;
|
||||||
|
@Autowired
|
||||||
|
private DocumentRepository documentRepository;
|
||||||
@Autowired
|
@Autowired
|
||||||
private ApplicationFormRepository applicationFormRepository;
|
private ApplicationFormRepository applicationFormRepository;
|
||||||
|
|
||||||
@@ -90,9 +92,13 @@ public class ApplicationDao {
|
|||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private CompanyService companyService;
|
private CompanyService companyService;
|
||||||
|
@Autowired
|
||||||
|
private S3PathConfig s3PathConfig;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private SystemEmailTemplatesService systemEmailTemplatesService;
|
private SystemEmailTemplatesService systemEmailTemplatesService;
|
||||||
|
@Autowired
|
||||||
|
private AssignedApplicationsRepository assignedApplicationsRepository;
|
||||||
|
|
||||||
@Value("${default_System_Receiver_Email}")
|
@Value("${default_System_Receiver_Email}")
|
||||||
private String defaultSystemReceiverEmail;
|
private String defaultSystemReceiverEmail;
|
||||||
@@ -969,5 +975,73 @@ public class ApplicationDao {
|
|||||||
applicationEntity = saveApplicationEntity(applicationEntity);
|
applicationEntity = saveApplicationEntity(applicationEntity);
|
||||||
return getApplicationResponse(applicationEntity);
|
return getApplicationResponse(applicationEntity);
|
||||||
}
|
}
|
||||||
|
public byte[] downloadApplicationDocumentsAsZip(HttpServletRequest request,Long applicationId) {
|
||||||
|
ApplicationEntity applicationEntity = validateApplication(applicationId);
|
||||||
|
AssignedApplicationsEntity assignedApplications = assignedApplicationsRepository.findByApplicationIdAndIsDeletedFalse(applicationId).orElse(null);
|
||||||
|
|
||||||
|
List<ApplicationFormEntity> applicationForms = applicationFormRepository.findByApplicationId(applicationId);
|
||||||
|
if(assignedApplications!=null){
|
||||||
|
validator.validatePreInstructor(request,assignedApplications.getUserId());}
|
||||||
|
Set<Long> documentIds = new HashSet<>();
|
||||||
|
applicationForms.forEach(applicationForm -> {
|
||||||
|
FormEntity formEntity = applicationForm.getForm();
|
||||||
|
if (formEntity != null) {
|
||||||
|
List<ContentResponseBean> contentResponseBeans = formDao.convertFormEntityToFormResponseBean(formEntity).getContent();
|
||||||
|
contentResponseBeans.stream()
|
||||||
|
.filter(content -> "fileupload".equals(content.getName()))
|
||||||
|
.forEach(content -> {
|
||||||
|
Optional<ApplicationFormFieldEntity> formField = applicationFormFieldRepository
|
||||||
|
.findByFieldIdAndApplicationFormIdAndApplicationFormApplicationId(
|
||||||
|
content.getId(), applicationForm.getId(), applicationId);
|
||||||
|
formField.ifPresent(field -> {
|
||||||
|
if (field.getFieldValue() != null) {
|
||||||
|
Arrays.stream(field.getFieldValue().split(","))
|
||||||
|
.map(String::trim)
|
||||||
|
.map(Long::valueOf)
|
||||||
|
.forEach(documentIds::add);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
List<DocumentEntity> documents = documentRepository.findAllById(documentIds);
|
||||||
|
ApplicationSignedDocumentEntity signedDocument = applicationSignedDocumentRepository
|
||||||
|
.findByApplicationIdAndStatus(applicationId, ApplicationSignedDocumentStatusEnum.ACTIVE.getValue());
|
||||||
|
if (documents.isEmpty() && signedDocument == null) {
|
||||||
|
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) {
|
||||||
|
String s3Folder = s3PathConfig.generateDocumentPath(DocumentSourceTypeEnum.APPLICATION, applicationEntity.getCall().getId(), applicationId);
|
||||||
|
try (InputStream fileInputStream = amazonS3Service.getFile(s3Folder, document.getFilePath())) {
|
||||||
|
String fileName = Utils.extractFileName(document.getFilePath());
|
||||||
|
zos.putNextEntry(new ZipEntry(fileName));
|
||||||
|
IOUtils.copy(fileInputStream, zos);
|
||||||
|
zos.closeEntry();
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException("Error downloading or adding document to ZIP: " + document.getFileName(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (signedDocument != null) {
|
||||||
|
String s3Folder = s3PathConfig.generateDocumentPathForOther(DocOtherSourceTypeEnum.USER_SIGNED_DOCUMENT, applicationEntity.getCall().getId(), applicationId);
|
||||||
|
try (InputStream fileInputStream = amazonS3Service.getFile(s3Folder, signedDocument.getFilePath())) {
|
||||||
|
String fileName = signedDocument.getFileName();
|
||||||
|
zos.putNextEntry(new ZipEntry(fileName));
|
||||||
|
IOUtils.copy(fileInputStream, zos);
|
||||||
|
zos.closeEntry();
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException("Error downloading or adding signed document to ZIP: " + signedDocument.getFileName(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
zos.finish();
|
||||||
|
return zipOutputStream.toByteArray();
|
||||||
|
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException("Error while creating ZIP file", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,5 +41,5 @@ public interface ApplicationService {
|
|||||||
public void deleteSignedDocument(HttpServletRequest request, Long applicationId);
|
public void deleteSignedDocument(HttpServletRequest request, Long applicationId);
|
||||||
|
|
||||||
public ApplicationResponse validateApplication(HttpServletRequest request, Long applicationId);
|
public ApplicationResponse validateApplication(HttpServletRequest request, Long applicationId);
|
||||||
|
byte[] downloadApplicationDocumentsAsZip(HttpServletRequest request, Long applicationId);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -116,6 +116,10 @@ public class ApplicationServiceImpl implements ApplicationService {
|
|||||||
public ApplicationResponse validateApplication(HttpServletRequest request, Long applicationId) {
|
public ApplicationResponse validateApplication(HttpServletRequest request, Long applicationId) {
|
||||||
return applicationDao.validateApplication(request, applicationId);
|
return applicationDao.validateApplication(request, applicationId);
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
|
@Transactional(readOnly = true)
|
||||||
|
public byte[] downloadApplicationDocumentsAsZip(HttpServletRequest request, Long applicationId) {
|
||||||
|
return applicationDao.downloadApplicationDocumentsAsZip(request,applicationId);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -200,6 +200,18 @@ public interface ApplicationApi {
|
|||||||
ResponseEntity<Response<ApplicationResponse>> validateApplication(HttpServletRequest request,
|
ResponseEntity<Response<ApplicationResponse>> validateApplication(HttpServletRequest request,
|
||||||
@Parameter(description = "The application id", required = true) @PathVariable("applicationId") Long applicationId);
|
@Parameter(description = "The application id", required = true) @PathVariable("applicationId") Long applicationId);
|
||||||
|
|
||||||
|
@Operation(summary = "Api to download all the File inserted by beneficiary in 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 = "/{applicationId}/documents/zip")
|
||||||
|
ResponseEntity<byte[]> downloadApplicationDocumentsAsZip(HttpServletRequest httpServletRequest,
|
||||||
|
@Parameter(required = true) @PathVariable("applicationId") Long applicationId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -148,5 +148,21 @@ public class ApplicationApiController implements ApplicationApi {
|
|||||||
return ResponseEntity.status(HttpStatus.OK)
|
return ResponseEntity.status(HttpStatus.OK)
|
||||||
.body(new Response<>(applicationResponse, Status.SUCCESS, Translator.toLocale(GepafinConstant.APPLICATION_STATUS_UPDATED_SUCCESSFULLY)));
|
.body(new Response<>(applicationResponse, Status.SUCCESS, Translator.toLocale(GepafinConstant.APPLICATION_STATUS_UPDATED_SUCCESSFULLY)));
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
|
public ResponseEntity<byte[]> downloadApplicationDocumentsAsZip(HttpServletRequest request, Long applicationId) {
|
||||||
|
byte[] zipFile = applicationService.downloadApplicationDocumentsAsZip(request, applicationId);
|
||||||
|
|
||||||
|
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.APPLICATION_DOCUMENTS_NOT_FOUND_MSG);
|
||||||
|
return ResponseEntity.status(HttpStatus.NOT_FOUND)
|
||||||
|
.body(notFoundMessage.getBytes());
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ResponseEntity<>(zipFile, headers, HttpStatus.OK);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -306,4 +306,5 @@ comment.not.associate.with.amendment = Comment Not Associated with Amendment Req
|
|||||||
amendment.found.success = Amendment Request Found Successfully.
|
amendment.found.success = Amendment Request Found Successfully.
|
||||||
invalid.amendment.for.comment = Invalid Amendment Request for the Given Comment.
|
invalid.amendment.for.comment = Invalid Amendment Request for the Given Comment.
|
||||||
DD_MM_YYYY_HH_MM = dd_MM_yyyy HH:mm
|
DD_MM_YYYY_HH_MM = dd_MM_yyyy HH:mm
|
||||||
|
application.documents.not.found=No documents found for the application.
|
||||||
beneficiary.call.duplicate = A preferred call with this call ID and company ID already exists for this user.
|
beneficiary.call.duplicate = A preferred call with this call ID and company ID already exists for this user.
|
||||||
@@ -299,6 +299,7 @@ amendment.found.success = Richiesta di emendamento trovata con successo.
|
|||||||
invalid.amendment.for.comment = Richiesta di emendamento non valida per il commento fornito.
|
invalid.amendment.for.comment = Richiesta di emendamento non valida per il commento fornito.
|
||||||
DD_MM_YYYY_HH_MM = dd_MM_yyyy HH:mm
|
DD_MM_YYYY_HH_MM = dd_MM_yyyy HH:mm
|
||||||
create.application.data.amendment.msg =Emendamento alla domanda inviato con successo
|
create.application.data.amendment.msg =Emendamento alla domanda inviato con successo
|
||||||
beneficiary.email.not.found.msg=L'indirizzo email per il beneficiario non è stato trovato. Si prega di assicurarsi che il beneficiario abbia un indirizzo email valido.
|
beneficiary.email.not.found.msg=L'indirizzo email per il beneficiario non <EFBFBD> stato trovato. Si prega di assicurarsi che il beneficiario abbia un indirizzo email valido.
|
||||||
reminder.email.sent.success.msg=Email di promemoria inviata con successo!
|
reminder.email.sent.success.msg=Email di promemoria inviata con successo!
|
||||||
beneficiary.call.duplicate = Una chiamata preferita con questo ID di chiamata e ID azienda esiste già per questo utente.
|
application.documents.not.found=Nessun documento trovato per la domanda.
|
||||||
|
beneficiary.call.duplicate = Una chiamata preferita con questo ID di chiamata e ID azienda esiste gi<67> per questo utente.
|
||||||
|
|||||||
Reference in New Issue
Block a user