Merge pull request #87 from Kitzanos/feature/GEPAFINBE-84

GEPAFINBE- 84 & GEPAFINBE - 92 (Email Tracking Management)
This commit is contained in:
rbonazzo-KZ
2024-11-19 12:38:35 +01:00
committed by GitHub
28 changed files with 549 additions and 112 deletions

View File

@@ -11,10 +11,7 @@ import net.gepafin.tendermanagement.constants.GepafinConstant;
import net.gepafin.tendermanagement.entities.*;
import net.gepafin.tendermanagement.entities.SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum;
import net.gepafin.tendermanagement.enums.*;
import net.gepafin.tendermanagement.model.request.ApplicationAmendmentRequest;
import net.gepafin.tendermanagement.model.request.ApplicationAmendmentRequestBean;
import net.gepafin.tendermanagement.model.request.ApplicationFormFieldRequestBean;
import net.gepafin.tendermanagement.model.request.CloseAmendmentRequest;
import net.gepafin.tendermanagement.model.request.*;
import net.gepafin.tendermanagement.model.response.*;
import net.gepafin.tendermanagement.repositories.*;
import net.gepafin.tendermanagement.service.*;
@@ -97,6 +94,9 @@ public class ApplicationAmendmentRequestDao {
@Autowired
private Validator validator;
@Autowired
private EmailLogDao emailLogDao;
public ApplicationAmendmentRequestResponse getApplicationDataForAmendment(Long applicationEvaluationId) {
log.info("Fetching the application data for the Amendment process {}", applicationEvaluationId);
ApplicationEvaluationEntity applicationEvaluationEntity = applicationEvaluationService.validateApplicationEvaluation(applicationEvaluationId);
@@ -732,8 +732,9 @@ public class ApplicationAmendmentRequestDao {
String subject = prepareSubject(emailTemplate, amendment, beneficiaryUser);
String body = prepareBody(emailTemplate, amendment, beneficiaryUser);
String email = beneficiaryUser.getEmail();
if (Boolean.TRUE.equals(amendment.getIsEmail()) && email != null && !email.isEmpty()) {
emailNotificationDao.sendMail(hub.getId(), subject, body, List.of(email));
if (Boolean.TRUE.equals(amendment.getIsEmail())&&email != null && !email.isEmpty()) {
EmailLogRequest emailLogRequest=emailLogDao.createEmailLogRequest(emailTemplate.getEmailScenario(),RecipientTypeEnum.USER,beneficiaryUser.getId(),email,beneficiaryUser.getId(),applicationEntity.getId(),amendment.getId(),applicationEntity.getCall().getId());
emailNotificationDao.sendMail(hub.getId(), subject, body, List.of(email),emailLogRequest);
} else {
throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.BENEFICIARY_EMAIL_NOT_FOUND_MSG));
}

View File

@@ -8,6 +8,7 @@ import net.gepafin.tendermanagement.enums.*;
import net.gepafin.tendermanagement.model.request.ApplicationFormFieldRequestBean;
import net.gepafin.tendermanagement.model.request.ApplicationRequest;
import net.gepafin.tendermanagement.model.request.ApplicationRequestBean;
import net.gepafin.tendermanagement.model.request.EmailLogRequest;
import net.gepafin.tendermanagement.model.response.*;
import net.gepafin.tendermanagement.repositories.*;
import net.gepafin.tendermanagement.service.AmazonS3Service;
@@ -142,6 +143,8 @@ public class ApplicationDao {
@Autowired
private FormDao formDao;
@Autowired
private EmailLogDao emailLogDao;
public ApplicationResponseBean createApplication(HttpServletRequest request, ApplicationRequestBean applicationRequestBean, Long formId, Long applicationId) {
FormEntity formEntity = formService.validateForm(formId);
@@ -795,25 +798,32 @@ public class ApplicationDao {
// 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();
EmailLogRequest emailLogRequest=emailLogDao.createEmailLogRequest(systemEmailTemplateResponse.getEmailScenario(),RecipientTypeEnum.USER,userEntity.getId(),userEntity.getEmail(),userEntity.getId(),applicationEntity.getId(),null,applicationEntity.getCall().getId());
String email = userEntity.getEmail();
if (userEntity.getBeneficiary() != null) {
emailLogRequest.setRecipientType(RecipientTypeEnum.BENEFICIARY);
email = userEntity.getBeneficiary().getEmail();
emailLogRequest.setUserId(userEntity.getBeneficiary().getId());
}
emailNotificationDao.sendMail(hub.getId(), subject, body, List.of(email));
emailNotificationDao.sendMail(hub.getId(), subject, body, List.of(email),emailLogRequest);
List<String> recipientEmails = new ArrayList<>();
// recipientEmails.add(email);
String companyEmail = company.getEmail();
String contactEmail = company.getContactEmail();
if (companyEmail != null && !companyEmail.isEmpty()) {
recipientEmails.add(companyEmail);
}
if (contactEmail != null && !contactEmail.isEmpty() && !contactEmail.equals(companyEmail)) {
recipientEmails.add(contactEmail);
}
emailNotificationDao.sendMail(hub.getId(), subject, body, recipientEmails);
// recipientEmails.add(email);
String companyEmail = company.getEmail();
String contactEmail = company.getContactEmail();
if (companyEmail != null && !companyEmail.isEmpty()) {
recipientEmails.add(companyEmail);
}
if (contactEmail != null && !contactEmail.isEmpty() && !contactEmail.equals(companyEmail)) {
recipientEmails.add(contactEmail);
}
if(Boolean.FALSE.equals(recipientEmails.isEmpty())){
emailLogRequest.setRecipientId(applicationEntity.getCompany().getId());
emailLogRequest.setRecipientType(RecipientTypeEnum.COMPANY);
emailLogRequest.setRecipientEmails(companyEmail);
}
emailNotificationDao.sendMail(hub.getId(), subject, body, recipientEmails,emailLogRequest);
}
private void sendMailTodefaultSystemAndGepafin(UserEntity userEntity, ApplicationEntity applicationEntity) {
CallEntity call = applicationEntity.getCall();
@@ -840,17 +850,22 @@ public class ApplicationDao {
String subject = Utils.replacePlaceholders(systemEmailTemplateResponse.getSubject(), subjectPlaceholders);
String body = Utils.replacePlaceholders(systemEmailTemplateResponse.getHtmlContent(), bodyPlaceholders);
EmailLogRequest emailLogRequest=emailLogDao.createEmailLogRequest(systemEmailTemplateResponse.getEmailScenario(),RecipientTypeEnum.PROPERTIES,null,userEntity.getEmail(),userEntity.getId(),applicationEntity.getId(),null,applicationEntity.getCall().getId());
// mailUtil.sendByMailGun(subject, body, List.of(defaultSystemReceiverEmail), null);
// mailUtil.sendByMailGun(subject, body, List.of(gepafinEmail), null);
// mailUtil.sendByMailGun(subject, body, List.of(rinaldoEmail), null);
if(validator.isProductionProfileActivated()) {
emailLogRequest.setRecipientEmails(carloEmail);
// mailUtil.sendByMailGun(subject, body, List.of(carloEmail), null);
emailNotificationDao.sendMail(hub.getId(), subject, body, List.of(carloEmail));
emailNotificationDao.sendMail(hub.getId(), subject, body, List.of(carloEmail),emailLogRequest);
}
emailNotificationDao.sendMail(hub.getId(), subject, body, List.of(hub.getEmail()));
emailNotificationDao.sendMail(hub.getId(), subject, body, List.of(defaultSystemReceiverEmail));
emailNotificationDao.sendMail(hub.getId(), subject, body, List.of(rinaldoEmail));
emailLogRequest.setRecipientEmails(hub.getEmail());
emailNotificationDao.sendMail(hub.getId(), subject, body, List.of(hub.getEmail()),emailLogRequest);
emailLogRequest.setRecipientEmails(defaultSystemReceiverEmail);
emailNotificationDao.sendMail(hub.getId(), subject, body, List.of(defaultSystemReceiverEmail),emailLogRequest);
emailLogRequest.setRecipientEmails(rinaldoEmail);
emailNotificationDao.sendMail(hub.getId(), subject, body, List.of(rinaldoEmail),emailLogRequest);
}
public ApplicationSignedDocumentResponse uploadSignedDocument(HttpServletRequest request, Long applicationId,

View File

@@ -0,0 +1,59 @@
package net.gepafin.tendermanagement.dao;
import net.gepafin.tendermanagement.entities.EmailLogEntity;
import net.gepafin.tendermanagement.enums.EmailScenarioTypeEnum;
import net.gepafin.tendermanagement.enums.EmailEntityTypeEnum;
import net.gepafin.tendermanagement.enums.RecipientTypeEnum;
import net.gepafin.tendermanagement.model.request.EmailLogRequest;
import net.gepafin.tendermanagement.repositories.EmailLogRepository;
import net.gepafin.tendermanagement.util.DateTimeUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
@Component
public class EmailLogDao {
@Autowired
private EmailLogRepository emailLogRepository;
public EmailLogEntity createEmailLog(EmailLogRequest emailLogRequest){
EmailLogEntity emailLogEntity=new EmailLogEntity();
emailLogEntity.setEmailType(emailLogRequest.getEmailType().getValue());
emailLogEntity.setRecipientType(emailLogRequest.getRecipientType().getValue());
emailLogEntity.setRecipientId(emailLogRequest.getRecipientId());
emailLogEntity.setEmailSubject(emailLogRequest.getEmailSubject());
emailLogEntity.setEmailBody(emailLogRequest.getEmailBody());
emailLogEntity.setSendStatus(emailLogRequest.getSendStatus());
emailLogEntity.setSendDateTime(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); // Set to now if null
emailLogEntity.setErrorMessage(emailLogRequest.getErrorMessage());
emailLogEntity.setUserId(emailLogRequest.getUserId());
emailLogEntity.setEmailServiceResponse(emailLogRequest.getEmailServiceResponse());
emailLogEntity.setRecipientEmails(emailLogRequest.getRecipientEmails());
emailLogEntity.setEmailServiceType(emailLogRequest.getEmailServiceType().getValue());
emailLogEntity.setIsDeleted(false);
emailLogEntity.setApplicationId(emailLogRequest.getApplicatioId());
emailLogEntity.setAmendmentId(emailLogRequest.getAmendmentId());
emailLogEntity.setCallId(emailLogRequest.getCallId());
emailLogEntity=saveEmailLogEntity(emailLogEntity);
return emailLogEntity;
}
public EmailLogEntity saveEmailLogEntity(EmailLogEntity emailLogEntity){
return emailLogRepository.save(emailLogEntity);
}
public EmailLogRequest createEmailLogRequest(EmailScenarioTypeEnum emailType, RecipientTypeEnum recipientType, Long recipientId,
String recipientEmails, Long userId,Long applicationId,Long amendmentId,Long callId) {
EmailLogRequest emailLogRequest = new EmailLogRequest();
emailLogRequest.setEmailType(emailType);
emailLogRequest.setRecipientType(recipientType);
emailLogRequest.setRecipientId(recipientId);
emailLogRequest.setUserId(userId);
emailLogRequest.setRecipientEmails(recipientEmails);
emailLogRequest.setApplicatioId(applicationId);
emailLogRequest.setAmendmentId(amendmentId);
emailLogRequest.setCallId(callId);
return emailLogRequest;
}
}

View File

@@ -4,9 +4,15 @@ import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import net.gepafin.tendermanagement.constants.GepafinConstant;
import net.gepafin.tendermanagement.entities.*;
import net.gepafin.tendermanagement.entities.*;
import net.gepafin.tendermanagement.enums.EmailEntityTypeEnum;
import net.gepafin.tendermanagement.enums.RecipientTypeEnum;
import net.gepafin.tendermanagement.enums.StatusTypeEnum;
import net.gepafin.tendermanagement.entities.*;
import net.gepafin.tendermanagement.model.request.EmailConfig;
import net.gepafin.tendermanagement.model.request.EmailLogRequest;
import net.gepafin.tendermanagement.model.response.SystemEmailTemplateResponse;
import net.gepafin.tendermanagement.repositories.EmailLogRepository;
import net.gepafin.tendermanagement.repositories.HubRepository;
import net.gepafin.tendermanagement.service.ApplicationService;
import net.gepafin.tendermanagement.service.HubService;
@@ -21,10 +27,8 @@ import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.time.LocalDateTime;
import java.util.*;
@Component
public class EmailNotificationDao {
@@ -49,8 +53,15 @@ public class EmailNotificationDao {
@Autowired
HubRepository hubRepository;
@Autowired
private EmailLogDao emailLogDao;
@Autowired
private EmailLogRepository emailLogRepository;
private void sendEmail(ApplicationEntity applicationEntity, SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum templateType,
Map<String, String> bodyPlaceholders, List<String> additionalRecipients) {
Map<String, String> bodyPlaceholders, List<String> additionalRecipients,Long amendmentId) {
HubEntity hubEntity = hubService.valdateHub(applicationEntity.getHubId());
String service = determineService(applicationEntity.getHubId());
@@ -66,7 +77,8 @@ public class EmailNotificationDao {
UserEntity userEntity = userService.validateUser(applicationEntity.getUserId());
List<String> recipientEmails = getRecipientEmails(applicationEntity, userEntity, additionalRecipients);
sendMail(applicationEntity.getHubId(), subject, body, recipientEmails);
EmailLogRequest emailLogRequest=emailLogDao.createEmailLogRequest(systemEmailTemplateResponse.getEmailScenario(), RecipientTypeEnum.BENEFICIARY,userEntity.getBeneficiary().getId(),Utils.listToCommaSeparatedString(recipientEmails),userEntity.getId(),applicationEntity.getId(),amendmentId ,applicationEntity.getCall().getId());
sendMail(applicationEntity.getHubId(), subject, body, recipientEmails,emailLogRequest);
}
private List<String> getRecipientEmails(ApplicationEntity applicationEntity, UserEntity userEntity, List<String> additionalRecipients) {
List<String> recipientEmails = new ArrayList<>();
@@ -125,17 +137,24 @@ public class EmailNotificationDao {
log.error("Failed to parse form fields JSON: ", e);
}
bodyPlaceholders.put("{{note}}", applicationAmendmentRequest.getNote());
sendEmail(applicationEntity, SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum.DOCUMENTATION_INTEGRATION_REQUEST, bodyPlaceholders, null);
sendEmail(applicationEntity, SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum.DOCUMENTATION_INTEGRATION_REQUEST, bodyPlaceholders, null,applicationAmendmentRequest.getId());
}
public void sendApplicationFailureNotificationEmail(ApplicationAmendmentRequestEntity amendmentRequest) {
ApplicationEntity applicationEntity = applicationService.validateApplication(amendmentRequest.getApplicationId());
UserEntity user = userService.validateUser(applicationEntity.getUserId());
Map<String, String> bodyPlaceholders = new HashMap<>();
bodyPlaceholders.put("{{call_name}}", applicationEntity.getCall().getName());
bodyPlaceholders.put("{{date_time_emailSend}}", DateTimeUtil.formatLocalDateTime(amendmentRequest.getCreatedDate(), GepafinConstant.DD_MM_YYYY_HH_MM));
LocalDateTime lastReminderDateTime=amendmentRequest.getCreatedDate();
List<EmailLogEntity> emailLogEntity = emailLogRepository.findByUserIdAndAmendmentIdAndIsDeletedFalse(user.getId(),amendmentRequest.getId());
if(emailLogEntity!=null && (!emailLogEntity.isEmpty())){
EmailLogEntity emailLogEntity1=emailLogEntity.get(0);
lastReminderDateTime=emailLogEntity1.getSendDateTime();
}
bodyPlaceholders.put("{{date_time_emailSend}}", DateTimeUtil.formatLocalDateTime(lastReminderDateTime, GepafinConstant.DD_MM_YYYY));
sendEmail(applicationEntity, SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum.INADMISSIBILITY_NOTIFICATION_DUE_TO_FAILURE, bodyPlaceholders, null);
sendEmail(applicationEntity, SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum.INADMISSIBILITY_NOTIFICATION_DUE_TO_FAILURE, bodyPlaceholders, null,amendmentRequest.getId());
}
public void sendAdmissibilityNotificationEmailForApprovedApplication(ApplicationEntity applicationEntity) {
@@ -145,7 +164,7 @@ public class EmailNotificationDao {
bodyPlaceholders.put("{{protocol_date}}", DateTimeUtil.formatCreatedDate(applicationEntity.getProtocol().getCreatedDate()));
bodyPlaceholders.put("{{protocol_time}}", DateTimeUtil.parseLocalTimeToString(applicationEntity.getProtocol().getTime(), GepafinConstant.HH_MM_SS));
sendEmail(applicationEntity, SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum.ADMISSIBILITY_NOTIFICATION, bodyPlaceholders, null);
sendEmail(applicationEntity, SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum.ADMISSIBILITY_NOTIFICATION, bodyPlaceholders, null,null);
}
public void sendInadmissibilityEmailForRejectedApplication(ApplicationEntity applicationEntity,ApplicationEvaluationEntity applicationEvaluationEntity) {
@@ -156,14 +175,14 @@ public class EmailNotificationDao {
bodyPlaceholders.put("{{protocol_time}}", DateTimeUtil.parseLocalTimeToString(applicationEntity.getProtocol().getTime(), GepafinConstant.HH_MM_SS));
bodyPlaceholders.put("{{form_text}}", applicationEvaluationEntity.getNote());
sendEmail(applicationEntity, SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum.INADMISSIBILITY_TEMPLATE, bodyPlaceholders, null);
sendEmail(applicationEntity, SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum.INADMISSIBILITY_TEMPLATE, bodyPlaceholders, null,null);
}
public void sendMail(Long hubId, String subject, String body, List<String> recipientEmails) {
public void sendMail(Long hubId, String subject, String body, List<String> recipientEmails, EmailLogRequest emailLogRequest) {
EmailConfig emailConfig = retrieveEmailConfig(hubId);
EmailService emailService = emailServiceFactory.getEmailService(emailConfig.getEmailServiceType());
emailService.sendEmail(subject, body, recipientEmails, emailConfig);
emailService.sendEmail(subject, body, recipientEmails, emailConfig,emailLogRequest);
}
public EmailConfig retrieveEmailConfig(Long hubId) {

View File

@@ -4,6 +4,7 @@ import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import net.gepafin.tendermanagement.enums.EmailScenarioTypeEnum;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
@@ -78,6 +79,7 @@ public class SystemEmailTemplatesDao {
systemEmailTemplateResponse.setHtmlContent(htmlContent);
systemEmailTemplateResponse.setSubject(subject);
systemEmailTemplateResponse.setJsonMap(languageMap);
systemEmailTemplateResponse.setEmailScenario(EmailScenarioTypeEnum.valueOf(dbSystemEmailTemplatesEntity.getEmailScenario()));
return systemEmailTemplateResponse;
}

View File

@@ -0,0 +1,60 @@
package net.gepafin.tendermanagement.entities;
import jakarta.persistence.*;
import lombok.Data;
import java.time.LocalDateTime;
@Entity
@Data
@Table(name = "email_log")
public class EmailLogEntity extends BaseEntity{
@Column(name = "email_type", nullable = false, length = 255)
private String emailType;
@Column(name = "recipient_type", nullable = false, columnDefinition = "TEXT")
private String recipientType;
@Column(name = "recipient_id", nullable = false)
private Long recipientId;
@Column(name = "email_subject", columnDefinition = "TEXT")
private String emailSubject;
@Column(name = "email_body", columnDefinition = "TEXT")
private String emailBody;
@Column(name = "send_status", length = 255)
private String sendStatus;
@Column(name = "send_date_time")
private LocalDateTime sendDateTime;
@Column(name = "error_message", columnDefinition = "TEXT")
private String errorMessage;
@Column(name = "email_service_response")
private String emailServiceResponse;
@Column(name = "email_service_type")
private String emailServiceType;
@Column(name = "recipient_emails")
private String recipientEmails;
@Column(name = "user_id")
private Long userId;
@Column(name = "application_id")
private Long applicationId;
@Column(name = "amendment_id")
private Long amendmentId;
@Column(name = "call_id")
private Long callId;
@Column(name = "is_deleted")
private Boolean isDeleted;
}

View File

@@ -35,6 +35,9 @@ public class SystemEmailTemplatesEntity extends BaseEntity {
@Column(name ="IS_DELETED", nullable = false)
private Boolean isDeleted = false;
@Column(name = "email_scenario")
private String emailScenario;
public enum SystemEmailTemplatesEntityTypeEnum {

View File

@@ -0,0 +1,20 @@
package net.gepafin.tendermanagement.enums;
import com.fasterxml.jackson.annotation.JsonValue;
public enum EmailEntityTypeEnum {
AMENDMENT("AMENDMENT"),
APPLICATION("APPLICATION");
private String value;
EmailEntityTypeEnum(String value) {
this.value = value;
}
@JsonValue
public String getValue() {
return value;
}
}

View File

@@ -0,0 +1,24 @@
package net.gepafin.tendermanagement.enums;
import com.fasterxml.jackson.annotation.JsonValue;
public enum EmailScenarioTypeEnum {
APPLICATION_SUBMITTED("APPLICATION_SUBMITTED"),
APPLICATION_AMENDMENT_REQUESTED("APPLICATION_AMENDMENT_REQUESTED"),
APPLICATION_AMENDMENT_EXPIRED("APPLICATION_AMENDMENT_EXPIRED"),
APPLICATION_AMENDMENT_REMINDER("APPLICATION_AMENDMENT_REMINDER"),
APPLICATION_APPROVED("APPLICATION_APPROVED"),
APPLICATION_REJECTED("APPLICATION_REJECTED");
private final String value;
EmailScenarioTypeEnum(String value) {
this.value = value;
}
@JsonValue
public String getValue() {
return value;
}
}

View File

@@ -0,0 +1,20 @@
package net.gepafin.tendermanagement.enums;
import com.fasterxml.jackson.annotation.JsonValue;
public enum EmailServiceTypeEnum {
MAILGUN_SERVICE("MAILGUN_SERVICE"),
PEC_SERVICE("PEC_SERVICE");
private String value;
EmailServiceTypeEnum(String value) {
this.value = value;
}
@JsonValue
public String getValue() {
return value;
}
}

View File

@@ -0,0 +1,22 @@
package net.gepafin.tendermanagement.enums;
import com.fasterxml.jackson.annotation.JsonValue;
public enum RecipientTypeEnum {
BENEFICIARY ("BENEFICIARY"),
USER("USER"),
COMPANY("COMPANY"),
PROPERTIES("PROPERTIES");
private String value;
RecipientTypeEnum(String value) {
this.value = value;
}
@JsonValue
public String getValue() {
return value;
}
}

View File

@@ -0,0 +1,20 @@
package net.gepafin.tendermanagement.enums;
import com.fasterxml.jackson.annotation.JsonValue;
public enum StatusTypeEnum {
SUCCESS ("SUCCESS"),
FAILED("FAILED");
private String value;
StatusTypeEnum(String value) {
this.value = value;
}
@JsonValue
public String getValue() {
return value;
}
}

View File

@@ -13,6 +13,7 @@ public class EmailConfig {
private String domain;
private String mailgunApiUrl;
private String pecApiUrl;
private String url;
}

View File

@@ -0,0 +1,40 @@
package net.gepafin.tendermanagement.model.request;
import lombok.Data;
import net.gepafin.tendermanagement.enums.EmailScenarioTypeEnum;
import net.gepafin.tendermanagement.enums.EmailEntityTypeEnum;
import net.gepafin.tendermanagement.enums.EmailServiceTypeEnum;
import net.gepafin.tendermanagement.enums.RecipientTypeEnum;
@Data
public class EmailLogRequest {
private EmailScenarioTypeEnum emailType;
private RecipientTypeEnum recipientType;
private Long recipientId;
private String emailSubject;
private String emailBody;
private String sendStatus;
private String errorMessage;
private Long userId;
private String emailServiceResponse;
private EmailServiceTypeEnum emailServiceType;
private String recipientEmails;
private Long applicatioId;
private Long amendmentId;
private Long callId;
}

View File

@@ -0,0 +1,16 @@
package net.gepafin.tendermanagement.model.request;
import lombok.Data;
import net.gepafin.tendermanagement.entities.EmailLogEntity;
@Data
public class EmailTrackingRequest {
private EmailLogEntity emailLogEntity;
private Long userId;
private Long entityId;
private String entityType;
}

View File

@@ -3,10 +3,13 @@ package net.gepafin.tendermanagement.model.response;
import java.util.Map;
import lombok.Data;
import net.gepafin.tendermanagement.enums.EmailScenarioTypeEnum;
@Data
public class SystemEmailTemplateResponse {
EmailScenarioTypeEnum emailScenario;
String htmlContent;
String subject;

View File

@@ -0,0 +1,11 @@
package net.gepafin.tendermanagement.repositories;
import net.gepafin.tendermanagement.entities.EmailLogEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
public interface EmailLogRepository extends JpaRepository<EmailLogEntity,Long> {
List<EmailLogEntity> findByUserIdAndAmendmentIdAndIsDeletedFalse(Long userId,Long amendmentId);
}

View File

@@ -4,6 +4,8 @@ import net.gepafin.tendermanagement.dao.EmailNotificationDao;
import net.gepafin.tendermanagement.entities.ApplicationAmendmentRequestEntity;
import net.gepafin.tendermanagement.entities.ApplicationEntity;
import net.gepafin.tendermanagement.entities.UserEntity;
import net.gepafin.tendermanagement.enums.ApplicationAmendmentRequestEnum;
import net.gepafin.tendermanagement.enums.ApplicationStatusTypeEnum;
import net.gepafin.tendermanagement.repositories.ApplicationAmendmentRequestRepository;
import net.gepafin.tendermanagement.repositories.ApplicationRepository;
import net.gepafin.tendermanagement.repositories.UserRepository;
@@ -41,12 +43,12 @@ public class NotificationScheduler {
ApplicationAmendmentRequestEntity amendmentRequest = getAmendmentRequestForApplication(application, amendmentRequestList);
if (amendmentRequest != null) {
LocalDateTime requestDate = amendmentRequest.getCreatedDate();
if (requestDate.plusDays(amendmentRequest.getResponseDays()).isAfter(today)) {
LocalDateTime requestDate = amendmentRequest.getStartDate();
if (requestDate.plusDays(amendmentRequest.getResponseDays()).isBefore(today)) {
// Update the application status to REJECTED
application.setStatus("REJECTED");
application.setStatus(ApplicationStatusTypeEnum.REJECTED.getValue());
applicationRepository.save(application);
amendmentRequest.setStatus("CLOSE");
amendmentRequest.setStatus(ApplicationAmendmentRequestEnum.CLOSE.getValue());
applicationAmendmentRepository.save(amendmentRequest);
emailNotificationDao.sendApplicationFailureNotificationEmail(amendmentRequest);
}
@@ -56,6 +58,6 @@ public class NotificationScheduler {
private ApplicationAmendmentRequestEntity getAmendmentRequestForApplication(ApplicationEntity application, List<ApplicationAmendmentRequestEntity> amendmentRequestList) {
return amendmentRequestList.stream().filter(request -> request.getId().equals(application.getId())).findFirst().orElse(null);
return amendmentRequestList.stream().filter(request -> request.getApplicationId().equals(application.getId())).findFirst().orElse(null);
}
}

View File

@@ -1,24 +0,0 @@
package net.gepafin.tendermanagement.service.feignClient;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.List;
@FeignClient(name = "mailgunClient", url = "${mailGun_base_url}")
public interface MailgunFeignClient {
@PostMapping("/v3/{domain}/messages")
ResponseEntity<Void> sendEmail(
@PathVariable("domain") String domain,
@RequestParam("from") String from,
@RequestParam("to") List<String> to,
@RequestParam("subject") String subject,
@RequestParam("html") String htmlBody,
@RequestHeader("Authorization") String authorizationHeader);
}

View File

@@ -1,17 +0,0 @@
package net.gepafin.tendermanagement.service.feignClient;
import feign.Headers;
import net.gepafin.tendermanagement.model.request.PecEmailRequest;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
@FeignClient(name = "pecClient", url = "${api.pecUrl}")
public interface PecFeignClient {
@PostMapping("/send")
ResponseEntity<Void> sendEmail(@RequestHeader("Authorization") String token,
@RequestBody PecEmailRequest emailRequest);
}

View File

@@ -1,11 +1,12 @@
package net.gepafin.tendermanagement.service.impl;
import net.gepafin.tendermanagement.model.request.EmailConfig;
import net.gepafin.tendermanagement.model.request.EmailLogRequest;
import java.util.List;
public interface EmailService {
void sendEmail(String subject, String body, List<String> recipientEmails, EmailConfig emailConfig);
void sendEmail(String subject, String body, List<String> recipientEmails, EmailConfig emailConfig, EmailLogRequest emailLogRequest);
}

View File

@@ -1,12 +1,18 @@
package net.gepafin.tendermanagement.service.impl;
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;
import net.gepafin.tendermanagement.dao.EmailLogDao;
import net.gepafin.tendermanagement.entities.EmailLogEntity;
import net.gepafin.tendermanagement.enums.EmailServiceTypeEnum;
import net.gepafin.tendermanagement.enums.StatusTypeEnum;
import net.gepafin.tendermanagement.model.request.EmailConfig;
import net.gepafin.tendermanagement.service.feignClient.MailgunFeignClient;
import net.gepafin.tendermanagement.model.request.EmailLogRequest;
import net.gepafin.tendermanagement.util.Utils;
import net.gepafin.tendermanagement.util.Validator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import java.util.Base64;
@@ -14,9 +20,6 @@ import java.util.List;
@Service
public class MailgunEmailService implements EmailService {
@Autowired
private MailgunFeignClient mailgunFeignClient;
@Value("${isMailSendingEnabled}")
private String isEmailSendingEnabled;
@@ -24,25 +27,50 @@ public class MailgunEmailService implements EmailService {
@Autowired
private Validator validator;
@Autowired
private EmailLogDao emailLogDao;
@Override
public void sendEmail(String subject, String body, List<String> recipientEmails, EmailConfig emailConfig) {
public void sendEmail(String subject, String body, List<String> recipientEmails, EmailConfig emailConfig, EmailLogRequest emailLogRequest) {
if (Boolean.FALSE.equals(Boolean.parseBoolean(isEmailSendingEnabled))) {
return;
}
String domain = emailConfig.getDomain();
String url = emailConfig.getUrl();
String from = emailConfig.getSender();
String apiKey = emailConfig.getApiKey();
String authHeader = "Basic " + Base64.getEncoder().encodeToString(("api:" + apiKey).getBytes());
// Send email via Mailgun API
HttpResponse<String> response2=null;
if (Boolean.FALSE.equals(validator.isTestProfileActivated())) {
ResponseEntity<Void> response = mailgunFeignClient.sendEmail(domain, from, recipientEmails, subject, body, authHeader);
if (!response.getStatusCode().is2xxSuccessful()) {
throw new RuntimeException("Failed to send email via Mailgun: " + response.getStatusCode());
emailLogRequest.setEmailSubject(subject);
emailLogRequest.setEmailBody(body);
emailLogRequest.setSendStatus(StatusTypeEnum.SUCCESS.getValue());
emailLogRequest.setRecipientEmails(Utils.listToCommaSeparatedString(recipientEmails));
try {
Unirest.setTimeouts(0, 0);
response2 = Unirest.post(url)
.header("Authorization", authHeader)
// .header("content-type", "multipart/form-data")
.field("from", from)
.field("to", recipientEmails)
.field("subject", subject)
.field("html", body)
.asString();
}catch(Exception e) {
emailLogRequest.setSendStatus(StatusTypeEnum.FAILED.getValue());
emailLogRequest.setEmailServiceType(EmailServiceTypeEnum.MAILGUN_SERVICE);
emailLogRequest.setErrorMessage(e.getMessage());
EmailLogEntity emailLogEntity= emailLogDao.createEmailLog(emailLogRequest);
throw new RuntimeException("Failed to send email via Mailgun: " + response2.getStatus());
}
emailLogRequest.setEmailServiceResponse(response2.getBody());
}
emailLogRequest.setEmailServiceType(EmailServiceTypeEnum.MAILGUN_SERVICE);
EmailLogEntity emailLogEntity= emailLogDao.createEmailLog(emailLogRequest);
}
}

View File

@@ -1,14 +1,20 @@
package net.gepafin.tendermanagement.service.impl;
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;
import lombok.extern.slf4j.Slf4j;
import net.gepafin.tendermanagement.dao.EmailLogDao;
import net.gepafin.tendermanagement.entities.EmailLogEntity;
import net.gepafin.tendermanagement.enums.EmailServiceTypeEnum;
import net.gepafin.tendermanagement.enums.StatusTypeEnum;
import net.gepafin.tendermanagement.model.request.EmailConfig;
import net.gepafin.tendermanagement.model.request.EmailLogRequest;
import net.gepafin.tendermanagement.model.request.PecEmailRequest;
import net.gepafin.tendermanagement.service.feignClient.PecFeignClient;
import net.gepafin.tendermanagement.util.Utils;
import net.gepafin.tendermanagement.util.Validator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import java.util.List;
@@ -16,12 +22,6 @@ import java.util.List;
@Slf4j
@Service
public class PecEmailService implements EmailService {
private final PecFeignClient pecFeignClient;
public PecEmailService(PecFeignClient pecFeignClient) {
this.pecFeignClient = pecFeignClient;
}
@Value("${isMailSendingEnabled}")
private String isEmailSendingEnabled;
@@ -29,8 +29,11 @@ public class PecEmailService implements EmailService {
@Autowired
private Validator validator;
@Autowired
private EmailLogDao emailLogDao;
@Override
public void sendEmail(String subject, String body, List<String> recipientEmails, EmailConfig emailConfig) {
public void sendEmail(String subject, String body, List<String> recipientEmails, EmailConfig emailConfig, EmailLogRequest emailLogRequest) {
if (Boolean.FALSE.equals(Boolean.parseBoolean(isEmailSendingEnabled))) {
return;
@@ -38,20 +41,37 @@ public class PecEmailService implements EmailService {
PecEmailRequest emailRequest = new PecEmailRequest();
emailRequest.setSender(emailConfig.getSender());
emailRequest.setRecipient(recipientEmails);
emailRequest.setSubject(subject);
emailRequest.setBody(body);
emailRequest.setUsername(emailConfig.getUsername());
emailRequest.setPassword(emailConfig.getPassword());
emailRequest.setRecipient(recipientEmails);
String url=emailConfig.getUrl();
String authToken = emailConfig.getAuthToken();
HttpResponse<String> response2=null;
if (Boolean.FALSE.equals(validator.isTestProfileActivated())) {
ResponseEntity<Void> response = pecFeignClient.sendEmail("Bearer " + authToken, emailRequest);
log.info("Mail response status: {}, headers: {}, body: {}", response.getStatusCode(), response.getHeaders(), response.getBody());
if (!response.getStatusCode().is2xxSuccessful()) {
throw new RuntimeException("Failed to send email via PEC: " + response.getStatusCode());
}
emailLogRequest.setEmailSubject(emailRequest.getSubject());
emailLogRequest.setEmailBody(emailRequest.getBody());
emailLogRequest.setSendStatus(StatusTypeEnum.SUCCESS.getValue());
emailLogRequest.setRecipientEmails(Utils.listToCommaSeparatedString(emailRequest.getRecipient()));
try {
Unirest.setTimeouts(0, 0);
response2 = Unirest.post(url)
.header("Authorization", "Bearer " + authToken)
.header("Content-Type", "application/json")
.body(Utils.convertObjectToJson(emailRequest)) // Serialize the emailRequest object to JSON
.asString();
}catch(Exception e) {
emailLogRequest.setSendStatus(StatusTypeEnum.FAILED.getValue());
emailLogRequest.setEmailServiceType(EmailServiceTypeEnum.PEC_SERVICE);
emailLogRequest.setErrorMessage(e.getMessage());
EmailLogEntity emailLogEntity= emailLogDao.createEmailLog(emailLogRequest);
throw new RuntimeException("Failed to send email via PEC: " + response2.getStatus());
}
emailLogRequest.setEmailServiceResponse(response2.getBody());
}
emailLogRequest.setEmailServiceType(EmailServiceTypeEnum.PEC_SERVICE);
EmailLogEntity emailLogEntity= emailLogDao.createEmailLog(emailLogRequest);
}
}

View File

@@ -24,6 +24,7 @@ import net.gepafin.tendermanagement.constants.GepafinConstant;
import org.apache.commons.collections4.MapUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import com.fasterxml.jackson.core.JsonProcessingException;
@@ -40,6 +41,7 @@ import net.gepafin.tendermanagement.web.rest.api.errors.FeignClientForbiddenExce
import net.gepafin.tendermanagement.web.rest.api.errors.FeignClientNotFoundException;
import net.gepafin.tendermanagement.web.rest.api.errors.FeignClientUnauthorizedException;
import net.gepafin.tendermanagement.web.rest.api.errors.FeignClientValidationException;
import org.springframework.http.MediaType;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
@@ -515,4 +517,7 @@ public class Utils {
}
return null;
}
public static <T> String listToCommaSeparatedString(List<T> list) {
return String.join(", ", list.stream().map(String::valueOf).toList());
}
}

View File

@@ -1720,11 +1720,50 @@
<sqlFile dbms="postgresql"
path="db/dump/update_system_email_template_for_notification_mail_05_11_2024_4.sql"/>
</changeSet>
<changeSet id="15-11-2024_1" author="Nisha Kashyap">
<createTable tableName="email_log">
<column autoIncrement="true" name="id" type="INTEGER">
<constraints nullable="false" primaryKey="true"
primaryKeyName="pk_email_logs"/>
</column>
<column name="email_type" type="VARCHAR(255)">
<constraints nullable="false"/>
</column>
<column name="recipient_type" type="VARCHAR(255)">
<constraints nullable="false"/>
</column>
<column name="recipient_id" type="INTEGER">
</column>
<column name="email_subject" type="TEXT"/>
<column name="email_body" type="TEXT"/>
<column name="send_status" type="VARCHAR(255)"/>
<column name="send_date_time" type="TIMESTAMP WITHOUT TIME ZONE"/>
<column name="created_date" type="TIMESTAMP WITHOUT TIME ZONE" defaultValueComputed="CURRENT_TIMESTAMP"/>
<column name="updated_date" type="TIMESTAMP WITHOUT TIME ZONE"/>
<column name="email_service_response" type="TEXT"></column>
<column name="email_service_type" type="VARCHAR(255)"></column>
<column name="recipient_emails" type="TEXT"></column>
<column name="user_id" type="INTEGER"></column>
<column name="error_message" type="TEXT"/>
<column name="entity_id" type="INTEGER"></column>
<column name="entity_type" type="VARCHAR(255)"></column>
</createTable>
</changeSet>
<changeSet id="15-11-2024_2" author="Nisha kashyap">
<addColumn tableName="system_email_template">
<column name="email_scenario" type="VARCHAR(255)"></column>
</addColumn>
<sqlFile dbms="postgresql"
path="db/dump/updated_system_email_template_for_email_scenario_15-11-2024.sql"/>
<sqlFile dbms="postgresql"
path="db/dump/updated_hub_data_for_email_service_config_15-11-2024.sql"/>
</changeSet>
<changeSet id="13-11-2024_1" author="Rajesh Khore">
<dropNotNullConstraint tableName="application_amendment_request" columnName="is_email"/>
<dropNotNullConstraint tableName="application_amendment_request" columnName="is_notification"/>
</changeSet>
<changeSet id="13-11-2024_2" author="Harish Bagora">
<addColumn tableName="beneficiary_preferred_call">
<column name="is_deleted" type="BOOLEAN" defaultValueBoolean="false">
@@ -1732,4 +1771,18 @@
</column>
</addColumn>
</changeSet>
<changeSet id="18-11-2024_1" author="Nisha Kashyap">
<addColumn tableName="email_log">
<column name="is_deleted" type="BOOLEAN" defaultValueBoolean="false"></column>
<column name="application_id" type="INTEGER" ></column>
<column name="amendment_id" type="INTEGER"></column>
<column name="call_id" type="INTEGER"></column>
</addColumn>
<dropColumn tableName="email_log">
<column name="entity_id"></column>
<column name="entity_type"></column>
</dropColumn>
</changeSet>
</databaseChangeLog>

View File

@@ -0,0 +1,9 @@
UPDATE hub
SET email_service_type = 'PEC_SERVICE',
email_service_config = 'JkFbBfuVvq7VWwp5LcWIi+hAa1RJ1ekI0jq3w7gLTXETZiTaN8zC4OBWD53x8FtbfFTh3L/5805CIYTH1BQGa3X9q16q9SDzMy7DKHdmJzOnLKhn74C5akoXKaeXUCGnzp0cSk2c01FV6lwefC29IshijFSumCHtVlgWNeZigBzmWK+M7NS+EXf4goIMzguL5bHpYXfoQunQozeY1SpOo+28gDDpzZRMXdtcwKkTgESFGwsy6S1m1TBxJwZC7p8W'
WHERE UNIQUE_UUID = 'p4lk3bcx1RStqTaIVVbXs';
UPDATE hub
SET email_service_type = 'MAILGUN_SERVICE',
email_service_config = 'QlICHJMvBHd09ci/B2+EDR0q6kFsEdu5gOSI1hgG/7SAm2wXQZagDsAbkBrA6JPHXUS3Bkw6UD9x5boYYxBi3tnpu16i0NgdZqcc2BBhMF1VgRlJMgX+KgsOJsnQbHAJ/9YZaeIVrJpxceHFx93NTbfjT3TzzaZ9cW/64wbeZFspEp6WwgKgV1/3+j297Q1QtKIiWKanolYaU9myx9KwPJZc8AmPe0PR2ViyA7VyGn6iQSrX2pr15tBw3xVIm0tfHh6pktHro4gRYs5CEypQ2cSbP5wv4Z6pDa//FHXzYpRvnb1AUh0thGOix5FZl9Kn'
WHERE UNIQUE_UUID = 't7jh5wfg9QXylNaTZkPoE';

View File

@@ -0,0 +1,17 @@
UPDATE gepafin_schema.system_email_template SET email_scenario='APPLICATION_SUBMITTED' WHERE "type"='APPLICATION_SUBMISSION_TO_USER_AND_COMPANY' AND "system"=true ;
UPDATE gepafin_schema.system_email_template SET email_scenario='APPLICATION_SUBMITTED' WHERE "type"='APPLICATION_SUBMISSION_TO_GEPAFIN' AND "system"=true ;
UPDATE gepafin_schema.system_email_template SET email_scenario='APPLICATION_AMENDMENT_REMINDER' WHERE "type"='AMENDMENT_REMINDER' AND "system"=true ;
UPDATE gepafin_schema.system_email_template SET email_scenario='APPLICATION_AMENDMENT_EXPIRED' WHERE "type"='INADMISSIBILITY_NOTIFICATION_DUE_TO_FAILURE' AND "system"=true ;
UPDATE gepafin_schema.system_email_template SET email_scenario='APPLICATION_APPROVED' WHERE "type"='ADMISSIBILITY_NOTIFICATION' AND "system"=true ;
UPDATE gepafin_schema.system_email_template SET email_scenario='APPLICATION_REJECTED' WHERE "type"='INADMISSIBILITY_NOTIFICATION' AND "system"=true ;
UPDATE gepafin_schema.system_email_template SET email_scenario='APPLICATION_AMENDMENT_REQUESTED' WHERE "type"='DOCUMENTATION_INTEGRATION_REQUEST' AND "system"=true ;