Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add max amount of tickets per customer for product families #506

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
10 changes: 10 additions & 0 deletions src/main/java/ch/wisv/events/core/repository/TicketRepository.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,16 @@ public interface TicketRepository extends JpaRepository<Ticket, Integer> {
*/
List<Ticket> findAllByProductAndOwner(Product product, Customer owner);

/**
* Find all Ticket by Products and Customer.
*
* @param products of type List<Product></Product>
* @param owner of type Customer
*
* @return List
*/
List<Ticket> findAllByProductInAndOwner(List<Product> products, Customer owner);

/**
* Find all Ticket by Product.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import ch.wisv.events.core.model.product.Product;
import ch.wisv.events.core.repository.OrderRepository;
import ch.wisv.events.core.service.event.EventService;
import ch.wisv.events.core.service.product.ProductService;
import ch.wisv.events.core.service.ticket.TicketService;
import java.time.LocalDateTime;
import java.util.List;
Expand All @@ -31,6 +32,9 @@ public class OrderValidationServiceImpl implements OrderValidationService {
/** TicketService. */
private final TicketService ticketService;

/** ProductService. */
private final ProductService productService;

/** EventService. */
private final EventService eventService;

Expand All @@ -42,9 +46,10 @@ public class OrderValidationServiceImpl implements OrderValidationService {
* @param eventService of type EventService
*/
@Autowired
public OrderValidationServiceImpl(OrderRepository orderRepository, TicketService ticketService, EventService eventService) {
public OrderValidationServiceImpl(OrderRepository orderRepository, TicketService ticketService, ProductService productService, EventService eventService) {
this.orderRepository = orderRepository;
this.ticketService = ticketService;
this.productService = productService;
this.eventService = eventService;
}

Expand Down Expand Up @@ -80,16 +85,23 @@ public void assertOrderIsValidForCustomer(Order order, Customer customer) throws
continue;
}

int ticketSold = ticketService.getAllByProductAndCustomer(orderProduct.getProduct(), customer).size();
List<Product> relatedProducts = productService.getRelatedProducts(orderProduct.getProduct());

int ticketSold = ticketService.getAllByProductsAndCustomer(relatedProducts, customer).size();

ticketSold += reservationOrders.stream()
.mapToInt(reservationOrder -> reservationOrder.getOrderProducts().stream()
.filter(reservationOrderProduct -> orderProduct.getProduct().equals(reservationOrderProduct.getProduct()))
.filter(reservationOrderProduct -> relatedProducts.contains(reservationOrderProduct.getProduct()))
.mapToInt(reservationOrderProduct -> reservationOrderProduct.getAmount().intValue())
.sum()
).sum();

if (ticketSold + orderProduct.getAmount() > maxSoldPerCustomer) {
int tryingToOrder = order.getOrderProducts().stream()
.filter(relatedOrderProduct -> relatedProducts.contains(relatedOrderProduct.getProduct()))
.mapToInt(relatedOrderProduct -> relatedOrderProduct.getAmount().intValue())
.sum();

if (ticketSold + tryingToOrder > maxSoldPerCustomer) {
throw new OrderExceedCustomerLimitException(maxSoldPerCustomer - ticketSold);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,13 @@ public interface ProductService {
*/
List<Product> getPossibleParentProductsByProduct(Product product);

/**
* Get the parent, children, and sibling products, including the original product
*
* @return Collection of Products
*/
List<Product> getRelatedProducts(Product product);

/**
* Get Product by Key.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@
import ch.wisv.events.core.model.product.Product;
import ch.wisv.events.core.repository.ProductRepository;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.*;
import java.util.stream.Collectors;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
Expand Down Expand Up @@ -72,6 +70,28 @@ public List<Product> getPossibleParentProductsByProduct(Product product) {
.collect(Collectors.toList());
}

/**
* Get the parent, children, and sibling products, including the original product
*
* @return Collection of Products
*/
@Override
public List<Product> getRelatedProducts(Product product) {
List<Product> result = new ArrayList<>();
Product parent = product;
while (parent.getParentProduct() != null) {
parent = parent.getParentProduct();
}
Queue<Product> q = new LinkedList<>();
q.add(parent);
while (!q.isEmpty()) {
Product p = q.remove();
result.add(p);
q.addAll(p.getChildProducts());
}
return result;
}

/**
* Get Product by Key.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,16 @@ public interface TicketService {
*/
List<Ticket> getAllByProductAndCustomer(Product product, Customer customer);

/**
* Get all Ticket for one of multiple products and Customer.
*
* @param products of type List<Product></Product>
* @param customer of type Customer
*
* @return List of Tickets
*/
List<Ticket> getAllByProductsAndCustomer(List<Product> products, Customer customer);

/**
* Get all Ticket by a Product.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,19 @@ public List<Ticket> getAllByProductAndCustomer(Product product, Customer custome
return ticketRepository.findAllByProductAndOwner(product, customer);
}

/**
* Get all Ticket for one of multiple products and Customer.
*
* @param products of type List<Product></Product>
* @param customer of type Customer
*
* @return List of Tickets
*/
@Override
public List<Ticket> getAllByProductsAndCustomer(List<Product> products, Customer customer) {
return ticketRepository.findAllByProductInAndOwner(products, customer);
}

/**
* Get all Ticket by a Product.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,14 @@
import ch.wisv.events.core.service.event.EventService;
import ch.wisv.events.core.service.order.OrderValidationService;
import ch.wisv.events.core.service.order.OrderValidationServiceImpl;
import ch.wisv.events.core.service.product.ProductService;
import ch.wisv.events.core.service.ticket.TicketService;
import ch.wisv.events.core.util.VatRate;
import com.google.common.collect.ImmutableList;
import java.time.LocalDateTime;
import java.util.Collections;
import java.util.List;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
Expand All @@ -43,6 +46,10 @@ public class OrderValidationServiceImplTest extends ServiceTest {
@Mock
private TicketService ticketService;

/** ProductService. */
@Mock
private ProductService productService;

/** EventService. */
@Mock
private EventService eventService;
Expand All @@ -56,7 +63,7 @@ public class OrderValidationServiceImplTest extends ServiceTest {

@Before
public void setUp() {
orderValidationService = new OrderValidationServiceImpl(orderRepository, ticketService, eventService);
orderValidationService = new OrderValidationServiceImpl(orderRepository, ticketService, productService, eventService);

product = mock(Product.class);
when(product.getVatRate()).thenReturn(VatRate.VAT_HIGH);
Expand Down Expand Up @@ -229,8 +236,9 @@ public void assertOrderIsValidForCustomerExceedSold() throws Exception {
Order prevOrder = mock(Order.class);

when(product.getMaxSoldPerCustomer()).thenReturn(1);
when(productService.getRelatedProducts(product)).thenReturn(ImmutableList.of(product));
when(orderRepository.findAllByOwnerAndStatus(customer, OrderStatus.RESERVATION)).thenReturn(ImmutableList.of(prevOrder));
when(ticketService.getAllByProductAndCustomer(product, customer)).thenReturn(ImmutableList.of(mock(Ticket.class)));
when(ticketService.getAllByProductsAndCustomer(List.of(product), customer)).thenReturn(ImmutableList.of(mock(Ticket.class)));

thrown.expect(OrderExceedCustomerLimitException.class);
thrown.expectMessage("Customer limit exceeded (max 0 tickets allowed).");
Expand All @@ -249,8 +257,9 @@ public void assertOrderIsValidForCustomerExceedReservation() throws Exception {
when(prevOrder.getOrderProducts()).thenReturn(ImmutableList.of(prevOrderProduct));

when(product.getMaxSoldPerCustomer()).thenReturn(1);
when(productService.getRelatedProducts(product)).thenReturn(ImmutableList.of(product));
when(orderRepository.findAllByOwnerAndStatus(customer, OrderStatus.RESERVATION)).thenReturn(ImmutableList.of(prevOrder));
when(ticketService.getAllByProductAndCustomer(product, customer)).thenReturn(ImmutableList.of());
when(ticketService.getAllByProductsAndCustomer(List.of(product), customer)).thenReturn(ImmutableList.of());

thrown.expect(OrderExceedCustomerLimitException.class);
thrown.expectMessage("Customer limit exceeded (max 0 tickets allowed).");
Expand Down
Loading