diff --git a/java/claim/pom.xml b/java/claim/pom.xml
index bb17d8bdc..8f153ffe0 100644
--- a/java/claim/pom.xml
+++ b/java/claim/pom.xml
@@ -52,6 +52,10 @@
org.springframework.boot
spring-boot-starter-data-jpa
+
+ org.springframework.boot
+ spring-boot-starter-data-jdbc
+
org.springframework.cloud
spring-cloud-gcp-starter-vision
@@ -154,6 +158,14 @@
json
20210307
+
+ org.freemarker
+ freemarker
+
+
+ org.springframework.boot
+ spring-boot-starter-quartz
+
diff --git a/java/claim/src/main/java/dev/sunbirdrc/claim/config/PropertyMapper.java b/java/claim/src/main/java/dev/sunbirdrc/claim/config/PropertyMapper.java
new file mode 100644
index 000000000..d56b98715
--- /dev/null
+++ b/java/claim/src/main/java/dev/sunbirdrc/claim/config/PropertyMapper.java
@@ -0,0 +1,21 @@
+package dev.sunbirdrc.claim.config;
+
+import lombok.Data;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+@Component
+@Data
+public class PropertyMapper {
+ @Value("${simple.mail.message.from}")
+ private String simpleMailMessageFrom;
+
+ @Value("${foreign.pending.item.subject}")
+ private String foreignPendingItemSubject;
+
+ @Value("${up.council.name}")
+ private String upCouncilName;
+
+ @Value("${regulator.table.name}")
+ private String regulatorTableName;
+}
diff --git a/java/claim/src/main/java/dev/sunbirdrc/claim/contants/AttributeNames.java b/java/claim/src/main/java/dev/sunbirdrc/claim/contants/AttributeNames.java
index d76ba5e3e..95442cce4 100644
--- a/java/claim/src/main/java/dev/sunbirdrc/claim/contants/AttributeNames.java
+++ b/java/claim/src/main/java/dev/sunbirdrc/claim/contants/AttributeNames.java
@@ -14,4 +14,10 @@ public class AttributeNames {
public static final String CONTENT = "content";
public static final String TOTAL_PAGES = "totalPages";
public static final String TOTAL_ELEMENTS = "totalElements";
+
+ public static final String JPG = "JPG";
+ public static final String JPEG = "JPEG";
+ public static final String PNG = "PNG";
+ public static final String GIF = "GIF";
+ public static final String PDF = "PDF";
}
diff --git a/java/claim/src/main/java/dev/sunbirdrc/claim/controller/EmailController.java b/java/claim/src/main/java/dev/sunbirdrc/claim/controller/EmailController.java
index 4016b1b7d..d41cf3e54 100644
--- a/java/claim/src/main/java/dev/sunbirdrc/claim/controller/EmailController.java
+++ b/java/claim/src/main/java/dev/sunbirdrc/claim/controller/EmailController.java
@@ -1,7 +1,9 @@
package dev.sunbirdrc.claim.controller;
import dev.sunbirdrc.claim.dto.BarCode;
+import dev.sunbirdrc.claim.dto.CertificateMailDto;
import dev.sunbirdrc.claim.dto.MailDto;
+import dev.sunbirdrc.claim.dto.PendingMailDTO;
import dev.sunbirdrc.claim.service.EmailService;
import net.sourceforge.barbecue.Barcode;
import net.sourceforge.barbecue.BarcodeFactory;
@@ -111,5 +113,16 @@ private String prepareBody(String idLink, String name, String credType) {
return body;
}
+ @RequestMapping(value = "/api/v1/sendCertificateMail", method = RequestMethod.POST)
+ public ResponseEntity sendCertificateMail(@RequestBody CertificateMailDto certificateMailDto) {
+ emailService.sendCertificateMail(certificateMailDto);
+ return new ResponseEntity<>("Mail is sending", HttpStatus.OK);
+ }
+ @RequestMapping(value = "/api/v1/sendPendingForeignItemMail", method = RequestMethod.POST)
+ public ResponseEntity sendPendingItemMail(@RequestHeader HttpHeaders headers,
+ @RequestBody PendingMailDTO pendingMailDTO) {
+ emailService.sendManualPendingMail(pendingMailDTO);
+ return new ResponseEntity<>("Mail is sending", HttpStatus.OK);
+ }
}
diff --git a/java/claim/src/main/java/dev/sunbirdrc/claim/controller/FileController.java b/java/claim/src/main/java/dev/sunbirdrc/claim/controller/FileController.java
index 267339141..d758e8982 100644
--- a/java/claim/src/main/java/dev/sunbirdrc/claim/controller/FileController.java
+++ b/java/claim/src/main/java/dev/sunbirdrc/claim/controller/FileController.java
@@ -45,9 +45,16 @@ public ResponseEntity downloadFile(
ByteArrayResource resource = fileService.downloadFile(fileName);
HttpHeaders headers = new HttpHeaders();
headers.add(HttpHeaders.CONTENT_DISPOSITION, "filename=\"" + fileName + "\"");
- return ResponseEntity.ok().
- contentType(MediaType.APPLICATION_PDF).
- headers(headers).body(resource);
+
+ try {
+ MediaType mediaType = fileService.getFileMediaType(fileName);
+
+ return ResponseEntity.ok()
+ .contentType(mediaType)
+ .headers(headers).body(resource);
+ } catch (Exception e) {
+ return new ResponseEntity<>(HttpStatus.EXPECTATION_FAILED);
+ }
}
/**
diff --git a/java/claim/src/main/java/dev/sunbirdrc/claim/dto/CertificateMailDto.java b/java/claim/src/main/java/dev/sunbirdrc/claim/dto/CertificateMailDto.java
new file mode 100644
index 000000000..da666cd9d
--- /dev/null
+++ b/java/claim/src/main/java/dev/sunbirdrc/claim/dto/CertificateMailDto.java
@@ -0,0 +1,21 @@
+package dev.sunbirdrc.claim.dto;
+
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@Builder
+public class CertificateMailDto {
+ private String name;
+ private String certificate;
+ private String emailAddress;
+
+ private String credentialsType;
+
+ private String certificateBase64;
+}
diff --git a/java/claim/src/main/java/dev/sunbirdrc/claim/dto/PendingMailDTO.java b/java/claim/src/main/java/dev/sunbirdrc/claim/dto/PendingMailDTO.java
new file mode 100644
index 000000000..b54401151
--- /dev/null
+++ b/java/claim/src/main/java/dev/sunbirdrc/claim/dto/PendingMailDTO.java
@@ -0,0 +1,22 @@
+package dev.sunbirdrc.claim.dto;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Builder
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class PendingMailDTO {
+ private String name;
+ private String emailAddress;
+ private String council;
+ private String itemName;
+ private String refNo;
+ private String regulatorName;
+ private String regulatorEmail;
+ private String credType;
+ private String registrationNumber;
+}
diff --git a/java/claim/src/main/java/dev/sunbirdrc/claim/entity/Regulator.java b/java/claim/src/main/java/dev/sunbirdrc/claim/entity/Regulator.java
new file mode 100644
index 000000000..37139c340
--- /dev/null
+++ b/java/claim/src/main/java/dev/sunbirdrc/claim/entity/Regulator.java
@@ -0,0 +1,32 @@
+package dev.sunbirdrc.claim.entity;
+
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.persistence.Column;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class Regulator {
+ @Id
+ @GeneratedValue(strategy = GenerationType.TABLE)
+ private String ID;
+ @Column
+ private String name;
+ @Column
+ private String phoneNumber;
+ @Column
+ private String council;
+ @Column
+ private String email;
+ @Column
+ private String osOwner;
+ @Column
+ private String osid;
+}
\ No newline at end of file
diff --git a/java/claim/src/main/java/dev/sunbirdrc/claim/exception/ClaimMailException.java b/java/claim/src/main/java/dev/sunbirdrc/claim/exception/ClaimMailException.java
new file mode 100644
index 000000000..2e3377d87
--- /dev/null
+++ b/java/claim/src/main/java/dev/sunbirdrc/claim/exception/ClaimMailException.java
@@ -0,0 +1,7 @@
+package dev.sunbirdrc.claim.exception;
+
+public class ClaimMailException extends RuntimeException {
+ public ClaimMailException(String message) {
+ super(message);
+ }
+}
diff --git a/java/claim/src/main/java/dev/sunbirdrc/claim/quartz/JobCreator.java b/java/claim/src/main/java/dev/sunbirdrc/claim/quartz/JobCreator.java
new file mode 100644
index 000000000..1d9804377
--- /dev/null
+++ b/java/claim/src/main/java/dev/sunbirdrc/claim/quartz/JobCreator.java
@@ -0,0 +1,93 @@
+package dev.sunbirdrc.claim.quartz;
+
+import lombok.extern.slf4j.Slf4j;
+import org.quartz.CronTrigger;
+import org.quartz.JobDataMap;
+import org.quartz.JobDetail;
+import org.quartz.SimpleTrigger;
+import org.springframework.context.ApplicationContext;
+import org.springframework.scheduling.quartz.CronTriggerFactoryBean;
+import org.springframework.scheduling.quartz.JobDetailFactoryBean;
+import org.springframework.scheduling.quartz.QuartzJobBean;
+import org.springframework.scheduling.quartz.SimpleTriggerFactoryBean;
+import org.springframework.stereotype.Component;
+
+import java.text.ParseException;
+import java.util.Date;
+
+@Slf4j
+@Component
+public class JobCreator {
+
+ /**
+ * Create Quartz Job.
+ *
+ * @param jobClass Class whose executeInternal() method needs to be called.
+ * @param isDurable Job needs to be persisted even after completion. if true, job will be persisted, not otherwise.
+ * @param context Spring application context.
+ * @param jobName Job name.
+ * @param jobGroup Job group.
+ * @return JobDetail object
+ */
+ public JobDetail createJob(Class extends QuartzJobBean> jobClass, boolean isDurable,
+ ApplicationContext context, String jobName, String jobGroup) {
+ JobDetailFactoryBean factoryBean = new JobDetailFactoryBean();
+ factoryBean.setJobClass(jobClass);
+ factoryBean.setDurability(isDurable);
+ factoryBean.setApplicationContext(context);
+ factoryBean.setName(jobName);
+ factoryBean.setGroup(jobGroup);
+
+ // set job data map
+ JobDataMap jobDataMap = new JobDataMap();
+ jobDataMap.put(jobName + jobGroup, jobClass.getName());
+ factoryBean.setJobDataMap(jobDataMap);
+
+ factoryBean.afterPropertiesSet();
+
+ return factoryBean.getObject();
+ }
+
+ /**
+ * Create cron trigger.
+ *
+ * @param triggerName Trigger name.
+ * @param startTime Trigger start time.
+ * @param cronExpression Cron expression.
+ * @param misFireInstruction Misfire instruction (what to do in case of misfire happens).
+ * @return {@link CronTrigger}
+ */
+ public CronTrigger createCronTrigger(String triggerName, Date startTime, String cronExpression, int misFireInstruction) {
+ CronTriggerFactoryBean factoryBean = new CronTriggerFactoryBean();
+ factoryBean.setName(triggerName);
+ factoryBean.setStartTime(startTime);
+ factoryBean.setCronExpression(cronExpression);
+ factoryBean.setMisfireInstruction(misFireInstruction);
+ try {
+ factoryBean.afterPropertiesSet();
+ } catch (ParseException e) {
+ log.error(e.getMessage(), e);
+ }
+ return factoryBean.getObject();
+ }
+
+ /**
+ * Create simple trigger.
+ *
+ * @param triggerName Trigger name.
+ * @param startTime Trigger start time.
+ * @param repeatTime Job repeat period mills
+ * @param misFireInstruction Misfire instruction (what to do in case of misfire happens).
+ * @return {@link SimpleTrigger}
+ */
+ public SimpleTrigger createSimpleTrigger(String triggerName, Date startTime, Long repeatTime, int misFireInstruction) {
+ SimpleTriggerFactoryBean factoryBean = new SimpleTriggerFactoryBean();
+ factoryBean.setName(triggerName);
+ factoryBean.setStartTime(startTime);
+ factoryBean.setRepeatInterval(repeatTime);
+ factoryBean.setRepeatCount(SimpleTrigger.REPEAT_INDEFINITELY);
+ factoryBean.setMisfireInstruction(misFireInstruction);
+ factoryBean.afterPropertiesSet();
+ return factoryBean.getObject();
+ }
+}
diff --git a/java/claim/src/main/java/dev/sunbirdrc/claim/quartz/MailingJobExecutor.java b/java/claim/src/main/java/dev/sunbirdrc/claim/quartz/MailingJobExecutor.java
new file mode 100644
index 000000000..6b4d092d3
--- /dev/null
+++ b/java/claim/src/main/java/dev/sunbirdrc/claim/quartz/MailingJobExecutor.java
@@ -0,0 +1,28 @@
+package dev.sunbirdrc.claim.quartz;
+
+import dev.sunbirdrc.claim.service.EmailService;
+import lombok.extern.slf4j.Slf4j;
+import org.quartz.JobExecutionContext;
+import org.quartz.JobExecutionException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.quartz.QuartzJobBean;
+import org.springframework.stereotype.Component;
+
+import java.util.Date;
+
+@Slf4j
+@Component
+public class MailingJobExecutor extends QuartzJobBean {
+
+ @Autowired
+ private EmailService emailService;
+
+ @Override
+ protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
+ log.info(">>>>>>>>>>>> Mail for foreign council job started :: " + new Date(System.currentTimeMillis()) + " <<<<<<<<<<<<<<<<");
+
+ emailService.sendForeignPendingItemMail();
+
+ log.info(">>>>>>>>>>>> Mail for foreign council has been completed :: " + new Date(System.currentTimeMillis()) + " <<<<<<<<<<<<<<<<");
+ }
+}
diff --git a/java/claim/src/main/java/dev/sunbirdrc/claim/quartz/SchedulerConfig.java b/java/claim/src/main/java/dev/sunbirdrc/claim/quartz/SchedulerConfig.java
new file mode 100644
index 000000000..6a2c87631
--- /dev/null
+++ b/java/claim/src/main/java/dev/sunbirdrc/claim/quartz/SchedulerConfig.java
@@ -0,0 +1,72 @@
+package dev.sunbirdrc.claim.quartz;
+
+import org.quartz.JobDetail;
+import org.quartz.SimpleTrigger;
+import org.quartz.Trigger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.autoconfigure.quartz.QuartzProperties;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.quartz.CronTriggerFactoryBean;
+import org.springframework.scheduling.quartz.SchedulerFactoryBean;
+
+import javax.sql.DataSource;
+import java.util.Properties;
+
+@Configuration
+public class SchedulerConfig {
+ @Autowired
+ private DataSource dataSource;
+
+ @Autowired
+ private ApplicationContext applicationContext;
+
+ @Autowired
+ private QuartzProperties quartzProperties;
+
+ @Autowired
+ private JobCreator jobCreator;
+
+ /**
+ * create scheduler factory
+ */
+ @Bean
+ public SchedulerFactoryBean schedulerFactoryBean(@Qualifier("searchJobTrigger") Trigger searchJobTrigger) {
+
+ SchedulerJobFactory jobFactory = new SchedulerJobFactory();
+ jobFactory.setApplicationContext(applicationContext);
+
+ Properties properties = new Properties();
+ properties.putAll(quartzProperties.getProperties());
+
+ SchedulerFactoryBean factory = new SchedulerFactoryBean();
+ factory.setOverwriteExistingJobs(true);
+ factory.setDataSource(dataSource);
+ factory.setQuartzProperties(properties);
+ factory.setJobFactory(jobFactory);
+ factory.setTriggers(searchJobTrigger);
+ return factory;
+ }
+
+ @Bean(name = "searchJobTrigger")
+ public CronTriggerFactoryBean sampleJobTrigger(@Qualifier("quartzJobDetail") JobDetail jobDetail,
+ @Value("${samplejob.frequency}") String frequency) {
+ return createCronTrigger(jobDetail, frequency);
+ }
+
+ private static CronTriggerFactoryBean createCronTrigger(JobDetail jobDetail, String cronExpression) {
+ CronTriggerFactoryBean factoryBean = new CronTriggerFactoryBean();
+ factoryBean.setJobDetail(jobDetail);
+ factoryBean.setCronExpression(cronExpression);
+ factoryBean.setMisfireInstruction(SimpleTrigger.MISFIRE_INSTRUCTION_FIRE_NOW);
+ return factoryBean;
+ }
+
+ @Bean
+ public JobDetail quartzJobDetail() {
+ return jobCreator.createJob(MailingJobExecutor.class, true, applicationContext, "Send mail", "Mail Event Group");
+ }
+}
diff --git a/java/claim/src/main/java/dev/sunbirdrc/claim/quartz/SchedulerJobFactory.java b/java/claim/src/main/java/dev/sunbirdrc/claim/quartz/SchedulerJobFactory.java
new file mode 100644
index 000000000..db35e10ab
--- /dev/null
+++ b/java/claim/src/main/java/dev/sunbirdrc/claim/quartz/SchedulerJobFactory.java
@@ -0,0 +1,24 @@
+package dev.sunbirdrc.claim.quartz;
+
+import org.quartz.spi.TriggerFiredBundle;
+import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.scheduling.quartz.SpringBeanJobFactory;
+
+public class SchedulerJobFactory extends SpringBeanJobFactory implements ApplicationContextAware {
+
+ private AutowireCapableBeanFactory beanFactory;
+
+ @Override
+ public void setApplicationContext(final ApplicationContext context) {
+ beanFactory = context.getAutowireCapableBeanFactory();
+ }
+
+ @Override
+ protected Object createJobInstance(final TriggerFiredBundle bundle) throws Exception {
+ final Object job = super.createJobInstance(bundle);
+ beanFactory.autowireBean(job);
+ return job;
+ }
+}
\ No newline at end of file
diff --git a/java/claim/src/main/java/dev/sunbirdrc/claim/repository/RegulatorRowMapper.java b/java/claim/src/main/java/dev/sunbirdrc/claim/repository/RegulatorRowMapper.java
new file mode 100644
index 000000000..25d684de6
--- /dev/null
+++ b/java/claim/src/main/java/dev/sunbirdrc/claim/repository/RegulatorRowMapper.java
@@ -0,0 +1,23 @@
+package dev.sunbirdrc.claim.repository;
+
+import dev.sunbirdrc.claim.entity.Regulator;
+import org.springframework.jdbc.core.RowMapper;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+public class RegulatorRowMapper implements RowMapper {
+ @Override
+ public Regulator mapRow(ResultSet rs, int rowNum) throws SQLException {
+ return new Regulator(
+ rs.getString("ID"),
+ rs.getString("name"),
+ rs.getString("phoneNumber"),
+ rs.getString("council"),
+ rs.getString("email"),
+ rs.getString("osOwner"),
+ rs.getString("osid")
+
+ );
+ }
+}
diff --git a/java/claim/src/main/java/dev/sunbirdrc/claim/service/EmailService.java b/java/claim/src/main/java/dev/sunbirdrc/claim/service/EmailService.java
index a40f8dcd3..6ded2a89c 100644
--- a/java/claim/src/main/java/dev/sunbirdrc/claim/service/EmailService.java
+++ b/java/claim/src/main/java/dev/sunbirdrc/claim/service/EmailService.java
@@ -1,27 +1,68 @@
package dev.sunbirdrc.claim.service;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import dev.sunbirdrc.claim.config.PropertyMapper;
+import dev.sunbirdrc.claim.controller.EmailController;
+import dev.sunbirdrc.claim.dto.CertificateMailDto;
+import dev.sunbirdrc.claim.dto.MailDto;
+import dev.sunbirdrc.claim.dto.PendingMailDTO;
+import dev.sunbirdrc.claim.entity.Claim;
+import dev.sunbirdrc.claim.entity.Regulator;
+import dev.sunbirdrc.claim.exception.ClaimMailException;
+import dev.sunbirdrc.claim.model.ClaimStatus;
+import freemarker.template.Configuration;
+import freemarker.template.Template;
+import freemarker.template.TemplateException;
+import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.FileSystemResource;
+import org.springframework.lang.NonNull;
import org.springframework.mail.MailException;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.mail.javamail.MimeMessagePreparator;
+import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
+import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;
import javax.mail.Message;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.io.File;
+import java.io.IOException;
+import java.util.*;
+import java.util.stream.Collectors;
@Service("emailService")
public class EmailService
{
+ private static final Logger logger = LoggerFactory.getLogger(EmailController.class);
@Autowired
private JavaMailSender mailSender;
@Autowired
private SimpleMailMessage preConfiguredMessage;
+
+ @Autowired
+ private Configuration freeMarkerConfiguration;
+
+ @Value("${simple.mail.message.from}")
+ private String simpleMailMessageFrom;
+
+ @Autowired
+ private PropertyMapper propertyMapper;
+
+ @Autowired
+ private ClaimService claimService;
+
+ @Autowired
+ private RegulatorService regulatorService;
/**
* This method will send compose and send the message
@@ -99,4 +140,245 @@ public void prepare(MimeMessage mimeMessage) throws Exception
System.err.println(ex.getMessage());
}
}
+
+ @Async
+ public void sendCertificateMail(CertificateMailDto certificateMailDto) {
+ String subject = certificateMailDto.getCredentialsType();
+
+ try {
+ MimeMessage mimeMessage = mailSender.createMimeMessage();
+
+ MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true);
+
+ mimeMessageHelper.setSubject(subject);
+ mimeMessageHelper.setFrom(new InternetAddress(propertyMapper.getSimpleMailMessageFrom(), certificateMailDto.getName()));
+ mimeMessageHelper.setTo(certificateMailDto.getEmailAddress());
+ mimeMessageHelper.setText(generateAttachedCertificateMailContent(certificateMailDto), true);
+
+
+ byte[] doc = Base64.getDecoder().decode(certificateMailDto.getCertificateBase64());
+ mimeMessageHelper.addAttachment("certificate.pdf", new ByteArrayResource(doc));
+
+ mailSender.send(mimeMessageHelper.getMimeMessage());
+ } catch (Exception e) {
+ logger.error("Exception while sending mail: ", e);
+ throw new ClaimMailException("Exception while composing and sending mail with OTP");
+ }
+ }
+
+ private String generateAttachedCertificateMailContent(CertificateMailDto certificateMailDto) {
+ String processedTemplateString = null;
+
+ Map mailMap = new HashMap<>();
+ mailMap.put("name", certificateMailDto.getName());
+ mailMap.put("credType", certificateMailDto.getCredentialsType());
+ mailMap.put("idLink", certificateMailDto.getCertificate());
+
+ try {
+ freeMarkerConfiguration.setClassForTemplateLoading(this.getClass(), "/templates/");
+ Template template = freeMarkerConfiguration.getTemplate("credentials-mail.ftl");
+ processedTemplateString = FreeMarkerTemplateUtils.processTemplateIntoString(template, mailMap);
+
+ } catch (TemplateException e) {
+ logger.error("TemplateException while creating mail template for certificate ", e);
+ throw new ClaimMailException("Error while creating mail template for certificate");
+ } catch (IOException e) {
+ logger.error("IOException while creating mail template for certificate ", e);
+ throw new ClaimMailException("Error while creating mail template for certificate");
+ }
+ return processedTemplateString;
+ }
+
+ @Async
+ public void sendPendingMail(@NonNull List pendingMailDTOList, @NonNull String regulatorName,
+ @NonNull String regulatorEmail) {
+
+ try {
+ MimeMessage mimeMessage = mailSender.createMimeMessage();
+
+ MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true);
+
+ mimeMessageHelper.setSubject(propertyMapper.getForeignPendingItemSubject());
+ mimeMessageHelper.setFrom(new InternetAddress(propertyMapper.getSimpleMailMessageFrom(),
+ "Pending Action Item"));
+ mimeMessageHelper.setTo(regulatorEmail);
+ mimeMessageHelper.setText(generatePendingMailContent(pendingMailDTOList, regulatorName), true);
+
+ mailSender.send(mimeMessageHelper.getMimeMessage());
+ } catch (Exception e) {
+ logger.error("Exception while sending mail: ", e);
+ throw new ClaimMailException("Exception while composing and sending mail with OTP");
+ }
+
+ }
+
+ /**
+ * @param mailDto
+ * @return
+ */
+ private String generatePendingMailContent(@NonNull List pendingMailDTOList,
+ @NonNull String regulatorName) {
+ String processedTemplateString = null;
+
+ Map mailMap = new HashMap<>();
+ mailMap.put("candidates", pendingMailDTOList);
+ mailMap.put("regulatorName", regulatorName);
+
+ try {
+ freeMarkerConfiguration.setClassForTemplateLoading(this.getClass(), "/templates/");
+ Template template = freeMarkerConfiguration.getTemplate("pending-item-mail.ftl");
+ processedTemplateString = FreeMarkerTemplateUtils.processTemplateIntoString(template, mailMap);
+
+ } catch (TemplateException e) {
+ logger.error("TemplateException while creating mail template for certificate ", e);
+ throw new ClaimMailException("Error while creating mail template for certificate");
+ } catch (IOException e) {
+ logger.error("IOException while creating mail template for certificate ", e);
+ throw new ClaimMailException("Error while creating mail template for certificate");
+ }
+ return processedTemplateString;
+ }
+
+ public void sendForeignPendingItemMail() {
+ if (!regulatorService.isRegulatorTableExist()) {
+ logger.error(">>>>>>>>>>> Unable to find regulator table in database: No further process will be occurred");
+ return;
+ }
+
+ List allClaimList = claimService.findAll();
+
+ if (allClaimList != null && !allClaimList.isEmpty()) {
+ List foreignCouncilNames = getPendingForeignCouncilList(allClaimList);
+
+ for (String foreignCouncilName : foreignCouncilNames) {
+
+ List foreignCouncilClaims = allClaimList.stream()
+ .filter(claim -> foreignCouncilName.equalsIgnoreCase(getCouncilName(claim.getPropertyData())))
+ .collect(Collectors.toList());
+
+ List pendingMailDTOList = collectEntityDetailsForMail(foreignCouncilClaims);
+
+ List regulatorList = regulatorService.findByCouncil(foreignCouncilName);
+
+ for (Regulator regulator : regulatorList) {
+ sendPendingMail(pendingMailDTOList, regulator.getName(), regulator.getEmail());
+ }
+ }
+ }
+ }
+
+ /**
+ * @param claimList
+ * @return
+ */
+ private @NonNull List getPendingForeignCouncilList(@NonNull List claimList) {
+ List councilList = claimList.stream()
+ .filter(claim -> !propertyMapper.getUpCouncilName()
+ .equalsIgnoreCase(getCouncilName(claim.getPropertyData()))
+ )
+ .filter(claim -> ClaimStatus.OPEN.name().equalsIgnoreCase(claim.getStatus()))
+ .map(claim -> getCouncilName(claim.getPropertyData()))
+ .distinct()
+ .collect(Collectors.toList());
+
+ if (councilList == null) {
+ logger.error(">>>>>>>> Unale to find any pending foreign council list");
+ return Collections.emptyList();
+ } else {
+ return councilList;
+ }
+ }
+
+ private @NonNull List collectEntityDetailsForMail(@NonNull List claimList) {
+ List pendingMailDTOList = new ArrayList<>();
+
+ try {
+ for (Claim claim : claimList) {
+ String propertyData = claim.getPropertyData();
+ ObjectMapper objectMapper = new ObjectMapper();
+ JsonNode jsonNode = objectMapper.readTree(propertyData);
+
+ PendingMailDTO pendingMailDTO = PendingMailDTO.builder()
+ .credType(jsonNode.get("credType") != null ? jsonNode.get("credType").asText() : "")
+ .emailAddress(jsonNode.get("email") != null ? jsonNode.get("email").asText() : "")
+ .refNo(jsonNode.get("refNo") != null ? jsonNode.get("refNo").asText() : "")
+ .name(jsonNode.get("name") != null ? jsonNode.get("name").asText() : "")
+ .registrationNumber(jsonNode.get("registrationNumber") != null ? jsonNode.get("registrationNumber").asText() : "")
+ .build();
+
+ pendingMailDTOList.add(pendingMailDTO);
+ }
+ } catch (Exception e) {
+ logger.error(">>>>>>>>>>> Unable to read council name from claim property data", e);
+ }
+
+
+ return pendingMailDTOList;
+ }
+
+ private @NonNull String getCouncilName(String propertyData) {
+ String council = "";
+ if (StringUtils.isEmpty(propertyData)) {
+ logger.error(">>>>>>> Error while fetching council name from property data in Claim");
+ }
+
+ try {
+ ObjectMapper objectMapper = new ObjectMapper();
+ JsonNode jsonNode = objectMapper.readTree(propertyData);
+ council = jsonNode.get("council").asText();
+ } catch (Exception e) {
+ logger.error(">>>>>>>>>>> Unable to read council name from claim property data", e);
+ }
+
+ return council;
+ }
+
+ @Async
+ public void sendManualPendingMail(PendingMailDTO pendingMailDTO) {
+
+ try {
+ MimeMessage mimeMessage = mailSender.createMimeMessage();
+
+ MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true);
+
+ mimeMessageHelper.setSubject(propertyMapper.getForeignPendingItemSubject());
+ mimeMessageHelper.setFrom(new InternetAddress(propertyMapper.getSimpleMailMessageFrom(),pendingMailDTO.getName()));
+ mimeMessageHelper.setTo(pendingMailDTO.getEmailAddress());
+ mimeMessageHelper.setText(generateManualPendingMailContent(pendingMailDTO), true);
+
+ mailSender.send(mimeMessageHelper.getMimeMessage());
+ } catch (Exception e) {
+ logger.error("Exception while sending mail: ", e);
+ throw new ClaimMailException("Exception while composing and sending mail with OTP");
+ }
+
+ }
+
+ /**
+ * @param mailDto
+ * @return
+ */
+ private String generateManualPendingMailContent(PendingMailDTO pendingMailDTO) {
+ String processedTemplateString = null;
+
+ Map mailMap = new HashMap<>();
+ mailMap.put("name", pendingMailDTO.getName());
+ mailMap.put("council", pendingMailDTO.getCouncil());
+ mailMap.put("itemName", pendingMailDTO.getItemName());
+
+ try {
+ freeMarkerConfiguration.setClassForTemplateLoading(this.getClass(), "/templates/");
+ Template template = freeMarkerConfiguration.getTemplate("manual-pending-item-mail.ftl");
+ processedTemplateString = FreeMarkerTemplateUtils.processTemplateIntoString(template, mailMap);
+
+ } catch (TemplateException e) {
+ logger.error("TemplateException while creating mail template for certificate ", e);
+ throw new ClaimMailException("Error while creating mail template for certificate");
+ } catch (IOException e) {
+ logger.error("IOException while creating mail template for certificate ", e);
+ throw new ClaimMailException("Error while creating mail template for certificate");
+ }
+ return processedTemplateString;
+ }
+
}
diff --git a/java/claim/src/main/java/dev/sunbirdrc/claim/service/FileService.java b/java/claim/src/main/java/dev/sunbirdrc/claim/service/FileService.java
index 3de1b64da..ffb6e8e3d 100644
--- a/java/claim/src/main/java/dev/sunbirdrc/claim/service/FileService.java
+++ b/java/claim/src/main/java/dev/sunbirdrc/claim/service/FileService.java
@@ -2,6 +2,7 @@
import dev.sunbirdrc.claim.dto.FileDto;
import org.springframework.core.io.ByteArrayResource;
+import org.springframework.http.MediaType;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
@@ -14,4 +15,6 @@ public interface FileService {
FileDto uploadFile(MultipartFile file) throws IOException;
List uploadMultipleFile(MultipartFile[] files, String entityName, String entityId);
+
+ MediaType getFileMediaType(String fileName) throws Exception;
}
\ No newline at end of file
diff --git a/java/claim/src/main/java/dev/sunbirdrc/claim/service/FileServiceImpl.java b/java/claim/src/main/java/dev/sunbirdrc/claim/service/FileServiceImpl.java
index fc6f5ae99..917047bf4 100644
--- a/java/claim/src/main/java/dev/sunbirdrc/claim/service/FileServiceImpl.java
+++ b/java/claim/src/main/java/dev/sunbirdrc/claim/service/FileServiceImpl.java
@@ -6,11 +6,14 @@
import dev.sunbirdrc.claim.exception.GCPFileUploadException;
import dev.sunbirdrc.claim.utils.GCPBucketUtil;
import lombok.RequiredArgsConstructor;
+import org.apache.commons.io.FilenameUtils;
+import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ByteArrayResource;
+import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
@@ -21,6 +24,9 @@
import java.util.ArrayList;
import java.util.List;
+import static dev.sunbirdrc.claim.contants.AttributeNames.*;
+import static dev.sunbirdrc.claim.contants.AttributeNames.PDF;
+
@Service
@RequiredArgsConstructor
@@ -71,6 +77,7 @@ public List uploadMultipleFile(MultipartFile[] files, String entityName
for (MultipartFile file : files) {
FileDto fileDto = new FileDto();
String originalFileName = entityName + "_" + entityId + "_" + file.getOriginalFilename();
+ originalFileName = StringUtils.deleteWhitespace(originalFileName);
Path path = new File(originalFileName).toPath();
try {
@@ -87,4 +94,40 @@ public List uploadMultipleFile(MultipartFile[] files, String entityName
}
return fileDtoList;
}
+
+ /**
+ * @param fileName
+ * @return
+ * @throws Exception
+ */
+ @Override
+ public MediaType getFileMediaType(String fileName) throws Exception {
+ if (StringUtils.isEmpty(fileName)) {
+ LOGGER.error("File name is either empty or blank - while finding file type");
+ throw new Exception("File name is either empty or blank - while finding file type");
+ }
+
+ MediaType mediaType = MediaType.APPLICATION_PDF;
+
+ String extension = FilenameUtils.getExtension(fileName);
+ extension = StringUtils.upperCase(extension);
+
+ switch (extension) {
+ case JPG:
+ case JPEG:
+ mediaType = MediaType.IMAGE_JPEG;
+ break;
+ case PNG:
+ mediaType = MediaType.IMAGE_PNG;
+ break;
+ case PDF:
+ mediaType = MediaType.APPLICATION_PDF;
+ break;
+ default:
+ LOGGER.error("File type not supported");
+ throw new Exception("File type not supported");
+ }
+
+ return mediaType;
+ }
}
\ No newline at end of file
diff --git a/java/claim/src/main/java/dev/sunbirdrc/claim/service/RegulatorService.java b/java/claim/src/main/java/dev/sunbirdrc/claim/service/RegulatorService.java
new file mode 100644
index 000000000..678549a1a
--- /dev/null
+++ b/java/claim/src/main/java/dev/sunbirdrc/claim/service/RegulatorService.java
@@ -0,0 +1,45 @@
+package dev.sunbirdrc.claim.service;
+
+import dev.sunbirdrc.claim.config.PropertyMapper;
+import dev.sunbirdrc.claim.entity.Regulator;
+import dev.sunbirdrc.claim.repository.RegulatorRowMapper;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.dao.IncorrectResultSizeDataAccessException;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Service
+public class RegulatorService {
+
+ @Autowired
+ private PropertyMapper propertyMapper;
+
+ @Autowired
+ private JdbcTemplate jdbcTemplate;
+
+ public List findByCouncil(String council) {
+ try {
+ return jdbcTemplate.query("SELECT * FROM \"" + propertyMapper.getRegulatorTableName()
+ + "\" where council=?", new RegulatorRowMapper(), council);
+
+ } catch (IncorrectResultSizeDataAccessException e) {
+ return null;
+ }
+ }
+
+ public List findAll() {
+ return jdbcTemplate.query("SELECT * from \"" + propertyMapper.getRegulatorTableName() + "\"",
+ new RegulatorRowMapper());
+ }
+
+ public boolean isRegulatorTableExist() {
+ String sqlQuery = "SELECT count(*) FROM information_schema.tables WHERE table_name = '"
+ + propertyMapper.getRegulatorTableName() + "'";
+
+ Integer tableCount = jdbcTemplate.queryForObject(sqlQuery, Integer.class);
+
+ return tableCount > 0;
+ }
+}
diff --git a/java/claim/src/main/resources/application.properties b/java/claim/src/main/resources/application.properties
index bbe651c90..caaba96c9 100644
--- a/java/claim/src/main/resources/application.properties
+++ b/java/claim/src/main/resources/application.properties
@@ -1,11 +1,12 @@
server.port=8082
-spring.datasource.url=${connectionInfo_uri:jdbc:postgresql://localhost:5432/registry10}
+spring.datasource.url=${connectionInfo_uri:jdbc:postgresql://localhost:5432/registry}
spring.datasource.username=${connectionInfo_username:postgres}
spring.datasource.password=${connectionInfo_password:postgres}
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.hibernate.ddl-auto=update
+spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true
sunbirdrc.url=${sunbirdrc_url:http://localhost:8081}
@@ -42,4 +43,35 @@ gcp.file.validity=2
spring.servlet.multipart.max-file-size=10MB
spring.servlet.multipart.max-request-size=10MB
+# Mail config
+simple.mail.message.from = r.kishor.rahu@gmail.com
+foreign.pending.item.subject = Pending Item
+
+#Pending Item config
+up.council.name = upsmfac
+regulator.table.name = V_Regulator
+
+#---------------------------- QUARTZ CONFIGS ----------------------------
+samplejob.frequency=0 40 15 ? * * *
+#samplejob.frequency=0 */5 * ? * *
+
+quartz.enabled=true
+spring.quartz.job-store-type=jdbc
+spring.quartz.jdbc.initialize-schema=never
+
+spring.quartz.properties.org.quartz.scheduler.instanceName=quartz-mail-event
+spring.quartz.properties.org.quartz.scheduler.instanceId=AUTO
+#spring.quartz.properties.org.quartz.scheduler.instanceIdGenerator.class=com.helixz.quartz.demo.component.CustomQuartzInstanceIdGenerator
+spring.quartz.properties.org.quartz.threadPool.threadCount=20
+spring.quartz.properties.org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX
+#spring.quartz.properties.org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate
+spring.quartz.properties.org.quartz.jobStore.useProperties=true
+spring.quartz.properties.org.quartz.jobStore.misfireThreshold=60000
+spring.quartz.properties.org.quartz.jobStore.tablePrefix=qrtz_
+spring.quartz.properties.org.quartz.jobStore.isClustered=true
+spring.quartz.properties.org.quartz.plugin.shutdownHook.class=org.quartz.plugins.management.ShutdownHookPlugin
+spring.quartz.properties.org.quartz.plugin.shutdownHook.cleanShutdown=TRUE
+spring.quartz.properties.org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.PostgreSQLDelegate
+#------------------------------------------------------
+
diff --git a/java/claim/src/main/resources/templates/credentials-mail.ftl b/java/claim/src/main/resources/templates/credentials-mail.ftl
new file mode 100644
index 000000000..98d67435c
--- /dev/null
+++ b/java/claim/src/main/resources/templates/credentials-mail.ftl
@@ -0,0 +1,12 @@
+
+
+ Hi ${name}
+
+ "We are pleased to inform you that a ${credType} has been issued to you. You can view and download the credential by using the following link.
+
+ ${idLink}
+
+ Thank you,
+ < Registration Credential Issuing Authority >
+
+
diff --git a/java/claim/src/main/resources/templates/manual-pending-item-mail.ftl b/java/claim/src/main/resources/templates/manual-pending-item-mail.ftl
new file mode 100644
index 000000000..9b7a765d5
--- /dev/null
+++ b/java/claim/src/main/resources/templates/manual-pending-item-mail.ftl
@@ -0,0 +1,12 @@
+
+
+ Hi ${name}
+
+ We have pending item for ${council}, which have been requested
+
+ Item name:
${itemName}
+
+ Thank you,
+ < Registration Credential Issuing Authority >
+
+
\ No newline at end of file
diff --git a/java/claim/src/main/resources/templates/pending-item-mail.ftl b/java/claim/src/main/resources/templates/pending-item-mail.ftl
new file mode 100644
index 000000000..5f786b2d1
--- /dev/null
+++ b/java/claim/src/main/resources/templates/pending-item-mail.ftl
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+ Hi ${regulatorName}
+
+ Following candidate has applied for registration certificate from your institution as claimed by candidate.
+
+
Candidate list:
+
+
+
+ Name |
+ Cred Type |
+ Reference Number |
+ Registration Number |
+ Email |
+
+ <#list candidates as candidate >
+
+ ${candidate.name} |
+ ${candidate.credType} |
+ ${candidate.refNo} |
+ ${candidate.registrationNumber} |
+ ${candidate.emailAddress} |
+
+ #list>
+
+
+
+ your response awaited
+
+ Thank you,
+ < Registration Credential Issuing Authority >
+
+
diff --git a/java/registry/src/main/java/dev/sunbirdrc/registry/controller/RegistryEntityController.java b/java/registry/src/main/java/dev/sunbirdrc/registry/controller/RegistryEntityController.java
index 909e3458d..c225777ed 100644
--- a/java/registry/src/main/java/dev/sunbirdrc/registry/controller/RegistryEntityController.java
+++ b/java/registry/src/main/java/dev/sunbirdrc/registry/controller/RegistryEntityController.java
@@ -26,11 +26,13 @@
import dev.sunbirdrc.registry.middleware.util.JSONUtil;
import dev.sunbirdrc.registry.middleware.util.OSSystemFields;
import dev.sunbirdrc.registry.model.dto.MailDto;
+import dev.sunbirdrc.registry.model.dto.ManualPendingMailDTO;
import dev.sunbirdrc.registry.service.FileStorageService;
import dev.sunbirdrc.registry.service.impl.CertificateServiceImpl;
import dev.sunbirdrc.registry.transform.Configuration;
import dev.sunbirdrc.registry.transform.Data;
import dev.sunbirdrc.registry.transform.ITransformer;
+import dev.sunbirdrc.registry.util.ClaimRequestClient;
import org.agrona.Strings;
import dev.sunbirdrc.registry.util.DigiLockerUtils;
import dev.sunbirdrc.registry.util.DocDetails;
@@ -87,6 +89,9 @@ public class RegistryEntityController extends AbstractController {
@Autowired
private ViewTemplateManager viewTemplateManager;
+ @Autowired
+ private ClaimRequestClient claimRequestClient;
+
@Value("${authentication.enabled:true}")
boolean securityEnabled;
@Value("${certificate.enableExternalTemplates:false}")
@@ -1433,5 +1438,30 @@ public JsonNode searchEntity(ObjectNode searchNode, String entityName) {
return result;
}
+ @RequestMapping(value = "/api/v1/{entityName}/sendPendingForeignItemMail", method = RequestMethod.POST)
+ public ResponseEntity