diff --git a/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java b/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java index 813790f6..bf25387c 100644 --- a/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java +++ b/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java @@ -623,7 +623,14 @@ public class GepafinConstant { public static final List MANUAL_EMAIL_KEYS = Arrays.asList(SUBJECT, MESSAGE); public static final String INVALID_EMAIL_JSON = "invalid.email.json"; public static final String MORE_FIELDS_REQUIRED_FOR_REJECTION="more.fields.required"; - + public static final String CREATE_APPLICATION_CONTRACT="create.application.contract"; + public static final String APPLICATION_CONTRACT_NOT_FOUND="application.contract.not.found"; + public static final String APPLICATION_CONTRACT_FETCHED="application.contract.fetched"; + public static final String APPLICATION_CONTRACT_UPDATED="application.contract.updated"; + public static final String FILES_REQUIRED_FOR_CONTRACT="files.required.for.contract"; + public static final String APPLICATION_CONTRACT_ALREADY_EXIST="application.contract.already.exist"; + public static final String APPLICATION_NOT_APPROVED="application.not.approved"; + public static final String SUBJECT_AND_BODY_REQUIRED="subject.body.required"; } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java index 0a0dd23f..73dc49ad 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java @@ -662,7 +662,7 @@ public class ApplicationAmendmentRequestDao { response.setApplicationFormFields(fileDetails); } - private List getDocumentResponseBean(String documentId) { + public List getDocumentResponseBean(String documentId) { List documentIds = extractIds(documentId); List documentResponseBeans = documentIds.stream() .map(id -> { diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationContractDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationContractDao.java new file mode 100644 index 00000000..e8e0a44d --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationContractDao.java @@ -0,0 +1,220 @@ +package net.gepafin.tendermanagement.dao; + +import jakarta.servlet.http.HttpServletRequest; +import net.gepafin.tendermanagement.config.Translator; +import net.gepafin.tendermanagement.constants.GepafinConstant; +import net.gepafin.tendermanagement.entities.ApplicationContractEntity; +import net.gepafin.tendermanagement.entities.ApplicationEntity; +import net.gepafin.tendermanagement.entities.ApplicationEvaluationEntity; +import net.gepafin.tendermanagement.entities.UserEntity; +import net.gepafin.tendermanagement.enums.*; +import net.gepafin.tendermanagement.model.request.ApplicationContractRequest; +import net.gepafin.tendermanagement.model.request.VersionHistoryRequest; +import net.gepafin.tendermanagement.model.response.ApplicationContractResponse; +import net.gepafin.tendermanagement.model.response.DocumentResponseBean; +import net.gepafin.tendermanagement.repositories.ApplicationContractRepository; +import net.gepafin.tendermanagement.repositories.ApplicationRepository; +import net.gepafin.tendermanagement.util.DateTimeUtil; +import net.gepafin.tendermanagement.util.LoggingUtil; +import net.gepafin.tendermanagement.util.Utils; +import net.gepafin.tendermanagement.web.rest.api.errors.CustomValidationException; +import net.gepafin.tendermanagement.web.rest.api.errors.Status; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.web.multipart.MultipartFile; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +@Component +public class ApplicationContractDao { + + @Autowired + private ApplicationDao applicationDao; + + @Autowired + private DocumentDao documentDao; + + @Autowired + private ApplicationContractRepository applicationContractRepository; + + @Autowired + private ApplicationRepository applicationRepository; + + @Autowired + private HttpServletRequest request; + + @Autowired + private LoggingUtil loggingUtil; + + @Autowired + private ApplicationAmendmentRequestDao applicationAmendmentRequestDao; + + @Autowired + private EmailNotificationDao emailNotificationDao; + + @Autowired + private ApplicationEvaluationDao applicationEvaluationDao; + + @Autowired + private NotificationDao notificationDao; + + public ApplicationContractResponse createApplicationContract(Long applicationId, List contractDocuments, ApplicationContractRequest applicationContractRequest, UserEntity user) { + ApplicationEntity applicationEntity = applicationDao.validateApplication(applicationId); + + if (Boolean.FALSE.equals(applicationEntity.getStatus().equals(ApplicationStatusTypeEnum.APPROVED.getValue()))) { + throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.APPLICATION_NOT_APPROVED)); + } + if (applicationContractRequest.getSubject() == null || applicationContractRequest.getText() == null) { + throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.SUBJECT_AND_BODY_REQUIRED)); + } + ApplicationEntity oldApplicationData = Utils.getClonedEntityForData(applicationEntity); + ApplicationContractEntity existingApplicationContractEntity = applicationContractRepository.findByApplicationIdAndIsDeletedFalse(applicationId); + if (existingApplicationContractEntity != null) { + throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.APPLICATION_CONTRACT_ALREADY_EXIST)); + } + ApplicationContractEntity applicationContractEntity = createApplicationContractEntity(applicationContractRequest, user, applicationEntity); + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.INSERT).oldData(null).newData(applicationContractEntity).build()); + List documentResponseBeans = setContractDocuments(contractDocuments, user, applicationContractEntity); + applicationEntity.setStatus(ApplicationStatusTypeEnum.AWAITING_CONTRACT.getValue()); + applicationRepository.save(applicationEntity); + loggingUtil.addVersionHistory( + VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplicationData).newData(applicationEntity).build()); + emailNotificationDao.sendEmailForApplicationContracted(applicationEntity, applicationContractEntity, user); + return createApplicationContractResponse(applicationContractEntity, documentResponseBeans, null); + } + + private ApplicationContractResponse createApplicationContractResponse(ApplicationContractEntity applicationContractEntity, List instructorDocuments, List beneficiaryDocuments) { + ApplicationContractResponse applicationContractResponse = new ApplicationContractResponse(); + applicationContractResponse.setId(applicationContractEntity.getId()); + applicationContractResponse.setText(applicationContractEntity.getText()); + applicationContractResponse.setSubject(applicationContractEntity.getSubject()); + applicationContractResponse.setInstructorId(applicationContractEntity.getInstructorId()); + applicationContractResponse.setStatus(ApplicationContractStatusEnum.valueOf(applicationContractEntity.getStatus())); + applicationContractResponse.setInstructorDocuments(instructorDocuments); + applicationContractResponse.setBeneficiaryDocuments(beneficiaryDocuments); + applicationContractResponse.setCompletionDate(applicationContractEntity.getCompletionDate()); + applicationContractResponse.setBeneficiaryUserId(applicationContractEntity.getBeneficiaryUserId()); + return applicationContractResponse; + } + + private List setContractDocuments(List contractDocuments, UserEntity user, ApplicationContractEntity applicationContractEntity) { + List documentResponseBeans = uploadContractDocument(user.getId(), contractDocuments, applicationContractEntity.getId()); + List contractDocumentIds = documentResponseBeans.stream() + .map(DocumentResponseBean::getId) + .collect(Collectors.toList()); + String contractDocumentId = contractDocumentIds.stream() + .map(String::valueOf) + .collect(Collectors.joining(",")); + applicationContractEntity.setInstructorDocument(contractDocumentId); + applicationContractRepository.save(applicationContractEntity); + return documentResponseBeans; + } + + private ApplicationContractEntity createApplicationContractEntity(ApplicationContractRequest applicationContractRequest, UserEntity user, ApplicationEntity applicationEntity) { + ApplicationContractEntity applicationContractEntity = new ApplicationContractEntity(); + applicationContractEntity.setSubject(applicationContractRequest.getSubject()); + applicationContractEntity.setText(applicationContractRequest.getText()); + applicationContractEntity.setApplicationId(applicationEntity.getId()); + applicationContractEntity.setInstructorId(user.getId()); + applicationContractEntity.setIsDeleted(Boolean.FALSE); + applicationContractEntity.setApplicationId(applicationEntity.getId()); + applicationContractEntity.setStatus(ApplicationContractStatusEnum.DRAFT.getValue()); + applicationContractEntity.setBeneficiaryUserId(applicationEntity.getUserId()); + applicationContractRepository.save(applicationContractEntity); + return applicationContractEntity; + } + + public List uploadContractDocument(Long userId, List files, Long applicationContractId) { + if (files != null) { + return documentDao.uploadFiles(userId, files, applicationContractId, DocumentSourceTypeEnum.CONTRACT, DocumentTypeEnum.DOCUMENT); + } + return new ArrayList<>(); + } + + public ApplicationContractResponse updateApplicationContract(Long applicationContractId, List beneficiaryContractDocuments, UserEntity user) { + ApplicationContractEntity applicationContractEntity = validateApplicationContract(applicationContractId); + ApplicationContractEntity oldApplicationContract = Utils.getClonedEntityForData(applicationContractEntity); + applicationContractEntity.setCompletionDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); + applicationContractEntity.setStatus(ApplicationContractStatusEnum.SIGNED.getValue()); + List beneficiaryContractDocuments1 = setBeneficiaryContractDocuments(beneficiaryContractDocuments, user, applicationContractEntity); + List documentResponseBeans = applicationAmendmentRequestDao.getDocumentResponseBean(applicationContractEntity.getInstructorDocument()); + loggingUtil.addVersionHistory( + VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplicationContract).newData(applicationContractEntity).build()); + ApplicationEntity applicationEntity = applicationDao.validateApplication(applicationContractEntity.getApplicationId()); + ApplicationEntity oldApplicationData = Utils.getClonedEntityForData(applicationEntity); + ApplicationEvaluationEntity applicationEvaluationEntity = applicationEvaluationDao.validateApplicationEvaluation(applicationEntity.getApplicationEvaluationId()); + applicationEntity.setStatus(ApplicationStatusTypeEnum.CONTRACT_SIGNED.getValue()); + applicationRepository.save(applicationEntity); + loggingUtil.addVersionHistory( + VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplicationData).newData(applicationEntity).build()); + Map placeHolders = new HashMap<>(); + placeHolders.put("{{call_name}}", applicationEntity.getCall().getName()); + String protocolNumber = applicationEntity.getProtocol().getExternalProtocolNumber(); + if (protocolNumber == null) { + protocolNumber = String.valueOf(applicationEntity.getProtocol().getProtocolNumber()); + } + placeHolders.put("{{protocol_number}}", protocolNumber); + notificationDao.sendNotificationToInstructor(placeHolders, applicationEvaluationEntity, NotificationTypeEnum.CONTRACT_UPLOAD); + + return createApplicationContractResponse(applicationContractEntity, documentResponseBeans, beneficiaryContractDocuments1); + } + + public ApplicationContractEntity validateApplicationContract(Long applicationContractId) { + ApplicationContractEntity applicationContractEntity = applicationContractRepository.findByIdAndIsDeletedFalse(applicationContractId); + if (applicationContractEntity == null) { + throw new CustomValidationException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.APPLICATION_CONTRACT_NOT_FOUND)); + } + return applicationContractEntity; + } + + private List setBeneficiaryContractDocuments(List contractDocuments, UserEntity user, ApplicationContractEntity applicationContractEntity) { + List documentResponseBeans = uploadContractDocument(user.getId(), contractDocuments, applicationContractEntity.getId()); + List contractDocumentIds = documentResponseBeans.stream() + .map(DocumentResponseBean::getId) + .collect(Collectors.toList()); + String contractDocumentId = contractDocumentIds.stream() + .map(String::valueOf) + .collect(Collectors.joining(",")); + applicationContractEntity.setBeneficiaryDocument(contractDocumentId); + applicationContractRepository.save(applicationContractEntity); + return documentResponseBeans; + } + + public ApplicationContractResponse getContractById(Long contractId) { + ApplicationContractEntity applicationContractEntity = validateApplicationContract(contractId); + return createApplicationContractResponseFromEntity(applicationContractEntity); + } + + private ApplicationContractResponse createApplicationContractResponseFromEntity(ApplicationContractEntity applicationContractEntity) { + List instructorDocuments = applicationAmendmentRequestDao.getDocumentResponseBean(applicationContractEntity.getInstructorDocument()); + List beneficiaryDocuments = applicationAmendmentRequestDao.getDocumentResponseBean(applicationContractEntity.getBeneficiaryDocument()); + return createApplicationContractResponse(applicationContractEntity, instructorDocuments, beneficiaryDocuments); + } + + public ApplicationContractResponse getContractByApplicationId(Long applicationId) { + ApplicationContractEntity applicationContractEntity = applicationContractRepository.findByApplicationIdAndIsDeletedFalse(applicationId); + if (applicationContractEntity == null) { + return null; + } + return createApplicationContractResponseFromEntity(applicationContractEntity); + } + + public List getContractByBeneficiaryUserId(UserEntity user) { + + List applicationContractEntities = applicationContractRepository.findByBeneficiaryUserIdAndStatusAndIsDeletedFalse(user.getId(), ApplicationContractStatusEnum.DRAFT.getValue()); + if (applicationContractEntities.isEmpty()) { + return null; + } + List applicationContractResponses = new ArrayList<>(); + for (ApplicationContractEntity applicationContractEntity : applicationContractEntities) { + ApplicationContractResponse applicationContractResponse = createApplicationContractResponseFromEntity(applicationContractEntity); + applicationContractResponses.add(applicationContractResponse); + } + return applicationContractResponses; + } +} diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java index d4000034..56e267be 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java @@ -229,6 +229,9 @@ public class ApplicationDao { @Autowired private SystemEmailTemplatesDao systemEmailTemplatesDao; + @Autowired + private ApplicationContractRepository applicationContractRepository; + public final Random random = new Random(); public ApplicationResponseBean createApplication(HttpServletRequest request, ApplicationRequestBean applicationRequestBean, Long formId, Long applicationId) { @@ -1383,7 +1386,7 @@ public class ApplicationDao { ApplicationSignedDocumentEntity oldApplicationSignedDocument = Utils.getClonedEntityForData(applicationSignedDocumentEntity); String oldS3Path = applicationSignedDocumentEntity.getFilePath(); log.debug("Old S3 path: {} ", oldS3Path); - String newS3Path = s3ConfigBean.generateDocumentPathForOther(DocOtherSourceTypeEnum.DELETED_USER_SIGNED_DOCUMENT,applicationSignedDocumentEntity.getApplication().getCall().getId(),applicationSignedDocumentEntity.getApplication().getId(),0L,0L); + String newS3Path = s3ConfigBean.generateDocumentPathForOther(DocOtherSourceTypeEnum.DELETED_USER_SIGNED_DOCUMENT,applicationSignedDocumentEntity.getApplication().getCall().getId(),applicationSignedDocumentEntity.getApplication().getId(),0L,0L,0l); log.debug("Generated new S3 path for deleted document: {}", newS3Path); UploadFileOnAmazonS3Response response = amazonS3Service.moveFile(applicationSignedDocumentEntity.getFileName(), oldS3Path, newS3Path); @@ -1418,7 +1421,7 @@ public class ApplicationDao { } private String generateS3PathForDelegation(Long callId, Long applicationId) { try { - return s3ConfigBean.generateDocumentPathForOther(DocOtherSourceTypeEnum.USER_SIGNED_DOCUMENT, callId, applicationId,0L,0L); + return s3ConfigBean.generateDocumentPathForOther(DocOtherSourceTypeEnum.USER_SIGNED_DOCUMENT, callId, applicationId,0L,0L,0L); } catch (IllegalArgumentException e) { log.error("Failed to generate S3 path for delegation | callId: {}, applicationId: {}, error: {}", callId, applicationId, e.getMessage(), e); throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.S3_PATH_GENERATION_ERROR_MSG)); @@ -1541,11 +1544,12 @@ public class ApplicationDao { List amendmentDocuments = fetchAmendmentDocuments(applicationId); List evaluationDocuments = fetchEvaluationDocuments(applicationId); List communicationnDocuments = fetchCommunicationDocuments(applicationId); + List contractDocuments=fetchContractDocuments(applicationId); if (documents.isEmpty() && signedDocument == null && amendmentDocuments.isEmpty() && evaluationDocuments.isEmpty()) { log.warn("No documents found for applicationId: {}", applicationId); throw new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.DOCUMENT_NOT_FOUND)); } - return createZipWithDocuments(applicationEntity, documents, signedDocument, amendmentDocuments, evaluationDocuments, applicationId,communicationnDocuments); + return createZipWithDocuments(applicationEntity, documents, signedDocument, amendmentDocuments, evaluationDocuments, applicationId,communicationnDocuments,contractDocuments); } private void validateAssignedUser(HttpServletRequest request, Long applicationId) { @@ -1637,12 +1641,12 @@ public class ApplicationDao { } } private byte[] createZipWithDocuments(ApplicationEntity applicationEntity, List documents, ApplicationSignedDocumentEntity signedDocument, - List amendmentDocuments, List evaluationDocuments, Long applicationId,List communicationDocuments) { + List amendmentDocuments, List evaluationDocuments, Long applicationId,List communicationDocuments,List contractDocuments) { try (ByteArrayOutputStream zipOutputStream = new ByteArrayOutputStream(); ZipOutputStream zos = new ZipOutputStream(zipOutputStream)) { Long callId = applicationEntity.getCall().getId(); // Add Application Documents - String appS3Folder = s3PathConfig.generateDocumentPath(DocumentSourceTypeEnum.APPLICATION, callId, applicationId, 0L,0L); + String appS3Folder = s3PathConfig.generateDocumentPath(DocumentSourceTypeEnum.APPLICATION, callId, applicationId, 0L,0L,0L); for (DocumentEntity document : documents) { String fileName = Utils.extractFileName(document.getFilePath()); addDocumentToZip(zos, appS3Folder, document.getFilePath(), fileName); @@ -1650,7 +1654,7 @@ public class ApplicationDao { // Add Signed Document if (signedDocument != null) { String signedFolder = "SIGNED_DOCUMENT/"; - String signedDocS3Folder = s3PathConfig.generateDocumentPathForOther(DocOtherSourceTypeEnum.USER_SIGNED_DOCUMENT, callId, applicationId, 0L,0L); + String signedDocS3Folder = s3PathConfig.generateDocumentPathForOther(DocOtherSourceTypeEnum.USER_SIGNED_DOCUMENT, callId, applicationId, 0L,0L,0L); String fileName = signedDocument.getFileName(); addDocumentToZip(zos, signedDocS3Folder, signedDocument.getFilePath(), signedFolder + fileName); } @@ -1658,23 +1662,30 @@ public class ApplicationDao { for (DocumentEntity amendmentDocument : amendmentDocuments) { String protocolNumber = fetchProtocolNumberForAmendment(amendmentDocument.getSourceId()); String amendmentFolder = "SOCCORSO_" + protocolNumber + "/"; - String amendmentS3Folder = s3PathConfig.generateDocumentPath(DocumentSourceTypeEnum.AMENDMENT, callId, applicationId, amendmentDocument.getSourceId(),0L); + String amendmentS3Folder = s3PathConfig.generateDocumentPath(DocumentSourceTypeEnum.AMENDMENT, callId, applicationId, amendmentDocument.getSourceId(),0L,0L); String fileName = Utils.extractFileName(amendmentDocument.getFilePath()); addDocumentToZip(zos, amendmentS3Folder, amendmentDocument.getFilePath(), amendmentFolder + fileName); } // Add Evaluation Documents for (DocumentEntity evaluationDocument : evaluationDocuments) { String evaluationFolder = "EVALUATION/"; - String evaluationS3Folder = s3PathConfig.generateDocumentPath(DocumentSourceTypeEnum.EVALUATION, callId, applicationId, evaluationDocument.getSourceId(),0L); + String evaluationS3Folder = s3PathConfig.generateDocumentPath(DocumentSourceTypeEnum.EVALUATION, callId, applicationId, evaluationDocument.getSourceId(),0L,0L); String fileName = Utils.extractFileName(evaluationDocument.getFilePath()); addDocumentToZip(zos, evaluationS3Folder, evaluationDocument.getFilePath(), evaluationFolder + fileName); } for (DocumentEntity communicationDocument : communicationDocuments) { Optional communicationEntity=communicationRepository.findByIdAndIsDeletedFalse(communicationDocument.getSourceId()); - String evaluationFolder = "COMMUNICATION/"; - String evaluationS3Folder = s3PathConfig.generateDocumentPath(DocumentSourceTypeEnum.COMMUNICATION, callId, applicationId, communicationEntity.get().getApplicationAmendmentRequest().getId(),communicationDocument.getSourceId()); + String communicationFolder = "COMMUNICATION/"; + String communicationS3Folder = s3PathConfig.generateDocumentPath(DocumentSourceTypeEnum.COMMUNICATION, callId, applicationId, communicationEntity.get().getApplicationAmendmentRequest().getId(),communicationDocument.getSourceId(),0L); String fileName = Utils.extractFileName(communicationDocument.getFilePath()); - addDocumentToZip(zos, evaluationS3Folder, communicationDocument.getFilePath(), evaluationFolder + fileName); + addDocumentToZip(zos, communicationS3Folder, communicationDocument.getFilePath(), communicationFolder + fileName); + } + for (DocumentEntity contractDocument : contractDocuments) { + ApplicationContractEntity applicationContractEntity=applicationContractRepository.findByIdAndIsDeletedFalse(contractDocument.getSourceId()); + String contractFolder = "CONTRACT/"; + String contractS3Folder = s3PathConfig.generateDocumentPath(DocumentSourceTypeEnum.CONTRACT, callId, applicationId, 0L,contractDocument.getSourceId(),applicationContractEntity.getApplicationId()); + String fileName = Utils.extractFileName(contractDocument.getFilePath()); + addDocumentToZip(zos, contractS3Folder, contractDocument.getFilePath(), contractFolder + fileName); } zos.finish(); return zipOutputStream.toByteArray(); @@ -2599,5 +2610,18 @@ public class ApplicationDao { return out.toByteArray(); } + private List fetchContractDocuments(Long applicationId) { + log.info("Fetching contract documents for applicationId: {}", applicationId); + ApplicationContractEntity applicationContractEntity=applicationContractRepository.findByApplicationIdAndIsDeletedFalse(applicationId); + List documentEntities=new ArrayList<>(); + if(applicationContractEntity!=null){ + Long contractId = applicationContractEntity.getId(); + log.debug("Found contract entity with id: {}", contractId); + List communicationDocuments= documentRepository.findBySourceIdInAndSourceAndIsDeletedFalse(Collections.singleton(contractId), DocumentSourceTypeEnum.CONTRACT.getValue()); + documentEntities.addAll(communicationDocuments); + return documentEntities; + } + return Collections.emptyList(); + } } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java b/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java index 0f688aaf..f5c2b7c0 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java @@ -155,7 +155,7 @@ public class CallDao { for (DocumentEntity document : documents) { log.info("Adding document to ZIP: documentId={}, fileName={}", document.getId(), document.getFileName()); - String s3Folder = s3PathConfig.generateDocumentPath(DocumentSourceTypeEnum.CALL, callId, 0L,0L,0L); + String s3Folder = s3PathConfig.generateDocumentPath(DocumentSourceTypeEnum.CALL, callId, 0L,0L,0L,0L); try (InputStream fileInputStream = amazonS3Service.getFile(s3Folder, document.getFilePath())) { String fileName = Utils.extractFileName(document.getFilePath()); ZipEntry zipEntry = new ZipEntry(fileName); diff --git a/src/main/java/net/gepafin/tendermanagement/dao/CompanyDocumentDao.java b/src/main/java/net/gepafin/tendermanagement/dao/CompanyDocumentDao.java index 2f25bd75..c034a985 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/CompanyDocumentDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/CompanyDocumentDao.java @@ -281,7 +281,7 @@ public class CompanyDocumentDao { validator.validateUserWithCompany(request,companyDocumentEntity.getCompanyId()); String companyDocumentPath = companyDocumentEntity.getFilePath(); - String documentPath = s3ConfigBean.generateDocumentPath(DocumentSourceTypeEnum.APPLICATION,applicationEntity.getCall().getId(),applicationId,0L,0L); + String documentPath = s3ConfigBean.generateDocumentPath(DocumentSourceTypeEnum.APPLICATION,applicationEntity.getCall().getId(),applicationId,0L,0L,0L); log.info("Original Paths - oldPath: {}, newPath: {}", companyDocumentPath, documentPath); diff --git a/src/main/java/net/gepafin/tendermanagement/dao/DelegationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/DelegationDao.java index 6af7e820..24d9c15e 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/DelegationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/DelegationDao.java @@ -92,7 +92,7 @@ public class DelegationDao { public ByteArrayOutputStream generateDocument(Map placeholders, String templateName) { try { - String s3Folder = s3ConfigBean.generateDocumentPathForOther(DocOtherSourceTypeEnum.TEMPLATE, 0L, 0L,0L,0L); + String s3Folder = s3ConfigBean.generateDocumentPathForOther(DocOtherSourceTypeEnum.TEMPLATE, 0L, 0L,0L,0L,0L); InputStream templateStream = amazonS3Service.getFile(s3Folder ,templateName); XWPFDocument doc = loadTemplate(templateStream); replacePlaceholders(doc, placeholders); diff --git a/src/main/java/net/gepafin/tendermanagement/dao/DocumentDao.java b/src/main/java/net/gepafin/tendermanagement/dao/DocumentDao.java index 5fdf7e99..810fec9c 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/DocumentDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/DocumentDao.java @@ -93,6 +93,9 @@ public class DocumentDao { @Autowired private CommunicationRepository communicationRepository; + @Autowired + private ApplicationContractRepository applicationContractRepository; + // @Value("${aws.s3.url.folder}") // private String s3Folder; @@ -172,6 +175,7 @@ public class DocumentDao { Long amendmentId = 0L; Long evaluationId = 0L; Long communicationId = 0L; + Long contractId=0L; Long callId = sourceId; if (type == DocumentSourceTypeEnum.APPLICATION) { applicationId = sourceId; @@ -197,9 +201,16 @@ public class DocumentDao { applicationId=applicationAmendmentRequestEntity.get().getApplicationId(); callId = applicationAmendmentRequestEntity.get().getApplicationEvaluationEntity().getAssignedApplicationsEntity().getApplication().getCall().getId(); log.info("Processing document of type COMMUNICATION .Resolved evaluationId={}, applicationId={}, callId={}", evaluationId, applicationId, callId); + }else if (type == DocumentSourceTypeEnum.CONTRACT) { + contractId = sourceId; + ApplicationContractEntity applicationContractEntity=applicationContractRepository.findByIdAndIsDeletedFalse(contractId); + ApplicationEntity applicationEntity=applicationService.validateApplication(applicationContractEntity.getApplicationId()); + applicationId=applicationEntity.getId(); + callId = applicationEntity.getCall().getId(); + log.info("Processing document of type CONTRACT .Resolved evaluationId={}, applicationId={}, callId={}, contractId={}", evaluationId, applicationId, callId,contractId); } try { - String s3Path = generateS3Path(type, callId, applicationId, amendmentId,communicationId); + String s3Path = generateS3Path(type, callId, applicationId, amendmentId,communicationId,contractId); log.info("Generated S3 path {}", s3Path); return amazonS3Service.uploadFileOnAmazonS3(s3Path, file); } catch (Exception e) { @@ -210,9 +221,9 @@ public class DocumentDao { } - public String generateS3Path(DocumentSourceTypeEnum typeOfDocument, Long callId, Long applicationId, Long amendmentId,Long communicationId) { + public String generateS3Path(DocumentSourceTypeEnum typeOfDocument, Long callId, Long applicationId, Long amendmentId,Long communicationId,Long contractId) { try { - return s3ConfigBean.generateDocumentPath(typeOfDocument, callId, applicationId, amendmentId,communicationId); + return s3ConfigBean.generateDocumentPath(typeOfDocument, callId, applicationId, amendmentId,communicationId,contractId); } catch (IllegalArgumentException e) { throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.S3_PATH_GENERATION_ERROR_MSG)); } @@ -245,6 +256,7 @@ public class DocumentDao { Long amendmentId = null; Long evaluationId = null; Long communicationId=null; + Long contractId=null; if (DocumentSourceTypeEnum.CALL.getValue().equalsIgnoreCase(documentEntity.getSource())) { callId = documentEntity.getSourceId(); @@ -340,9 +352,20 @@ public class DocumentDao { communicationEntity1.setDocuments(updatedValue); communicationRepository.save(communicationEntity1); } + } + else if(DocumentSourceTypeEnum.CONTRACT.getValue().equalsIgnoreCase(documentEntity.getSource())) { + contractId = documentEntity.getSourceId(); + ApplicationContractEntity applicationContractEntity=applicationContractRepository.findByIdAndIsDeletedFalse(contractId); + ApplicationEntity applicationEntity=applicationService.validateApplication(applicationContractEntity.getApplicationId()); + String beneficiaryDocument=applicationContractEntity.getBeneficiaryDocument(); + if(beneficiaryDocument!=null) { + String updatedValue = removeDocumentIdFromFieldValue(beneficiaryDocument, documentId); + applicationContractEntity.setBeneficiaryDocument(updatedValue); + applicationContractRepository.save(applicationContractEntity); + } } - deleteFileFromS3(documentEntity, callId, applicationId,amendmentId,communicationId); + deleteFileFromS3(documentEntity, callId, applicationId,amendmentId,communicationId,contractId); log.info("Successfully deleted file from S3 for documentId={}", documentId); } @@ -387,6 +410,7 @@ public class DocumentDao { Long amendmentId=null; Long evaluationId=null; Long communicationId=null; + Long contractId=null; if (type.equals(DocumentSourceTypeEnum.APPLICATION)) { callId = applicationRepository.findCallIdById(id); applicationId = id; @@ -412,6 +436,13 @@ public class DocumentDao { applicationId=applicationAmendmentRequestEntity.get().getApplicationId(); callId = applicationAmendmentRequestEntity.get().getApplicationEvaluationEntity().getAssignedApplicationsEntity().getApplication().getCall().getId(); log.info("Processing document of type EVALUATION .Resolved evaluationId={}, applicationId={}, callId={}", evaluationId, applicationId, callId); + }else if (type == DocumentSourceTypeEnum.CONTRACT) { + contractId = id; + ApplicationContractEntity applicationContractEntity=applicationContractRepository.findByIdAndIsDeletedFalse(contractId); + ApplicationEntity applicationEntity=applicationService.validateApplication(applicationContractEntity.getApplicationId()); + applicationId=applicationContractEntity.getApplicationId(); + callId = applicationEntity.getCall().getId(); + log.info("Processing document of type CONTRACT .Resolved evaluationId={}, applicationId={}, callId={}, contractId={}", evaluationId, applicationId, callId,contractId); } else { @@ -419,7 +450,7 @@ public class DocumentDao { applicationId = 0L; log.info("Processing document of type CALL . Resolved callId={}", callId); } - String s3Path = generateS3Path(type, callId, applicationId,amendmentId,communicationId); + String s3Path = generateS3Path(type, callId, applicationId,amendmentId,communicationId,contractId); log.info("Generated S3 path {}", s3Path); return amazonS3Service.uploadFileOnAmazonS3(s3Path, file); } catch (Exception e) { @@ -432,12 +463,12 @@ public class DocumentDao { return callDao.convertToDocumentResponseBean(documentEntity); } - public void deleteFileFromS3(DocumentEntity documentEntity, Long callId, Long applicationId,Long amendmentId,Long communicationId) { + public void deleteFileFromS3(DocumentEntity documentEntity, Long callId, Long applicationId,Long amendmentId,Long communicationId,Long contractId) { try { DocumentEntity oldDocumentEntity = Utils.getClonedEntityForData(documentEntity); String oldS3Path = documentEntity.getFilePath(); - String newS3Path = s3ConfigBean.generateDocumentPathForOther(DocOtherSourceTypeEnum.valueOf("DELETED_" + documentEntity.getSource().toUpperCase()), callId, applicationId,amendmentId,communicationId); + String newS3Path = s3ConfigBean.generateDocumentPathForOther(DocOtherSourceTypeEnum.valueOf("DELETED_" + documentEntity.getSource().toUpperCase()), callId, applicationId,amendmentId,communicationId,contractId); log.info("Moving file to deleted path: oldS3Path={}, newS3Path={}", oldS3Path, newS3Path); UploadFileOnAmazonS3Response response = amazonS3Service.moveFile(documentEntity.getFileName(), oldS3Path, newS3Path); documentEntity.setFileName(response.getFileName()); diff --git a/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java index 1d7ebd86..da689b79 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java @@ -97,6 +97,9 @@ public class EmailNotificationDao { @Autowired private ApplicationDao applicationDao; + @Autowired + private ApplicationContractDao applicationContractDao; + public void sendEmail(ApplicationEntity applicationEntity, SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum templateType, Map bodyPlaceholders, List additionalRecipients, Long amendmentId,String emailType) { @@ -106,7 +109,7 @@ public class EmailNotificationDao { EmailContentResponse emailContent = prepareEmailContent(applicationEntity, templateType, hubEntity, bodyPlaceholders,emailType); UserEntity userEntity = userService.validateUser(applicationEntity.getUserId()); - sendEmails(applicationEntity, userEntity, additionalRecipients,amendmentId,emailContent.getSystemEmailTemplateResponse(),emailContent.getSubject(),emailContent.getBody()); + sendEmails(applicationEntity, userEntity, additionalRecipients,amendmentId,emailContent.getSystemEmailTemplateResponse(),emailContent.getSubject(),emailContent.getBody(),null); } public EmailContentResponse prepareEmailContent( @@ -131,7 +134,7 @@ public class EmailNotificationDao { return new EmailContentResponse(subject, body, systemEmailTemplateResponse); } - private void sendEmails(ApplicationEntity applicationEntity, UserEntity userEntity, List additionalRecipients,Long amendmentId,SystemEmailTemplateResponse systemEmailTemplateResponse,String subject,String body) { + private void sendEmails(ApplicationEntity applicationEntity, UserEntity userEntity, List additionalRecipients,Long amendmentId,SystemEmailTemplateResponse systemEmailTemplateResponse,String subject,String body,Long contractId) { Optional applicationEvaluationEntity = applicationEvaluationRepository.findByApplicationIdAndIsDeletedFalse(applicationEntity.getId()); CompanyEntity company = companyService.validateCompany(applicationEntity.getCompanyId()); @@ -177,6 +180,14 @@ public class EmailNotificationDao { : new HashSet<>(documentIds); documentEntities=documentRepository.findAllByIdInAndIsDeletedFalse(setOfDocumentIds); } + if(Boolean.TRUE.equals(userEntity.getHub().getUniqueUuid().equals(defaultHubUuid)) && Boolean.TRUE.equals(systemEmailTemplateResponse.getEmailScenario().equals(EmailScenarioTypeEnum.APPLICATION_CONTRACT_CREATED))) { + ApplicationContractEntity applicationContractEntity=applicationContractDao.validateApplicationContract(contractId); + List documentIds=applicationDao.validateDocumentIds(applicationContractEntity.getInstructorDocument()); + Set setOfDocumentIds = (documentIds == null) + ? Collections.emptySet() + : new HashSet<>(documentIds); + documentEntities=documentRepository.findAllByIdInAndIsDeletedFalse(setOfDocumentIds); + } urls = documentEntities.stream() .map(DocumentEntity::getFilePath) // or getUrl() @@ -225,7 +236,7 @@ public class EmailNotificationDao { } } - if (userEntity.getBeneficiary().getEmail() != null) { + if (userEntity.getBeneficiary()!= null) { String beneficiaryEmail = null; RecipientTypeEnum recipientTypeEnum=RecipientTypeEnum.BENEFICIARY; if (Boolean.TRUE.equals(userEntity.getHub().getUniqueUuid().equals(defaultHubUuid))){ @@ -514,4 +525,33 @@ public class EmailNotificationDao { sendEmail(applicationEntity, SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum.SPECIAL_APPLICATION_AMENDMENT_REQUESTED, bodyPlaceholders, null, applicationAmendmentRequestEntity.getId(),null); } + public void sendEmailForApplicationContracted(ApplicationEntity applicationEntity,ApplicationContractEntity applicationContractEntity,UserEntity user) { + Map bodyPlaceholders = new HashMap<>(); + bodyPlaceholders.put("{{call_name}}", applicationEntity.getCall().getName()); + String protocolNumber=applicationEntity.getProtocol().getExternalProtocolNumber(); + if(protocolNumber==null){ + protocolNumber= String.valueOf(applicationEntity.getProtocol().getProtocolNumber()); + } + bodyPlaceholders.put("{{protocol_number}}", protocolNumber); + String protocolDate= DateTimeUtil.formatLocalDateTime(applicationEntity.getProtocol().getCreatedDate(), GepafinConstant.DD_MM_YYYY); + if(applicationEntity.getProtocol().getExternalProtocolDate()!=null){ + protocolDate= DateTimeUtil.formatLocalDateTime(applicationEntity.getProtocol().getExternalProtocolDate(), GepafinConstant.DD_MM_YYYY); + } + bodyPlaceholders.put("{{protocol_date}}", protocolDate); + bodyPlaceholders.put("{{protocol_time}}", DateTimeUtil.parseLocalTimeToString(applicationEntity.getProtocol().getTime(), GepafinConstant.HH_MM_SS)); + HubEntity hubEntity = hubService.valdateHub(applicationEntity.getHubId()); + Map subjectPlaceholders = new HashMap<>(); + CompanyEntity company = companyService.validateCompany(applicationEntity.getCompanyId()); + subjectPlaceholders.put("{{call_name}}", applicationEntity.getCall().getName()); + subjectPlaceholders.put("{{company_name}}", company.getCompanyName()); +// bodyPlaceholders.put("{{legal_mail}}", legalMail); + String subject = Utils.replacePlaceholders(applicationContractEntity.getSubject(), subjectPlaceholders); + String body = Utils.replacePlaceholders(applicationContractEntity.getText(), bodyPlaceholders); + SystemEmailTemplateResponse systemEmailTemplateResponse=new SystemEmailTemplateResponse(); + systemEmailTemplateResponse.setSubject(subject); + systemEmailTemplateResponse.setHtmlContent(body); + systemEmailTemplateResponse.setEmailScenario(EmailScenarioTypeEnum.APPLICATION_CONTRACT_CREATED); + EmailContentResponse emailContentResponse= new EmailContentResponse(subject, body, systemEmailTemplateResponse); + sendEmails(applicationEntity, user, null,null,emailContentResponse.getSystemEmailTemplateResponse(),emailContentResponse.getSubject(),emailContentResponse.getBody(),applicationContractEntity.getId()); + } } \ No newline at end of file diff --git a/src/main/java/net/gepafin/tendermanagement/dao/S3PathConfig.java b/src/main/java/net/gepafin/tendermanagement/dao/S3PathConfig.java index 9cbc1b26..a3b82544 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/S3PathConfig.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/S3PathConfig.java @@ -15,27 +15,28 @@ public class S3PathConfig { @Autowired S3ConfigRepository s3ConfigRepository; - public String generateDocumentPath(DocumentSourceTypeEnum type, Long callId, Long applicationId,Long amendmentId,Long communicationId) { + public String generateDocumentPath(DocumentSourceTypeEnum type, Long callId, Long applicationId,Long amendmentId,Long communicationId,Long contractId) { S3ConfigEntity config = getDocumentPath(type); - return config.getParentFolder() + "/" + buildS3Path(config.getPath(), callId, applicationId,amendmentId,communicationId); + return config.getParentFolder() + "/" + buildS3Path(config.getPath(), callId, applicationId,amendmentId,communicationId,contractId); } - public String generateDocumentPathForOther(DocOtherSourceTypeEnum type, Long callId, Long applicationId,Long amendmentId,Long communicationId) { + public String generateDocumentPathForOther(DocOtherSourceTypeEnum type, Long callId, Long applicationId,Long amendmentId,Long communicationId,Long contractId) { S3ConfigEntity config = getDocumentPathForOther(type); - return config.getParentFolder() + "/" + buildS3Path(config.getPath(), callId, applicationId,amendmentId,communicationId); + return config.getParentFolder() + "/" + buildS3Path(config.getPath(), callId, applicationId,amendmentId,communicationId,contractId); } public String generateDocumentPathForDelegationAndSignedDocument(DocOtherSourceTypeEnum type) { S3ConfigEntity config = getDocumentPathForOther(type); return config.getParentFolder() + "/" + config.getPath(); } - private String buildS3Path(String pathTemplate, Long callId, Long applicationId, Long amendmentId,Long communicationId) { + private String buildS3Path(String pathTemplate, Long callId, Long applicationId, Long amendmentId,Long communicationId,Long contractId) { return pathTemplate .replace("{call_id}", callId != null && callId != 0L ? "call_" + callId : "") .replace("{application_id}", applicationId != null && applicationId != 0L ? "application_" + applicationId : "") .replace("{amendment_id}", amendmentId != null && amendmentId != 0L ? "amendment_" + amendmentId : "") - .replace("{communication_id}", communicationId != null && communicationId != 0L ? "communication_" + communicationId : ""); + .replace("{communication_id}", communicationId != null && communicationId != 0L ? "communication_" + communicationId : "") + .replace("{contract_id}", contractId != null && contractId != 0L ? "contract_" + contractId : ""); } private S3ConfigEntity getDocumentPath(DocumentSourceTypeEnum type) { diff --git a/src/main/java/net/gepafin/tendermanagement/entities/ApplicationContractEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/ApplicationContractEntity.java new file mode 100644 index 00000000..d482e5d2 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/entities/ApplicationContractEntity.java @@ -0,0 +1,46 @@ +package net.gepafin.tendermanagement.entities; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Table; +import lombok.Data; +import org.hibernate.annotations.Where; + +import java.time.LocalDateTime; + +@Entity +@Table(name = "APPLICATION_CONTRACT") +@Data +@Where(clause = "is_deleted = false") +public class ApplicationContractEntity extends BaseEntity{ + + @Column(name = "SUBJECT") + private String subject; + + @Column(name = "TEXT") + private String text; + + @Column(name = "INSTRUCTOR_DOCUMENT") + private String instructorDocument; + + @Column(name = "STATUS") + private String status; + + @Column(name = "BENEFICIARY_DOCUMENT") + private String beneficiaryDocument; + + @Column(name = "BENEFICIARY_USER_ID") + private Long beneficiaryUserId; + + @Column(name = "INSTRUCTOR_ID") + private Long instructorId; + + @Column(name = "IS_DELETED") + private Boolean isDeleted; + + @Column(name = "COMPLETION_DATE") + private LocalDateTime completionDate; + + @Column(name = "APPLICATION_ID") + private Long applicationId; +} diff --git a/src/main/java/net/gepafin/tendermanagement/enums/ApplicationContractStatusEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/ApplicationContractStatusEnum.java new file mode 100644 index 00000000..9483fe01 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/enums/ApplicationContractStatusEnum.java @@ -0,0 +1,22 @@ +package net.gepafin.tendermanagement.enums; + +import com.fasterxml.jackson.annotation.JsonValue; + +public enum ApplicationContractStatusEnum { + + DRAFT("DRAFT"), + + SIGNED("SIGNED"); + + + private final String value; + + ApplicationContractStatusEnum(String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } +} diff --git a/src/main/java/net/gepafin/tendermanagement/enums/ApplicationStatusTypeEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/ApplicationStatusTypeEnum.java index fd48ab9a..d686a347 100644 --- a/src/main/java/net/gepafin/tendermanagement/enums/ApplicationStatusTypeEnum.java +++ b/src/main/java/net/gepafin/tendermanagement/enums/ApplicationStatusTypeEnum.java @@ -18,7 +18,9 @@ public enum ApplicationStatusTypeEnum { ADMISSIBLE("ADMISSIBLE"), TECHNICAL_EVALUATION("TECHNICAL_EVALUATION"), TECHNICAL_EVALUATION_REJECTED("TECHNICAL_EVALUATION_REJECTED"), - AWAITING_TECHNICAL_EVALUATION("AWAITING_TECHNICAL_EVALUATION") ; + AWAITING_TECHNICAL_EVALUATION("AWAITING_TECHNICAL_EVALUATION"), + AWAITING_CONTRACT("AWAITING_CONTRACT"), + CONTRACT_SIGNED("CONTRACT_SIGNED"); private String value; diff --git a/src/main/java/net/gepafin/tendermanagement/enums/DocumentSourceTypeEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/DocumentSourceTypeEnum.java index 2e10a873..68d482fb 100644 --- a/src/main/java/net/gepafin/tendermanagement/enums/DocumentSourceTypeEnum.java +++ b/src/main/java/net/gepafin/tendermanagement/enums/DocumentSourceTypeEnum.java @@ -6,7 +6,8 @@ public enum DocumentSourceTypeEnum { APPLICATION("APPLICATION"), EVALUATION("EVALUATION"), AMENDMENT("AMENDMENT"), - COMMUNICATION("COMMUNICATION"); + COMMUNICATION("COMMUNICATION"), + CONTRACT("CONTRACT"); private String value; diff --git a/src/main/java/net/gepafin/tendermanagement/enums/EmailScenarioTypeEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/EmailScenarioTypeEnum.java index c459239d..fe8d64b2 100644 --- a/src/main/java/net/gepafin/tendermanagement/enums/EmailScenarioTypeEnum.java +++ b/src/main/java/net/gepafin/tendermanagement/enums/EmailScenarioTypeEnum.java @@ -14,7 +14,8 @@ public enum EmailScenarioTypeEnum { APPLICATION_REJECTED("APPLICATION_REJECTED"), APPLICATION_SUBMISSION_FAILURE("APPLICATION_SUBMISSION_FAILURE"), APPLICATION_TECHNICAL_EVALUATION_REJECTED("APPLICATION_TECHNICAL_EVALUATION_REJECTED"), - SPECIAL_APPLICATION_AMENDMENT_REQUESTED("SPECIAL_APPLICATION_AMENDMENT_REQUESTED"); + SPECIAL_APPLICATION_AMENDMENT_REQUESTED("SPECIAL_APPLICATION_AMENDMENT_REQUESTED"), + APPLICATION_CONTRACT_CREATED("APPLICATION_CONTRACT_CREATED"); private final String value; diff --git a/src/main/java/net/gepafin/tendermanagement/enums/NotificationTypeEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/NotificationTypeEnum.java index 4430c2d6..c979bb2a 100644 --- a/src/main/java/net/gepafin/tendermanagement/enums/NotificationTypeEnum.java +++ b/src/main/java/net/gepafin/tendermanagement/enums/NotificationTypeEnum.java @@ -15,7 +15,8 @@ public enum NotificationTypeEnum { AMENDMENT_EXPIRATION_REMINDER("AMENDMENT_EXPIRATION_REMINDER"), EVALUATION_EXPIRATION_REMINDER("EVALUATION_EXPIRATION_REMINDER"), COMPANY_DOCUMENT_EXPIRATION_REMINDER("COMPANY_DOCUMENT_EXPIRATION_REMINDER"), - PEC_EMAIL_SENDING_FAILURE("PEC_EMAIL_SENDING_FAILURE"); + PEC_EMAIL_SENDING_FAILURE("PEC_EMAIL_SENDING_FAILURE"), + CONTRACT_UPLOAD("CONTRACT_UPLOAD"); private final 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 32847535..98aca8cf 100644 --- a/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java +++ b/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java @@ -224,7 +224,13 @@ public enum UserActionContextEnum { RESEND_EMAIL("RESEND_EMAIL"), SEND_REMINDER_EMAIL("SEND_REMINDER_EMAIL"), CREATE_SPECIAL_AMENDMENT("CREATE_SPECIAL_AMENDMENT"), - UPDATE_APPLICATION_TO_TECHNICAL_EVALUATION_REJECTED("UPDATE_APPLICATION_TO_TECHNICAL_EVALUATION_REJECTED"); + UPDATE_APPLICATION_TO_TECHNICAL_EVALUATION_REJECTED("UPDATE_APPLICATION_TO_TECHNICAL_EVALUATION_REJECTED"), + CREATE_CONTRACT_FOR_APPLICATION("CREATE_CONTRACT_FOR_APPLICATION"), + UPDATE_APPLICATION_CONTRACT("UPDATE_APPLICATION_CONTRACT"), + FETCH_APPLICATION_CONTRACT("FETCH_APPLICATION_CONTRACT"), + FETCH_APPLICATION_CONTRACT_BY_APPLICATION_ID("FETCH_APPLICATION_CONTRACT_BY_APPLICATION_ID"), + FETCH_APPLICATION_CONTRACT_BY_BENEFICIARY_USER_ID("FETCH_APPLICATION_CONTRACT_BY_BENEFICIARY_USER_ID"); + private final String value; diff --git a/src/main/java/net/gepafin/tendermanagement/model/request/ApplicationContractRequest.java b/src/main/java/net/gepafin/tendermanagement/model/request/ApplicationContractRequest.java new file mode 100644 index 00000000..25e875b6 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/model/request/ApplicationContractRequest.java @@ -0,0 +1,10 @@ +package net.gepafin.tendermanagement.model.request; + +import lombok.Data; + +@Data +public class ApplicationContractRequest { + + private String subject; + private String text; +} diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationContractResponse.java b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationContractResponse.java new file mode 100644 index 00000000..d3d19dac --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationContractResponse.java @@ -0,0 +1,30 @@ +package net.gepafin.tendermanagement.model.response; + +import lombok.Data; +import net.gepafin.tendermanagement.enums.ApplicationContractStatusEnum; + +import java.time.LocalDateTime; +import java.util.List; + +@Data +public class ApplicationContractResponse { + + private Long id; + + private String subject; + + private String text; + + private ApplicationContractStatusEnum status; + + private List instructorDocuments; + + private Long instructorId; + + private List beneficiaryDocuments; + + private Long beneficiaryUserId; + + private LocalDateTime completionDate; + +} diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationContractRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationContractRepository.java new file mode 100644 index 00000000..0f8d3d27 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationContractRepository.java @@ -0,0 +1,18 @@ +package net.gepafin.tendermanagement.repositories; + +import net.gepafin.tendermanagement.entities.ApplicationContractEntity; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +public interface ApplicationContractRepository extends JpaRepository { + + ApplicationContractEntity findByIdAndIsDeletedFalse(Long id); + + ApplicationContractEntity findByApplicationIdAndIsDeletedFalse(Long applicationId); + + List findByBeneficiaryUserIdAndStatusAndIsDeletedFalse(Long applicationId,String status); + +} diff --git a/src/main/java/net/gepafin/tendermanagement/service/ApplicationContractService.java b/src/main/java/net/gepafin/tendermanagement/service/ApplicationContractService.java new file mode 100644 index 00000000..bf562cdf --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/service/ApplicationContractService.java @@ -0,0 +1,21 @@ +package net.gepafin.tendermanagement.service; + +import jakarta.servlet.http.HttpServletRequest; +import net.gepafin.tendermanagement.model.request.ApplicationContractRequest; +import net.gepafin.tendermanagement.model.response.ApplicationContractResponse; +import org.springframework.web.multipart.MultipartFile; + +import java.util.List; + +public interface ApplicationContractService { + + public ApplicationContractResponse createApplicationContract(HttpServletRequest httpServletRequest, Long applicationId, List contractDocuments, ApplicationContractRequest applicationContractRequest); + + public ApplicationContractResponse updateApplicationContract(HttpServletRequest httpServletRequest, Long applicationContractId,List beneficiaryContractDocuments); + + public ApplicationContractResponse getContractById(Long contractId); + + public ApplicationContractResponse getContractByApplicationId(Long applicationContractId); + + List getContractByBeneficiaryUserId(Long beneficiaryUserId); + } diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationContractServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationContractServiceImpl.java new file mode 100644 index 00000000..5e1ea5c0 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationContractServiceImpl.java @@ -0,0 +1,68 @@ +package net.gepafin.tendermanagement.service.impl; + +import jakarta.servlet.http.HttpServletRequest; +import net.gepafin.tendermanagement.config.Translator; +import net.gepafin.tendermanagement.constants.GepafinConstant; +import net.gepafin.tendermanagement.dao.ApplicationContractDao; +import net.gepafin.tendermanagement.dao.UserDao; +import net.gepafin.tendermanagement.entities.UserEntity; +import net.gepafin.tendermanagement.model.request.ApplicationContractRequest; +import net.gepafin.tendermanagement.model.response.ApplicationContractResponse; +import net.gepafin.tendermanagement.service.ApplicationContractService; +import net.gepafin.tendermanagement.util.Utils; +import net.gepafin.tendermanagement.util.Validator; +import net.gepafin.tendermanagement.web.rest.api.errors.CustomValidationException; +import net.gepafin.tendermanagement.web.rest.api.errors.Status; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +import java.util.List; +import java.util.Map; + +@Service +public class ApplicationContractServiceImpl implements ApplicationContractService { + + @Autowired + private ApplicationContractDao applicationContractDao; + + @Autowired + private Validator validator; + + @Autowired + private UserDao userDao; + + @Override + public ApplicationContractResponse createApplicationContract(HttpServletRequest httpServletRequest, Long applicationId, List contractDocuments, ApplicationContractRequest applicationContractRequest) { + UserEntity user= validator.validateUser(httpServletRequest); + if(contractDocuments==null) { + throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.FILES_REQUIRED_FOR_CONTRACT)); + } + contractDocuments.forEach(Utils::validateFileType); + return applicationContractDao.createApplicationContract(applicationId,contractDocuments,applicationContractRequest,user); + } + + @Override + public ApplicationContractResponse updateApplicationContract(HttpServletRequest httpServletRequest, Long applicationContractId, List beneficiaryContractDocuments) { + UserEntity user= validator.validateUser(httpServletRequest); + if(beneficiaryContractDocuments==null) { + throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.FILES_REQUIRED_FOR_CONTRACT)); + } + return applicationContractDao.updateApplicationContract(applicationContractId,beneficiaryContractDocuments,user); + } + + @Override + public ApplicationContractResponse getContractById(Long contractId) { + return applicationContractDao.getContractById(contractId); + } + + @Override + public ApplicationContractResponse getContractByApplicationId(Long applicationId) { + return applicationContractDao.getContractByApplicationId(applicationId); + } + @Override + public List getContractByBeneficiaryUserId(Long beneficiaryUserId) { + UserEntity user=userDao.validateUser(beneficiaryUserId); + return applicationContractDao.getContractByBeneficiaryUserId(user); + } +} diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/S3ReUploadMigrationService.java b/src/main/java/net/gepafin/tendermanagement/service/impl/S3ReUploadMigrationService.java index fdb09116..cbd6af2d 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/S3ReUploadMigrationService.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/S3ReUploadMigrationService.java @@ -9,6 +9,7 @@ import com.amazonaws.services.s3.model.ObjectMetadata; import lombok.extern.slf4j.Slf4j; import net.gepafin.tendermanagement.dao.DocumentDao; import net.gepafin.tendermanagement.dao.S3PathConfig; +import net.gepafin.tendermanagement.entities.ApplicationContractEntity; import net.gepafin.tendermanagement.entities.ApplicationEntity; import net.gepafin.tendermanagement.entities.CommunicationEntity; import net.gepafin.tendermanagement.entities.DocumentEntity; @@ -81,6 +82,9 @@ public class S3ReUploadMigrationService { @Autowired private DocumentDao documentDao; + @Autowired + private ApplicationContractRepository applicationContractRepository; + private boolean migrationCompleted = false; @@ -114,6 +118,7 @@ public class S3ReUploadMigrationService { Long amendmentId = null; Long evaluationId = null; Long communicationId=null; + Long contractId=null; if (DocumentSourceTypeEnum.CALL.getValue().equalsIgnoreCase(document.getSource())) { callId = document.getSourceId(); } else if (DocumentSourceTypeEnum.APPLICATION.getValue().equalsIgnoreCase(document.getSource())) { @@ -138,9 +143,15 @@ public class S3ReUploadMigrationService { applicationId = applicationEntity.getId(); callId = applicationEntity.getCall().getId(); } + else if(DocumentSourceTypeEnum.CONTRACT.getValue().equalsIgnoreCase(document.getSource())){ + contractId = document.getSourceId(); + ApplicationContractEntity applicationContractEntity=applicationContractRepository.findByIdAndIsDeletedFalse(contractId); + ApplicationEntity applicationEntity=applicationService.validateApplication(applicationContractEntity.getApplicationId()); + applicationId = applicationEntity.getId(); + callId = applicationEntity.getCall().getId(); + } - - documentDao.deleteFileFromS3(document,callId,applicationId,amendmentId,communicationId); + documentDao.deleteFileFromS3(document,callId,applicationId,amendmentId,communicationId,contractId); processDocuments++; } catch (Exception e) { @@ -231,10 +242,10 @@ public class S3ReUploadMigrationService { Long callId; if (sourceType.equals(DocumentSourceTypeEnum.CALL)) { - return s3ConfigBean.generateDocumentPath(sourceType, document.getSourceId(), 0L,0L,0L); + return s3ConfigBean.generateDocumentPath(sourceType, document.getSourceId(), 0L,0L,0L,0L); } else { callId = applicationRepository.findCallIdById(document.getSourceId()); - return s3ConfigBean.generateDocumentPath(sourceType, callId, document.getSourceId(),0L,0L); + return s3ConfigBean.generateDocumentPath(sourceType, callId, document.getSourceId(),0L,0L,0L); } } diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/UserSignedAndDelegationServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/UserSignedAndDelegationServiceImpl.java index e6ba7821..d86b96be 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/UserSignedAndDelegationServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/UserSignedAndDelegationServiceImpl.java @@ -139,7 +139,7 @@ public class UserSignedAndDelegationServiceImpl { private String generateNewS3PathForDelegationDoc() { - return s3ConfigBean.generateDocumentPathForOther(DocOtherSourceTypeEnum.USER_DELEGATION, 0L, 0L,0L,0L); + return s3ConfigBean.generateDocumentPathForOther(DocOtherSourceTypeEnum.USER_DELEGATION, 0L, 0L,0L,0L,0L); } private String generateNewS3PathForUserSignedDoc(ApplicationSignedDocumentEntity document) { diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/ApplicationContractApi.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/ApplicationContractApi.java new file mode 100644 index 00000000..c81e9a2b --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/ApplicationContractApi.java @@ -0,0 +1,96 @@ +package net.gepafin.tendermanagement.web.rest.api; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.ExampleObject; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.validation.Valid; +import net.gepafin.tendermanagement.model.request.ApplicationAmendmentSpecialRequest; +import net.gepafin.tendermanagement.model.request.ApplicationContractRequest; +import net.gepafin.tendermanagement.model.request.ApplicationEvaluationRequest; +import net.gepafin.tendermanagement.model.response.ApplicationAmendmentRequestResponse; +import net.gepafin.tendermanagement.model.response.ApplicationContractResponse; +import net.gepafin.tendermanagement.model.util.Response; +import net.gepafin.tendermanagement.web.rest.api.errors.ErrorConstants; +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; + +import java.util.List; + +@Validated +public interface ApplicationContractApi { + + @Operation(summary = "Api to create application contract", + 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 = "/application/{applicationId}", produces = "application/json", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) + @PreAuthorize("hasRole('ROLE_SUPER_ADMIN') || hasRole('ROLE_INSTRUCTOR_MANAGER')|| hasRole('ROLE_PRE_INSTRUCTOR')") + ResponseEntity> createApplicationContract(HttpServletRequest request, + @Parameter(description = "Application ID", required = true) @PathVariable("applicationId") Long applicationId, @Parameter(description = "List of files to upload", required = true) + @RequestPart(required = true) List contractDocuments, + @Parameter(description = "Application Contract Request Body", required = true) @RequestPart ApplicationContractRequest applicationContractRequest); + + @Operation(summary = "Api to update application contract from beneficiary side", + 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) })) }) + @PutMapping(value = "{applicationContractId}", produces = "application/json", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) + @PreAuthorize( "hasRole('ROLE_SUPER_ADMIN') || hasRole('ROLE_BENEFICIARY') || hasRole('ROLE_CONFIDI')") + ResponseEntity> updateApplicationContract(HttpServletRequest request, + @Parameter(description = "Application Contract ID", required = true) @PathVariable("applicationContractId") Long applicationContractId, @Parameter(description = "List of files to upload", required = true) + @RequestPart(required = true) List beneficiaryContractDocuments); + + @Operation(summary = "Api to get an application contract by id", + 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 = "{applicationContractId}", produces = "application/json") + ResponseEntity> getApplicationContractById(HttpServletRequest request,@Parameter(description = "The application contract id", required = true) @RequestParam(value = "id", required = true) Long id); + + @Operation(summary = "Api to get an application contract by application id", + 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 = "/application/{applicationId}", produces = "application/json") + ResponseEntity> getApplicationContractByApplicationId(HttpServletRequest request,@Parameter(description = "The application id", required = true) @RequestParam(value = "applicationId", required = true) Long applicationId); + + @Operation(summary = "Api to get an application contract by beneficiary user id", + 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 = "/user/{userId}", produces = "application/json") + ResponseEntity>> getApplicationContractByBeneficiaryUserId(HttpServletRequest request,@Parameter(description = "The user id", required = true) @RequestParam(value = "userId", required = true) Long userId); + +} diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/ApplicationContractApiController.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/ApplicationContractApiController.java new file mode 100644 index 00000000..4d5227e9 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/ApplicationContractApiController.java @@ -0,0 +1,86 @@ +package net.gepafin.tendermanagement.web.rest.api.impl; + +import jakarta.servlet.http.HttpServletRequest; +import net.gepafin.tendermanagement.config.Translator; +import net.gepafin.tendermanagement.constants.GepafinConstant; +import net.gepafin.tendermanagement.enums.UserActionContextEnum; +import net.gepafin.tendermanagement.enums.UserActionLogsEnum; +import net.gepafin.tendermanagement.model.request.ApplicationContractRequest; +import net.gepafin.tendermanagement.model.request.UserActionRequest; +import net.gepafin.tendermanagement.model.response.ApplicationContractResponse; +import net.gepafin.tendermanagement.model.util.Response; +import net.gepafin.tendermanagement.service.ApplicationContractService; +import net.gepafin.tendermanagement.util.LoggingUtil; +import net.gepafin.tendermanagement.web.rest.api.ApplicationContractApi; +import net.gepafin.tendermanagement.web.rest.api.errors.Status; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.multipart.MultipartFile; + +import java.util.List; + +@RestController +@RequestMapping("${openapi.gepafin.base-path:/v1/applicationContract}") +public class ApplicationContractApiController implements ApplicationContractApi { + + @Autowired + private LoggingUtil loggingUtil; + + @Autowired + private ApplicationContractService applicationContractService; + + @Override + public ResponseEntity> createApplicationContract(HttpServletRequest request, Long applicationId, List contractDocuments, ApplicationContractRequest applicationContractRequest) { + loggingUtil.logUserAction( + UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.INSERT).actionContext(UserActionContextEnum.CREATE_CONTRACT_FOR_APPLICATION).build()); + ApplicationContractResponse applicationContractResponse=applicationContractService.createApplicationContract(request,applicationId,contractDocuments,applicationContractRequest); + + return ResponseEntity.status(HttpStatus.OK) + .body(new Response<>(applicationContractResponse, Status.SUCCESS, Translator.toLocale(GepafinConstant.CREATE_APPLICATION_CONTRACT))); + + } + + @Override + public ResponseEntity> updateApplicationContract(HttpServletRequest request, Long applicationId, List beneficiaryContractDocuments) { + loggingUtil.logUserAction( + UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.UPDATE).actionContext(UserActionContextEnum.UPDATE_APPLICATION_CONTRACT).build()); + ApplicationContractResponse applicationContractResponse=applicationContractService.updateApplicationContract(request,applicationId,beneficiaryContractDocuments); + + return ResponseEntity.status(HttpStatus.OK) + .body(new Response<>(applicationContractResponse, Status.SUCCESS, Translator.toLocale(GepafinConstant.APPLICATION_CONTRACT_UPDATED))); + } + + @Override + public ResponseEntity> getApplicationContractById(HttpServletRequest request, Long id) { + loggingUtil.logUserAction( + UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.VIEW).actionContext(UserActionContextEnum.FETCH_APPLICATION_CONTRACT).build()); + ApplicationContractResponse applicationContractResponse=applicationContractService.getContractById(id); + + return ResponseEntity.status(HttpStatus.OK) + .body(new Response<>(applicationContractResponse, Status.SUCCESS, Translator.toLocale(GepafinConstant.APPLICATION_CONTRACT_FETCHED))); + } + + @Override + public ResponseEntity> getApplicationContractByApplicationId(HttpServletRequest request, Long applicationId) { + loggingUtil.logUserAction( + UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.VIEW).actionContext(UserActionContextEnum.FETCH_APPLICATION_CONTRACT_BY_APPLICATION_ID).build()); + ApplicationContractResponse applicationContractResponse=applicationContractService.getContractByApplicationId(applicationId); + + return ResponseEntity.status(HttpStatus.OK) + .body(new Response<>(applicationContractResponse, Status.SUCCESS, Translator.toLocale(GepafinConstant.APPLICATION_CONTRACT_FETCHED))); + } + + @Override + public ResponseEntity>> getApplicationContractByBeneficiaryUserId(HttpServletRequest request, Long beneficiaryUserId) { + loggingUtil.logUserAction( + UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.VIEW).actionContext(UserActionContextEnum.FETCH_APPLICATION_CONTRACT_BY_BENEFICIARY_USER_ID).build()); + List applicationContractResponse=applicationContractService.getContractByBeneficiaryUserId(beneficiaryUserId); + + return ResponseEntity.status(HttpStatus.OK) + .body(new Response<>(applicationContractResponse, Status.SUCCESS, Translator.toLocale(GepafinConstant.APPLICATION_CONTRACT_FETCHED))); + } + +} 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 a1698fc2..e96d0bf7 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 @@ -3100,4 +3100,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/db/dump/insert_notification_template_for_contract_upload.sql b/src/main/resources/db/dump/insert_notification_template_for_contract_upload.sql new file mode 100644 index 00000000..7100bc6a --- /dev/null +++ b/src/main/resources/db/dump/insert_notification_template_for_contract_upload.sql @@ -0,0 +1,2 @@ +INSERT INTO notification_type (notification_name,title, json_template,created_date,updated_date,is_deleted) VALUES +('CONTRACT_UPLOAD', 'Documento caricato per contratto','La richiesta in {{call_name}} con protocollo n. {{protocol_number}} ha caricato un documento per il contratto.','2025-11-04T15:16:26.472Z','2025-11-04T15:16:26.472Z','false'); \ No newline at end of file diff --git a/src/main/resources/message_en.properties b/src/main/resources/message_en.properties index c02deff6..48b7a1d6 100644 --- a/src/main/resources/message_en.properties +++ b/src/main/resources/message_en.properties @@ -416,5 +416,11 @@ pec.email.required=PEC email is required. application.technical.evaluation.rejected.success=Application changes to status application technical evaluation rejected successfully. invalid.email.json=Invalid email json. more.fields.required=Subject, reason, and motivation are required when rejecting the application. - - +create.application.contract=Application contract created successfully. +application.contract.not.found=Application contract not found. +application.contract.fetched=Application contract fetched successfully. +application.contract.updated=Application contract updated successfully. +files.required.for.contract=Files are required for contract. +application.contract.already.exist=Application contract already exist for this application. +application.not.approved=Application is not approved. +subject.body.required=Subject and body is required to create contract. diff --git a/src/main/resources/message_it.properties b/src/main/resources/message_it.properties index e18f529a..9a0f2724 100644 --- a/src/main/resources/message_it.properties +++ b/src/main/resources/message_it.properties @@ -407,3 +407,11 @@ pec.email.required=Obbligatorio l'indirizzo e-mail PEC. application.technical.evaluation.rejected.success=Lo stato dell'applicazione cambia: valutazione tecnica dell'applicazione rifiutata con successo. invalid.email.json=Codice email json non valido. more.fields.required=Per rifiutare la domanda sono richiesti oggetto, motivo e motivazione. +create.application.contract=Contratto di candidatura creato con successo. +application.contract.not.found=Contratto di candidatura non trovato. +application.contract.fetched=Contratto di candidatura recuperato con successo. +application.contract.updated=Contratto di candidatura aggiornato con successo. +files.required.for.contract=I file sono necessari per il contratto. +application.contract.already.exist=Il contratto di applicazione esiste già per questa applicazione. +application.not.approved=La domanda non è stata approvata. +subject.body.required=Per creare un contratto sono necessari oggetto e corpo.