Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
457a6a6
feat: 🎸 Add paymentReminderSent field to order
Kwandes Oct 25, 2022
c422bb2
feat: 🎸 Add payment reminder email
Kwandes Oct 25, 2022
77b9ca9
feat: 🎸 Add commented out scheduled method
Oct 26, 2022
d155beb
feat: 🎸 Add get unpayed orders list method
Sintry1 Oct 26, 2022
e915942
feat: 🎸 Add Spring Import
Oct 27, 2022
a86bfb6
feat: 🎸 Change payment reminder email slightly
Sintry1 Oct 27, 2022
fb69653
feat: 🎸 Add logic to scheduled method
Sintry1 Oct 27, 2022
666583c
feat: 🎸 Add logic to OrderService method
Sintry1 Oct 27, 2022
4b84fa0
feat: 🎸 Add logic to fetch order method
Sintry1 Oct 27, 2022
2dc8ee5
feat: 🎸 Add logic to OrderService method
Sintry1 Oct 27, 2022
5e37582
feat: 🎸 Move fetch order logic to OrderService
Sintry1 Oct 27, 2022
18bee32
feat: 🎸 Fix conflicts
Sintry1 Oct 27, 2022
c1b0ac4
feat: 🎸 Remove unneeded line
Sintry1 Oct 27, 2022
daba1c1
feat: 🎸 Change frequency of cron expression
Sintry1 Oct 27, 2022
9a645a5
feat: 🎸 Add payment link to template
Sintry1 Oct 28, 2022
a42677c
feat: 🎸 Add check for time to scheduled method
Sintry1 Oct 30, 2022
3a82171
feat: 🎸 Fix payment link in email template and add time check
Sintry1 Oct 30, 2022
7aa9b64
feat: 🎸 Change CRON to 1hr
Sintry1 Oct 30, 2022
c46d823
style: 💄 Formatting
Sintry1 Oct 30, 2022
3cedbcc
Merge branch 'development' into feat/#274-add-payment-reminder-email
Teodor25 Oct 30, 2022
2ceebe2
Merge branch 'development' into feat/#274-add-payment-reminder-email
Kwandes Oct 30, 2022
e817732
refactor: 💡 Rename paymentReminderSent variable in data.sql
Kwandes Oct 30, 2022
1b372f1
chore: 🤖 Fix order of fields in data.sql
Kwandes Oct 30, 2022
5ad6f9b
Merge branch 'development' into feat/#274-add-payment-reminder-email
Kwandes Nov 3, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions apps/api/src/main/java/dk/treecreate/api/mail/MailService.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -46,6 +47,7 @@ public class MailService {
@Autowired LinkService linkService;
@Autowired OrderService orderService;
@Autowired CustomPropertiesConfig customPropertiesConfig;
@Autowired QuickpayService quickpayService;

public MailService(
TemplateEngine templateEngine,
Expand Down Expand Up @@ -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()));

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't use normal console logs for this, use the Logger
But this log is redundant anyway since the ordersService already logs this, so it can be removed

Suggested change
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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
30 changes: 29 additions & 1 deletion apps/api/src/main/java/dk/treecreate/api/order/Order.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -99,6 +109,16 @@ public class Order {
@ApiModelProperty(notes = "Transaction items of the given order")
private List<TransactionItem> 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")
Expand Down Expand Up @@ -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;
Expand Down
38 changes: 38 additions & 0 deletions apps/api/src/main/java/dk/treecreate/api/order/OrderService.java
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand All @@ -45,6 +50,7 @@ public class OrderService {
@Autowired UserRepository userRepository;
@Autowired AuthUserService authUserService;
@Autowired OrderRepository orderRepository;
@Autowired OrderController orderController;

@Autowired MailService mailService;

Expand Down Expand Up @@ -300,6 +306,38 @@ public void sendOrderConfirmationEmail(Order order) {
}
}

public List<Order> getAllUnpaidOrders() {
List<Order> allOrders = orderRepository.findAll();
List<Order> initialOrders = new ArrayList<Order>();
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<Order> 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());
Expand Down
6 changes: 6 additions & 0 deletions apps/api/src/main/resources/data.sql
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand Down
159 changes: 159 additions & 0 deletions apps/api/src/main/resources/templates/emails/payment-reminder.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional //EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<!--[if gte mso 9
]><xml
><o:OfficeDocumentSettings
><o:AllowPNG /><o:PixelsPerInch>96</o:PixelsPerInch></o:OfficeDocumentSettings
></xml
><!
[endif]-->
<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
<meta content="width=device-width" name="viewport" />
<!--[if !mso]><!-->
<meta content="IE=edge" http-equiv="X-UA-Compatible" />
<!--<![endif]-->
<title></title>
<!--[if !mso]><!-->
<!--<![endif]-->
<style type="text/css">
body {
margin: 0;
padding: 0;
}

table,
td,
tr {
vertical-align: top;
border-collapse: collapse;
}

* {
line-height: inherit;
}

a[x-apple-data-detectors='true'] {
color: #af7949 !important;
text-decoration: none !important;
}
</style>
<style id="media-query" type="text/css">
@media (max-width: 580px) {
.block-grid,
.col {
min-width: 320px !important;
max-width: 100% !important;
display: block !important;
}

.block-grid {
width: 100% !important;
}

.col {
width: 100% !important;
}

.col_cont {
margin: 0 auto;
}

img.fullwidth,
img.fullwidthOnMobile {
width: 100% !important;
}

.no-stack .col {
min-width: 0 !important;
display: table-cell !important;
}

.no-stack.two-up .col {
width: 50% !important;
}

.no-stack .col.num2 {
width: 16.6% !important;
}

.no-stack .col.num3 {
width: 25% !important;
}

.no-stack .col.num4 {
width: 33% !important;
}

.no-stack .col.num5 {
width: 41.6% !important;
}

.no-stack .col.num6 {
width: 50% !important;
}

.no-stack .col.num7 {
width: 58.3% !important;
}

.no-stack .col.num8 {
width: 66.6% !important;
}

.no-stack .col.num9 {
width: 75% !important;
}

.no-stack .col.num10 {
width: 83.3% !important;
}

.video-block {
max-width: none !important;
}

.mobile_hide {
min-height: 0px;
max-height: 0px;
max-width: 0px;
display: none;
overflow: hidden;
font-size: 0px;
}

.desktop_hide {
display: block !important;
max-height: none !important;
}

.img-container.big img {
width: auto !important;
}
}
</style>
<style id="icon-media-query" type="text/css">
@media (max-width: 580px) {
.icons-inner {
text-align: center;
}

.icons-inner td {
margin: 0 auto;
}
}
</style>
</head>

<body class="clean-body" style="margin: 0; padding: 0; -webkit-text-size-adjust: 100%; background-color: #ffffff">
<div>
<p>Here's your payment link: <a th:href="${paymentLink}" target="_blank"
style="
text-decoration: underline;
color: #000000;
"
rel="noopener">Complete Payment</a>
</p>
</div>
</body>
</html>