Skip to content

Commit

Permalink
#19 notification at order creation
Browse files Browse the repository at this point in the history
  • Loading branch information
Benjamin POCHAT authored and Benjamin POCHAT committed Jan 5, 2021
1 parent 22c5fe3 commit 232fdde
Show file tree
Hide file tree
Showing 21 changed files with 294 additions and 28 deletions.
17 changes: 16 additions & 1 deletion core/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,19 @@ USER localeat

# Wait for Postgre database (localhost:5432)
# and then start java core application
ENTRYPOINT ["wait-for-it", "localhost:5432", "--timeout=10", "--", "mvn", "exec:java", "-s", "/usr/share/maven/ref/settings-docker.xml", "-f", "./core/pom.xml", "-Dspring.profiles.active=prod", "-Ddatasource_url=${localeat_datasource_url}", "-Ddatasource_username=${localeat_datasource_username}", "-Ddatasource_password=${localeat_datasource_password}"]
ENTRYPOINT ["wait-for-it",
"localhost:5432",
"--timeout=10",
"--",
"mvn",
"exec:java",
"-s",
"/usr/share/maven/ref/settings-docker.xml",
"-f",
"./core/pom.xml",
"-Dspring.profiles.active=prod",
"-Ddatasource_url=${localeat_datasource_url}",
"-Ddatasource_username=${localeat_datasource_username}",
"-Ddatasource_password=${localeat_datasource_password}",
"-Dlocaleat_smtp_username=${localeat_smtp_username}",
"-Dlocaleat_smtp_password=${localeat_smtp_password}"]
15 changes: 14 additions & 1 deletion core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,12 @@
<spring-security-version>5.2.4.RELEASE</spring-security-version>
<spring-restdocs-asciidoctor-version>2.0.4.RELEASE</spring-restdocs-asciidoctor-version>
<jaxb-version>2.3.0</jaxb-version>
<javamail-version>1.5.0-b01</javamail-version>
<postgre-version>42.2.5</postgre-version>
<h2.version>1.4.200</h2.version>
<slf4j-version>1.7.26</slf4j-version>
<log4j-version>1.2.17</log4j-version>
<junit-version>5.3.2</junit-version>
<junit-version>5.6.3</junit-version>
<assertj-version>3.14.0</assertj-version>
<mockito-version>3.1.0</mockito-version>
<compiler-version>3.8.0</compiler-version>
Expand Down Expand Up @@ -62,6 +63,11 @@
<artifactId>jaxb-api</artifactId>
</dependency>

<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.restdocs</groupId>
<artifactId>spring-restdocs-mockmvc</artifactId>
Expand Down Expand Up @@ -245,6 +251,13 @@
<version>${jaxb-version}</version>
</dependency>

<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>${javamail-version}</version>
</dependency>


<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
Expand Down
10 changes: 4 additions & 6 deletions core/src/main/java/com/localeat/core/commons/EmailService.java
Original file line number Diff line number Diff line change
@@ -1,19 +1,17 @@
package com.localeat.core.commons;

import com.localeat.core.config.email.EmailConfig;
import com.localeat.core.config.security.LocalEatRSAKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

import org.springframework.stereotype.Service;
import javax.mail.*;
import javax.mail.internet.MimeMessage;

