From c43de36cc0c04a077012edc7d5beeb8c075c5bd3 Mon Sep 17 00:00:00 2001 From: rajesh Date: Thu, 26 Mar 2026 16:30:31 +0530 Subject: [PATCH] Done task GEPAFINBE-6311 Implemented upload application company document flow --- .../dao/ApplicationEvaluationDao.java | 7 ++ .../dao/CompanyDocumentDao.java | 106 +++++++++++++++--- .../tendermanagement/dao/NotificationDao.java | 36 +++++- .../entities/CompanyDocumentEntity.java | 2 + .../enums/CompanyDocumentTypeEnum.java | 3 +- .../enums/UserActionContextEnum.java | 1 + .../ApplicationEvaluationFormResponse.java | 1 + .../ApplicationEvaluationResponse.java | 1 + .../response/CompanyDocumentResponseBean.java | 2 + .../CompanyDocumentRepository.java | 2 + .../UserWithCompanyRepository.java | 2 + .../CompanyDocumentExpirationScheduler.java | 2 +- .../service/CompanyDocumentService.java | 2 +- .../impl/CompanyDocumentServiceImpl.java | 16 +++ .../web/rest/api/CompanyDocumentApi.java | 22 ++++ .../impl/CompanyDocumentApiControlller.java | 8 ++ .../db/changelog/db.changelog-1.0.0.xml | 7 ++ 17 files changed, 197 insertions(+), 23 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java index d5edecb7..052feb17 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java @@ -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; } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/CompanyDocumentDao.java b/src/main/java/net/gepafin/tendermanagement/dao/CompanyDocumentDao.java index 2eba35f5..ac92bf04 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/CompanyDocumentDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/CompanyDocumentDao.java @@ -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 uploadInstructorCompanyDocumentToApplication(Long userId, List 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 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 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 uploadFileForCompany(Long userId, List 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 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 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 listApplicationCompanyDocumentsForEvaluation(Long applicationId, Long companyId) { + if (applicationId == null || companyId == null) { + return List.of(); + } + List entities = companyDocumentRepository.findByApplicationIdAndCompanyIdAndTypeAndStatusNot( + applicationId, + companyId, + CompanyDocumentTypeEnum.APPLICATION_DOCUMENT.getValue(), + CompanyDocumentStatusEnum.EXPIRED.getValue()); + return entities.stream().map(this::convertToCompanyDocumentResponseBean).collect(Collectors.toList()); + } } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/NotificationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/NotificationDao.java index 57236418..2f923c3d 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/NotificationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/NotificationDao.java @@ -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 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 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 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> getNotificationsByUserIdAndCompanyIdByPagination(Long userId, Long companyId, NotificationRequestBean notificationRequestBean) { diff --git a/src/main/java/net/gepafin/tendermanagement/entities/CompanyDocumentEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/CompanyDocumentEntity.java index 1a08fffc..22ebd420 100644 --- a/src/main/java/net/gepafin/tendermanagement/entities/CompanyDocumentEntity.java +++ b/src/main/java/net/gepafin/tendermanagement/entities/CompanyDocumentEntity.java @@ -44,5 +44,7 @@ public class CompanyDocumentEntity extends BaseEntity { @JoinColumn(name = "DOCUMENT_CATEGORY_ID") private DocumentCategoryEntity categoryEntity; + @Column(name = "APPLICATION_ID") + private Long applicationId; } diff --git a/src/main/java/net/gepafin/tendermanagement/enums/CompanyDocumentTypeEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/CompanyDocumentTypeEnum.java index 9b163da0..973d17c4 100644 --- a/src/main/java/net/gepafin/tendermanagement/enums/CompanyDocumentTypeEnum.java +++ b/src/main/java/net/gepafin/tendermanagement/enums/CompanyDocumentTypeEnum.java @@ -2,7 +2,8 @@ package net.gepafin.tendermanagement.enums; public enum CompanyDocumentTypeEnum { COMPANY_DOCUMENT("COMPANY_DOCUMENT"), - PERSONAL_DOCUMENT("PERSONAL_DOCUMENT"); + PERSONAL_DOCUMENT("PERSONAL_DOCUMENT"), + APPLICATION_DOCUMENT("APPLICATION_DOCUMENT"); private String value; diff --git a/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java index 9dc8b16d..5cf65f56 100644 --- a/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java +++ b/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java @@ -204,6 +204,7 @@ public enum UserActionContextEnum { GET_COMPANY_DOCUMENT("GET_COMPANY_DOCUMENT"), DELETE_COMPANY_DOCUMENT("DELETE_COMPANY_DOCUMENT"), UPLOAD_COMPANY_DOCUMENT("UPLOAD_COMPANY_DOCUMENT"), + UPLOAD_COMPANY_APPLICATION_DOCUMENT("UPLOAD_COMPANY_APPLICATION_DOCUMENT"), UPLOAD_COMPANY_PERSONAL_DOCUMENT("UPLOAD_COMPANY_PERSONAL_DOCUMENT"), GET_ALL_COMPANY_DOCUMENT("GET_ALL_COMPANY_DOCUMENT"), UPDATE_COMPANY_DOCUMENT("UPDATE_COMPANY_DOCUMENT"), diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationEvaluationFormResponse.java b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationEvaluationFormResponse.java index 3903daed..4e117c6f 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationEvaluationFormResponse.java +++ b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationEvaluationFormResponse.java @@ -24,6 +24,7 @@ public class ApplicationEvaluationFormResponse { private ApplicationEvaluationFormResponseBean applicationEvaluationFormResponse; private List files; private List evaluationDocument; + private List applicationCompanyDocuments; private List amendmentDetails; private LocalDateTime createdDate; private LocalDateTime updatedDate; diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationEvaluationResponse.java b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationEvaluationResponse.java index d05f5816..86788e88 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationEvaluationResponse.java +++ b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationEvaluationResponse.java @@ -25,6 +25,7 @@ public class ApplicationEvaluationResponse { private List checklist; private List files; private List evaluationDocument; + private List applicationCompanyDocuments; private List amendmentDetails; private LocalDateTime createdDate; private LocalDateTime updatedDate; diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/CompanyDocumentResponseBean.java b/src/main/java/net/gepafin/tendermanagement/model/response/CompanyDocumentResponseBean.java index 73c13fdc..47aa3d00 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/response/CompanyDocumentResponseBean.java +++ b/src/main/java/net/gepafin/tendermanagement/model/response/CompanyDocumentResponseBean.java @@ -26,6 +26,8 @@ public class CompanyDocumentResponseBean extends BaseBean { private Long userWithCompanyId; + private Long applicationId; + private DocumentCategoryResponse category; } diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/CompanyDocumentRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/CompanyDocumentRepository.java index c37b993a..39731a4e 100644 --- a/src/main/java/net/gepafin/tendermanagement/repositories/CompanyDocumentRepository.java +++ b/src/main/java/net/gepafin/tendermanagement/repositories/CompanyDocumentRepository.java @@ -37,5 +37,7 @@ public interface CompanyDocumentRepository extends JpaRepository findByIdInAndIsDeletedFalseAndStatusNot(List ids, String status); + List findByApplicationIdAndCompanyIdAndTypeAndStatusNot( + Long applicationId, Long companyId, String type, String status); } diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/UserWithCompanyRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/UserWithCompanyRepository.java index 13a197f1..357c3b0e 100644 --- a/src/main/java/net/gepafin/tendermanagement/repositories/UserWithCompanyRepository.java +++ b/src/main/java/net/gepafin/tendermanagement/repositories/UserWithCompanyRepository.java @@ -20,4 +20,6 @@ public interface UserWithCompanyRepository extends JpaRepository findByCompanyIdAndIsDeletedFalse(Long companyId); + } diff --git a/src/main/java/net/gepafin/tendermanagement/scheduler/CompanyDocumentExpirationScheduler.java b/src/main/java/net/gepafin/tendermanagement/scheduler/CompanyDocumentExpirationScheduler.java index e5a40408..6cd8b592 100644 --- a/src/main/java/net/gepafin/tendermanagement/scheduler/CompanyDocumentExpirationScheduler.java +++ b/src/main/java/net/gepafin/tendermanagement/scheduler/CompanyDocumentExpirationScheduler.java @@ -38,7 +38,7 @@ public class CompanyDocumentExpirationScheduler { @Autowired private ExpirationConfigRepository expirationConfigRepository; - private static final Logger log = LoggerFactory.getLogger(ExpirationScheduler.class); + private static final Logger log = LoggerFactory.getLogger(CompanyDocumentExpirationScheduler.class); @Scheduled(cron = "0 0 4 * * ?") public void processDocumentExpiration(){ diff --git a/src/main/java/net/gepafin/tendermanagement/service/CompanyDocumentService.java b/src/main/java/net/gepafin/tendermanagement/service/CompanyDocumentService.java index ab640840..69cd7391 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/CompanyDocumentService.java +++ b/src/main/java/net/gepafin/tendermanagement/service/CompanyDocumentService.java @@ -24,6 +24,6 @@ public interface CompanyDocumentService { List getAllCompanyDocument(HttpServletRequest request ,Long companyId , CompanyDocumentTypeEnum typeEnum); - + List uploadInstructorCompanyDocumentToApplication(HttpServletRequest request, List files, Long companyId, Long applicationId, Long documentCategoryId, LocalDateTime expirationDate, String name); } diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/CompanyDocumentServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/CompanyDocumentServiceImpl.java index b76a82f0..2281a79a 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/CompanyDocumentServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/CompanyDocumentServiceImpl.java @@ -2,6 +2,7 @@ package net.gepafin.tendermanagement.service.impl; import jakarta.servlet.http.HttpServletRequest; import net.gepafin.tendermanagement.dao.CompanyDocumentDao; +import net.gepafin.tendermanagement.entities.CompanyEntity; import net.gepafin.tendermanagement.entities.UserEntity; import net.gepafin.tendermanagement.enums.CompanyDocumentTypeEnum; import net.gepafin.tendermanagement.enums.DocumentTypeEnum; @@ -9,6 +10,7 @@ import net.gepafin.tendermanagement.model.request.CompanyDocumentRequest; import net.gepafin.tendermanagement.model.response.CompanyDocumentResponseBean; import net.gepafin.tendermanagement.model.response.DocumentResponseBean; import net.gepafin.tendermanagement.service.CompanyDocumentService; +import net.gepafin.tendermanagement.service.CompanyService; import net.gepafin.tendermanagement.util.Utils; import net.gepafin.tendermanagement.util.Validator; import org.springframework.beans.factory.annotation.Autowired; @@ -28,6 +30,9 @@ public class CompanyDocumentServiceImpl implements CompanyDocumentService { @Autowired private CompanyDocumentDao companyDocumentDao; + @Autowired + private CompanyService companyService; + @Override public List uploadFileForCompany(HttpServletRequest request, List files, Long companyId, Long documentCategoryId , CompanyDocumentTypeEnum documentSourceTypeEnum, LocalDateTime expirationDate,String name) { Map userInfo = validator.getUserInfoFromToken(request); @@ -37,6 +42,17 @@ public class CompanyDocumentServiceImpl implements CompanyDocumentService { return companyDocumentDao.uploadFileForCompany(userId,files,companyId,documentCategoryId,documentSourceTypeEnum,expirationDate,name); } + @Override + public List uploadInstructorCompanyDocumentToApplication(HttpServletRequest request, List files, Long companyId, Long applicationId, Long documentCategoryId, LocalDateTime expirationDate, String name) { + Map userInfo = validator.getUserInfoFromToken(request); + Long userId = validator.getUserId(userInfo); + files.forEach(Utils::validateFileType); + validator.validateUser(request); + CompanyEntity company = companyService.validateCompany(companyId); + validator.validateHubId(request, company.getHub().getId()); + return companyDocumentDao.uploadInstructorCompanyDocumentToApplication(userId, files, companyId, applicationId, documentCategoryId, expirationDate, name); + } + @Override public CompanyDocumentResponseBean updateCompanyDocument(HttpServletRequest request, Long companyDocumentId, CompanyDocumentRequest companyDocumentRequest) { validator.validateUser(request); diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/CompanyDocumentApi.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/CompanyDocumentApi.java index fdd53635..4b8656ca 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/CompanyDocumentApi.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/CompanyDocumentApi.java @@ -19,6 +19,7 @@ import org.springframework.format.annotation.DateTimeFormat; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; @@ -48,6 +49,27 @@ public interface CompanyDocumentApi { return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED); } + @PreAuthorize("hasRole('ROLE_SUPER_ADMIN') || hasRole('ROLE_INSTRUCTOR_MANAGER') || hasRole('ROLE_PRE_INSTRUCTOR')") + @Operation(summary = "API to upload company document for an application (Only for instructor)", + 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) }))}) + @PostMapping(value = "company/{companyId}/application/{applicationId}/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) + default ResponseEntity>> uploadInstructorCompanyDocumentToApplication(HttpServletRequest httpServletRequest, + @Parameter(description = "Company Id", required = true) @PathVariable("companyId") Long companyId, + @Parameter(description = "Application Id", required = true) @PathVariable("applicationId") Long applicationId, + @Parameter(description = "Document category id", required = true) @RequestParam(value = "documentCategoryId") Long documentCategoryId, + @Parameter(description = "Display name", required = true) @RequestParam(value = "name") String name, + @Parameter(description = "Expiration date (ISO-8601)", required = true) @RequestParam("expirationDate") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime expirationDate, + @RequestParam("file") List files) { + return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED); + } + @Operation(summary = "Api to update company document", responses = { @ApiResponse(responseCode = "200", description = "OK"), diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/CompanyDocumentApiControlller.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/CompanyDocumentApiControlller.java index 543ec40d..191d7a31 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/CompanyDocumentApiControlller.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/CompanyDocumentApiControlller.java @@ -57,6 +57,14 @@ public class CompanyDocumentApiControlller implements CompanyDocumentApi { } } + @Override + public ResponseEntity>> uploadInstructorCompanyDocumentToApplication(HttpServletRequest request, Long companyId, Long applicationId, Long documentCategoryId, String name, LocalDateTime expirationDate, List files) { + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.UPLOAD).actionContext(UserActionContextEnum.UPLOAD_COMPANY_DOCUMENT_TO_APPLICATION).build()); + List responseBeans = companyDocumentService.uploadInstructorCompanyDocumentToApplication(request, files, companyId, applicationId, documentCategoryId, expirationDate, name); + return ResponseEntity.status(HttpStatus.CREATED) + .body(new Response<>(responseBeans, Status.SUCCESS, Translator.toLocale(GepafinConstant.FILES_UPLOADED_MSG))); + } + @Override public ResponseEntity> updateCompanyDocument(HttpServletRequest httpServletRequest, Long companyDocumentId, CompanyDocumentRequest companyDocumentRequest) { diff --git a/src/main/resources/db/changelog/db.changelog-1.0.0.xml b/src/main/resources/db/changelog/db.changelog-1.0.0.xml index 173a6bd4..8f066cc5 100644 --- a/src/main/resources/db/changelog/db.changelog-1.0.0.xml +++ b/src/main/resources/db/changelog/db.changelog-1.0.0.xml @@ -3213,4 +3213,11 @@ + + + + + + +