diff --git a/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java b/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java index 37623cf7..e53385fa 100644 --- a/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java +++ b/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java @@ -277,5 +277,14 @@ public class GepafinConstant { public static final String GET_APPLICATION_AMENDMENT_SUCCESS_MSG = "application.amendment.get.success"; public static final String APPLICATION_AMENDMENT_UPDATE_SUCCESSFULLY_MSG = "application.amendment.update.successfully"; + public static final String COMMUNICATION_ADDED_TO_AMENDMENT_REQUEST_SUCCESS = "added.comment.to.amendment.request.success"; + public static final String COMMENT_NOT_FOUND = "comment.not.found"; + public static final String COMMENT_UPDATED_SUCCESS_MSG = "comment.updated.successfully"; + public static final String COMMENT_DELETED_SUCCESS_MSG = "comment.deleted.successfully"; + public static final String COMMENT_NOT_ASSOCIATE_WITH_AMENDMENT_ID_ERROR_MSG = "comment.not.associate.with.amendment"; + public static final String AMENDMENT_FOUND_SUCCESS = "amendment.found.success"; + public static final String INVALID_AMENDMENT_FOR_COMMENT = "invalid.amendment.for.comment"; + public static final String DD_MM_YYYY_HH_MM = "DD_MM_YYYY_HH_MM"; + } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java index 59cc5802..af220008 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java @@ -43,9 +43,6 @@ public class ApplicationAmendmentRequestDao { @Autowired private ApplicationService applicationService; - @Autowired - private FormRepository formRepository; - @Autowired private UserService userService; @@ -62,11 +59,14 @@ public class ApplicationAmendmentRequestDao { private ApplicationFormFieldRepository applicationFormFieldRepository; @Autowired - private DocumentRepository documentRepository; - + private CommunicationDao communicationDao; @Autowired private ApplicationEvaluationService applicationEvaluationService; + + @Autowired + private ProtocolDao protocolDao; + @Autowired private AssignedApplicationsService assignedApplicationsService; @@ -173,9 +173,12 @@ public class ApplicationAmendmentRequestDao { public ApplicationAmendmentRequestResponse createApplicationAmendmentRequest(Long applicationEvaluationId, ApplicationAmendmentRequest applicationAmendmentRequest){ log.info("Submiting application data for amendment Process with details: {}", applicationEvaluationId); - ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity = createApplicationAmendmentRequestEntity(applicationAmendmentRequest,applicationEvaluationId); + ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity = createApplicationAmendmentRequestEntity(applicationAmendmentRequest, applicationEvaluationId); ApplicationAmendmentRequestResponse applicationAmendmentRequestResponse = convertEntityToResponse(applicationAmendmentRequestEntity); log.info("Application submitted successfully for amendment", applicationAmendmentRequestResponse); + if(Boolean.TRUE.equals(applicationAmendmentRequestResponse.isSendEmail())){ + communicationDao.sendMailToNotifyBeneficiaryRegardingNewAmendment(applicationAmendmentRequestEntity); + } return applicationAmendmentRequestResponse; } @@ -197,7 +200,12 @@ public class ApplicationAmendmentRequestDao { .collect(Collectors.joining(",")); applicationAmendmentRequestEntity.setFormFields(fieldIdsString); } - + UserEntity userEntity = userService.validateUser(applicationEvaluationId); + Long protocolNumber = protocolDao.getProtocolNumber(userEntity.getHub()); + ProtocolEntity protocolEntity = protocolDao.createProtocolEntity( + applicationEvaluationEntity.getAssignedApplicationsEntity().getApplication(), protocolNumber, + userEntity.getHub().getId()); + applicationAmendmentRequestEntity.setProtocol(protocolEntity); applicationAmendmentRequestEntity.setIsEmail(false); applicationAmendmentRequestEntity.setIsNotification(false); ApplicationAmendmentRequestEntity applicationAmendment = saveApplicationAmendmentRequestEntity(applicationAmendmentRequestEntity); @@ -241,8 +249,8 @@ public class ApplicationAmendmentRequestDao { applicationAmendmentRequestResponse.setSendEmail(applicationAmendmentRequestEntity.getIsEmail()); applicationAmendmentRequestResponse.setSendNotification(applicationAmendmentRequestEntity.getIsNotification()); String callName = application.getCall().getName(); - Long protocolNumber = (application.getProtocol() != null && application.getProtocol().getProtocolNumber() != null) - ? application.getProtocol().getProtocolNumber() + Long protocolNumber = (applicationAmendmentRequestEntity.getProtocol() != null && applicationAmendmentRequestEntity.getProtocol().getProtocolNumber() != null) + ? applicationAmendmentRequestEntity.getProtocol().getProtocolNumber() : null; UserEntity userEntity = userService.validateUser(application.getUserId()); String firstName = userEntity.getBeneficiary() != null ? userEntity.getBeneficiary().getFirstName() : ""; @@ -286,18 +294,17 @@ public class ApplicationAmendmentRequestDao { return applicationAmendmentRequestResponse; } - public ApplicationAmendmentRequestEntity validateApplicationAmendmentRequest(Long id){ - ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity = applicationAmendmentRequestRepository.findByIdAndIsDeletedFalse(id).orElseThrow(()-> - new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.APPLICATION_AMENDMENT_NOT_FOUND_MSG))); - return applicationAmendmentRequestEntity; - } - + public ApplicationAmendmentRequestEntity validateApplicationAmendmentRequest(Long id) { + return applicationAmendmentRequestRepository.findByIdAndIsDeletedFalse(id) + .orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND, + Translator.toLocale(GepafinConstant.APPLICATION_AMENDMENT_NOT_FOUND_MSG))); + } public void deleteById(Long id) { log.info("Deleting assigned application with ID: {}", id); ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity= validateApplicationAmendmentRequest(id); applicationAmendmentRequestEntity.setIsDeleted(true); - applicationAmendmentRequestEntity= saveApplicationAmendmentRequestEntity(applicationAmendmentRequestEntity); + saveApplicationAmendmentRequestEntity(applicationAmendmentRequestEntity); log.info(" Application amendment deleted with ID: {}", id); } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java index 2332a194..e1cf0820 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java @@ -44,7 +44,6 @@ import jakarta.servlet.http.HttpServletRequest; import java.text.MessageFormat; import java.time.LocalDateTime; -import java.time.LocalTime; import java.util.*; import java.util.stream.Collectors; @@ -91,9 +90,6 @@ public class ApplicationDao { @Autowired private CompanyService companyService; - - @Autowired - private ProtocolRepository protocolRepository; @Autowired private SystemEmailTemplatesService systemEmailTemplatesService; @@ -122,14 +118,14 @@ public class ApplicationDao { @Value("${aws.s3.url.folder.signed.document}") private String signedDocumentS3Folder; - @Value("${default.hub.uuid}") - private String defaultHubUuid; - @Autowired private UserService userService; @Autowired - S3PathConfig s3ConfigBean; + private S3PathConfig s3ConfigBean; + + @Autowired + private ProtocolDao protocolDao; public ApplicationResponseBean createApplication(HttpServletRequest request, ApplicationRequestBean applicationRequestBean, Long formId, Long applicationId) { @@ -606,8 +602,8 @@ public class ApplicationDao { } if (status.equals(ApplicationStatusTypeEnum.SUBMIT) && Boolean.TRUE.equals(applicationEntity.getStatus().equals(ApplicationStatusTypeEnum.READY.getValue()))) { callService.validatePublishedCall(applicationEntity.getCall().getId(), userEntity.getHub().getId()); - Long protocolNumber = getProtocolNumber(userEntity.getHub()); - ProtocolEntity protocolEntity = createProtocolEntity(applicationEntity,protocolNumber, userEntity.getHub().getId()); + Long protocolNumber = protocolDao.getProtocolNumber(userEntity.getHub()); + ProtocolEntity protocolEntity = protocolDao.createProtocolEntity(applicationEntity,protocolNumber, userEntity.getHub().getId()); applicationEntity.setProtocol(protocolEntity); applicationEntity.setStatus(ApplicationStatusTypeEnum.SUBMIT.getValue()); applicationEntity.setSubmissionDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); @@ -622,14 +618,7 @@ public class ApplicationDao { return getApplicationResponse(applicationEntity); } - private Long getProtocolNumber(HubEntity hubEntity) { - Long maxProtocolNumber = protocolRepository.findMaxProtocolNumberAndHubId(hubEntity.getId()); - Long startNumber = 10000001L; - if(Boolean.FALSE.equals(defaultHubUuid.equals(hubEntity.getUniqueUuid()))) { - startNumber = 20000001L; - } - return (maxProtocolNumber != null) ? maxProtocolNumber + 1 : startNumber; - } + public Integer calculateProgress(Long totalSteps, Long completedSteps) { if (FieldValidator.isNullOrZero(totalSteps)) { throw new CustomValidationException(Status.BAD_REQUEST,Translator.toLocale(GepafinConstant.TOTAL_STEPS_NOT_BE_ZERO)); @@ -703,18 +692,6 @@ public class ApplicationDao { } } - public ProtocolEntity createProtocolEntity(ApplicationEntity applicationEntity,Long protocolNumber, Long hubId){ - ProtocolEntity protocolEntity=new ProtocolEntity(); - protocolEntity.setCall(applicationEntity.getCall().getId()); - LocalDateTime utcDateTime = DateTimeUtil.DateServerToUTC(LocalDateTime.now()); - protocolEntity.setYear(utcDateTime.getYear()); - protocolEntity.setProtocolNumber(protocolNumber); - protocolEntity.setTime(LocalTime.now()); - protocolEntity.setApplicationId(applicationEntity.getId()); - protocolEntity.setHubId(hubId); - protocolRepository.save(protocolEntity); - return protocolEntity; - } private void sendMailToUserAndCompany(UserEntity userEntity, ApplicationEntity applicationEntity) { CallEntity call =applicationEntity.getCall(); CompanyEntity company = applicationEntity.getCompany(); diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java index 6c15ef76..c8366d7d 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java @@ -65,7 +65,7 @@ public class ApplicationEvaluationDao { entity.setUserId(user.getId()); entity.setCriteria(Utils.convertObjectToJson(req.getCriteria())); entity.setChecklist(Utils.convertObjectToJson(req.getChecklist())); - entity.setFile(Utils.convertObjectToJson(req.getField())); + entity.setFile(Utils.convertObjectToJson(req.getFiles())); entity.setNote(req.getNote()); entity.setIsDeleted(false); entity.setStatus(ApplicationEvaluationStatusTypeEnum.OPEN.getValue()); @@ -467,7 +467,7 @@ public class ApplicationEvaluationDao { Map existingFieldMap = existingFieldList.stream() .collect(Collectors.toMap(FieldResponse::getId, field -> field)); - List updatedFieldList = req.getField().stream() + List updatedFieldList = req.getFiles().stream() .map(incoming -> { FieldRequest request = new FieldRequest(); request.setId(incoming.getId()); diff --git a/src/main/java/net/gepafin/tendermanagement/dao/CommunicationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/CommunicationDao.java new file mode 100644 index 00000000..9d546496 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/dao/CommunicationDao.java @@ -0,0 +1,249 @@ +package net.gepafin.tendermanagement.dao; + +import net.gepafin.tendermanagement.config.Translator; +import net.gepafin.tendermanagement.constants.GepafinConstant; +import net.gepafin.tendermanagement.entities.ApplicationAmendmentRequestEntity; +import net.gepafin.tendermanagement.entities.ApplicationEntity; +import net.gepafin.tendermanagement.entities.CallEntity; +import net.gepafin.tendermanagement.entities.CommunicationEntity; +import net.gepafin.tendermanagement.entities.CompanyEntity; +import net.gepafin.tendermanagement.entities.ProtocolEntity; +import net.gepafin.tendermanagement.entities.SystemEmailTemplatesEntity; +import net.gepafin.tendermanagement.entities.UserEntity; +import net.gepafin.tendermanagement.model.request.CommunicationRequestBean; +import net.gepafin.tendermanagement.model.response.ApplicationAmendmentResponse; +import net.gepafin.tendermanagement.model.response.CommunicationResponseBean; +import net.gepafin.tendermanagement.model.response.SystemEmailTemplateResponse; +import net.gepafin.tendermanagement.repositories.CommunicationRepository; +import net.gepafin.tendermanagement.service.ApplicationAmendmentRequestService; +import net.gepafin.tendermanagement.service.ApplicationService; +import net.gepafin.tendermanagement.service.SystemEmailTemplatesService; +import net.gepafin.tendermanagement.service.UserService; +import net.gepafin.tendermanagement.util.DateTimeUtil; +import net.gepafin.tendermanagement.util.MailUtil; +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.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.time.LocalDateTime; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Component +public class CommunicationDao { + private static final Logger log = LoggerFactory.getLogger(CommunicationDao.class); + + @Autowired + private CommunicationRepository communicationRepository; + + @Autowired + ApplicationAmendmentRequestService applicationAmendmentRequestService; + + @Autowired + private MailUtil mailUtil; + + @Autowired + private SystemEmailTemplatesService systemEmailTemplatesService; + + @Autowired + private ApplicationService applicationService; + + @Autowired + private UserService userService; + + + public CommunicationResponseBean addCommentToAmendmentRequest(CommunicationRequestBean communicationReq, Long amendmentId) { + + log.info("Adding communication request..."); + CommunicationEntity communicationEntity = convertToCommunicationCommentEntity(communicationReq, amendmentId); + communicationEntity = communicationRepository.save(communicationEntity); + log.info("Added comment: {}", communicationEntity); + return convertToCommunicationResponseBean(communicationEntity); + } + + public String deleteComment(Long amendmentId, Long commentId) { + + CommunicationEntity data = communicationRepository.findById(commentId) + .orElseThrow(() -> new CustomValidationException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.COMMENT_NOT_FOUND))); + if (!data.getApplicationAmendmentRequest().getId().equals(amendmentId)) { + throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.INVALID_AMENDMENT_FOR_COMMENT)); + } + data.setIsDeleted(true); + communicationRepository.save(data); + return "Deleted Comment Successfully."; + } + + public ApplicationAmendmentResponse getAmendmentComments(Long amendmentId) { + + ApplicationAmendmentRequestEntity amendmentData = applicationAmendmentRequestService.validateApplicationAmendmentRequest(amendmentId); + List commentsList = communicationRepository.findCommentDetailsByAmendmentId(amendmentId); + if (commentsList == null) { + throw new CustomValidationException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.COMMENT_NOT_FOUND)); + } + return new ApplicationAmendmentResponse(amendmentData, commentsList); + } + + public CommunicationResponseBean updateAmendmentComment(CommunicationRequestBean communicationRequestBean, Long amendmentId, Long commentId) { + + log.info("Updating communication comment..."); + CommunicationEntity existingComment = communicationRepository.findById(commentId) + .orElseThrow(() -> new CustomValidationException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.COMMENT_NOT_FOUND))); + if (!existingComment.getApplicationAmendmentRequest().getId().equals(amendmentId)) { + throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.COMMENT_NOT_ASSOCIATE_WITH_AMENDMENT_ID_ERROR_MSG)); + } + existingComment.setCommunicationTitle(communicationRequestBean.getTitle()); + existingComment.setCommunicationComment(communicationRequestBean.getComment()); + existingComment.setCommentedDate(LocalDateTime.now()); + existingComment = communicationRepository.save(existingComment); + log.info("Updated Comment: {}", existingComment); + return convertToCommunicationResponseBean(existingComment); + } + + private CommunicationResponseBean convertToCommunicationResponseBean(CommunicationEntity entity) { + + CommunicationResponseBean response = new CommunicationResponseBean(); + response.setComment(entity.getCommunicationComment()); + response.setCommentedDate(entity.getCommentedDate()); + response.setAmendmentId(entity.getApplicationAmendmentRequest().getId()); + response.setCreatedDate(entity.getCreatedDate()); + response.setUpdatedDate(entity.getUpdatedDate()); + response.setTitle(entity.getCommunicationTitle()); + return response; + } + + private CommunicationEntity convertToCommunicationCommentEntity(CommunicationRequestBean communicationReq, Long amendmentId) { + + ApplicationAmendmentRequestEntity amendmentRequest = applicationAmendmentRequestService.validateApplicationAmendmentRequest(amendmentId); + CommunicationEntity communicationEntity = new CommunicationEntity(); + communicationEntity.setApplicationAmendmentRequest(amendmentRequest); + communicationEntity.setCommunicationTitle(communicationReq.getTitle()); + communicationEntity.setCommunicationComment(communicationReq.getComment()); + communicationEntity.setIsDeleted(false); + communicationEntity.setCommentedDate(LocalDateTime.now()); + return communicationEntity; + } + + public void sendMailToNotifyBeneficiaryRegardingNewAmendment(ApplicationAmendmentRequestEntity applicationAmendmentRequest) { + + ApplicationEntity applicationEntity = applicationService.validateApplication(applicationAmendmentRequest.getApplicationId()); + + SystemEmailTemplateResponse systemEmailTemplateResponse = systemEmailTemplatesService.retrieveTemplateByTypeAndCall( + SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum.DOCUMENTATION_INTEGRATION_REQUEST, applicationEntity.getCall(), null); + + // Create the map for subject placeholders + Map subjectPlaceholders = new HashMap<>(); + subjectPlaceholders.put("{{call_name}}", applicationEntity.getCall().getName()); + subjectPlaceholders.put("{{company_name}}", applicationEntity.getCompany().getCompanyName()); + + // Create the map for body placeholders + Map bodyPlaceholders = new HashMap<>(); + bodyPlaceholders.put("{{call_name}}", applicationEntity.getCall().getName()); + bodyPlaceholders.put("{{protocol_number}}", applicationEntity.getProtocol().getProtocolNumber().toString()); + bodyPlaceholders.put("{{protocol_date}}", DateTimeUtil.formatLocalDateTime(applicationAmendmentRequest.getProtocol().getCreatedDate(), GepafinConstant.DD_MM_YYYY)); + bodyPlaceholders.put("{{protocol_time}}", DateTimeUtil.parseLocalTimeToString(applicationAmendmentRequest.getProtocol().getTime(), GepafinConstant.HH_MM_SS)); + bodyPlaceholders.put("{{form_dataInput}}", ""); + + // Replace placeholders in the subject and body + String subject = Utils.replacePlaceholders(systemEmailTemplateResponse.getSubject(), subjectPlaceholders); + String body = Utils.replacePlaceholders(systemEmailTemplateResponse.getHtmlContent(), bodyPlaceholders); + UserEntity userEntity = userService.validateUser(applicationEntity.getUserId()); + mailUtil.sendByMailGun(subject, body, List.of(userEntity.getBeneficiary().getEmail()), null); + } + + public void sendApplicationFailureNotificationEmail(String userEmail, ApplicationEntity applicationEntity) { + + CallEntity call = applicationEntity.getCall(); + CompanyEntity company = applicationEntity.getCompany(); + ProtocolEntity protocol = applicationEntity.getProtocol(); + SystemEmailTemplateResponse systemEmailTemplateResponse = systemEmailTemplatesService.retrieveTemplateByTypeAndCall( + SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum.INADMISSIBILITY_NOTIFICATION_DUE_TO_FAILURE, call, null); + + // Create the map for subject placeholders + Map subjectPlaceholders = new HashMap<>(); + subjectPlaceholders.put("{{call_name}}", call.getName()); + subjectPlaceholders.put("{{company_name}}", company.getCompanyName()); + + // Create the map for body placeholders + Map bodyPlaceholders = new HashMap<>(); + bodyPlaceholders.put("{{call_name}}", call.getName()); + bodyPlaceholders.put("{{date_time_emailSend}}", DateTimeUtil.formatLocalDateTime(protocol.getCreatedDate(), GepafinConstant.DD_MM_YYYY_HH_MM)); + + // Replace placeholders in the subject and body + String subject = Utils.replacePlaceholders(systemEmailTemplateResponse.getSubject(), subjectPlaceholders); + String body = Utils.replacePlaceholders(systemEmailTemplateResponse.getHtmlContent(), bodyPlaceholders); + + mailUtil.sendByMailGun(subject, body, List.of(userEmail), null); + mailUtil.sendByMailGun(subject, body, List.of(applicationEntity.getCompany().getEmail()), null); + } + + private void sendAdmissibilityNotificationEmail(UserEntity userEntity, ApplicationEntity applicationEntity) { + + CallEntity call = applicationEntity.getCall(); + CompanyEntity company = applicationEntity.getCompany(); + ProtocolEntity protocol = applicationEntity.getProtocol(); + SystemEmailTemplateResponse systemEmailTemplateResponse = systemEmailTemplatesService.retrieveTemplateByTypeAndCall( + SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum.ADMISSIBILITY_NOTIFICATION, call, null); + + // Create the map for subject placeholders + Map subjectPlaceholders = new HashMap<>(); + subjectPlaceholders.put("{{call_name}}", call.getName()); + subjectPlaceholders.put("{{company_name}}", company.getCompanyName()); + + // Create the map for body placeholders + Map bodyPlaceholders = new HashMap<>(); + bodyPlaceholders.put("{{call_name}}", call.getName()); + bodyPlaceholders.put("{{protocol_number}}", protocol.getProtocolNumber().toString()); + bodyPlaceholders.put("{{protocol_date}}", DateTimeUtil.formatCreatedDate(protocol.getCreatedDate())); + bodyPlaceholders.put("{{protocol_time}}", DateTimeUtil.parseLocalTimeToString(protocol.getTime(), GepafinConstant.HH_MM_SS)); + + // Replace placeholders in the subject and body + String subject = Utils.replacePlaceholders(systemEmailTemplateResponse.getSubject(), subjectPlaceholders); + String body = Utils.replacePlaceholders(systemEmailTemplateResponse.getHtmlContent(), bodyPlaceholders); + + String email = userEntity.getEmail(); + if (userEntity.getBeneficiary() != null) { + email = userEntity.getBeneficiary().getEmail(); + } + mailUtil.sendByMailGun(subject, body, List.of(email), null); + mailUtil.sendByMailGun(subject, body, List.of(applicationEntity.getCompany().getEmail()), null); + } + + private void sendInadmissibilityTemplateEmail(UserEntity userEntity, ApplicationEntity applicationEntity) { + + CallEntity call = applicationEntity.getCall(); + CompanyEntity company = applicationEntity.getCompany(); + ProtocolEntity protocol = applicationEntity.getProtocol(); + SystemEmailTemplateResponse systemEmailTemplateResponse = systemEmailTemplatesService.retrieveTemplateByTypeAndCall( + SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum.INADMISSIBILITY_TEMPLATE, call, null); + + // Create the map for subject placeholders + Map subjectPlaceholders = new HashMap<>(); + subjectPlaceholders.put("{{call_name}}", call.getName()); + subjectPlaceholders.put("{{company_name}}", company.getCompanyName()); + + // Create the map for body placeholders + Map bodyPlaceholders = new HashMap<>(); + bodyPlaceholders.put("{{call_name}}", call.getName()); + bodyPlaceholders.put("{{protocol_number}}", protocol.getProtocolNumber().toString()); + bodyPlaceholders.put("{{protocol_date}}", DateTimeUtil.formatCreatedDate(protocol.getCreatedDate())); + bodyPlaceholders.put("{{protocol_time}}", DateTimeUtil.parseLocalTimeToString(protocol.getTime(), GepafinConstant.HH_MM_SS)); + bodyPlaceholders.put("{{form_text}}", "YOUR_FORM_TEXT_HERE"); // Replace with actual data input if available + + // Replace placeholders in the subject and body + String subject = Utils.replacePlaceholders(systemEmailTemplateResponse.getSubject(), subjectPlaceholders); + String body = Utils.replacePlaceholders(systemEmailTemplateResponse.getHtmlContent(), bodyPlaceholders); + + String email = userEntity.getEmail(); + if (userEntity.getBeneficiary() != null) { + email = userEntity.getBeneficiary().getEmail(); + } + mailUtil.sendByMailGun(subject, body, List.of(email), null); + mailUtil.sendByMailGun(subject, body, List.of(applicationEntity.getCompany().getEmail()), null); + } + +} diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ProtocolDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ProtocolDao.java new file mode 100644 index 00000000..97ecde18 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/dao/ProtocolDao.java @@ -0,0 +1,48 @@ +package net.gepafin.tendermanagement.dao; + +import java.time.LocalDateTime; +import java.time.LocalTime; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import net.gepafin.tendermanagement.entities.ApplicationEntity; +import net.gepafin.tendermanagement.entities.HubEntity; +import net.gepafin.tendermanagement.entities.ProtocolEntity; +import net.gepafin.tendermanagement.repositories.ProtocolRepository; +import net.gepafin.tendermanagement.util.DateTimeUtil; + +@Component +public class ProtocolDao { + + @Autowired + private ProtocolRepository protocolRepository; + + + @Value("${default.hub.uuid}") + private String defaultHubUuid; + + + public Long getProtocolNumber(HubEntity hubEntity) { + Long maxProtocolNumber = protocolRepository.findMaxProtocolNumberAndHubId(hubEntity.getId()); + Long startNumber = 10000001L; + if(Boolean.FALSE.equals(defaultHubUuid.equals(hubEntity.getUniqueUuid()))) { + startNumber = 20000001L; + } + return (maxProtocolNumber != null) ? maxProtocolNumber + 1 : startNumber; + } + + public ProtocolEntity createProtocolEntity(ApplicationEntity applicationEntity,Long protocolNumber, Long hubId){ + ProtocolEntity protocolEntity=new ProtocolEntity(); + protocolEntity.setCall(applicationEntity.getCall().getId()); + LocalDateTime utcDateTime = DateTimeUtil.DateServerToUTC(LocalDateTime.now()); + protocolEntity.setYear(utcDateTime.getYear()); + protocolEntity.setProtocolNumber(protocolNumber); + protocolEntity.setTime(LocalTime.now()); + protocolEntity.setApplicationId(applicationEntity.getId()); + protocolEntity.setHubId(hubId); + protocolRepository.save(protocolEntity); + return protocolEntity; + } +} diff --git a/src/main/java/net/gepafin/tendermanagement/entities/ApplicationAmendmentRequestEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/ApplicationAmendmentRequestEntity.java index 3746927d..6f5a4c40 100644 --- a/src/main/java/net/gepafin/tendermanagement/entities/ApplicationAmendmentRequestEntity.java +++ b/src/main/java/net/gepafin/tendermanagement/entities/ApplicationAmendmentRequestEntity.java @@ -32,5 +32,9 @@ public class ApplicationAmendmentRequestEntity extends BaseEntity { @ManyToOne @JoinColumn(name = "APPLICATION_EVALUATION_ID", nullable = false) private ApplicationEvaluationEntity applicationEvaluationEntity; + + @OneToOne + @JoinColumn(name = "PROTOCOL_Id") + private ProtocolEntity protocol; } diff --git a/src/main/java/net/gepafin/tendermanagement/entities/ApplicationEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/ApplicationEntity.java index 5ddebe5c..68c433e2 100644 --- a/src/main/java/net/gepafin/tendermanagement/entities/ApplicationEntity.java +++ b/src/main/java/net/gepafin/tendermanagement/entities/ApplicationEntity.java @@ -8,9 +8,6 @@ import java.time.LocalDateTime; @Entity @Table(name = "APPLICATION") @Data -@NoArgsConstructor -@AllArgsConstructor -@Builder public class ApplicationEntity extends BaseEntity { @Column(name = "USER_ID") diff --git a/src/main/java/net/gepafin/tendermanagement/entities/ApplicationEvaluationEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/ApplicationEvaluationEntity.java index 2ddad5ae..dae9a3fb 100644 --- a/src/main/java/net/gepafin/tendermanagement/entities/ApplicationEvaluationEntity.java +++ b/src/main/java/net/gepafin/tendermanagement/entities/ApplicationEvaluationEntity.java @@ -3,14 +3,14 @@ package net.gepafin.tendermanagement.entities; import jakarta.persistence.*; import lombok.Data; -import java.time.LocalDateTime; -import java.util.List; @Data @Entity @Table(name = "application_evaluation") public class ApplicationEvaluationEntity extends BaseEntity{ + @Column(name = "application_Id") private Long applicationId; + @Column(name = "user_id") private Long userId; @@ -35,4 +35,5 @@ public class ApplicationEvaluationEntity extends BaseEntity{ @ManyToOne @JoinColumn(name = "assigned_applications_id", nullable = true) private AssignedApplicationsEntity assignedApplicationsEntity; + } diff --git a/src/main/java/net/gepafin/tendermanagement/entities/CommunicationEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/CommunicationEntity.java new file mode 100644 index 00000000..7aa43acd --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/entities/CommunicationEntity.java @@ -0,0 +1,33 @@ +package net.gepafin.tendermanagement.entities; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.Table; +import lombok.Data; + +import java.time.LocalDateTime; + +@Entity +@Table(name = "communication") +@Data +public class CommunicationEntity extends BaseEntity { + + @Column(name = "COMMUNICATION_TITLE") + private String communicationTitle; + + @Column(name = "COMMUNICATION_COMMENT") + private String communicationComment; + + @Column(name = "IS_DELETED") + private Boolean isDeleted = false; + + @Column(name = "COMMENTED_DATE") + private LocalDateTime commentedDate; + + @ManyToOne + @JoinColumn(name = "AMENDMENT_ID", referencedColumnName = "id", nullable = false) + private ApplicationAmendmentRequestEntity applicationAmendmentRequest; + +} \ No newline at end of file diff --git a/src/main/java/net/gepafin/tendermanagement/entities/SystemEmailTemplatesEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/SystemEmailTemplatesEntity.java index 9ae12cbf..29e33277 100644 --- a/src/main/java/net/gepafin/tendermanagement/entities/SystemEmailTemplatesEntity.java +++ b/src/main/java/net/gepafin/tendermanagement/entities/SystemEmailTemplatesEntity.java @@ -39,7 +39,11 @@ public class SystemEmailTemplatesEntity extends BaseEntity { public enum SystemEmailTemplatesEntityTypeEnum { APPLICATION_SUBMISSION_TO_USER_AND_COMPANY("APPLICATION_SUBMISSION_TO_USER_AND_COMPANY"), - APPLICATION_SUBMISSION_TO_GEPAFIN("APPLICATION_SUBMISSION_TO_GEPAFIN"); + APPLICATION_SUBMISSION_TO_GEPAFIN("APPLICATION_SUBMISSION_TO_GEPAFIN"), + DOCUMENTATION_INTEGRATION_REQUEST("DOCUMENTATION_INTEGRATION_REQUEST"), + INADMISSIBILITY_NOTIFICATION_DUE_TO_FAILURE("INADMISSIBILITY_NOTIFICATION_DUE_TO_FAILURE"), + ADMISSIBILITY_NOTIFICATION("ADMISSIBILITY_NOTIFICATION"), + INADMISSIBILITY_TEMPLATE("INADMISSIBILITY_NOTIFICATION_2"); private String value; diff --git a/src/main/java/net/gepafin/tendermanagement/model/request/ApplicationEvaluationRequest.java b/src/main/java/net/gepafin/tendermanagement/model/request/ApplicationEvaluationRequest.java index 12fc7150..767b4aef 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/request/ApplicationEvaluationRequest.java +++ b/src/main/java/net/gepafin/tendermanagement/model/request/ApplicationEvaluationRequest.java @@ -1,7 +1,6 @@ package net.gepafin.tendermanagement.model.request; import lombok.Data; -import net.gepafin.tendermanagement.enums.ApplicationEvaluationStatusTypeEnum; import java.util.List; @Data @@ -9,6 +8,6 @@ public class ApplicationEvaluationRequest { private List criteria; private List checklist; - private List field; + private List files; private String note; } diff --git a/src/main/java/net/gepafin/tendermanagement/model/request/CommunicationRequestBean.java b/src/main/java/net/gepafin/tendermanagement/model/request/CommunicationRequestBean.java new file mode 100644 index 00000000..d44e7eaa --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/model/request/CommunicationRequestBean.java @@ -0,0 +1,10 @@ +package net.gepafin.tendermanagement.model.request; + +import lombok.Data; + +@Data +public class CommunicationRequestBean { + private String title; + private String comment; +} + diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationAmendmentRequestResponse.java b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationAmendmentRequestResponse.java index 23273057..30fe2238 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationAmendmentRequestResponse.java +++ b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationAmendmentRequestResponse.java @@ -22,5 +22,6 @@ public class ApplicationAmendmentRequestResponse { private Long applicationId; private Long applicationEvaluationId; private LocalDateTime expirationDate; + private List commentsList; } diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationAmendmentResponse.java b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationAmendmentResponse.java new file mode 100644 index 00000000..52ae7285 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationAmendmentResponse.java @@ -0,0 +1,16 @@ +package net.gepafin.tendermanagement.model.response; + +import lombok.Data; +import net.gepafin.tendermanagement.entities.ApplicationAmendmentRequestEntity; + +import java.util.List; + +@Data +public class ApplicationAmendmentResponse { + private ApplicationAmendmentRequestEntity amendment; + private List commentsList; + public ApplicationAmendmentResponse(ApplicationAmendmentRequestEntity amendment, List comments) { + this.amendment = amendment; + this.commentsList = comments; + } +} diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/CommunicationResponseBean.java b/src/main/java/net/gepafin/tendermanagement/model/response/CommunicationResponseBean.java new file mode 100644 index 00000000..d1405dd8 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/model/response/CommunicationResponseBean.java @@ -0,0 +1,33 @@ +package net.gepafin.tendermanagement.model.response; + +import lombok.Data; + +import java.time.LocalDateTime; + +@Data +public class CommunicationResponseBean { + private LocalDateTime commentedDate; + + private String comment; + + private String title; + + private LocalDateTime createdDate; + + private LocalDateTime updatedDate; + + private Long amendmentId; + public CommunicationResponseBean(LocalDateTime commentedDate, String comment, String title, LocalDateTime createdDate, LocalDateTime updatedDate, Long amendmentId) { + + this.commentedDate = commentedDate; + this.comment = comment; + this.title = title; + this.createdDate = createdDate; + this.updatedDate = updatedDate; + this.amendmentId = amendmentId; + } + + public CommunicationResponseBean() { + + } +} diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/CommunicationRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/CommunicationRepository.java new file mode 100644 index 00000000..0e9d8d9c --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/repositories/CommunicationRepository.java @@ -0,0 +1,21 @@ +package net.gepafin.tendermanagement.repositories; + +import net.gepafin.tendermanagement.entities.CommunicationEntity; +import net.gepafin.tendermanagement.model.response.CommunicationResponseBean; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +import java.util.List; + +public interface CommunicationRepository extends JpaRepository { + + @Query("Select new net.gepafin.tendermanagement.model.response.CommunicationResponseBean(c.commentedDate, c.communicationComment, c.communicationTitle, c.createdDate, c.updatedDate, c.applicationAmendmentRequest.id) " + + "from CommunicationEntity c Where c.applicationAmendmentRequest.id = :applicationAmendmentRequestId") + List findCommentsByApplicationAmendmentRequestId(@Param("applicationAmendmentRequestId") Long amendmentRequestId); + + @Query("SELECT new net.gepafin.tendermanagement.model.response.CommunicationResponseBean( " + "c.commentedDate, c.communicationComment, c.communicationTitle, c.createdDate, c" + + ".updatedDate, c.applicationAmendmentRequest.id) " + "FROM CommunicationEntity c " + "WHERE c.applicationAmendmentRequest.id = :amendmentId AND c.isDeleted = false") + List findCommentDetailsByAmendmentId(@Param("amendmentId") Long amendmentId); + +} diff --git a/src/main/java/net/gepafin/tendermanagement/scheduler/NotificationScheduler.java b/src/main/java/net/gepafin/tendermanagement/scheduler/NotificationScheduler.java new file mode 100644 index 00000000..43d844b0 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/scheduler/NotificationScheduler.java @@ -0,0 +1,72 @@ +//package net.gepafin.tendermanagement.scheduler; +// +//import net.gepafin.tendermanagement.dao.CommunicationDao; +//import net.gepafin.tendermanagement.entities.ApplicationAmendmentRequestEntity; +//import net.gepafin.tendermanagement.entities.ApplicationEntity; +//import net.gepafin.tendermanagement.entities.UserEntity; +//import net.gepafin.tendermanagement.repositories.ApplicationAmendmentRepository; +//import net.gepafin.tendermanagement.repositories.ApplicationRepository; +//import net.gepafin.tendermanagement.repositories.UserRepository; +//import org.springframework.beans.factory.annotation.Autowired; +//import org.springframework.scheduling.annotation.Scheduled; +//import org.springframework.stereotype.Component; +// +//import java.time.LocalDateTime; +//import java.util.List; +// +//@Component +//public class NotificationScheduler { +// +// @Autowired +// UserRepository userRepository; +// +// @Autowired +// ApplicationRepository applicationRepository; +// +// @Autowired +// ApplicationAmendmentRepository applicationAmendmentRepository; +// +// @Autowired +// CommunicationDao communicationDao; +// +// @Scheduled(cron = "0 0/10 * * * ?", zone = "Asia/Kolkata") +// void sendNotificationForRejectedApplicationToBeneficiary() { +// +// List applicationsList = applicationRepository.findByIsDeletedFalse(); +// List amendmentRequestList = applicationAmendmentRepository.findByIsDeletedFalse(); +// +// LocalDateTime today = LocalDateTime.now(); +// +// for (ApplicationEntity application : applicationsList) { +// ApplicationAmendmentRequestEntity amendmentRequest = getAmendmentRequestForApplication(application, amendmentRequestList); +// +// if (amendmentRequest != null) { +// LocalDateTime requestDate = amendmentRequest.getStartedDate(); +// +// // Check if requestDate + 7 days is less than or equal to today +// if (requestDate.plusDays(7).isAfter(today)) { +// // Update the application status to REJECTED +// application.setStatus("REJECTED"); +// applicationRepository.save(application); // Save updated application +// +// // Update the amendment request status to CLOSED +// amendmentRequest.setStatus("CLOSED"); +// applicationAmendmentRepository.save(amendmentRequest); // Save updated amendment request +// +// // Get the user associated with the application +// UserEntity user = userRepository.findById(application.getUserId()).orElse(null); // Adjust according to your UserRepository's method +// +// // Send email notification if user is found +// if (user != null && user.getEmail() != null) { +// communicationDao.sendApplicationFailureNotificationEmail(user.getEmail(), application); +// } +// } +// } +// } +// } +// +// private ApplicationAmendmentRequestEntity getAmendmentRequestForApplication(ApplicationEntity application, List amendmentRequestList) { +// +// return amendmentRequestList.stream().filter(request -> request.getId().equals(application.getId())).findFirst().orElse(null); +// } +//} diff --git a/src/main/java/net/gepafin/tendermanagement/service/ApplicationService.java b/src/main/java/net/gepafin/tendermanagement/service/ApplicationService.java index c9a65fef..d2bb4b19 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/ApplicationService.java +++ b/src/main/java/net/gepafin/tendermanagement/service/ApplicationService.java @@ -26,7 +26,7 @@ public interface ApplicationService { void deleteApplication(HttpServletRequest request, Long applicationId); - public ApplicationEntity validateApplication(Long userId); + public ApplicationEntity validateApplication(Long applicationId); public ApplicationResponse createApplication(HttpServletRequest request, Long companyId, ApplicationRequest applicationRequest, Long callId); diff --git a/src/main/java/net/gepafin/tendermanagement/service/CommunicationService.java b/src/main/java/net/gepafin/tendermanagement/service/CommunicationService.java new file mode 100644 index 00000000..5f8f1cd3 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/service/CommunicationService.java @@ -0,0 +1,15 @@ +package net.gepafin.tendermanagement.service; + +import net.gepafin.tendermanagement.model.request.CommunicationRequestBean; +import net.gepafin.tendermanagement.model.response.ApplicationAmendmentResponse; +import net.gepafin.tendermanagement.model.response.CommunicationResponseBean; + +public interface CommunicationService { + CommunicationResponseBean addCommentToAmendmentRequest(CommunicationRequestBean communicationRequestBean, Long amendmentId); + + String deleteComment(Long amendmentId, Long commentId); + + CommunicationResponseBean updateAmendmentComment(CommunicationRequestBean communicationRequestBean, Long amendmentId, Long commentId); + + ApplicationAmendmentResponse getAmendmentComments(Long id); +} diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationAmendmentRequestServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationAmendmentRequestServiceImpl.java index 23af105f..1fb77c4b 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationAmendmentRequestServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationAmendmentRequestServiceImpl.java @@ -35,8 +35,6 @@ public class ApplicationAmendmentRequestServiceImpl implements ApplicationAmendm return applicationAmendmentRequestDao.createApplicationAmendmentRequest(applicationEvaluationId,applicationAmendmentRequest); } - - @Override public void deleteApplicationAmendmentRequest(HttpServletRequest request, Long id) { applicationAmendmentRequestDao.deleteById(id); diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationServiceImpl.java index 779a3d09..111ac099 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationServiceImpl.java @@ -56,8 +56,8 @@ public class ApplicationServiceImpl implements ApplicationService { } @Override - public ApplicationEntity validateApplication(Long id) { - return applicationDao.validateApplication(id); + public ApplicationEntity validateApplication(Long applicationId) { + return applicationDao.validateApplication(applicationId); } @Override diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/CommunicationServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/CommunicationServiceImpl.java new file mode 100644 index 00000000..5a9b9c06 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/CommunicationServiceImpl.java @@ -0,0 +1,43 @@ +package net.gepafin.tendermanagement.service.impl; + +import net.gepafin.tendermanagement.dao.CommunicationDao; +import net.gepafin.tendermanagement.model.request.CommunicationRequestBean; +import net.gepafin.tendermanagement.model.response.ApplicationAmendmentResponse; +import net.gepafin.tendermanagement.model.response.CommunicationResponseBean; +import net.gepafin.tendermanagement.service.CommunicationService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + + +@Service +public class CommunicationServiceImpl implements CommunicationService { + + @Autowired + CommunicationDao communicationDao; + + @Override + @Transactional(rollbackFor = Exception.class) + public CommunicationResponseBean addCommentToAmendmentRequest(CommunicationRequestBean communicationRequestBean, Long amendmentId) { + + return communicationDao.addCommentToAmendmentRequest(communicationRequestBean, amendmentId); + } + @Override + @Transactional(rollbackFor = Exception.class) + public String deleteComment(Long amendmentId, Long commentId) { + + return communicationDao.deleteComment(amendmentId, commentId); + } + @Override + @Transactional(rollbackFor = Exception.class) + public CommunicationResponseBean updateAmendmentComment(CommunicationRequestBean communicationRequestBean, Long amendmentId, Long commentId) { + + return communicationDao.updateAmendmentComment(communicationRequestBean, amendmentId, commentId); + } + @Override + @Transactional(readOnly = true) + public ApplicationAmendmentResponse getAmendmentComments(Long id) { + + return communicationDao.getAmendmentComments(id); + } +} 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 4db4ea12..6cdac900 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/S3ReUploadMigrationService.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/S3ReUploadMigrationService.java @@ -181,16 +181,10 @@ public class S3ReUploadMigrationService { private void updateDocumentPathAndDeleteOldEntry(DocumentEntity document, String newPath) { String fileName = extractFileName(newPath); - DocumentEntity newDocument = new DocumentEntity(); + DocumentEntity newDocument = document; newDocument.setFilePath(newPath); - newDocument.setSource(document.getSource()); - newDocument.setType(document.getType()); - newDocument.setIsDeleted(false); - newDocument.setSourceId(document.getSourceId()); newDocument.setFileName(fileName); - documentRepository.save(newDocument); - documentRepository.delete(document); log.info("Migrated document ID: {} to new path: {}", document.getId(), newPath); } 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 c1228565..f1813242 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/UserSignedAndDelegationServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/UserSignedAndDelegationServiceImpl.java @@ -229,15 +229,11 @@ public class UserSignedAndDelegationServiceImpl { private void updateDocumentPathAndDeleteOldEntry(ApplicationSignedDocumentEntity document, String newPath) { - ApplicationSignedDocumentEntity newDocument = new ApplicationSignedDocumentEntity(); + ApplicationSignedDocumentEntity newDocument = document; String fileName = extractFileNameFromPath(newPath); newDocument.setFilePath(newPath); newDocument.setFileName(fileName); - newDocument.setApplication(document.getApplication()); - newDocument.setStatus("ACTIVE"); - applicationSignedDocumentRepository.save(newDocument); - applicationSignedDocumentRepository.delete(document); log.info("Migrated document ID: {} to new path: {}", document.getId(), newPath); } @@ -245,17 +241,10 @@ public class UserSignedAndDelegationServiceImpl { private void updateDelegatedDocumentPathAndDeleteOldEntry(UserCompanyDelegationEntity document, String newPath) { String fileName = extractFileNameFromPath(newPath); - UserCompanyDelegationEntity newDocument = new UserCompanyDelegationEntity(); + UserCompanyDelegationEntity newDocument = document; newDocument.setFilePath(newPath); newDocument.setFileName(fileName); - newDocument.setBeneficiaryId(document.getBeneficiaryId()); - newDocument.setUserId(document.getUserId()); - newDocument.setCompanyId(document.getCompanyId()); - newDocument.setStatus("ACTIVE"); - userCompanyDelegationRepository.save(newDocument); - userCompanyDelegationRepository.delete(document); - log.info("Migrated document ID: {} to new path: {}", document.getId(), newPath); } } diff --git a/src/main/java/net/gepafin/tendermanagement/util/DateTimeUtil.java b/src/main/java/net/gepafin/tendermanagement/util/DateTimeUtil.java index 1fdf6c1a..ec7fe7d9 100644 --- a/src/main/java/net/gepafin/tendermanagement/util/DateTimeUtil.java +++ b/src/main/java/net/gepafin/tendermanagement/util/DateTimeUtil.java @@ -108,4 +108,12 @@ public class DateTimeUtil { return null; } } + public static String formatCreatedDate(LocalDateTime createdDate) { + + if (createdDate == null) { + return ""; + } + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy"); + return createdDate.format(formatter); + } } diff --git a/src/main/java/net/gepafin/tendermanagement/util/Utils.java b/src/main/java/net/gepafin/tendermanagement/util/Utils.java index 828644b0..a4cb7bf2 100644 --- a/src/main/java/net/gepafin/tendermanagement/util/Utils.java +++ b/src/main/java/net/gepafin/tendermanagement/util/Utils.java @@ -323,6 +323,7 @@ public class Utils { public static String convertObjectToJson(Object obj) { try { + if(obj == null){return null;} return new ObjectMapper().writeValueAsString(obj); } catch (JsonProcessingException e) { log.error("Failed to convert object to JSON: {}", e.getMessage(), e); diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/CommunicationApi.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/CommunicationApi.java new file mode 100644 index 00000000..98224277 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/CommunicationApi.java @@ -0,0 +1,69 @@ +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 net.gepafin.tendermanagement.model.request.CommunicationRequestBean; +import net.gepafin.tendermanagement.model.response.ApplicationAmendmentResponse; +import net.gepafin.tendermanagement.model.response.CommunicationResponseBean; +import net.gepafin.tendermanagement.model.util.Response; +import net.gepafin.tendermanagement.web.rest.api.errors.ErrorConstants; +import org.springframework.data.repository.query.Param; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; + +@Validated +public interface CommunicationApi { + @Operation(summary = "Api to create communication amendment comment", 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 = "/{amendmentId}", produces = { "application/json" }) + ResponseEntity> addCommentToAmendmentRequest(HttpServletRequest request, + @RequestBody @Parameter CommunicationRequestBean communicationResponseBean, @Param(value = "amendmentId") Long amendmentId); + + @Operation(summary = "API to Get Amendment Request Comment", 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 = "/{amendmentId}", produces = "application/json") + public ResponseEntity> getAmendmentComments(@PathVariable Long amendmentId); + + @Operation(summary = "Api to update communication comments", 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 = "/{amendmentId}/{commentId}", produces = { "application/json" }) + ResponseEntity> updateCommunicationAmendment(HttpServletRequest request, + @RequestBody @Parameter CommunicationRequestBean communicationResponseBean, @PathVariable Long amendmentId, @PathVariable Long commentId); + + @Operation(summary = "Api to delete communication comments", 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) })) }) + @DeleteMapping(value = "/{amendmentId}/{commentId}", produces = { "application/json" }) + ResponseEntity> deleteApplicationAmendmentComment(HttpServletRequest request, @Param(value = "amendmentId") Long amendmentId, + @Param(value = "commentId") Long commentId); +} diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/errors/GlobalExceptionHandler.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/errors/GlobalExceptionHandler.java index fd7ba455..cec3c224 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/errors/GlobalExceptionHandler.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/errors/GlobalExceptionHandler.java @@ -51,6 +51,8 @@ public class GlobalExceptionHandler { @ExceptionHandler(ResourceNotFoundException.class) public ResponseEntity> handleResourceNotFoundException(ResourceNotFoundException ex) { + log.error(ex.getMessage()); + log.error(ex.getLocalizedMessage(), ex); return ResponseEntity.status(HttpStatus.NOT_FOUND) .body(new Response<>(null, ex.getStatus(), ex.getMessage())); } diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/CommunicationController.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/CommunicationController.java new file mode 100644 index 00000000..4805d2ce --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/CommunicationController.java @@ -0,0 +1,56 @@ +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.model.request.CommunicationRequestBean; +import net.gepafin.tendermanagement.model.response.ApplicationAmendmentResponse; +import net.gepafin.tendermanagement.model.response.CommunicationResponseBean; +import net.gepafin.tendermanagement.model.util.Response; +import net.gepafin.tendermanagement.service.CommunicationService; +import net.gepafin.tendermanagement.web.rest.api.CommunicationApi; +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; + +@RestController +@RequestMapping("${openapi.gepafin.base-path:/v1/communication}") +public class CommunicationController implements CommunicationApi { + + @Autowired + CommunicationService communicationService; + + @Override + public ResponseEntity> addCommentToAmendmentRequest(HttpServletRequest request, CommunicationRequestBean communicationRequestBean, + Long amendmentId) { + + CommunicationResponseBean communicationResponseBean = communicationService.addCommentToAmendmentRequest(communicationRequestBean, amendmentId); + return ResponseEntity.status(HttpStatus.CREATED) + .body(new Response<>(communicationResponseBean, Status.SUCCESS, Translator.toLocale(GepafinConstant.COMMUNICATION_ADDED_TO_AMENDMENT_REQUEST_SUCCESS))); + } + @Override + public ResponseEntity> getAmendmentComments(Long amendmentId) { + + ApplicationAmendmentResponse response = communicationService.getAmendmentComments(amendmentId); + return ResponseEntity.ok(new Response<>(response, Status.SUCCESS, Translator.toLocale(GepafinConstant.AMENDMENT_FOUND_SUCCESS))); + } + @Override + public ResponseEntity> updateCommunicationAmendment(HttpServletRequest request, CommunicationRequestBean communicationRequestBean, + Long amendmentId, Long commentId) { + + CommunicationResponseBean communicationResponseBean = communicationService.updateAmendmentComment(communicationRequestBean, amendmentId, commentId); + return ResponseEntity.status(HttpStatus.OK) + .body(new Response<>(communicationResponseBean, Status.SUCCESS, Translator.toLocale(GepafinConstant.COMMENT_UPDATED_SUCCESS_MSG))); + } + @Override + public ResponseEntity> deleteApplicationAmendmentComment(HttpServletRequest request, Long applicationAmendId, Long commentId) { + + String communicationResponseBean = communicationService.deleteComment(applicationAmendId, commentId); + return ResponseEntity.status(HttpStatus.OK) + .body(new Response<>(communicationResponseBean, Status.SUCCESS, Translator.toLocale(GepafinConstant.COMMENT_DELETED_SUCCESS_MSG))); + } + +} 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 27a58cf3..91d15122 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 @@ -1336,21 +1336,20 @@ - - - - + + + - + @@ -1358,24 +1357,24 @@ - - - - + + + + - + @@ -1383,17 +1382,17 @@ - - - + + + @@ -1403,12 +1402,12 @@ - + @@ -1519,7 +1518,7 @@ - + @@ -1530,14 +1529,14 @@ referencedTableName="gepafin_user" referencedColumnNames="id" constraintName="fk_application_evaluation_gepafin_user" - onDelete="CASCADE" /> + onDelete="CASCADE"/> + onDelete="CASCADE"/> @@ -1590,6 +1589,61 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/db/dump/insert_system_email_template_for_notification_mail_27_10_2024.sql b/src/main/resources/db/dump/insert_system_email_template_for_notification_mail_27_10_2024.sql new file mode 100644 index 00000000..60556052 --- /dev/null +++ b/src/main/resources/db/dump/insert_system_email_template_for_notification_mail_27_10_2024.sql @@ -0,0 +1,134 @@ +INSERT INTO gepafin_schema.system_email_template +( + id, template_name, "type", html_content, subject, "json", "system", + is_deleted, created_date, updated_date +) +VALUES +( + 3, + 'Instructional Aid/Request for Documentation Integration Template', + 'DOCUMENTATION_INTEGRATION_REQUEST', + ' + +
+

RICHIESTA INTEGRAZIONE DOCUMENTALE

+

Buongiorno,

+

In riferimento alla domanda di concessione di Finanziamento agevolato a valere sul Fondo prestiti + {{call_name}} di cui al Protocollo n. {{protocol_number}} del + {{protocol_date}} e {{protocol_time}}, alla luce dell’attività istruttoria svolta, + segnaliamo quanto segue:

+
    +
  • {{form_dataInput}}
  • +
+

Vi invitiamo a fornire quanto sopra richiesto integrando la documentazione sia caricandola all’interno dello sportello + online https://bandi.gepafin.it/ che inviandola a mezzo PEC all’indirizzo + bandi.gepafin@legalmail.it entro e non oltre 10 giorni dal ricevimento della presente comunicazione, + precisando che, in caso di mancata ricezione nei termini indicati, saremo costretti a non prendere in considerazione la Vostra richiesta di finanziamento.

+

Vi informiamo che per la ricezione della PEC farà fede la ricevuta di avvenuta consegna che attesterà il buon esito + dell’invio. La documentazione trasmessa e le informazioni fornite saranno processate dall''istruttore assegnatario della pratica.

+

Distinti Saluti,

+

Gepafin S.p.a.

+
+ + ', + 'BANDO {{call_name}} - Domanda di concessione di finanziamento agevolato {{company_name}}', + NULL, + true, + false, + '2024-10-26 20:00:00', + '2024-10-26 20:00:00' +); +INSERT INTO gepafin_schema.system_email_template +( + id, template_name, "type", html_content, subject, "json", "system", + is_deleted, created_date, updated_date +) +VALUES +( + 4, + 'Notification of Inadmissibility Due to Failure to Respond Template', + 'INADMISSIBILITY_NOTIFICATION', + ' + +
+

Comunicazione di non ammissibilità per mancata risposta a richiesta integrazione documentale

+

Buongiorno,

+

Con posta elettronica certificata del {{date_time_emailSend}}, vi abbiamo comunicato che i documenti richiesti + dal Gestore sarebbero dovuti pervenire entro 10 giorni dal ricevimento di detta comunicazione. + Trascorso il termine senza la ricezione dei documenti richiesti, il Gestore non ha potuto prendere in considerazione la richiesta di finanziamento.

+

È possibile presentare ricorso tramite modello disponibile nello sportello online + https://bandi.gepafin.it/ entro 10 giorni dalla ricezione di questa comunicazione.

+

Distinti Saluti,

+

Gepafin S.p.a.

+
+ + ', + 'BANDO {{call_name}} - Domanda di finanziamento agevolato non ammessa {{company_name}}', + NULL, + true, + false, + '2024-10-26 20:00:00', + '2024-10-26 20:00:00' +); +INSERT INTO gepafin_schema.system_email_template +( + id, template_name, "type", html_content, subject, "json", "system", + is_deleted, created_date, updated_date +) +VALUES +( + 5, + 'Notification of Admissibility Template', + 'ADMISSIBILITY_NOTIFICATION', + ' + +
+

Buongiorno,

+

In riferimento alla domanda di concessione di Finanziamento agevolato “{{call_name}}” di cui al + Protocollo n. {{protocol_number}} del {{protocol_date}} alle {{protocol_time}}, l’istruttoria di ammissibilità + è stata completata con esito positivo.

+

Seguirà una comunicazione relativa alla valutazione tecnica ed economico-finanziaria ai fini della valutazione finale.

+

Distinti Saluti,

+

Gepafin S.p.a.

+
+ + ', + 'BANDO {{call_name}} – Esito positivo istruttoria di ammissibilità {{company_name}}', + NULL, + true, + false, + '2024-10-26 20:00:00', + '2024-10-26 20:00:00' +); +INSERT INTO gepafin_schema.system_email_template +( + id, template_name, "type", html_content, subject, "json", "system", + is_deleted, created_date, updated_date +) +VALUES +( + 6, + 'Notification of Inadmissibility Template', + 'INADMISSIBILITY_NOTIFICATION', + ' + +
+

Buongiorno,

+

In riferimento alla domanda di concessione di Finanziamento agevolato “{{call_name}}” di cui al + Protocollo n. {{protocol_number}} del {{protocol_date}} alle {{protocol_time}}, + l''istruttoria di ammissibilità è stata completata con esito negativo.

+

Motivazioni: {{form_text}}

+

È possibile presentare ricorso tramite modello disponibile nello sportello online + https://bandi.gepafin.it/ entro 10 giorni dalla ricezione di questa comunicazione.

+

Distinti Saluti,

+

Gepafin S.p.a.

+
+ + ', + 'BANDO {{call_name}} – Esito negativo istruttoria di ammissibilità {{company_name}}', + NULL, + true, + false, + '2024-10-26 20:00:00', + '2024-10-26 20:00:00' +); diff --git a/src/main/resources/message_en.properties b/src/main/resources/message_en.properties index 3c93b0e7..e47a62c8 100644 --- a/src/main/resources/message_en.properties +++ b/src/main/resources/message_en.properties @@ -290,4 +290,13 @@ delete.application.amendment.success = Application Amendment successfully delete create.application.data.amendment.msg = Application amendment submited succesfully. application.amendment.not.found = Application Amendment Request not found with the given ID. application.amendment.get.success = Application Amendment details fetched successfully with given ID. -application.amendment.update.successfully = Application Amendment Updated Successfully. \ No newline at end of file +application.amendment.update.successfully = Application Amendment Updated Successfully. + +added.comment.to.amendment.request.success = Application Amendment Comment Added Successfully.; +comment.not.found = Comment Not Found."; +comment.updated.successfully = Comment Updated Successfully."; +comment.deleted.successfully = Comment Deleted Successfully."; +comment.not.associate.with.amendment = Comment Not Associated with Amendment Request."; +amendment.found.success = Amendment Request Found Successfully."; +invalid.amendment.for.comment = Invalid Amendment Request for the Given Comment."; +DD_MM_YYYY_HH_MM = DD-MM-YYYY HH:MM."; diff --git a/src/main/resources/message_it.properties b/src/main/resources/message_it.properties index 12f29c59..1eaa302f 100644 --- a/src/main/resources/message_it.properties +++ b/src/main/resources/message_it.properties @@ -286,4 +286,13 @@ delete.application.amendment.success =Emendamento all'applicazione eliminato con application.amendment.not.found = Richiesta di modifica dell'applicazione non trovata con l'ID indicato. application.amendment.get.success = Dettagli della modifica dell'applicazione recuperati correttamente con l'ID fornito. application.amendment.update.successfully = Emendamento all'applicazione aggiornato con successo. -create.application.data.amendment.msg =Emendamento alla domanda inviato con successo \ No newline at end of file + +added.comment.to.amendment.request.success = Commento aggiunto con successo alla richiesta di emendamento. +comment.not.found = Commento non trovato. +comment.updated.successfully = Commento aggiornato con successo. +comment.deleted.successfully = Commento eliminato con successo. +comment.not.associate.with.amendment = Il commento non � associato alla richiesta di emendamento. +amendment.found.success = Richiesta di emendamento trovata con successo. +invalid.amendment.for.comment = Richiesta di emendamento non valida per il commento fornito. +DD_MM_YYYY_HH_MM = DD-MM-YYYY HH:MM. +create.application.data.amendment.msg =Emendamento alla domanda inviato con successo