diff --git a/apps/api/src/main/java/dk/treecreate/api/mail/MailService.java b/apps/api/src/main/java/dk/treecreate/api/mail/MailService.java index 6ff50ee5d..6d2558e4f 100644 --- a/apps/api/src/main/java/dk/treecreate/api/mail/MailService.java +++ b/apps/api/src/main/java/dk/treecreate/api/mail/MailService.java @@ -5,6 +5,7 @@ import dk.treecreate.api.order.OrderService; import dk.treecreate.api.order.dto.CreateCustomOrderRequest; import dk.treecreate.api.utils.LinkService; +import dk.treecreate.api.utils.QuickpayService; import io.sentry.Sentry; import java.io.File; import java.io.FileInputStream; @@ -46,6 +47,7 @@ public class MailService { @Autowired LinkService linkService; @Autowired OrderService orderService; @Autowired CustomPropertiesConfig customPropertiesConfig; + @Autowired QuickpayService quickpayService; public MailService( TemplateEngine templateEngine, @@ -188,6 +190,22 @@ public void sendCustomOrderRequestEmail(CreateCustomOrderRequest orderInfo) orderInfo.getImages()); } + public void sendOrderPaymentReminderEmail(Order order) throws Exception { + String subject = "Your Treecreate order is waiting for your payment!"; + Context context = new Context(new Locale("da")); + context.setVariable( + "paymentLink", quickpayService.getPaymentLink(order.getPaymentId()).getUrl()); + System.out.println(quickpayService.getPaymentLink(order.getPaymentId())); + if (order.getPaymentReminderSent() == false) { + sendMail( + order.getContactInfo().getEmail(), + MailDomain.INFO, + subject, + context, + MailTemplate.PAYMENT_REMINDER); + } + } + // No BCC email and no attachments private void sendMail( String to, MailDomain from, String subject, Context context, MailTemplate template) diff --git a/apps/api/src/main/java/dk/treecreate/api/mail/MailTemplate.java b/apps/api/src/main/java/dk/treecreate/api/mail/MailTemplate.java index 2153afe4a..a99ce947f 100644 --- a/apps/api/src/main/java/dk/treecreate/api/mail/MailTemplate.java +++ b/apps/api/src/main/java/dk/treecreate/api/mail/MailTemplate.java @@ -7,7 +7,8 @@ public enum MailTemplate { RESET_PASSWORD("reset-password"), ORDER_CONFIRMATION("order-confirmation"), CUSTOM_ORDER_REQUEST("custom-order-request"), - NEWSLETTER_DISCOUNT("newsletter-discount"); + NEWSLETTER_DISCOUNT("newsletter-discount"), + PAYMENT_REMINDER("payment-reminder"); public final String label; diff --git a/apps/api/src/main/java/dk/treecreate/api/order/Order.java b/apps/api/src/main/java/dk/treecreate/api/order/Order.java index 5a9ea5cb5..e292425d2 100644 --- a/apps/api/src/main/java/dk/treecreate/api/order/Order.java +++ b/apps/api/src/main/java/dk/treecreate/api/order/Order.java @@ -12,7 +12,17 @@ import java.util.List; import java.util.Objects; import java.util.UUID; -import javax.persistence.*; +import javax.persistence.Basic; +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; +import javax.persistence.OneToOne; +import javax.persistence.Table; import javax.validation.constraints.Min; import org.hibernate.annotations.CreationTimestamp; import org.hibernate.annotations.GenericGenerator; @@ -99,6 +109,16 @@ public class Order { @ApiModelProperty(notes = "Transaction items of the given order") private List transactionItems; + @Column( + name = "payment_reminder_sent", + columnDefinition = "boolean default false", + nullable = false) + @ApiModelProperty( + notes = "Has a payment reminder for this order been sent?", + example = "false", + required = false) + private boolean paymentReminderSent = false; + @ApiModelProperty( name = "Date the entity was created at", example = "2021-08-31T19:40:10.000+00:00") @@ -231,6 +251,14 @@ public void setUpdatedAt(Date updatedAt) { this.updatedAt = updatedAt; } + public boolean getPaymentReminderSent() { + return paymentReminderSent; + } + + public void setPaymentReminderSent(boolean paymentReminderSent) { + this.paymentReminderSent = paymentReminderSent; + } + @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/apps/api/src/main/java/dk/treecreate/api/order/OrderService.java b/apps/api/src/main/java/dk/treecreate/api/order/OrderService.java index 9fbc1ed5b..8f056ecb6 100644 --- a/apps/api/src/main/java/dk/treecreate/api/order/OrderService.java +++ b/apps/api/src/main/java/dk/treecreate/api/order/OrderService.java @@ -20,22 +20,27 @@ import dk.treecreate.api.user.UserRepository; import dk.treecreate.api.utils.OrderStatus; import dk.treecreate.api.utils.model.quickpay.ShippingMethod; +import io.sentry.Sentry; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.UUID; +import java.util.concurrent.TimeUnit; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.server.ResponseStatusException; @Service @Transactional +@EnableScheduling public class OrderService { private static final Logger LOGGER = LoggerFactory.getLogger(OrderService.class); @@ -45,6 +50,7 @@ public class OrderService { @Autowired UserRepository userRepository; @Autowired AuthUserService authUserService; @Autowired OrderRepository orderRepository; + @Autowired OrderController orderController; @Autowired MailService mailService; @@ -300,6 +306,38 @@ public void sendOrderConfirmationEmail(Order order) { } } + public List getAllUnpaidOrders() { + List allOrders = orderRepository.findAll(); + List initialOrders = new ArrayList(); + for (Order order : allOrders) { + if ((order.getStatus() == OrderStatus.INITIAL || order.getStatus() == OrderStatus.REJECTED) + && order.getPaymentReminderSent() == false) { + initialOrders.add(order); + } + } + return initialOrders; + } + + @Scheduled(cron = "* 1 * * * ?") + public void sendScheduledPaymentLink() { + List orderList = this.getAllUnpaidOrders(); + Date now = new Date(System.currentTimeMillis() - TimeUnit.MINUTES.toMillis(5)); + for (Order order : orderList) { + try { + if (now.after(order.getCreatedAt())) { + this.mailService.sendOrderPaymentReminderEmail(order); + order.setPaymentReminderSent(true); + orderRepository.save(order); + LOGGER.info("Payment reminder email has been sent to " + order.getOrderId()); + } + } catch (Exception e) { + LOGGER.error( + "Failed to process scheduled payment link to " + order.getContactInfo().getEmail(), e); + Sentry.captureException(e); + } + } + } + public Order setupOrderFromCreateRequest(CreateOrderRequest createOrderRequest) { Order order = new Order(); order.setSubtotal(createOrderRequest.getSubtotal()); diff --git a/apps/api/src/main/resources/data.sql b/apps/api/src/main/resources/data.sql index 67ced4190..2666cfee7 100644 --- a/apps/api/src/main/resources/data.sql +++ b/apps/api/src/main/resources/data.sql @@ -537,6 +537,7 @@ FROM (( , now() AS created_at , 0 AS currency , '291586595' AS payment_id + , 0 AS payment_reminder_sent , 1 AS planted_trees , 1 AS shipping_method , 0 AS status @@ -553,6 +554,7 @@ FROM (( , now() AS created_at , 0 AS currency , '291586768' AS payment_id + , 0 AS payment_reminder_sent , 1 AS planted_trees , 0 AS shipping_method , 0 AS status @@ -569,6 +571,7 @@ FROM (( , now() AS created_at , 0 AS currency , '291586909' AS payment_id + , 0 AS payment_reminder_sent , 1 AS planted_trees , 1 AS shipping_method , 0 AS status @@ -585,6 +588,7 @@ FROM (( , now() AS created_at , 0 AS currency , '291587163' AS payment_id + , 0 AS payment_reminder_sent , 1 AS planted_trees , 1 AS shipping_method , 0 AS status @@ -601,6 +605,7 @@ FROM (( , now() AS created_at , 0 AS currency , '291587312' AS payment_id + , 0 AS payment_reminder_sent , 1 AS planted_trees , 1 AS shipping_method , 0 AS status @@ -617,6 +622,7 @@ FROM (( , now() AS created_at , 0 AS currency , '291589918' AS payment_id + , 0 AS payment_reminder_sent , 3 AS planted_trees , 0 AS shipping_method , 0 AS status diff --git a/apps/api/src/main/resources/templates/emails/payment-reminder.html b/apps/api/src/main/resources/templates/emails/payment-reminder.html new file mode 100644 index 000000000..afe82ccf4 --- /dev/null +++ b/apps/api/src/main/resources/templates/emails/payment-reminder.html @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + +
+

Here's your payment link: Complete Payment +

+
+ +