Skip to content

Commit

Permalink
added sending email
Browse files Browse the repository at this point in the history
  • Loading branch information
tuongtran23 authored and rafal-nowak committed Aug 14, 2023
1 parent 4c9d508 commit 702197b
Show file tree
Hide file tree
Showing 38 changed files with 1,019 additions and 23 deletions.
5 changes: 5 additions & 0 deletions hla-product-ordering/backend/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,11 @@
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package com.amigoscode.api.email;


import com.amigoscode.appservices.EmailApplicationService;
import com.amigoscode.domain.email.Email;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

@RequiredArgsConstructor
@RestController
@RequestMapping(path = "/api/v1/emails",
produces = "application/json",
consumes = "application/json"
)
class EmailController {
private final EmailApplicationService emailService;

private final EmailDtoMapper emailMapper;

private final PageEmailDtoMapper pageEmailDtoMapper;

@GetMapping( path = "/{emailId}")
public ResponseEntity<EmailDto> getEmail(@PathVariable Integer emailId) {
Email email = emailService.findById(emailId);
return ResponseEntity
.ok(emailMapper.toDto(email));
}

@GetMapping
public ResponseEntity<PageEmailDto> getEmails(
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "3") int size
) {
Pageable pageable = PageRequest.of(page, size);
PageEmailDto pageEmails = pageEmailDtoMapper.toPageDto(emailService.findAll(pageable));

return ResponseEntity.ok(pageEmails);
}

