Done task GEPAFINBE-6311 Implemented upload application company document flow
This commit is contained in:
@@ -115,6 +115,9 @@ public class ApplicationEvaluationDao {
|
||||
@Autowired
|
||||
private ApplicationAmendmentRequestDao applicationAmendmentRequestDao;
|
||||
|
||||
@Autowired
|
||||
private CompanyDocumentDao companyDocumentDao;
|
||||
|
||||
@Autowired
|
||||
private HubService hubService;
|
||||
|
||||
@@ -215,6 +218,9 @@ public class ApplicationEvaluationDao {
|
||||
setEvaluationDocResponse(response, allDocs);
|
||||
setApplicationDetails(response, entity);
|
||||
setRejectedDocuments(applicationEntity, response);
|
||||
response.setApplicationCompanyDocuments(
|
||||
companyDocumentDao.listApplicationCompanyDocumentsForEvaluation(
|
||||
entity.getApplicationId(), applicationEntity.getCompanyId()));
|
||||
|
||||
return response;
|
||||
}
|
||||
@@ -2407,6 +2413,7 @@ public class ApplicationEvaluationDao {
|
||||
response.setAmountAccepted(applicationEvaluationResponse.getAmountAccepted());
|
||||
response.setDateAccepted(applicationEvaluationResponse.getDateAccepted());
|
||||
response.setDateRejected(applicationEvaluationResponse.getDateRejected());
|
||||
response.setApplicationCompanyDocuments(applicationEvaluationResponse.getApplicationCompanyDocuments());
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@ 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 jakarta.persistence.criteria.Join;
|
||||
import jakarta.persistence.criteria.JoinType;
|
||||
import jakarta.persistence.criteria.Predicate;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -18,6 +20,7 @@ import net.gepafin.tendermanagement.model.response.DocumentResponseBean;
|
||||
import net.gepafin.tendermanagement.model.response.UploadFileOnAmazonS3Response;
|
||||
import net.gepafin.tendermanagement.repositories.CompanyDocumentRepository;
|
||||
import net.gepafin.tendermanagement.repositories.DocumentRepository;
|
||||
import net.gepafin.tendermanagement.repositories.UserWithCompanyRepository;
|
||||
import net.gepafin.tendermanagement.service.AmazonS3Service;
|
||||
import net.gepafin.tendermanagement.service.ApplicationService;
|
||||
import net.gepafin.tendermanagement.service.CompanyService;
|
||||
@@ -38,6 +41,7 @@ import java.net.URL;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static net.gepafin.tendermanagement.util.Utils.setIfUpdated;
|
||||
@@ -91,6 +95,58 @@ public class CompanyDocumentDao {
|
||||
@Autowired
|
||||
private AmazonS3 amazonS3;
|
||||
|
||||
@Autowired
|
||||
private UserWithCompanyRepository userWithCompanyRepository;
|
||||
|
||||
/**
|
||||
* 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);
|
||||
DocumentCategoryEntity categoryEntity = categoryDao.validateCategory(documentCategoryId);
|
||||
Optional<UserWithCompanyEntity> userWithCompanyOpt = userWithCompanyRepository.findByUserIdAndCompanyIdAndIsDeletedFalse(userId, companyId);
|
||||
|
||||
LocalDateTime currentDate = LocalDateTime.now();
|
||||
if (expirationDate.isBefore(currentDate)) {
|
||||
log.warn("Expiration date {} is before current time {}", expirationDate, currentDate);
|
||||
throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.INVALID_EXPIRATION_DATE));
|
||||
}
|
||||
CompanyDocumentTypeEnum storedType = CompanyDocumentTypeEnum.APPLICATION_DOCUMENT;
|
||||
List<CompanyDocumentEntity> companyDocumentEntities = new ArrayList<>();
|
||||
for (MultipartFile file : files) {
|
||||
log.info("Uploading instructor company document '{}' for companyId={}, applicationId={}", file.getOriginalFilename(), companyId, applicationId);
|
||||
UploadFileOnAmazonS3Response uploadFileOnAmazonS3Response = uploadFileOnAmazonS3(file, CompanyDocumentTypeEnum.COMPANY_DOCUMENT, companyId);
|
||||
if (uploadFileOnAmazonS3Response != null) {
|
||||
CompanyDocumentEntity companyDocumentEntity = new CompanyDocumentEntity();
|
||||
companyDocumentEntity.setFileName(uploadFileOnAmazonS3Response.getFileName());
|
||||
companyDocumentEntity.setCompanyId(companyId);
|
||||
companyDocumentEntity.setApplicationId(applicationId);
|
||||
companyDocumentEntity.setType(storedType.getValue());
|
||||
companyDocumentEntity.setFilePath(uploadFileOnAmazonS3Response.getFilePath());
|
||||
companyDocumentEntity.setIsDeleted(false);
|
||||
companyDocumentEntity.setUploadedBy(userId);
|
||||
companyDocumentEntity.setName(name);
|
||||
if (expirationDate.isBefore(currentDate.plusDays(7))) {
|
||||
companyDocumentEntity.setStatus(CompanyDocumentStatusEnum.DUE.getValue());
|
||||
} else {
|
||||
companyDocumentEntity.setStatus(CompanyDocumentStatusEnum.VALID.getValue());
|
||||
}
|
||||
companyDocumentEntity.setCategoryEntity(categoryEntity);
|
||||
companyDocumentEntity.setUserWithCompany(userWithCompanyOpt.orElse(null));
|
||||
companyDocumentEntity.setExpirationDate(expirationDate);
|
||||
companyDocumentEntities.add(companyDocumentEntity);
|
||||
}
|
||||
}
|
||||
companyDocumentRepository.saveAll(companyDocumentEntities);
|
||||
companyDocumentEntities.forEach(entity -> loggingUtil.addVersionHistory(
|
||||
VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.INSERT).oldData(null).newData(entity).build()));
|
||||
return companyDocumentEntities.stream()
|
||||
.map(this::convertToCompanyDocumentResponseBean)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public List<CompanyDocumentResponseBean> uploadFileForCompany(Long userId, List<MultipartFile> files, Long companyId, Long documentCategoryId, CompanyDocumentTypeEnum companyDocumentSourceTypeEnum, LocalDateTime expirationDate,String name){
|
||||
|
||||
log.info("Uploading files for company. userId={}, companyId={}, documentCategoryId={}", userId, companyId, documentCategoryId);
|
||||
@@ -173,7 +229,9 @@ public class CompanyDocumentDao {
|
||||
public CompanyDocumentResponseBean convertToCompanyDocumentResponseBean(CompanyDocumentEntity entity) {
|
||||
CompanyDocumentResponseBean responseBean = new CompanyDocumentResponseBean();
|
||||
DocumentCategoryEntity categoryEntity = entity.getCategoryEntity();
|
||||
DocumentCategoryResponse responseCategory = categoryDao.convertToResponseBean(categoryEntity);
|
||||
if (categoryEntity != null) {
|
||||
responseBean.setCategory(categoryDao.convertToResponseBean(categoryEntity));
|
||||
}
|
||||
responseBean.setId(entity.getId());
|
||||
responseBean.setFileName(entity.getFileName());
|
||||
responseBean.setType(CompanyDocumentTypeEnum.valueOf(entity.getType()));
|
||||
@@ -182,9 +240,9 @@ public class CompanyDocumentDao {
|
||||
responseBean.setExpirationDate(entity.getExpirationDate());
|
||||
responseBean.setStatus(entity.getStatus());
|
||||
responseBean.setUploadedBy(entity.getUploadedBy());
|
||||
responseBean.setCategory(responseCategory);
|
||||
responseBean.setName(entity.getName());
|
||||
responseBean.setUserWithCompanyId(entity.getUserWithCompany().getId());
|
||||
responseBean.setUserWithCompanyId(entity.getUserWithCompany() != null ? entity.getUserWithCompany().getId() : null);
|
||||
responseBean.setApplicationId(entity.getApplicationId());
|
||||
responseBean.setCreatedDate(entity.getCreatedDate());
|
||||
responseBean.setUpdatedDate(entity.getUpdatedDate());
|
||||
|
||||
@@ -271,6 +329,9 @@ public class CompanyDocumentDao {
|
||||
else if(type.equals(CompanyDocumentTypeEnum.PERSONAL_DOCUMENT)){
|
||||
userActionContext = UserActionContextEnum.UPLOAD_COMPANY_PERSONAL_DOCUMENT;
|
||||
}
|
||||
else if (type.equals(CompanyDocumentTypeEnum.APPLICATION_DOCUMENT)) {
|
||||
userActionContext = UserActionContextEnum.UPLOAD_COMPANY_DOCUMENT_TO_APPLICATION;
|
||||
}
|
||||
return userActionContext;
|
||||
}
|
||||
|
||||
@@ -314,10 +375,14 @@ public class CompanyDocumentDao {
|
||||
|
||||
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);
|
||||
if(Boolean.TRUE.equals(validator.checkIsBeneficiary())) {
|
||||
validator.validateUserWithCompany(request, companyId);
|
||||
CompanyEntity companyEntity = companyService.validateCompany(companyId);
|
||||
if (Boolean.TRUE.equals(validator.checkIsBeneficiary())) {
|
||||
if (typeEnum == CompanyDocumentTypeEnum.PERSONAL_DOCUMENT || typeEnum == null) {
|
||||
validator.validateUserWithCompany(request, companyId);
|
||||
} else {
|
||||
validator.validateHubId(request, companyEntity.getHub().getId());
|
||||
}
|
||||
}
|
||||
companyService.validateCompany(companyId);
|
||||
|
||||
Specification<CompanyDocumentEntity> spec = filterCompanyDocuments(companyId, user.getId(), typeEnum);
|
||||
|
||||
@@ -345,6 +410,9 @@ public class CompanyDocumentDao {
|
||||
// Case 1: Fetch only COMPANY_DOCUMENT type documents for the given company
|
||||
predicate = builder.and(predicate, builder.equal(root.get("type"), CompanyDocumentTypeEnum.COMPANY_DOCUMENT.getValue()));
|
||||
|
||||
} else if (typeEnum == CompanyDocumentTypeEnum.APPLICATION_DOCUMENT) {
|
||||
predicate = builder.and(predicate, builder.equal(root.get("type"), CompanyDocumentTypeEnum.APPLICATION_DOCUMENT.getValue()));
|
||||
|
||||
} else if (typeEnum == CompanyDocumentTypeEnum.PERSONAL_DOCUMENT) {
|
||||
// Case 2: Fetch only PERSONAL_DOCUMENT type documents for the logged-in user
|
||||
predicate = builder.and(
|
||||
@@ -353,20 +421,28 @@ public class CompanyDocumentDao {
|
||||
builder.equal(root.get("userWithCompany").get("userId"), userId)
|
||||
);
|
||||
}
|
||||
}else {
|
||||
// Case 3: If typeEnum is null, fetch all documents for the company and personal documents for the user
|
||||
Predicate companyPredicate = builder.equal(root.get("companyId"), companyId);
|
||||
Predicate personalPredicate = builder.and(
|
||||
builder.equal(root.get("type"), CompanyDocumentTypeEnum.PERSONAL_DOCUMENT.getValue()),
|
||||
builder.equal(root.get("userWithCompany").get("userId"), userId)
|
||||
} else {
|
||||
|
||||
Predicate companyAndApplicationDocs = root.get("type").in(
|
||||
CompanyDocumentTypeEnum.COMPANY_DOCUMENT.getValue(),
|
||||
CompanyDocumentTypeEnum.APPLICATION_DOCUMENT.getValue()
|
||||
);
|
||||
predicate = builder.and(predicate, builder.or(companyPredicate, personalPredicate));
|
||||
predicate = builder.and(predicate, companyAndApplicationDocs);
|
||||
}
|
||||
return predicate;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
public List<CompanyDocumentResponseBean> listApplicationCompanyDocumentsForEvaluation(Long applicationId, Long companyId) {
|
||||
if (applicationId == null || companyId == null) {
|
||||
return List.of();
|
||||
}
|
||||
List<CompanyDocumentEntity> entities = companyDocumentRepository.findByApplicationIdAndCompanyIdAndTypeAndStatusNot(
|
||||
applicationId,
|
||||
companyId,
|
||||
CompanyDocumentTypeEnum.APPLICATION_DOCUMENT.getValue(),
|
||||
CompanyDocumentStatusEnum.EXPIRED.getValue());
|
||||
return entities.stream().map(this::convertToCompanyDocumentResponseBean).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ import org.springframework.stereotype.Component;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
@@ -423,15 +424,40 @@ public class NotificationDao {
|
||||
}
|
||||
|
||||
public void sendNotificationToBeneficiaryForDocumentExpiration(CompanyDocumentEntity companyDocumentEntity, NotificationTypeEnum notificationTypeEnum) {
|
||||
|
||||
CompanyEntity companyEntity = companyService.validateCompany(companyDocumentEntity.getCompanyId());
|
||||
Long companyId = companyDocumentEntity.getCompanyId();
|
||||
if (companyId == null) {
|
||||
log.warn("Skipping document expiration notification: companyId is null for document id {}", companyDocumentEntity.getId());
|
||||
return;
|
||||
}
|
||||
CompanyEntity companyEntity = companyService.validateCompany(companyId);
|
||||
List<UserWithCompanyEntity> linkedUsers = userWithCompanyRepository.findByCompanyIdAndIsDeletedFalse(companyId);
|
||||
if (linkedUsers == null || linkedUsers.isEmpty()) {
|
||||
log.warn("Skipping document expiration notification: no users linked to company {} for document id {}", companyId, companyDocumentEntity.getId());
|
||||
return;
|
||||
}
|
||||
Map<String, String> placeHolders = new HashMap<>();
|
||||
placeHolders.put("{{file_name}}", companyDocumentEntity.getFileName());
|
||||
placeHolders.put("{{company_name}}", companyEntity.getCompanyName());
|
||||
placeHolders.put("{{expiration_date}}", companyDocumentEntity.getExpirationDate().toString());
|
||||
NotificationReq notificationReq = createNotificationReq(notificationTypeEnum.getValue(), placeHolders, companyDocumentEntity.getUserWithCompany().getUserId(), companyDocumentEntity.getUserWithCompany(),
|
||||
listOf(companyDocumentEntity.getCompanyId()));
|
||||
sendNotification(notificationReq);
|
||||
Map<Long, UserWithCompanyEntity> oneRowPerUser = new LinkedHashMap<>();
|
||||
for (UserWithCompanyEntity uwc : linkedUsers) {
|
||||
if (uwc.getUserId() != null) {
|
||||
oneRowPerUser.putIfAbsent(uwc.getUserId(), uwc);
|
||||
}
|
||||
}
|
||||
if (oneRowPerUser.isEmpty()) {
|
||||
log.warn("Skipping document expiration notification: no user ids on USER_WITH_COMPANY for company {}, document id {}", companyId, companyDocumentEntity.getId());
|
||||
return;
|
||||
}
|
||||
for (UserWithCompanyEntity uwc : oneRowPerUser.values()) {
|
||||
NotificationReq notificationReq = createNotificationReq(
|
||||
notificationTypeEnum.getValue(),
|
||||
placeHolders,
|
||||
uwc.getUserId(),
|
||||
uwc,
|
||||
listOf(companyId));
|
||||
sendNotification(notificationReq);
|
||||
}
|
||||
}
|
||||
|
||||
public PageableResponseBean<List<NotificationResponse>> getNotificationsByUserIdAndCompanyIdByPagination(Long userId, Long companyId, NotificationRequestBean notificationRequestBean) {
|
||||
|
||||
Reference in New Issue
Block a user