FINERACT-1273: Triggered emails
Basically send an email when a client does an action: for now when a loan is approved, rejected and when a repayment is done. More triggers should be added in the future
This commit is contained in:
+6
-6
@@ -75,11 +75,11 @@ public class EmailCampaign extends AbstractPersistableCustom {
|
||||
@Column(name = "email_message", nullable = false)
|
||||
private String emailMessage;
|
||||
|
||||
@Column(name = "email_attachment_file_format", nullable = false)
|
||||
@Column(name = "email_attachment_file_format")
|
||||
private String emailAttachmentFileFormat;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "stretchy_report_id", nullable = false)
|
||||
@JoinColumn(name = "stretchy_report_id")
|
||||
private Report stretchyReport;
|
||||
|
||||
@Column(name = "stretchy_report_param_map", nullable = true)
|
||||
@@ -109,18 +109,18 @@ public class EmailCampaign extends AbstractPersistableCustom {
|
||||
@JoinColumn(name = "approvedon_userid", nullable = true)
|
||||
private AppUser approvedBy;
|
||||
|
||||
@Column(name = "recurrence", nullable = false)
|
||||
@Column(name = "recurrence")
|
||||
private String recurrence;
|
||||
|
||||
@Column(name = "next_trigger_date", nullable = false)
|
||||
@Column(name = "next_trigger_date")
|
||||
@Temporal(TemporalType.TIMESTAMP)
|
||||
private Date nextTriggerDate;
|
||||
|
||||
@Column(name = "last_trigger_date", nullable = false)
|
||||
@Column(name = "last_trigger_date")
|
||||
@Temporal(TemporalType.TIMESTAMP)
|
||||
private Date lastTriggerDate;
|
||||
|
||||
@Column(name = "recurrence_start_date", nullable = false)
|
||||
@Column(name = "recurrence_start_date")
|
||||
@Temporal(TemporalType.TIMESTAMP)
|
||||
private Date recurrenceStartDate;
|
||||
|
||||
|
||||
+8
-1
@@ -18,7 +18,14 @@
|
||||
*/
|
||||
package org.apache.fineract.infrastructure.campaigns.email.domain;
|
||||
|
||||
import java.util.List;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
|
||||
public interface EmailCampaignRepository extends JpaRepository<EmailCampaign, Long>, JpaSpecificationExecutor<EmailCampaign> {}
|
||||
public interface EmailCampaignRepository extends JpaRepository<EmailCampaign, Long>, JpaSpecificationExecutor<EmailCampaign> {
|
||||
|
||||
@Query("SELECT campaign FROM EmailCampaign campaign WHERE campaign.paramValue LIKE :reportPattern AND campaign.campaignType=:type AND campaign.status=300")
|
||||
List<EmailCampaign> findActiveEmailCampaigns(@Param("reportPattern") String reportPattern, @Param("type") Integer type);
|
||||
}
|
||||
|
||||
+9
-1
@@ -20,7 +20,8 @@ package org.apache.fineract.infrastructure.campaigns.email.domain;
|
||||
|
||||
public enum EmailCampaignType {
|
||||
|
||||
DIRECT(1, "emailCampaignStatusType.direct"), SCHEDULE(2, "emailCampaignStatusType.schedule");
|
||||
DIRECT(1, "emailCampaignStatusType.direct"), SCHEDULE(2, "emailCampaignStatusType.schedule"), TRIGGERED(3,
|
||||
"emailCampaignStatusType.triggered");
|
||||
|
||||
private final Integer value;
|
||||
private final String code;
|
||||
@@ -47,6 +48,9 @@ public enum EmailCampaignType {
|
||||
case 2:
|
||||
type = SCHEDULE;
|
||||
break;
|
||||
case 3:
|
||||
type = TRIGGERED;
|
||||
break;
|
||||
}
|
||||
return type;
|
||||
}
|
||||
@@ -58,4 +62,8 @@ public enum EmailCampaignType {
|
||||
public boolean isSchedule() {
|
||||
return this.value.equals(EmailCampaignType.SCHEDULE.getValue());
|
||||
}
|
||||
|
||||
public boolean isTriggered() {
|
||||
return this.value.equals(EmailCampaignType.TRIGGERED.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.infrastructure.campaigns.email.service;
|
||||
|
||||
public interface EmailCampaignDomainService {}
|
||||
+151
@@ -0,0 +1,151 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.infrastructure.campaigns.email.service;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.annotation.PostConstruct;
|
||||
import org.apache.fineract.infrastructure.campaigns.email.domain.EmailCampaign;
|
||||
import org.apache.fineract.infrastructure.campaigns.email.domain.EmailCampaignRepository;
|
||||
import org.apache.fineract.infrastructure.campaigns.sms.constants.SmsCampaignTriggerType;
|
||||
import org.apache.fineract.portfolio.common.BusinessEventNotificationConstants;
|
||||
import org.apache.fineract.portfolio.common.service.BusinessEventListener;
|
||||
import org.apache.fineract.portfolio.common.service.BusinessEventNotifierService;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.Loan;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanTransaction;
|
||||
import org.codehaus.jackson.map.ObjectMapper;
|
||||
import org.codehaus.jackson.type.TypeReference;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class EmailCampaignDomainServiceImpl implements EmailCampaignDomainService {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(EmailCampaignDomainServiceImpl.class);
|
||||
private final BusinessEventNotifierService businessEventNotifierService;
|
||||
private final EmailCampaignWritePlatformService emailCampaignWritePlatformService;
|
||||
private final EmailCampaignRepository emailCampaignRepository;
|
||||
|
||||
@Autowired
|
||||
public EmailCampaignDomainServiceImpl(BusinessEventNotifierService businessEventNotifierService,
|
||||
EmailCampaignWritePlatformService emailCampaignWritePlatformService, EmailCampaignRepository emailCampaignRepository) {
|
||||
this.businessEventNotifierService = businessEventNotifierService;
|
||||
this.emailCampaignWritePlatformService = emailCampaignWritePlatformService;
|
||||
this.emailCampaignRepository = emailCampaignRepository;
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void addListeners() {
|
||||
this.businessEventNotifierService.addBusinessEventPostListeners(BusinessEventNotificationConstants.BusinessEvents.LOAN_APPROVED,
|
||||
new EmailCampaignDomainServiceImpl.SendEmailOnLoanApproved());
|
||||
this.businessEventNotifierService.addBusinessEventPostListeners(BusinessEventNotificationConstants.BusinessEvents.LOAN_REJECTED,
|
||||
new EmailCampaignDomainServiceImpl.SendEmailOnLoanRejected());
|
||||
this.businessEventNotifierService.addBusinessEventPostListeners(
|
||||
BusinessEventNotificationConstants.BusinessEvents.LOAN_MAKE_REPAYMENT,
|
||||
new EmailCampaignDomainServiceImpl.SendEmailOnLoanRepayment());
|
||||
}
|
||||
|
||||
private class SendEmailOnLoanRepayment extends EmailBusinessEventAdapter {
|
||||
|
||||
@Override
|
||||
public void businessEventWasExecuted(Map<BusinessEventNotificationConstants.BusinessEntity, Object> businessEventEntity) {
|
||||
Object entity = businessEventEntity.get(BusinessEventNotificationConstants.BusinessEntity.LOAN_TRANSACTION);
|
||||
if (entity instanceof LoanTransaction) {
|
||||
LoanTransaction loanTransaction = (LoanTransaction) entity;
|
||||
try {
|
||||
notifyLoanOwner(loanTransaction, "Loan Repayment");
|
||||
} catch (IOException e) {
|
||||
LOG.error("Exception when trying to send triggered email: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class SendEmailOnLoanRejected extends EmailBusinessEventAdapter {
|
||||
|
||||
@Override
|
||||
public void businessEventWasExecuted(Map<BusinessEventNotificationConstants.BusinessEntity, Object> businessEventEntity) {
|
||||
Object entity = businessEventEntity.get(BusinessEventNotificationConstants.BusinessEntity.LOAN);
|
||||
if (entity instanceof Loan) {
|
||||
Loan loan = (Loan) entity;
|
||||
try {
|
||||
notifyLoanOwner(loan, "Loan Rejected");
|
||||
} catch (IOException e) {
|
||||
LOG.error("Exception when trying to send triggered email: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class SendEmailOnLoanApproved extends EmailBusinessEventAdapter {
|
||||
|
||||
@Override
|
||||
public void businessEventWasExecuted(Map<BusinessEventNotificationConstants.BusinessEntity, Object> businessEventEntity) {
|
||||
Object entity = businessEventEntity.get(BusinessEventNotificationConstants.BusinessEntity.LOAN);
|
||||
if (entity instanceof Loan) {
|
||||
Loan loan = (Loan) entity;
|
||||
try {
|
||||
notifyLoanOwner(loan, "Loan Approved");
|
||||
} catch (IOException e) {
|
||||
LOG.error("Exception when trying to send triggered email: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyLoanOwner(LoanTransaction loanTransaction, String paramValue) throws IOException {
|
||||
List<EmailCampaign> campaigns = this.retrieveEmailCampaigns(paramValue);
|
||||
for (EmailCampaign emailCampaign : campaigns) {
|
||||
HashMap<String, String> campaignParams = new ObjectMapper().readValue(emailCampaign.getParamValue(),
|
||||
new TypeReference<HashMap<String, String>>() {});
|
||||
campaignParams.put("loanId", loanTransaction.getLoan().getId().toString());
|
||||
campaignParams.put("loanTransactionId", loanTransaction.getId().toString());
|
||||
this.emailCampaignWritePlatformService.insertDirectCampaignIntoEmailOutboundTable(loanTransaction.getLoan(), emailCampaign,
|
||||
campaignParams);
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyLoanOwner(Loan loan, String paramValue) throws IOException {
|
||||
List<EmailCampaign> campaigns = this.retrieveEmailCampaigns(paramValue);
|
||||
for (EmailCampaign emailCampaign : campaigns) {
|
||||
HashMap<String, String> campaignParams = new ObjectMapper().readValue(emailCampaign.getParamValue(),
|
||||
new TypeReference<HashMap<String, String>>() {});
|
||||
campaignParams.put("loanId", loan.getId().toString());
|
||||
this.emailCampaignWritePlatformService.insertDirectCampaignIntoEmailOutboundTable(loan, emailCampaign, campaignParams);
|
||||
}
|
||||
}
|
||||
|
||||
private abstract static class EmailBusinessEventAdapter implements BusinessEventListener {
|
||||
|
||||
@Override
|
||||
public void businessEventToBeExecuted(Map<BusinessEventNotificationConstants.BusinessEntity, Object> businessEventEntity) {
|
||||
// Nothing to do
|
||||
}
|
||||
}
|
||||
|
||||
private List<EmailCampaign> retrieveEmailCampaigns(String paramValue) {
|
||||
List<EmailCampaign> emailCampaigns = emailCampaignRepository.findActiveEmailCampaigns("%" + paramValue + "%",
|
||||
SmsCampaignTriggerType.TRIGGERED.getValue());
|
||||
return emailCampaigns;
|
||||
}
|
||||
}
|
||||
+50
-28
@@ -158,20 +158,24 @@ public class EmailCampaignWritePlatformCommandHandlerImpl implements EmailCampai
|
||||
|
||||
final Long reportId = command.longValueOfParameterNamed(EmailCampaignValidator.stretchyReportId);
|
||||
|
||||
final Report report = this.reportRepository.findById(reportId).orElseThrow(() -> new ReportNotFoundException(reportId));
|
||||
Report report = null;
|
||||
Map<String, String> stretchyReportParams = null;
|
||||
if (reportId != null) {
|
||||
report = this.reportRepository.findById(reportId).orElseThrow(() -> new ReportNotFoundException(reportId));
|
||||
final Set<ReportParameterUsage> reportParameterUsages = report.getReportParameterUsages();
|
||||
stretchyReportParams = new HashMap<>();
|
||||
|
||||
// find all report parameters and store them as json string
|
||||
final Set<ReportParameterUsage> reportParameterUsages = report.getReportParameterUsages();
|
||||
final Map<String, String> stretchyReportParams = new HashMap<>();
|
||||
|
||||
if (reportParameterUsages != null && !reportParameterUsages.isEmpty()) {
|
||||
for (final ReportParameterUsage reportParameterUsage : reportParameterUsages) {
|
||||
stretchyReportParams.put(reportParameterUsage.getReportParameterName(), "");
|
||||
if (reportParameterUsages != null && !reportParameterUsages.isEmpty()) {
|
||||
for (final ReportParameterUsage reportParameterUsage : reportParameterUsages) {
|
||||
stretchyReportParams.put(reportParameterUsage.getReportParameterName(), "");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EmailCampaign emailCampaign = EmailCampaign.instance(currentUser, businessRule, report, command);
|
||||
emailCampaign.setStretchyReportParamMap(new Gson().toJson(stretchyReportParams));
|
||||
if (stretchyReportParams != null) {
|
||||
emailCampaign.setStretchyReportParamMap(new Gson().toJson(stretchyReportParams));
|
||||
}
|
||||
|
||||
this.emailCampaignRepository.save(emailCampaign);
|
||||
|
||||
@@ -241,6 +245,32 @@ public class EmailCampaignWritePlatformCommandHandlerImpl implements EmailCampai
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insertDirectCampaignIntoEmailOutboundTable(final Loan loan, final EmailCampaign emailCampaign,
|
||||
HashMap<String, String> campaignParams) {
|
||||
try {
|
||||
List<HashMap<String, Object>> runReportObject = this.getRunReportByServiceImpl(campaignParams.get("reportName"),
|
||||
campaignParams);
|
||||
|
||||
if (runReportObject != null) {
|
||||
for (HashMap<String, Object> entry : runReportObject) {
|
||||
String message = this.compileEmailTemplate(emailCampaign.getEmailMessage(), emailCampaign.getCampaignName(), entry);
|
||||
Client client = loan.getClient();
|
||||
String emailAddress = client.emailAddress();
|
||||
|
||||
if (emailAddress != null && isValidEmail(emailAddress)) {
|
||||
EmailMessage emailMessage = EmailMessage.pendingEmail(null, client, null, emailCampaign,
|
||||
emailCampaign.getEmailSubject(), message, emailAddress, emailCampaign.getCampaignName());
|
||||
this.emailMessageRepository.save(emailMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (final IOException e) {
|
||||
// TODO throw something here
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void insertDirectCampaignIntoEmailOutboundTable(final String emailParams, final String emailSubject,
|
||||
final String messageTemplate, final String campaignName, final Long campaignId) {
|
||||
try {
|
||||
@@ -589,8 +619,11 @@ public class EmailCampaignWritePlatformCommandHandlerImpl implements EmailCampai
|
||||
final EmailCampaign emailCampaign = this.emailCampaignRepository.findById(emailMessage.getEmailCampaign().getId())
|
||||
.orElse(null); //
|
||||
|
||||
final ScheduledEmailAttachmentFileFormat emailAttachmentFileFormat = ScheduledEmailAttachmentFileFormat
|
||||
.instance(emailCampaign.getEmailAttachmentFileFormat());
|
||||
ScheduledEmailAttachmentFileFormat emailAttachmentFileFormat = null;
|
||||
if (emailCampaign.getEmailAttachmentFileFormat() != null) {
|
||||
emailAttachmentFileFormat = ScheduledEmailAttachmentFileFormat
|
||||
.instance(emailCampaign.getEmailAttachmentFileFormat());
|
||||
}
|
||||
|
||||
final List<File> attachmentList = new ArrayList<>();
|
||||
|
||||
@@ -690,29 +723,16 @@ public class EmailCampaignWritePlatformCommandHandlerImpl implements EmailCampai
|
||||
|
||||
final EmailMessageWithAttachmentData emailMessageWithAttachmentData = EmailMessageWithAttachmentData.createNew(
|
||||
emailMessage.getEmailAddress(), emailMessage.getMessage(), emailMessage.getEmailSubject(), attachmentList);
|
||||
|
||||
if (!attachmentList.isEmpty() && attachmentList.size() > 0) { // only
|
||||
// send
|
||||
// email
|
||||
// message
|
||||
// if
|
||||
// there
|
||||
// is
|
||||
// an
|
||||
// attachment
|
||||
// to
|
||||
// it
|
||||
try {
|
||||
|
||||
this.emailMessageJobEmailService.sendEmailWithAttachment(emailMessageWithAttachmentData);
|
||||
|
||||
emailMessage.setStatusType(EmailMessageStatusType.SENT.getValue());
|
||||
|
||||
this.emailMessageRepository.save(emailMessage);
|
||||
} else {
|
||||
emailMessage.updateErrorMessage(errorLog.toString());
|
||||
|
||||
} catch (Exception e) {
|
||||
emailMessage.updateErrorMessage(e.getMessage());
|
||||
emailMessage.setStatusType(EmailMessageStatusType.FAILED.getValue());
|
||||
|
||||
this.emailMessageRepository.save(emailMessage);
|
||||
}
|
||||
}
|
||||
@@ -734,7 +754,9 @@ public class EmailCampaignWritePlatformCommandHandlerImpl implements EmailCampai
|
||||
*/
|
||||
private File generateAttachments(final EmailCampaign emailCampaign, final ScheduledEmailAttachmentFileFormat emailAttachmentFileFormat,
|
||||
final Map<String, String> reportParams, final String reportName, final StringBuilder errorLog) {
|
||||
|
||||
if (reportName == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
final ByteArrayOutputStream byteArrayOutputStream = this.readReportingService.generatePentahoReportAsOutputStream(reportName,
|
||||
emailAttachmentFileFormat.getValue(), reportParams, null, emailCampaign.getApprovedBy(), errorLog);
|
||||
|
||||
+5
@@ -18,11 +18,14 @@
|
||||
*/
|
||||
package org.apache.fineract.infrastructure.campaigns.email.service;
|
||||
|
||||
import java.util.HashMap;
|
||||
import org.apache.fineract.infrastructure.campaigns.email.data.PreviewCampaignMessage;
|
||||
import org.apache.fineract.infrastructure.campaigns.email.domain.EmailCampaign;
|
||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import org.apache.fineract.infrastructure.core.api.JsonQuery;
|
||||
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.apache.fineract.infrastructure.jobs.exception.JobExecutionException;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.Loan;
|
||||
|
||||
public interface EmailCampaignWritePlatformService {
|
||||
|
||||
@@ -44,4 +47,6 @@ public interface EmailCampaignWritePlatformService {
|
||||
|
||||
void sendEmailMessage() throws JobExecutionException;
|
||||
|
||||
void insertDirectCampaignIntoEmailOutboundTable(Loan loan, EmailCampaign emailCampaign, HashMap<String, String> campaignParams);
|
||||
|
||||
}
|
||||
|
||||
+26
-38
@@ -23,10 +23,9 @@ import java.util.List;
|
||||
import java.util.Properties;
|
||||
import javax.mail.MessagingException;
|
||||
import javax.mail.internet.MimeMessage;
|
||||
import org.apache.fineract.infrastructure.campaigns.email.EmailApiConstants;
|
||||
import org.apache.fineract.infrastructure.campaigns.email.data.EmailMessageWithAttachmentData;
|
||||
import org.apache.fineract.infrastructure.campaigns.email.domain.EmailConfiguration;
|
||||
import org.apache.fineract.infrastructure.campaigns.email.domain.EmailConfigurationRepository;
|
||||
import org.apache.fineract.infrastructure.configuration.data.SMTPCredentialsData;
|
||||
import org.apache.fineract.infrastructure.configuration.service.ExternalServicesPropertiesReadPlatformService;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -38,30 +37,33 @@ import org.springframework.stereotype.Service;
|
||||
public final class EmailMessageJobEmailServiceImpl implements EmailMessageJobEmailService {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(EmailMessageJobEmailServiceImpl.class);
|
||||
private EmailConfigurationRepository emailConfigurationRepository;
|
||||
private final ExternalServicesPropertiesReadPlatformService externalServicesReadPlatformService;
|
||||
|
||||
@Autowired
|
||||
private EmailMessageJobEmailServiceImpl(final EmailConfigurationRepository emailConfigurationRepository) {
|
||||
this.emailConfigurationRepository = emailConfigurationRepository;
|
||||
private EmailMessageJobEmailServiceImpl(ExternalServicesPropertiesReadPlatformService externalServicesReadPlatformService) {
|
||||
this.externalServicesReadPlatformService = externalServicesReadPlatformService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendEmailWithAttachment(EmailMessageWithAttachmentData emailMessageWithAttachmentData) {
|
||||
final SMTPCredentialsData smtpCredentialsData = this.externalServicesReadPlatformService.getSMTPCredentials();
|
||||
try {
|
||||
JavaMailSenderImpl javaMailSenderImpl = new JavaMailSenderImpl();
|
||||
javaMailSenderImpl.setHost(this.getGmailSmtpServer());
|
||||
javaMailSenderImpl.setPort(this.getGmailSmtpPort());
|
||||
javaMailSenderImpl.setUsername(this.getGmailSmtpUsername());
|
||||
javaMailSenderImpl.setPassword(this.getGmailSmtpPassword());
|
||||
javaMailSenderImpl.setJavaMailProperties(this.getJavaMailProperties());
|
||||
javaMailSenderImpl.setHost(smtpCredentialsData.getHost());
|
||||
javaMailSenderImpl.setPort(Integer.parseInt(smtpCredentialsData.getPort()));
|
||||
javaMailSenderImpl.setUsername(smtpCredentialsData.getUsername());
|
||||
javaMailSenderImpl.setPassword(smtpCredentialsData.getPassword());
|
||||
javaMailSenderImpl
|
||||
.setJavaMailProperties(this.getJavaMailProperties(smtpCredentialsData, javaMailSenderImpl.getJavaMailProperties()));
|
||||
|
||||
MimeMessage mimeMessage = javaMailSenderImpl.createMimeMessage();
|
||||
|
||||
// use the true flag to indicate you need a multipart message
|
||||
MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true);
|
||||
|
||||
mimeMessageHelper.setFrom(smtpCredentialsData.getFromEmail());
|
||||
mimeMessageHelper.setTo(emailMessageWithAttachmentData.getTo());
|
||||
mimeMessageHelper.setText(emailMessageWithAttachmentData.getText());
|
||||
mimeMessageHelper.setText(emailMessageWithAttachmentData.getText(), true);
|
||||
mimeMessageHelper.setSubject(emailMessageWithAttachmentData.getSubject());
|
||||
final List<File> attachments = emailMessageWithAttachmentData.getAttachments();
|
||||
if (attachments != null && attachments.size() > 0) {
|
||||
@@ -80,32 +82,18 @@ public final class EmailMessageJobEmailServiceImpl implements EmailMessageJobEma
|
||||
|
||||
}
|
||||
|
||||
private String getGmailSmtpServer() {
|
||||
final EmailConfiguration gmailSmtpServer = this.emailConfigurationRepository.findByName(EmailApiConstants.SMTP_SERVER);
|
||||
return (gmailSmtpServer != null) ? gmailSmtpServer.getValue() : null;
|
||||
}
|
||||
|
||||
private Integer getGmailSmtpPort() {
|
||||
final EmailConfiguration gmailSmtpPort = this.emailConfigurationRepository.findByName(EmailApiConstants.SMTP_PORT);
|
||||
return (gmailSmtpPort != null) ? Integer.parseInt(gmailSmtpPort.getValue()) : null;
|
||||
}
|
||||
|
||||
private String getGmailSmtpUsername() {
|
||||
final EmailConfiguration gmailSmtpUsername = this.emailConfigurationRepository.findByName(EmailApiConstants.SMTP_USERNAME);
|
||||
return (gmailSmtpUsername != null) ? gmailSmtpUsername.getValue() : null;
|
||||
}
|
||||
|
||||
private String getGmailSmtpPassword() {
|
||||
final EmailConfiguration gmailSmtpPassword = this.emailConfigurationRepository.findByName(EmailApiConstants.SMTP_PASSWORD);
|
||||
return (gmailSmtpPassword != null) ? gmailSmtpPassword.getValue() : null;
|
||||
}
|
||||
|
||||
private Properties getJavaMailProperties() {
|
||||
Properties properties = new Properties();
|
||||
properties.setProperty("mail.smtp.starttls.enable", "true");
|
||||
properties.setProperty("mail.smtp.auth", "true");
|
||||
properties.setProperty("mail.smtp.ssl.trust", this.getGmailSmtpServer());
|
||||
|
||||
private Properties getJavaMailProperties(SMTPCredentialsData smtpCredentialsData, Properties properties) {
|
||||
properties.put("mail.smtp.starttls.enable", "true");
|
||||
properties.put("mail.transport.protocol", "smtp");
|
||||
properties.put("mail.smtp.auth", "true");
|
||||
properties.put("mail.smtp.ssl.trust", smtpCredentialsData.getHost());
|
||||
if (smtpCredentialsData.isUseTLS()) {
|
||||
// Needs to disable startTLS if the port is 465 in order to send the email successfully when using the
|
||||
// smtp.gmail.com as the host
|
||||
if (smtpCredentialsData.getPort().equals("465")) {
|
||||
properties.put("mail.smtp.starttls.enable", "false");
|
||||
}
|
||||
}
|
||||
return properties;
|
||||
}
|
||||
}
|
||||
|
||||
+2
-5
@@ -74,9 +74,7 @@ public class AddressCommandFromApiJsonDeserializer {
|
||||
final List<FieldConfigurationData> configData = configurationData.stream().filter(FieldConfigurationData::isEnabled)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
final Set<String> supportedParameters = configData.stream()
|
||||
.map(FieldConfigurationData::getField)
|
||||
.collect(Collectors.toSet());
|
||||
final Set<String> supportedParameters = configData.stream().map(FieldConfigurationData::getField).collect(Collectors.toSet());
|
||||
|
||||
supportedParameters.add("locale");
|
||||
supportedParameters.add("dateFormat");
|
||||
@@ -85,8 +83,7 @@ public class AddressCommandFromApiJsonDeserializer {
|
||||
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParameters);
|
||||
|
||||
configData.forEach(fieldConfiguration -> {
|
||||
final String field =
|
||||
fieldConfiguration.getField().equals("addressType") ? "addressTypeId" : fieldConfiguration.getField();
|
||||
final String field = fieldConfiguration.getField().equals("addressType") ? "addressTypeId" : fieldConfiguration.getField();
|
||||
final String fieldValue = this.fromApiJsonHelper.extractStringNamed(field, element);
|
||||
|
||||
if (fieldConfiguration.getField().equals("addressType") && fromNewClient) {
|
||||
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
--
|
||||
-- Licensed to the Apache Software Foundation (ASF) under one
|
||||
-- or more contributor license agreements. See the NOTICE file
|
||||
-- distributed with this work for additional information
|
||||
-- regarding copyright ownership. The ASF licenses this file
|
||||
-- to you under the Apache License, Version 2.0 (the
|
||||
-- "License"); you may not use this file except in compliance
|
||||
-- with the License. You may obtain a copy of the License at
|
||||
--
|
||||
-- http://www.apache.org/licenses/LICENSE-2.0
|
||||
--
|
||||
-- Unless required by applicable law or agreed to in writing,
|
||||
-- software distributed under the License is distributed on an
|
||||
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
-- KIND, either express or implied. See the License for the
|
||||
-- specific language governing permissions and limitations
|
||||
-- under the License.
|
||||
--
|
||||
|
||||
INSERT INTO `stretchy_report` (`report_name`, `report_type`, `report_subtype`, `report_sql`, `description`, `core_report`, `use_report`, `self_service_user_report`) VALUES ('Loan Approved - Email', 'Email', 'Triggered', 'select ml.id as loanId, ifnull(mc.id,mc2.id) as id, ifnull(mc.firstname,mc2.firstname) as firstname, \nifnull(mc.middlename,ifnull(mc2.middlename,(\'\'))) as middlename, ifnull(mc.lastname,mc2.lastname) as lastname, \nifnull(mc.display_name,mc2.display_name) as display_name, ifnull(mc.status_enum,mc2.status_enum) as status_enum, \nifnull(mc.mobile_no,mc2.mobile_no) as mobile_no, ifnull(mg.office_id,mc2.office_id) as office_id, ifnull(mg.staff_id,mc2.staff_id) as staff_id, \nmg.id as group_id, mg.display_name as group_name, ifnull(mc.email_address,mc2.email_address) as emailAddress\nfrom m_loan ml left join m_group mg on mg.id = ml.group_id \nleft join m_group_client mgc on mgc.group_id = mg.id \nleft join m_client mc on mc.id = mgc.client_id \nleft join m_client mc2 on mc2.id = ml.client_id\nWHERE (mc.status_enum = 300 or mc2.status_enum = 300) and (mc.email_address is not null or mc2.email_address is not null) and ml.id = ${loanId}\n', 'Loan and client data of approved loan', '0', '1', '0');
|
||||
INSERT INTO `stretchy_report` (`report_name`, `report_type`, `report_subtype`, `report_sql`, `description`, `core_report`, `use_report`, `self_service_user_report`) VALUES ('Loan Rejected - Email', 'Email', 'Triggered', 'select ml.id as loanId, ifnull(mc.id,mc2.id) as id, ifnull(mc.firstname,mc2.firstname) as firstname, \nifnull(mc.middlename,ifnull(mc2.middlename,(\'\'))) as middlename, ifnull(mc.lastname,mc2.lastname) as lastname, \nifnull(mc.display_name,mc2.display_name) as display_name, ifnull(mc.status_enum,mc2.status_enum) as status_enum, \nifnull(mc.mobile_no,mc2.mobile_no) as mobile_no, ifnull(mg.office_id,mc2.office_id) as office_id, ifnull(mg.staff_id,mc2.staff_id) as staff_id, \nmg.id as group_id, mg.display_name as group_name, ifnull(mc.email_address,mc2.email_address) as emailAddress\nfrom m_loan ml left join m_group mg on mg.id = ml.group_id \nleft join m_group_client mgc on mgc.group_id = mg.id \nleft join m_client mc on mc.id = mgc.client_id \nleft join m_client mc2 on mc2.id = ml.client_id\nWHERE (mc.status_enum = 300 or mc2.status_enum = 300) and (mc.email_address is not null or mc2.email_address is not null) and ml.id = ${loanId}\n', 'Loan and client data of rejected loan', '0', '1', '0');
|
||||
INSERT INTO `stretchy_report` (`report_name`, `report_type`, `report_subtype`, `report_sql`, `description`, `core_report`, `use_report`, `self_service_user_report`) VALUES ('Loan Repayment - Email', 'Email', 'Triggered', 'select ml.id as loanId, ifnull(mc.id,mc2.id) as id, ifnull(mc.firstname,mc2.firstname) as firstname, \nifnull(mc.middlename,ifnull(mc2.middlename,(\'\'))) as middlename, ifnull(mc.lastname,mc2.lastname) as lastname, \nifnull(mc.display_name,mc2.display_name) as display_name, ifnull(mc.status_enum,mc2.status_enum) as status_enum, \nifnull(mc.mobile_no,mc2.mobile_no) as mobile_no, ifnull(mg.office_id,mc2.office_id) as office_id, ifnull(mg.staff_id,mc2.staff_id) as staff_id, \nmg.id as group_id, mg.display_name as group_name, ifnull(mc.email_address,mc2.email_address) as emailAddress, lt.amount as repaymentAmount \nfrom m_loan_transaction lt join m_loan ml on ml.id=lt.loan_id left join m_group mg on mg.id = ml.group_id \nleft join m_group_client mgc on mgc.group_id = mg.id \nleft join m_client mc on mc.id = mgc.client_id \nleft join m_client mc2 on mc2.id = ml.client_id\nWHERE (mc.status_enum = 300 or mc2.status_enum = 300) and (mc.email_address is not null or mc2.email_address is not null) and ml.id = ${loanId} and lt.id = ${loanTransactionId}\n', 'Loan and client data of rejected loan', '0', '1', '0');
|
||||
|
||||
ALTER TABLE `scheduled_email_campaign`
|
||||
CHANGE COLUMN `email_attachment_file_format` `email_attachment_file_format` VARCHAR(10) NULL ,
|
||||
CHANGE COLUMN `stretchy_report_id` `stretchy_report_id` INT(11) NULL ;
|
||||
+1
-1
@@ -35,7 +35,7 @@ public class ReportsTest extends IntegrationTest {
|
||||
|
||||
@Test
|
||||
void listReports() {
|
||||
assertThat(ok(fineract().reports.retrieveReportList())).hasSize(117);
|
||||
assertThat(ok(fineract().reports.retrieveReportList())).hasSize(120);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user