@PostMapping
public ResponseEntity<EmailDto> sendEmail(@RequestBody EmailDto dto){

Email sentEmail = emailService.send(emailMapper.toDomain(dto));
Email savedEmail = emailService.save(sentEmail);
return ResponseEntity
.ok(emailMapper.toDto(savedEmail));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.amigoscode.api.email;

import java.time.ZonedDateTime;
import java.util.List;

public record EmailDto(
Integer id,
Integer providerId,
ZonedDateTime createdAt,
Integer userId,
String content,
List<Integer> orders
) {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.amigoscode.api.email;

import com.amigoscode.api.email.EmailDto;
import com.amigoscode.domain.email.Email;
import org.mapstruct.Mapper;

@Mapper(componentModel = "spring")
public interface EmailDtoMapper {

EmailDto toDto(Email domain);

Email toDomain(EmailDto dto);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.amigoscode.api.email;

import com.amigoscode.api.order.OrderDto;

import java.util.List;

public record PageEmailDto(
List<EmailDto> emails,
Integer currentPage,
Integer totalPages,
Long totalElements
)
{}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.amigoscode.api.email;

import com.amigoscode.api.email.EmailDto;
import com.amigoscode.api.email.PageEmailDto;
import com.amigoscode.domain.email.Email;
import com.amigoscode.domain.email.PageEmail;
import org.mapstruct.IterableMapping;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Named;

import java.util.List;

@Mapper(componentModel = "spring")
public interface PageEmailDtoMapper {

@Mapping(target = "emails", qualifiedByName = "toEmailDtoList")
PageEmailDto toPageDto(PageEmail domain);

@Named("toEmailDtoList")
@IterableMapping(qualifiedByName = "emailToEmailDto")
List<EmailDto> toListDto(List<Email> emails);

@Named("emailToEmailDto")
EmailDto toDto(Email domain);
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@


import com.amigoscode.api.response.ErrorResponse;
import com.amigoscode.domain.email.EmailAlreadyExistsException;
import com.amigoscode.domain.email.EmailNotFoundException;
import com.amigoscode.domain.patient.PatientNotFoundException;
import com.amigoscode.domain.provider.ProviderAlreadyExistsException;
import com.amigoscode.domain.provider.ProviderNotFoundException;
Expand Down Expand Up @@ -58,6 +60,16 @@ public final ResponseEntity<ErrorResponse> handleOrderAlreadyExistsException(Ord
return buildResponse(ex, HttpStatus.CONFLICT);
}

@ExceptionHandler(EmailNotFoundException.class)
public final ResponseEntity<ErrorResponse> handleEmailNotFoundException(EmailNotFoundException ex) {
return buildResponse(ex, HttpStatus.NOT_FOUND);
}

@ExceptionHandler(EmailAlreadyExistsException.class)
public final ResponseEntity<ErrorResponse> handleEmailAlreadyExistsException(EmailAlreadyExistsException ex) {
return buildResponse(ex, HttpStatus.CONFLICT);
}


@ExceptionHandler(ScheduleNotFoundException.class)
public final ResponseEntity<ErrorResponse> handleScheduleNotFoundException(ScheduleNotFoundException ex) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.amigoscode.appservices;

import com.amigoscode.domain.email.Email;
import com.amigoscode.domain.email.EmailNotFoundException;
import com.amigoscode.domain.email.EmailService;
import com.amigoscode.domain.email.PageEmail;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@RequiredArgsConstructor
public class EmailApplicationService {
private final EmailService emailService;

public Email findById(Integer id){
return emailService.findById(id);
}

public PageEmail findAll(Pageable pageable) { return emailService.findAll(pageable); }

@Transactional
public Email save(Email email) {
return emailService.save(email);
}

public Email send(Email email) {
return emailService.send(email);
}


}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.amigoscode.config;

import com.amigoscode.appservices.IAuthenticationFacade;
import com.amigoscode.domain.note.NoteRepository;
import com.amigoscode.domain.note.NoteService;
import com.amigoscode.domain.order.OrderRepository;
Expand All @@ -15,6 +14,10 @@
import com.amigoscode.domain.user.UserService;
import com.amigoscode.domain.version.VersionRepository;
import com.amigoscode.domain.version.VersionService;
import com.amigoscode.external.email.EmailSenderIAdapter;
import com.amigoscode.external.storage.email.EmailEntityMapper;
import com.amigoscode.external.storage.email.EmailStorageAdapter;
import com.amigoscode.external.storage.email.JpaEmailRepository;
import com.amigoscode.external.storage.note.JpaNoteRepository;
import com.amigoscode.external.storage.note.NoteEntityMapper;
import com.amigoscode.external.storage.note.NoteStorageAdapter;
Expand All @@ -38,6 +41,7 @@
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.mail.javamail.JavaMailSender;

import java.time.Clock;

Expand Down Expand Up @@ -80,6 +84,20 @@ public OrderService orderService(OrderRepository orderRepository){
return new OrderService(orderRepository);
}

@Bean
public EmailRepository emailRepository(JpaEmailRepository jpaEmailRepository, EmailEntityMapper mapper){
return new EmailStorageAdapter(jpaEmailRepository, mapper);
}

@Bean
public EmailSender emailSender(JavaMailSender javaMailSender, ProviderService providerService){
return new EmailSenderIAdapter(javaMailSender, providerService);
}

@Bean
public EmailService emailService(EmailRepository emailRepository, EmailSender emailSender, OrderService orderService){
return new EmailService(emailRepository, emailSender, orderService);
}
@Bean
public ScheduleRepository scheduleRepository(JpaScheduleRepository jpaScheduleRepository, ScheduleEntityMapper mapper){
return new ScheduleStorageAdapter(jpaScheduleRepository, mapper);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.amigoscode.domain.email;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;

import java.time.ZonedDateTime;
import java.util.List;

@Data
@AllArgsConstructor
@ToString
@EqualsAndHashCode
public class Email {

private Integer id;
private Integer providerId;
private ZonedDateTime createdAt;
private Integer userId;
private String content;
private List<Integer> orders;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package com.amigoscode.domain.email;

public class EmailAlreadyExistsException extends RuntimeException {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package com.amigoscode.domain.email;

public class EmailNotFoundException extends RuntimeException{
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.amigoscode.domain.email;

import com.amigoscode.domain.email.Email;
import com.amigoscode.domain.email.PageEmail;
import org.springframework.data.domain.Pageable;

import java.util.Optional;

public interface EmailRepository {
Optional<Email> findById(Integer id);

PageEmail findAll(Pageable pageable);

Email save(Email email);


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.amigoscode.domain.email;

public interface EmailSender {
Email send(Email email);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package com.amigoscode.domain.email;

import com.amigoscode.domain.order.Order;
import com.amigoscode.domain.order.OrderService;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Pageable;

import java.util.List;

@RequiredArgsConstructor
public class EmailService {
private final EmailRepository emailRepository;
private final EmailSender emailSender;
private final OrderService orderService;


public Email findById(Integer id){
Email email = emailRepository.findById(id).
orElseThrow(EmailNotFoundException::new);
List<Order> orders = orderService.findByEmailId(id);
email.setOrders(orders.stream().map(Order::getId).toList());
return email;
}

public PageEmail findAll(Pageable pageable) {
final PageEmail pageEmail = emailRepository.findAll(pageable);
for (Email email : pageEmail.getEmails()) {
List<Order> orders = orderService.findByEmailId(email.getId());
email.setOrders(orders.stream().map(Order::getId).toList());
}

return pageEmail;
}

public Email save(Email email) {
Email savedEmail = emailRepository.save(email);
savedEmail.setOrders(email.getOrders());
markOrdersAsSentByEmail(savedEmail);
return savedEmail;
}

public Email send(Email email) {
final String currentContent = email.getContent();
final List<Integer> ordersWithoutEmailId = email.getOrders()
.stream()
.filter(id -> orderService.findById(id).getEmailId() == null).toList();
email.setOrders(ordersWithoutEmailId);
// information needed to order products
String orderRelatedContent = email.getOrders().toString();
email.setContent(currentContent + " " + orderRelatedContent);

emailSender.send(email);

return email;
}

private void markOrdersAsSentByEmail (Email email) {
for (Integer id: email.getOrders()) {
Order order = orderService.findById(id);
order.setEmailId(email.getId());
orderService.update(order);
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.amigoscode.domain.email;


import lombok.Value;

import java.io.Serializable;
import java.util.List;

@Value
public class PageEmail implements Serializable {

List<Email> emails;
Integer currentPage;
Integer totalPages;
Long totalElements;
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import com.amigoscode.domain.provider.PageProvider;

import org.springframework.data.domain.Pageable;

import java.util.List;
import java.util.Optional;

public interface OrderRepository {
Expand All @@ -16,5 +18,6 @@ public interface OrderRepository {

void removeById(Integer id);

List<Order> findByEmailId(Integer id);

}
Loading

0 comments on commit 702197b

Please sign in to comment.