@Controller
public class EmailController {
@Service
public class EmailService {

private static final Logger LOGGER = LoggerFactory.getLogger(EmailController.class);
private static final Logger LOGGER = LoggerFactory.getLogger(EmailService.class);

@Autowired
EmailConfig emailConfig;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.localeat.commons;
package com.localeat.core.commons;

import java.util.ArrayList;
import java.util.List;
Expand Down
24 changes: 22 additions & 2 deletions core/src/main/java/com/localeat/core/config/email/EmailConfig.java
Original file line number Diff line number Diff line change
@@ -1,16 +1,28 @@
package com.localeat.core.config.email;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

import java.util.Properties;

@ConfigurationProperties("localeat.smtp")
public class EmailProperties {
@Configuration
@ConfigurationProperties(prefix = "localeat.smtp")
public class EmailConfig {
private boolean authentication;
private boolean startTls;
private String host;
private String port;
private String sslTrust;
private String userName;
private String password;

public String getUserName() {
return userName;
}

public String getPassword() {
return password;
}

public boolean isAuthentication() {
return authentication;
Expand Down Expand Up @@ -52,6 +64,14 @@ public void setSslTrust(String sslTrust) {
this.sslTrust = sslTrust;
}

public void setUserName(String userName) {
this.userName = userName;
}

public void setPassword(String password) {
this.password = password;
}

public Properties getProperties() {
var properties = new Properties();
properties.put("mail.smtp.auth", authentication);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
package com.localeat.core.domains.actor;

public interface BreederRepository {
import com.localeat.core.domains.farm.Farm;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.query.Param;

public interface BreederRepository extends CrudRepository<Breeder, Long> {
@Query("SELECT b FROM Breeder b " +
"WHERE b.farm = :farm")
Iterable<Breeder> findBreedersByFarm(@Param("farm") Farm farm);
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
import javax.persistence.*;
import java.util.Set;

import static javax.persistence.CascadeType.ALL;
import static javax.persistence.FetchType.EAGER;

@Entity
@Table(name = "orders")
public class Order {
Expand All @@ -20,7 +23,7 @@ public class Order {
@ManyToOne
private Customer customer;

@OneToMany(cascade = {CascadeType.ALL}, mappedBy = "order")
@OneToMany(fetch = EAGER, cascade = {ALL}, mappedBy = "order")
@JsonManagedReference
private Set<OrderItem> orderedItems;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@
import com.localeat.core.domains.delivery.Delivery;
import com.localeat.core.domains.delivery.DeliveryController;
import com.localeat.core.domains.delivery.DeliveryRepository;
import com.localeat.core.domains.product.Batch;
import com.localeat.core.domains.product.BatchRepository;
import com.localeat.core.domains.security.Account;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
Expand All @@ -16,11 +14,6 @@
import org.springframework.web.server.ResponseStatusException;

import javax.websocket.server.PathParam;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

@RestController
public class OrderController {
Expand All @@ -34,13 +27,18 @@ public class OrderController {
@Autowired
private DeliveryController deliveryController;

@Autowired
private OrderNotificationService orderNotificationService;

@PostMapping(path = "/accounts/{account}/orders")
public Order createOrder(@PathParam("account") Account account, @RequestBody Order order){
Customer customer = (Customer) account.getActor();
order.setCustomer(customer);
Delivery delivery = deliveryRepository.findById(order.getDelivery().getId()).orElseThrow();
deliveryController.updateQuantitySoldInBatches(delivery);
return orderRepository.save(order);
Order orderSaved = orderRepository.save(order);
orderNotificationService.notifyByMail(orderSaved);
return orderSaved;
}

@GetMapping(path= "/accounts/{account}/orders")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,62 @@
package com.localeat.core.domains.order;

import com.localeat.core.commons.EmailService;
import com.localeat.core.domains.actor.Breeder;
import com.localeat.core.domains.actor.BreederRepository;
import com.localeat.core.domains.product.Batch;
import com.localeat.core.domains.product.BatchRepository;
import com.localeat.core.domains.slaughter.Slaughter;
import com.localeat.core.domains.slaughter.SlaughterRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.stream.Collectors;
import java.util.stream.StreamSupport;

@Service
public class OrderNotificationService {

@Autowired
private BatchRepository batchRepository;

@Autowired
private SlaughterRepository slaughterRepository;

@Autowired
private BreederRepository breederRepository;

@Autowired
private OrderItemRepository orderItemRepository;

@Autowired
private EmailService emailService;

public void notifyByMail(Order order) {
Slaughter slaughter = slaughterRepository.findByDelivery(order.getDelivery());
Iterable<Breeder> breeders = breederRepository.findBreedersByFarm(slaughter.getAnimal().getFinalFarm());
String recipient = StreamSupport.stream(breeders.spliterator(), false).map(Breeder::getEmail).collect(Collectors.joining(","));
String subject = "nouvelle commande !";
String body = String.format(
"<div>La commande n° %s a été enregistrée</div>"
+ "<div><ul>"
+ "<li>Montant de la commande : %s €TTC</li>"
+ "<li>Quantité commandée : %s kg</li>"
+ "</ul></div>",
order.getId(),
order.getOrderedItems().stream()
.mapToDouble(item -> {
Batch batch = batchRepository.findById(item.getBatch().getId()).orElseThrow();
return item.getQuantity() * batch.getProduct().getUnitPrice() * batch.getProduct().getNetWeight();
})
.sum(),
order.getOrderedItems().stream().mapToDouble(item -> {
Batch batch = batchRepository.findById(item.getBatch().getId()).orElseThrow();
return item.getQuantity() * batch.getProduct().getNetWeight();
}).sum());
sendMail(recipient, subject, body);
}

void sendMail(String recipient, String subject, String body) {
emailService.sendMail(recipient, subject, body);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import org.springframework.security.provisioning.JdbcUserDetailsManager;
import org.springframework.security.provisioning.UserDetailsManager;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
package com.localeat.core.domains.security;

import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.query.Param;

public interface AccountRepository extends CrudRepository<Account, Long> {
Account getAccountByUsername(String username);

@Query("SELECT a FROM Account a " +
"INNER JOIN a.actor act " +
"WHERE act.email = :email")
Iterable<Account> findByEmail(@Param("email") String email);
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,24 @@
package com.localeat.core.domains.security;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.server.ResponseStatusException;

import java.util.stream.StreamSupport;

@RestController
public class PasswordRenewalController {

@Autowired
AccountRepository accountRepository;

@PostMapping(path = "/passwordRenewal/{email}")
public String renewPassword(@PathVariable String email){
Account account = StreamSupport.stream(accountRepository.findByEmail(email).spliterator(), false).findFirst().orElseThrow(() -> new ResponseStatusException(HttpStatus.FORBIDDEN, String.format("No account for email address %s.", email)));
// TODO : générer un token et envoyer un mail
return String.format("An email has been sent to %s.", email);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.localeat.core.domains.slaughter;

import com.localeat.core.domains.delivery.Delivery;
import com.localeat.core.domains.farm.Farm;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;
Expand All @@ -10,4 +11,8 @@ public interface SlaughterRepository extends CrudRepository<Slaughter, Long> {
"INNER JOIN s.animal a " +
"WHERE a.finalFarm = :farm")
Iterable<Slaughter> findByFarm(@Param("farm") Farm farm);

@Query("SELECT s FROM Slaughter s " +
"WHERE s.delivery = :delivery")
Slaughter findByDelivery(@Param("delivery") Delivery delivery);
}
1 change: 0 additions & 1 deletion core/src/main/resources/application-dev.properties
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,3 @@ spring.jpa.hibernate.ddl-auto = update

logging.level.org.springframework.web = DEBUG
logging.level.com.localeat = DEBUG

6 changes: 6 additions & 0 deletions core/src/main/resources/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,9 @@ spring.jackson.serialization.FAIL_ON_EMPTY_BEANS=false

# Avoid errors at startup when trying to create contextual lob
#spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation = true

localeat.smtp.authentication = true
localeat.smtp.startTls = true
localeat.smtp.host = smtp.gmail.com
localeat.smtp.port = 587
localeat.smtp.sslTrust = smtp.gmail.com

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
package com.localeat.core.domains.order;

import com.localeat.core.commons.EmailService;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.restdocs.RestDocumentationContextProvider;
Expand All @@ -14,6 +18,9 @@
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.WebApplicationContext;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.when;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post;
Expand All @@ -31,6 +38,7 @@
"/sql/create/com/localeat/domains/security/security_test_data.sql",
"/sql/create/com/localeat/domains/farm/farm_test_data.sql",
"/sql/create/com/localeat/domains/actor/customer_test_data.sql",
"/sql/create/com/localeat/domains/actor/breeder_test_data.sql",
"/sql/create/com/localeat/domains/delivery/address_test_data.sql",
"/sql/create/com/localeat/domains/product/product_test_data.sql",
"/sql/create/com/localeat/domains/slaughter/slaughter_test_data.sql",
Expand All @@ -48,7 +56,8 @@ public class TestAndDocOrderController {
@BeforeEach
public void setUp(WebApplicationContext webApplicationContext,
RestDocumentationContextProvider restDocumentation) {
this.mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext)
MockitoAnnotations.initMocks(this);
mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext)
.apply(documentationConfiguration(restDocumentation))
.build();
}
Expand Down
Loading

0 comments on commit 232fdde

Please sign in to comment.