package net.gepafin.tendermanagement.dao; import java.util.stream.Collectors; import jakarta.servlet.http.HttpServletRequest; import lombok.extern.slf4j.Slf4j; import net.gepafin.tendermanagement.enums.DocumentSourceTypeEnum; import net.gepafin.tendermanagement.enums.UserActionContextEnum; import net.gepafin.tendermanagement.enums.VersionActionTypeEnum; import net.gepafin.tendermanagement.model.request.VersionHistoryRequest; import net.gepafin.tendermanagement.repositories.ApplicationRepository; import net.gepafin.tendermanagement.util.LoggingUtil; import net.gepafin.tendermanagement.util.Utils; import net.gepafin.tendermanagement.web.rest.api.errors.CustomValidationException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.web.multipart.MultipartFile; import net.gepafin.tendermanagement.config.Translator; import net.gepafin.tendermanagement.constants.GepafinConstant; import net.gepafin.tendermanagement.entities.CallEntity; import net.gepafin.tendermanagement.entities.DocumentEntity; import net.gepafin.tendermanagement.enums.DocumentTypeEnum; import net.gepafin.tendermanagement.model.response.DocumentResponseBean; import net.gepafin.tendermanagement.model.response.UploadFileOnAmazonS3Response; import net.gepafin.tendermanagement.repositories.DocumentRepository; import net.gepafin.tendermanagement.service.AmazonS3Service; import net.gepafin.tendermanagement.service.CallService; import net.gepafin.tendermanagement.web.rest.api.errors.ResourceNotFoundException; import net.gepafin.tendermanagement.web.rest.api.errors.Status; import java.util.ArrayList; import java.util.List; @Slf4j @Component public class DocumentDao { @Autowired private AmazonS3Service amazonS3Service; @Autowired private DocumentRepository documentRepository; @Autowired private CallDao callDao; @Autowired private CallService callService; @Autowired private S3PathConfig s3ConfigBean; @Autowired private ApplicationRepository applicationFormRepository; @Autowired private LoggingUtil loggingUtil; @Autowired private HttpServletRequest request; // @Value("${aws.s3.url.folder}") // private String s3Folder; public List uploadFiles(List files, Long sourceId, DocumentSourceTypeEnum sourceType, DocumentTypeEnum fileType) { List documentEntities = new ArrayList<>(); Long source = resolveSourceId(sourceId, sourceType); for (MultipartFile file : files) { UploadFileOnAmazonS3Response uploadFileOnAmazonS3Response = uploadFileOnAmazonS3(file, sourceType, sourceId); if (uploadFileOnAmazonS3Response != null) { DocumentEntity documentEntity = new DocumentEntity(); documentEntity.setFileName(uploadFileOnAmazonS3Response.getFileName()); documentEntity.setSource(sourceType.getValue()); documentEntity.setSourceId(source); documentEntity.setType(fileType.getValue()); documentEntity.setFilePath(uploadFileOnAmazonS3Response.getFilePath()); documentEntity.setIsDeleted(false); documentEntities.add(documentEntity); } } documentRepository.saveAll(documentEntities); /** This code is responsible for adding a version history log for the "Upload call or application document based on source type" operation. **/ documentEntities.forEach(entity -> loggingUtil.addVersionHistory( VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.INSERT).oldData(null).newData(entity).build())); return documentEntities.stream().map(callDao::convertToDocumentResponseBean).collect(Collectors.toList()); } public UserActionContextEnum getUserActionContextEnum(DocumentSourceTypeEnum sourceType, DocumentTypeEnum fileType) { UserActionContextEnum userActionContext = null; if (fileType.equals(DocumentTypeEnum.DOCUMENT) && sourceType.equals(DocumentSourceTypeEnum.CALL)) { userActionContext = UserActionContextEnum.UPLOAD_CALL_DOCUMENT; } else if (fileType.equals(DocumentTypeEnum.IMAGES) && sourceType.equals(DocumentSourceTypeEnum.CALL)) { userActionContext = UserActionContextEnum.UPLOAD_CALL_IMAGES; } else if (fileType.equals(DocumentTypeEnum.DOCUMENT) && sourceType.equals(DocumentSourceTypeEnum.APPLICATION)) { userActionContext = UserActionContextEnum.UPLOAD_APPLICATION_DOCUMENT; } else if (fileType.equals(DocumentTypeEnum.IMAGES) && sourceType.equals(DocumentSourceTypeEnum.APPLICATION)) { userActionContext = UserActionContextEnum.UPLOAD_APPLICATION_IMAGES; } return userActionContext; } public UserActionContextEnum getUserActionContextForUpdatingDocOrImage(DocumentTypeEnum documentTypeEnum) { UserActionContextEnum userActionContext; if (DocumentTypeEnum.DOCUMENT.equals(documentTypeEnum)) { userActionContext = UserActionContextEnum.UPDATE_DOCUMENT; } else{ userActionContext = UserActionContextEnum.UPDATE_IMAGES; } return userActionContext; } private UploadFileOnAmazonS3Response uploadFileOnAmazonS3(MultipartFile file, DocumentSourceTypeEnum type, Long sourceId) { Long applicationId = 0L; Long callId = sourceId; if (type == DocumentSourceTypeEnum.APPLICATION) { applicationId = sourceId; callId = applicationFormRepository.findCallIdById(applicationId); } try { String s3Path = generateS3Path(type, callId, applicationId); log.info("Generated S3 path {}", s3Path); return amazonS3Service.uploadFileOnAmazonS3(s3Path, file); } catch (Exception e) { throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.UPLOAD_ERROR_S3)); } } public String generateS3Path(DocumentSourceTypeEnum typeOfDocument, Long callId, Long applicationId) { try { return s3ConfigBean.generateDocumentPath(typeOfDocument, callId, applicationId); } catch (IllegalArgumentException e) { throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.S3_PATH_GENERATION_ERROR_MSG)); } } private Long resolveSourceId(Long sourceId, DocumentSourceTypeEnum sourceType) { if (sourceType == DocumentSourceTypeEnum.CALL) { CallEntity callEntity = callService.validateCall(sourceId); // callDao.validateUpdate(callEntity); return callEntity.getId(); } // else if (sourceType == SourceTypeEnum.APPLICATION) { // ApplicationEntity applicationEntity = applicationService.validateApplication(sourceId); // return applicationEntity.getId(); // Assuming ApplicationEntity has getId() // } // return sourceId; } public void deleteFile(Long documentId) { DocumentEntity documentEntity = documentRepository.findById(documentId) .orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.DOCUMENT_NOT_FOUND))); // String fileName= Utils.extractFileName(documentEntity.getFilePath()); // deleteFileOnAmazonS3(fileName); //cloned for old data DocumentEntity oldDocumentEntity = Utils.getClonedEntityForData(documentEntity); // String fileName= Utils.extractFileName(documentEntity.getFilePath()); // deleteFileOnAmazonS3(fileName); documentEntity.setIsDeleted(true); documentRepository.save(documentEntity); /** This code is responsible for adding a version history log for the "Soft delete document" operation. **/ loggingUtil.addVersionHistory( VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.SOFT_DELETE).oldData(oldDocumentEntity).newData(documentEntity).build()); } public DocumentEntity validateDocument(Long id) { return documentRepository.findByIdAndNotDeleted(id).orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.DOCUMENT_NOT_FOUND))); } public DocumentResponseBean updateDocument(Long documentId, MultipartFile file, DocumentTypeEnum documentTypeEnum) { DocumentEntity documentEntity = validateDocument(documentId); //cloned entity for old data DocumentEntity oldDocumentData = Utils.getClonedEntityForData(documentEntity); String type = documentEntity.getSource(); UploadFileOnAmazonS3Response uploadFileOnAmazonS3Response = updateFileOnAmazonS3(file, DocumentSourceTypeEnum.valueOf(type), documentEntity.getSourceId()); if (uploadFileOnAmazonS3Response != null) { documentEntity.setFileName(uploadFileOnAmazonS3Response.getFileName()); documentEntity.setFilePath(uploadFileOnAmazonS3Response.getFilePath()); documentEntity.setType(documentTypeEnum.getValue()); documentEntity.setSource(documentEntity.getSource()); documentEntity.setSourceId(documentEntity.getSourceId()); documentRepository.save(documentEntity); /** This code is responsible for adding a version history log for the "updating doc or image" operation. **/ loggingUtil.addVersionHistory( VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldDocumentData).newData(documentEntity).build()); } return callDao.convertToDocumentResponseBean(documentEntity); } private UploadFileOnAmazonS3Response updateFileOnAmazonS3(MultipartFile file, DocumentSourceTypeEnum type, Long id) { try { Long callId; Long applicationId; if(type.equals(DocumentSourceTypeEnum.APPLICATION)){ callId = applicationFormRepository.findCallIdById(id); applicationId = id; }else{ callId = id; applicationId = 0L; } String s3Path = generateS3Path(type, callId, applicationId); log.info("Generated S3 path {}", s3Path); return amazonS3Service.uploadFileOnAmazonS3(s3Path, file); } catch (Exception e) { throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.UPLOAD_ERROR_S3)); } } public DocumentResponseBean getDocument(Long documentId) { DocumentEntity documentEntity = validateDocument(documentId); return callDao.convertToDocumentResponseBean(documentEntity); } }