diff --git a/pom.xml b/pom.xml index 9a6ef12d..1e6d394a 100644 --- a/pom.xml +++ b/pom.xml @@ -179,6 +179,12 @@ 5.3.0 + + com.mailgun + mailgun-java + 1.0.2 + + org.apache.santuario xmlsec diff --git a/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java b/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java index 13ca091b..b1b05dc4 100644 --- a/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java +++ b/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java @@ -199,6 +199,8 @@ public class GepafinConstant { public static final String DELEGATION_NOT_FOUND = "delegation.not.found"; public static final String USER_COMPANY_RELATION_NOT_FOUND = "user.company.relation.not.found"; public static final String DELEGATION_DELETE_SUCCESS = "delegation.delete.success"; + public static final String HH_MM_SS = "HH:mm:ss"; + public static final String USER_NOT_AUTHORIZED_TO_CREATE_APPLICATION = "user.not.authorized.create.application"; public static final String APPLICATION_SUBMITTED_CANNOT_CHANGE = "application.submitted.cannot.change"; public static final String CALL_DOCUMENTS_FETCH_SUCCESS_MSG = "call.documents.fetch.success"; diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java index c79f7f99..6d7619d6 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java @@ -3,6 +3,7 @@ package net.gepafin.tendermanagement.dao; import net.gepafin.tendermanagement.config.Translator; import net.gepafin.tendermanagement.constants.GepafinConstant; import net.gepafin.tendermanagement.entities.*; +import net.gepafin.tendermanagement.entities.SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum; import net.gepafin.tendermanagement.enums.ApplicationSignedDocumentStatusEnum; import net.gepafin.tendermanagement.enums.ApplicationStatusTypeEnum; import net.gepafin.tendermanagement.enums.DocumentSourceTypeEnum; @@ -18,13 +19,16 @@ import net.gepafin.tendermanagement.service.CallService; import net.gepafin.tendermanagement.service.CompanyService; import net.gepafin.tendermanagement.service.DocumentService; import net.gepafin.tendermanagement.service.FormService; +import net.gepafin.tendermanagement.service.SystemEmailTemplatesService; import net.gepafin.tendermanagement.util.DateTimeUtil; import net.gepafin.tendermanagement.util.FieldValidator; +import net.gepafin.tendermanagement.util.MailUtil; import net.gepafin.tendermanagement.util.Utils; import net.gepafin.tendermanagement.util.Validator; import net.gepafin.tendermanagement.web.rest.api.errors.CustomValidationException; import net.gepafin.tendermanagement.web.rest.api.errors.ResourceNotFoundException; import net.gepafin.tendermanagement.web.rest.api.errors.Status; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -89,6 +93,24 @@ public class ApplicationDao { @Autowired private ProtocolRepository protocolRepository; + @Autowired + private SystemEmailTemplatesService systemEmailTemplatesService; + + @Autowired + private MailUtil mailUtil; + + @Value("${default_System_Receiver_Email}") + private String defaultSystemReceiverEmail; + + @Value("${gepafin_email}") + private String gepafinEmail; + + @Value("${rinaldo_email}") + private String rinaldoEmail; + + @Value("${carlo_email}") + private String carloEmail; + @Autowired private AmazonS3Service amazonS3Service; @@ -538,21 +560,21 @@ public class ApplicationDao { ApplicationRequest applicationRequest, Long callId, UserEntity userEntity) { CallEntity call = callService.validateCall(callId); // call = callService.validatePublishedCall(call.getId()); - checkIfApplicationExists(call, companyEntity); + checkIfApplicationExists(call, companyEntity, userEntity); ApplicationEntity applicationEntity = createApplicationEntity(userEntity, call, companyEntity); applicationEntity.setComments(applicationRequest.getComments()); applicationEntity = saveApplicationEntity(applicationEntity); ApplicationResponse applicationResponse = getApplicationResponse(applicationEntity); return applicationResponse; } - public void checkIfApplicationExists(CallEntity call, CompanyEntity companyEntity){ - Optional applicationEntity=applicationRepository.findByCompanyIdAndCallIdAndIsDeletedFalse(companyEntity.getId(),call.getId()); + public void checkIfApplicationExists(CallEntity call, CompanyEntity companyEntity, UserEntity userEntity){ + Optional applicationEntity=applicationRepository.findByUserIdAndCompanyIdAndCallIdAndIsDeletedFalse(userEntity.getId(), companyEntity.getId(),call.getId()); if(applicationEntity.isPresent()){ throw new CustomValidationException(Status.BAD_REQUEST,Translator.toLocale(GepafinConstant.APPLICATION_ALREADY_EXISTS)); } } - public ApplicationResponse updateApplicationStatus(Long applicationId, ApplicationStatusTypeEnum status) { + public ApplicationResponse updateApplicationStatus(UserEntity userEntity, Long applicationId, ApplicationStatusTypeEnum status) { ApplicationEntity applicationEntity = validateApplication(applicationId); if (ApplicationStatusTypeEnum.SUBMIT.getValue().equals(applicationEntity.getStatus())) { throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.APPLICATION_SUBMITTED_CANNOT_CHANGE)); @@ -586,6 +608,8 @@ public class ApplicationDao { applicationEntity.setProtocol(protocolEntity); applicationEntity.setStatus(ApplicationStatusTypeEnum.SUBMIT.getValue()); applicationEntity.setSubmissionDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); + sendMailToUserAndCompany(userEntity, applicationEntity); + sendMailTodefaultSystemAndGepafin(userEntity, applicationEntity); } else { applicationEntity.setStatus(status.getValue()); } @@ -594,7 +618,7 @@ public class ApplicationDao { return getApplicationResponse(applicationEntity); } - public Integer calculateProgress(Long totalSteps, Long completedSteps) { + 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)); } @@ -678,7 +702,70 @@ public class ApplicationDao { protocolRepository.save(protocolEntity); return protocolEntity; } + private void sendMailToUserAndCompany(UserEntity userEntity, ApplicationEntity applicationEntity) { + CallEntity call =applicationEntity.getCall(); + CompanyEntity company = applicationEntity.getCompany(); + ProtocolEntity protocol = applicationEntity.getProtocol(); + SystemEmailTemplateResponse systemEmailTemplateResponse = systemEmailTemplatesService + .retrieveTemplateByTypeAndCall(SystemEmailTemplatesEntityTypeEnum.APPLICATION_SUBMISSION_TO_USER_AND_COMPANY, + 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("{{date}}", DateTimeUtil.formatLocalDateTime(protocol.getCreatedDate(), GepafinConstant.YYYY_MM_DD_SLASH)); + bodyPlaceholders.put("{{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 sendMailTodefaultSystemAndGepafin(UserEntity userEntity, ApplicationEntity applicationEntity) { + CallEntity call = applicationEntity.getCall(); + CompanyEntity company = applicationEntity.getCompany(); + ProtocolEntity protocol = applicationEntity.getProtocol(); + SystemEmailTemplateResponse systemEmailTemplateResponse = systemEmailTemplatesService + .retrieveTemplateByTypeAndCall(SystemEmailTemplatesEntityTypeEnum.APPLICATION_SUBMISSION_TO_GEPAFIN, + 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("{{date}}", DateTimeUtil.formatLocalDateTime(protocol.getCreatedDate(), GepafinConstant.YYYY_MM_DD_SLASH)); + bodyPlaceholders.put("{{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); + + + mailUtil.sendByMailGun(subject, body, List.of(defaultSystemReceiverEmail), null); + mailUtil.sendByMailGun(subject, body, List.of(gepafinEmail), null); + mailUtil.sendByMailGun(subject, body, List.of(rinaldoEmail), null); + mailUtil.sendByMailGun(subject, body, List.of(carloEmail), null); + + } public ApplicationSignedDocumentResponse uploadSignedDocument(HttpServletRequest request, Long applicationId, MultipartFile file) { ApplicationEntity applicationEntity = validateApplication(applicationId); diff --git a/src/main/java/net/gepafin/tendermanagement/dao/SystemEmailTemplatesDao.java b/src/main/java/net/gepafin/tendermanagement/dao/SystemEmailTemplatesDao.java new file mode 100644 index 00000000..9218a33d --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/dao/SystemEmailTemplatesDao.java @@ -0,0 +1,116 @@ +package net.gepafin.tendermanagement.dao; + +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import net.gepafin.tendermanagement.entities.CallEntity; +import net.gepafin.tendermanagement.entities.SystemEmailTemplatesEntity; +import net.gepafin.tendermanagement.entities.SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum; +import net.gepafin.tendermanagement.model.response.SystemEmailTemplateResponse; +import net.gepafin.tendermanagement.repositories.SystemEmailTemplatesRespository; +import net.gepafin.tendermanagement.util.Utils; + +@Component +public class SystemEmailTemplatesDao { + + @Autowired + private SystemEmailTemplatesRespository systemEmailTemplatesRespository; + + @Value("${fe.base.url}") + private String feBaseUrl; + + + public SystemEmailTemplateResponse retrieveTemplate(SystemEmailTemplatesEntityTypeEnum type, CallEntity call, Locale language) { + SystemEmailTemplatesEntity dbSystemEmailTemplatesEntity = null; + if(call != null){ +// dbSystemEmailTemplatesEntity = systemEmailTemplatesRespository +// .findByTypeAndCallId(type.getValue(), call.getId()); + } + if(dbSystemEmailTemplatesEntity == null){ + dbSystemEmailTemplatesEntity = systemEmailTemplatesRespository + .findByType(type.getValue()); + } + + SystemEmailTemplateResponse systemEmailTemplateResponse = replaceHtmlContant(dbSystemEmailTemplatesEntity, call, language, Boolean.TRUE); + return systemEmailTemplateResponse; + } + + private SystemEmailTemplateResponse replaceHtmlContant(SystemEmailTemplatesEntity dbSystemEmailTemplatesEntity, + CallEntity call, Locale language1, Boolean isDefaultReplace) { + String language = null; + String htmlContent = dbSystemEmailTemplatesEntity.getHtmlContent(); + String subject = dbSystemEmailTemplatesEntity.getSubject(); + + if (language1 == null) { +// language = getLanguage(LocaleContextHolder.getLocale()); + language="italian"; + }else{ + language="italian"; + } + Map languageMap = new HashMap<>(); + String jsonContent = dbSystemEmailTemplatesEntity.getJson(); + if (Boolean.FALSE.equals(StringUtils.isEmpty(jsonContent))) { + Map> jsonMap = Utils.parseJsonContent(jsonContent); + if (jsonMap != null && jsonMap.containsKey(language)) { + languageMap = jsonMap.get(language); + htmlContent = replacePlaceholders(htmlContent, languageMap); + subject = replaceSubjectPlaceholders(subject, languageMap); + + } + } + if(Boolean.TRUE.equals(StringUtils.isEmpty(subject))){ + subject = ""; + } + + + htmlContent = replacePlatformLinkPlaceholder(call, htmlContent, languageMap); + SystemEmailTemplateResponse systemEmailTemplateResponse = new SystemEmailTemplateResponse(); + systemEmailTemplateResponse.setHtmlContent(htmlContent); + systemEmailTemplateResponse.setSubject(subject); + systemEmailTemplateResponse.setJsonMap(languageMap); + return systemEmailTemplateResponse; + } + + + +// private String getLanguage(Locale locale) { +// return switch (locale.getLanguage()) { +// case "en" -> "english"; +// case "it" -> "italian"; +// default -> "italian"; +// }; +// } + + private String replacePlaceholders(String htmlContent, Map languageMap) { + for (Map.Entry entry : languageMap.entrySet()) { + htmlContent = htmlContent.replace("{{" + entry.getKey() + "}}", entry.getValue()); + } + return htmlContent; + } + + private String replaceSubjectPlaceholders(String subject, Map languageMap) { + if(languageMap.containsKey("subject") && subject != null){ + String value = languageMap.get("subject"); + subject = subject.replace("{{subject}}", value); + return subject; + } + return ""; + } + private String replacePlatformLinkPlaceholder(CallEntity call, String htmlContent, + Map languageMap) { + String platformLink = feBaseUrl; + +// if(hubEntity != null && Boolean.FALSE.equals(isEmpty(hubEntity.getDomainName()))){ +// platformLink = hubEntity.getDomainName(); +// } + htmlContent = htmlContent.replace("{{platform_link}}", platformLink); + return htmlContent; + } + +} diff --git a/src/main/java/net/gepafin/tendermanagement/entities/SystemEmailTemplatesEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/SystemEmailTemplatesEntity.java new file mode 100644 index 00000000..9ae12cbf --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/entities/SystemEmailTemplatesEntity.java @@ -0,0 +1,56 @@ +package net.gepafin.tendermanagement.entities; + +import com.fasterxml.jackson.annotation.JsonValue; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.Table; +import lombok.Data; + +@Entity +@Table(name = "system_email_template") +@Data +public class SystemEmailTemplatesEntity extends BaseEntity { + + + @Column(name = "TEMPLATE_NAME") + private String templateName; + + @Column(name = "TYPE") + private String type; + + @Column(name = "HTML_CONTENT", columnDefinition = "TEXT") + private String htmlContent; + + @Column(name = "SUBJECT") + private String subject; + + @Column(name = "JSON", columnDefinition = "TEXT") + private String json; + + @Column(name = "SYSTEM") + private Boolean system; + + @Column(name ="IS_DELETED", nullable = false) + private Boolean isDeleted = false; + + public enum SystemEmailTemplatesEntityTypeEnum { + + APPLICATION_SUBMISSION_TO_USER_AND_COMPANY("APPLICATION_SUBMISSION_TO_USER_AND_COMPANY"), + APPLICATION_SUBMISSION_TO_GEPAFIN("APPLICATION_SUBMISSION_TO_GEPAFIN"); + + private String value; + + SystemEmailTemplatesEntityTypeEnum(String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } + } + +} diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/SystemEmailTemplateResponse.java b/src/main/java/net/gepafin/tendermanagement/model/response/SystemEmailTemplateResponse.java new file mode 100644 index 00000000..cd65e6e4 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/model/response/SystemEmailTemplateResponse.java @@ -0,0 +1,16 @@ +package net.gepafin.tendermanagement.model.response; + +import java.util.Map; + +import lombok.Data; + +@Data +public class SystemEmailTemplateResponse { + + String htmlContent; + + String subject; + + Map jsonMap; + +} diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationRepository.java index 567c8198..a1c3a474 100644 --- a/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationRepository.java +++ b/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationRepository.java @@ -1,7 +1,6 @@ package net.gepafin.tendermanagement.repositories; import net.gepafin.tendermanagement.entities.ApplicationEntity; -import net.gepafin.tendermanagement.entities.FaqEntity; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.jpa.repository.Query; @@ -25,7 +24,7 @@ public interface ApplicationRepository extends JpaRepository findByIdAndUserIdAndIsDeletedFalse(Long id,Long userId); - Optional findByCompanyIdAndCallIdAndIsDeletedFalse(Long companyId, Long callId); + Optional findByUserIdAndCompanyIdAndCallIdAndIsDeletedFalse(Long userId, Long companyId, Long callId); public Optional findByIdAndUserIdAndCallIdAndIsDeletedFalse(Long applicationId, Long userId, Long callId); diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/SystemEmailTemplatesRespository.java b/src/main/java/net/gepafin/tendermanagement/repositories/SystemEmailTemplatesRespository.java new file mode 100644 index 00000000..9e3e9bb9 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/repositories/SystemEmailTemplatesRespository.java @@ -0,0 +1,17 @@ +package net.gepafin.tendermanagement.repositories; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +import net.gepafin.tendermanagement.entities.SystemEmailTemplatesEntity; + +public interface SystemEmailTemplatesRespository extends JpaRepository { + +// @Query("select s from SystemEmailTemplatesEntity s where s.type=:type and s.call.id=:callId and s.isDeleted =false and s.system = false") +// SystemEmailTemplatesEntity findByTypeAndCallId(@Param("type") String type, @Param("callId") Long callId); + + @Query("select s from SystemEmailTemplatesEntity s where s.type=:type and s.isDeleted =false and s.system = true") + SystemEmailTemplatesEntity findByType(@Param("type") String type); + +} diff --git a/src/main/java/net/gepafin/tendermanagement/service/SystemEmailTemplatesService.java b/src/main/java/net/gepafin/tendermanagement/service/SystemEmailTemplatesService.java new file mode 100644 index 00000000..b40dc80f --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/service/SystemEmailTemplatesService.java @@ -0,0 +1,13 @@ +package net.gepafin.tendermanagement.service; + +import java.util.Locale; + +import net.gepafin.tendermanagement.entities.CallEntity; +import net.gepafin.tendermanagement.entities.SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum; +import net.gepafin.tendermanagement.model.response.SystemEmailTemplateResponse; + +public interface SystemEmailTemplatesService { + + SystemEmailTemplateResponse retrieveTemplateByTypeAndCall(SystemEmailTemplatesEntityTypeEnum type, CallEntity call, Locale language); + +} 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 faa890d3..1ea6e7ea 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationServiceImpl.java @@ -80,7 +80,8 @@ public class ApplicationServiceImpl implements ApplicationService { @Override @Transactional(rollbackFor = Exception.class) public ApplicationResponse updateApplicationStatus(HttpServletRequest request, Long applicationId, ApplicationStatusTypeEnum status) { - return applicationDao.updateApplicationStatus(applicationId, status); + UserEntity userEntity = validator.validateUser(request); + return applicationDao.updateApplicationStatus(userEntity, applicationId, status); } diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/SystemEmailTemplatesServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/SystemEmailTemplatesServiceImpl.java new file mode 100644 index 00000000..802f2580 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/SystemEmailTemplatesServiceImpl.java @@ -0,0 +1,27 @@ +package net.gepafin.tendermanagement.service.impl; + +import java.util.Locale; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import net.gepafin.tendermanagement.dao.SystemEmailTemplatesDao; +import net.gepafin.tendermanagement.entities.CallEntity; +import net.gepafin.tendermanagement.entities.SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum; +import net.gepafin.tendermanagement.model.response.SystemEmailTemplateResponse; +import net.gepafin.tendermanagement.service.SystemEmailTemplatesService; + +@Service +public class SystemEmailTemplatesServiceImpl implements SystemEmailTemplatesService { + + @Autowired + private SystemEmailTemplatesDao systemEmailTemplatesDao; + + + @Override + public SystemEmailTemplateResponse retrieveTemplateByTypeAndCall(SystemEmailTemplatesEntityTypeEnum type, CallEntity call, Locale language) { + return systemEmailTemplatesDao.retrieveTemplate(type, call, language); + } + + +} diff --git a/src/main/java/net/gepafin/tendermanagement/util/DateTimeUtil.java b/src/main/java/net/gepafin/tendermanagement/util/DateTimeUtil.java index 342ca2b2..92da73eb 100644 --- a/src/main/java/net/gepafin/tendermanagement/util/DateTimeUtil.java +++ b/src/main/java/net/gepafin/tendermanagement/util/DateTimeUtil.java @@ -92,4 +92,20 @@ public class DateTimeUtil { DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern); return LocalDateTime.parse(dateTimeStr, formatter); } + + public static String parseLocalTimeToString(LocalTime time, String format) { + DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format); + return time.format(formatter); + } + + // Method 2: Convert String and format to LocalTime + public static LocalTime parseStringToLocalTime(String timeString, String format) { + try { + DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format); + return LocalTime.parse(timeString, formatter); + } catch (DateTimeParseException e) { + System.out.println("Invalid time format: " + e.getMessage()); + return null; + } + } } diff --git a/src/main/java/net/gepafin/tendermanagement/util/MailUtil.java b/src/main/java/net/gepafin/tendermanagement/util/MailUtil.java new file mode 100644 index 00000000..8b41ea3f --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/util/MailUtil.java @@ -0,0 +1,78 @@ +package net.gepafin.tendermanagement.util; + +import java.util.Arrays; +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.core.env.Environment; +import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; + +import com.mailgun.api.v3.MailgunMessagesApi; +import com.mailgun.client.MailgunClient; + +@Component +public class MailUtil { + + @Value("${apiKey}") + private String apiKeyValue; + + @Value("${mailGun_user}") + private String mailGunUser; + + @Value("${mailGun_apiKey}") + private String mailGunApiKey; + + @Value("${mailGun_domainName}") + private String mailGunDomainName; + + @Value("${mailGun_base_url}") + private String mailGunBaseUrl; + + @Value("${isMailSendingEnabled}") + private String isEmailSendingEnabled; + + @Autowired + private Environment environment; + + public Boolean isTestProfileActivated() { + String[] activeProfiles = environment.getActiveProfiles(); + return Arrays.stream(activeProfiles).anyMatch("test"::equals); + } + + public void sendMailByMailGunAPI(List recipents, List CC, List BCC, String subject, + String body, String replyTo) { + if (Boolean.FALSE.equals(Boolean.parseBoolean(isEmailSendingEnabled))) { + return; + } + + MailgunMessagesApi mailgunMessagesApi = MailgunClient.config(mailGunBaseUrl, mailGunApiKey) + .createApi(MailgunMessagesApi.class); + + String mailFrom = mailGunUser; + + com.mailgun.model.message.Message.MessageBuilder temp = com.mailgun.model.message.Message.builder() + .replyTo(replyTo).from(mailFrom).to(recipents).subject(subject).html(body); + + if (Boolean.FALSE.equals(CollectionUtils.isEmpty(CC))) { + temp.cc(CC); + } + + if (Boolean.FALSE.equals(CollectionUtils.isEmpty(BCC))) { + temp.bcc(BCC); + } + + if (Boolean.FALSE.equals(isTestProfileActivated())) { + com.mailgun.model.message.Message message = temp.build(); + mailgunMessagesApi.sendMessage(mailGunDomainName, message); + } + + } + + public void sendByMailGun(String subject, String body, List receiverEmails, String replyTo) { + sendMailByMailGunAPI(receiverEmails, null, null, subject, body, replyTo); + + } + +} diff --git a/src/main/java/net/gepafin/tendermanagement/util/Utils.java b/src/main/java/net/gepafin/tendermanagement/util/Utils.java index 746c8e8d..d7da174b 100644 --- a/src/main/java/net/gepafin/tendermanagement/util/Utils.java +++ b/src/main/java/net/gepafin/tendermanagement/util/Utils.java @@ -5,6 +5,7 @@ import java.lang.reflect.Type; import java.nio.charset.StandardCharsets; import java.security.SecureRandom; import java.util.Base64; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.function.Consumer; @@ -276,4 +277,30 @@ public class Utils { } } + public static Map> parseJsonContent(String jsonContent) { + ObjectMapper objectMapper = new ObjectMapper(); + try { + return mapper.readValue(jsonContent, HashMap.class); + } catch (Exception exception) { + log.error(exception.getMessage()); + } + return new HashMap<>(); + } + + // Utility method to replace placeholders with their values, handling nulls + public static String replacePlaceholders(String text, Map placeholders) { + if (text == null) { + return ""; + } + for (Map.Entry entry : placeholders.entrySet()) { + text = replaceNull(text, entry.getKey(), entry.getValue()); + } + return text; + } + + // Method to safely replace nulls with an empty string or a default value + private static String replaceNull(String text, String target, String replacement) { + return text.replace(target, replacement != null ? replacement : ""); + } + } diff --git a/src/main/resources/application-dev.properties b/src/main/resources/application-dev.properties index 19588213..5b6ca7a9 100644 --- a/src/main/resources/application-dev.properties +++ b/src/main/resources/application-dev.properties @@ -8,3 +8,4 @@ spring.datasource.driver-class-name=org.postgresql.Driver spring.h2.console.enabled=true isVatCheckGloballyDisabled = false +isMailSendingEnabled = true diff --git a/src/main/resources/application-production.properties b/src/main/resources/application-production.properties index 7aed447a..91fb1979 100644 --- a/src/main/resources/application-production.properties +++ b/src/main/resources/application-production.properties @@ -14,3 +14,4 @@ fe.base.url=https://bandi.gepafin.it #SPID configuration spid.ipd.base.url=https://login.regione.umbria.it active.profile.folder=production +isMailSendingEnabled = true diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 175c7e6c..11d23d5d 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -51,3 +51,17 @@ vatCheckNewToken: 66026bd891a51044e90e08c4 spid.ipd.base.url=https://federatest.umbriadigitale.it active.profile.folder=dev +# MailGun API Key +mailGun_apiKey= 398e3dea1911fe941af261906ec99362-07e2c238-8094421f +mailGun_user=comunicazione@paghiamoci.ai +mailGun_domainName=paghiamoci.ai +mailGun_base_url=https://api.eu.mailgun.net/ +# SendinBlue API key +apiKey=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 +#senderEmail=mailer@bflows.net +isMailSendingEnabled = false +default_System_Receiver_Email=attivazione@bflows.net +gepafin_email=bandi@pec.gepafin.it +rinaldo_email=rinaldo.bonazzo@bflows.net +carlo_email=carlo.mancosu@bflows.net + 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 a1369e93..0f6aeeb2 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 @@ -973,6 +973,30 @@ + + + + + + + + + + + + + + + + + + + + + + @@ -995,7 +1019,13 @@ referencedColumnNames="ID" constraintName="fk_application_signed_document_application"/> - + + + + + name='table' + + diff --git a/src/main/resources/db/dump/insert_system_email_template_for_application_submission.sql b/src/main/resources/db/dump/insert_system_email_template_for_application_submission.sql new file mode 100644 index 00000000..acd205bd --- /dev/null +++ b/src/main/resources/db/dump/insert_system_email_template_for_application_submission.sql @@ -0,0 +1,34 @@ +INSERT INTO gepafin_schema.system_email_template (id, template_name, "type", html_content, subject, "json", "system", is_deleted, created_date, updated_date) VALUES(1, 'Application submission template to beneficiary and company', 'APPLICATION_SUBMISSION_TO_USER_AND_COMPANY', ' + +
+

Buongiorno,

+

+ Si comunica che, in riferimento alla domanda di concessione di + Finanziamento agevolato a valere sul Fondo prestiti + {{call_name}} di cui all''oggetto, la stessa è stata + regolarmente acquisita ed è stata registrata con Protocollo n. + {{protocol_number}} del {{date}} alle + {{time}}. +

+

Distinti Saluti,

+

+ Gepafin S.p.a. +

+
+ +', 'BANDO {{call_name}} - Domanda di concessione di finanziamento agevolato {{company_name}}', NULL, true, false, '2024-10-10 16:10:31.035', '2024-10-11 10:09:23.037'); +INSERT INTO gepafin_schema.system_email_template (id, template_name, "type", html_content, subject, "json", "system", is_deleted, created_date, updated_date) VALUES(2, 'Application submission template to gepafin', 'APPLICATION_SUBMISSION_TO_GEPAFIN', ' + +
+

+ In riferimento alla domanda di concessione di Finanziamento agevolato a valere sul Fondo prestiti + {{call_name}} di cui all’oggetto, la stessa è stata regolarmente acquisita ed è stata + registrata con Protocollo n. {{protocol_number}} del {{date}} e {{time}}. +

+

Distinti Saluti,

+

+ Gepafin S.p.a. +

+
+ +', 'BANDO {{call_name}} - Domanda di concessione di finanziamento agevolato {{company_name}}', NULL, true, false, '2024-10-10 16:10:31.035', '2024-10-11 10:09:57.224'); \ No newline at end of file