Implemented logic to copy company document to evaluation

This commit is contained in:
rajesh
2026-03-30 12:40:02 +05:30
parent c2ad88997f
commit 4a46cf68af
3 changed files with 123 additions and 7 deletions

View File

@@ -218,10 +218,6 @@ public class ApplicationEvaluationDao {
setEvaluationDocResponse(response, allDocs);
setApplicationDetails(response, entity);
setRejectedDocuments(applicationEntity, response);
response.setApplicationCompanyDocuments(
companyDocumentDao.listApplicationCompanyDocumentsForEvaluation(
entity.getApplicationId(), applicationEntity.getCompanyId()));
return response;
}
@@ -2413,7 +2409,6 @@ public class ApplicationEvaluationDao {
response.setAmountAccepted(applicationEvaluationResponse.getAmountAccepted());
response.setDateAccepted(applicationEvaluationResponse.getDateAccepted());
response.setDateRejected(applicationEvaluationResponse.getDateRejected());
response.setApplicationCompanyDocuments(applicationEvaluationResponse.getApplicationCompanyDocuments());
return response;
}

View File

@@ -3,6 +3,7 @@ package net.gepafin.tendermanagement.dao;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.model.CopyObjectRequest;
import com.fasterxml.jackson.core.type.TypeReference;
import jakarta.persistence.criteria.Join;
import jakarta.persistence.criteria.JoinType;
import jakarta.persistence.criteria.Predicate;
@@ -13,11 +14,14 @@ import net.gepafin.tendermanagement.constants.GepafinConstant;
import net.gepafin.tendermanagement.entities.*;
import net.gepafin.tendermanagement.enums.*;
import net.gepafin.tendermanagement.model.request.CompanyDocumentRequest;
import net.gepafin.tendermanagement.model.request.EvaluationDocumentRequest;
import net.gepafin.tendermanagement.model.request.VersionHistoryRequest;
import net.gepafin.tendermanagement.model.response.DocumentCategoryResponse;
import net.gepafin.tendermanagement.model.response.CompanyDocumentResponseBean;
import net.gepafin.tendermanagement.model.response.DocumentResponseBean;
import net.gepafin.tendermanagement.model.response.UploadFileOnAmazonS3Response;
import net.gepafin.tendermanagement.model.util.NanoIdUtils;
import net.gepafin.tendermanagement.repositories.ApplicationEvaluationRepository;
import net.gepafin.tendermanagement.repositories.CompanyDocumentRepository;
import net.gepafin.tendermanagement.repositories.DocumentRepository;
import net.gepafin.tendermanagement.repositories.UserWithCompanyRepository;
@@ -38,7 +42,10 @@ import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import java.net.URL;
import java.security.SecureRandom;
import java.time.LocalDateTime;
import org.apache.commons.lang3.StringUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
@@ -98,13 +105,16 @@ public class CompanyDocumentDao {
@Autowired
private UserWithCompanyRepository userWithCompanyRepository;
@Autowired
private ApplicationEvaluationRepository applicationEvaluationRepository;
/**
* Instructor uploads a company document tied to an application. Files are stored under the same S3 layout as
* {@link CompanyDocumentTypeEnum#COMPANY_DOCUMENT}; persisted row type remains {@link CompanyDocumentTypeEnum#APPLICATION_DOCUMENT}.
*/
public List<CompanyDocumentResponseBean> uploadInstructorCompanyDocumentToApplication(Long userId, List<MultipartFile> files, Long companyId, Long applicationId, Long documentCategoryId, LocalDateTime expirationDate, String name) {
log.info("Instructor upload company document to application. userId={}, companyId={}, applicationId={}", userId, companyId, applicationId);
applicationService.validateApplicationWithCompany(applicationId, companyId);
ApplicationEntity application = applicationService.validateApplicationWithCompany(applicationId, companyId);
DocumentCategoryEntity categoryEntity = categoryDao.validateCategory(documentCategoryId);
Optional<UserWithCompanyEntity> userWithCompanyOpt = userWithCompanyRepository.findByUserIdAndCompanyIdAndIsDeletedFalse(userId, companyId);
@@ -142,6 +152,9 @@ public class CompanyDocumentDao {
companyDocumentRepository.saveAll(companyDocumentEntities);
companyDocumentEntities.forEach(entity -> loggingUtil.addVersionHistory(
VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.INSERT).oldData(null).newData(entity).build()));
copyInstructorCompanyDocumentsToEvaluationDocuments(application, companyDocumentEntities, userId);
return companyDocumentEntities.stream()
.map(this::convertToCompanyDocumentResponseBean)
.collect(Collectors.toList());
@@ -373,6 +386,115 @@ public class CompanyDocumentDao {
return responseBean;
}
/**
* For instructor uploads: copies each saved company document into the evaluation S3 folder, persists
* {@link DocumentEntity} rows (source EVALUATION), and merges entries into the existing {@code EVALUATION_DOCUMENT}
* column ({@link ApplicationEvaluationEntity#getEvaluationDocument()} JSON array of {@link EvaluationDocumentRequest}),
* appending to any data already stored there.
*/
private void copyInstructorCompanyDocumentsToEvaluationDocuments(ApplicationEntity application,
List<CompanyDocumentEntity> instructorCompanyDocuments, Long userId) {
if (instructorCompanyDocuments == null || instructorCompanyDocuments.isEmpty()) {
return;
}
Long evaluationId = application.getApplicationEvaluationId();
if (evaluationId == null || evaluationId <= 0) {
log.debug("Skip evaluation document copy for applicationId={}: no applicationEvaluationId set", application.getId());
return;
}
Optional<ApplicationEvaluationEntity> evaluationOpt = applicationEvaluationRepository.findByIdAndIsDeletedFalse(evaluationId);
if (evaluationOpt.isEmpty()) {
log.warn("Skip evaluation document copy: applicationEvaluationId={} not found or deleted", evaluationId);
return;
}
Long callId = application.getCall().getId();
Long applicationId = application.getId();
String evaluationFolderPath = s3ConfigBean.generateDocumentPath(
DocumentSourceTypeEnum.EVALUATION, callId, applicationId, evaluationId, 0L, 0L);
List<EvaluationDocumentRequest> newEntries = new ArrayList<>();
for (CompanyDocumentEntity companyDoc : instructorCompanyDocuments) {
DocumentEntity saved = persistInstructorCompanyDocumentAsEvaluationDocument(
companyDoc, evaluationFolderPath, evaluationId, userId);
if (saved.getId() == null) {
continue;
}
EvaluationDocumentRequest entry = new EvaluationDocumentRequest();
SecureRandom random = new SecureRandom();
String key = NanoIdUtils.randomNanoId(
random,
NanoIdUtils.DEFAULT_ALPHABET,
10
);
entry.setFieldId(key);
entry.setNameValue(instructorDocumentDisplayName(companyDoc));
entry.setFileValue(String.valueOf(saved.getId()));
entry.setValid(null);
newEntries.add(entry);
}
if (newEntries.isEmpty()) {
return;
}
ApplicationEvaluationEntity evaluation = evaluationOpt.get();
List<EvaluationDocumentRequest> merged = new ArrayList<>(parseEvaluationDocumentJson(evaluation.getEvaluationDocument()));
merged.addAll(newEntries);
evaluation.setEvaluationDocument(Utils.convertObjectToJson(merged));
applicationEvaluationRepository.save(evaluation);
}
private static List<EvaluationDocumentRequest> parseEvaluationDocumentJson(String json) {
if (StringUtils.isBlank(json)) {
return new ArrayList<>();
}
List<EvaluationDocumentRequest> parsed = Utils.convertJsonToList(json,
new TypeReference<List<EvaluationDocumentRequest>>() {});
return parsed != null ? new ArrayList<>(parsed) : new ArrayList<>();
}
private static String instructorDocumentDisplayName(CompanyDocumentEntity companyDoc) {
if (companyDoc == null) {
return "";
}
if (StringUtils.isNotBlank(companyDoc.getName())) {
return companyDoc.getName().trim();
}
return StringUtils.defaultString(companyDoc.getFileName());
}
private DocumentEntity persistInstructorCompanyDocumentAsEvaluationDocument(CompanyDocumentEntity companyDocumentEntity,
String evaluationDocumentFolderPath, Long evaluationId, Long userId) {
String companyDocumentPath = companyDocumentEntity.getFilePath();
log.info("Instructor evaluation copy: companyDocumentId={}, oldPath={}, evaluationFolder={}",
companyDocumentEntity.getId(), companyDocumentPath, evaluationDocumentFolderPath);
UploadFileOnAmazonS3Response response;
try {
response = amazonS3ServiceImpl.copyFile(companyDocumentEntity.getName(), companyDocumentPath, evaluationDocumentFolderPath);
} catch (Exception e) {
log.error("Error copying instructor company document id={} to evaluation folder: {}",
companyDocumentEntity.getId(), e.getMessage(), e);
throw new CustomValidationException(Status.VALIDATION_ERROR,
Translator.toLocale(GepafinConstant.UPLOAD_ERROR_S3));
}
DocumentEntity entity = new DocumentEntity();
entity.setFilePath(response.getFilePath());
entity.setFileName(response.getFileName());
entity.setSource(DocumentSourceTypeEnum.EVALUATION.getValue());
entity.setType(DocumentTypeEnum.DOCUMENT.getValue());
entity.setSourceId(evaluationId);
entity.setUploadedBy(userId);
documentRepository.save(entity);
loggingUtil.addVersionHistory(
VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.INSERT).oldData(null).newData(entity).build());
return entity;
}
public List<CompanyDocumentResponseBean> getAllCompanyDocument(UserEntity user , Long companyId, CompanyDocumentTypeEnum typeEnum){
log.info("Fetching all company documents for Company ID '{}', User ID '{}', Type '{}'", companyId, user.getId(), typeEnum);
CompanyEntity companyEntity = companyService.validateCompany(companyId);

View File

@@ -25,7 +25,6 @@ public class ApplicationEvaluationResponse {
private List<ChecklistResponse> checklist;
private List<FieldResponse> files;
private List<EvaluationDocumentResponse> evaluationDocument;
private List<CompanyDocumentResponseBean> applicationCompanyDocuments;
private List<AmendmentDocumentResponseBean> amendmentDetails;
private LocalDateTime createdDate;
private LocalDateTime updatedDate;