Skip to content

Commit

Permalink
Merge pull request #20 from leung018:order-service
Browse files Browse the repository at this point in the history
Order service part 3
  • Loading branch information
leung018 authored Dec 10, 2024
2 parents d900698 + fbd6105 commit 5e06efc
Show file tree
Hide file tree
Showing 12 changed files with 169 additions and 68 deletions.
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ dependencies {
implementation "org.springframework.boot:spring-boot-starter-security"
implementation 'io.jsonwebtoken:jjwt-api:0.12.6'
implementation "com.google.guava:guava:33.3.1-jre"
implementation "org.springframework.retry:spring-retry"
runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.12.6'
runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.12.6'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.leungcheng.spring_simple_backend;

import org.springframework.context.annotation.Configuration;
import org.springframework.retry.annotation.EnableRetry;

@EnableRetry
@Configuration
public class RetryConfig {}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.fasterxml.jackson.annotation.JsonProperty;
import com.leungcheng.spring_simple_backend.validation.ObjectValidator;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
Expand Down Expand Up @@ -71,6 +72,7 @@ public Builder toBuilder() {

@NotBlank private String name;

@Column(precision = 19, scale = 5)
@Min(0)
private BigDecimal price;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ public User.Builder toBuilder() {
@NotBlank private String password;

@Min(0)
@Column(precision = 19, scale = 10)
private BigDecimal balance;

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,35 +8,34 @@
import java.math.BigDecimal;
import java.util.Map;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

@Service
public class OrderService {
private final UserRepository userRepository;
private final ProductRepository productRepository;
private final OrderRepository orderRepository;

public OrderService(
UserRepository userRepository,
ProductRepository productRepository,
OrderRepository orderRepository) {
this.userRepository = userRepository;
this.productRepository = productRepository;
this.orderRepository = orderRepository;
private @Autowired UserRepository userRepository;
private @Autowired ProductRepository productRepository;
private @Autowired OrderRepository orderRepository;

public static class CreateOrderException extends IllegalArgumentException {
public CreateOrderException(String message) {
super(message);
}
}

@Retryable(noRetryFor = CreateOrderException.class)
@Transactional(isolation = Isolation.SERIALIZABLE)
public Order createOrder(String buyerUserId, PurchaseItems purchaseItems) {
User buyer =
getUser(buyerUserId)
.orElseThrow(() -> new IllegalArgumentException("Buyer does not exist"));
getUser(buyerUserId).orElseThrow(() -> new CreateOrderException("Buyer does not exist"));

BigDecimal totalCost = processPurchaseItems(purchaseItems);

if (buyer.getBalance().compareTo(totalCost) < 0) {
throw new IllegalArgumentException("Insufficient balance");
throw new CreateOrderException("Insufficient balance");
}
saveNewBalance(buyer, buyer.getBalance().subtract(totalCost));

Expand All @@ -60,7 +59,7 @@ private Order addNewOrder(String buyerUserId, PurchaseItems purchaseItems) {
private BigDecimal processPurchaseItems(PurchaseItems purchaseItems) {
ImmutableMap<String, Integer> productIdToQuantity = purchaseItems.getProductIdToQuantity();
if (productIdToQuantity.isEmpty()) {
throw new IllegalArgumentException("Purchase items cannot be empty");
throw new CreateOrderException("Purchase items cannot be empty");
}

BigDecimal totalCost = BigDecimal.ZERO;
Expand All @@ -80,7 +79,7 @@ private BigDecimal processPurchaseItems(PurchaseItems purchaseItems) {

private void reduceProductStock(Product product, int purchaseQuantity) {
if (purchaseQuantity > product.getQuantity()) {
throw new IllegalArgumentException("Insufficient stock for product: " + product.getId());
throw new CreateOrderException("Insufficient stock for product: " + product.getId());
}
int newQuantity = product.getQuantity() - purchaseQuantity;
Product updatedProduct = product.toBuilder().quantity(newQuantity).build();
Expand All @@ -97,7 +96,6 @@ private void addProfitToSeller(Product product, int purchaseQuantity) {
private Product getProduct(String productId) {
return productRepository
.findById(productId)
.orElseThrow(
() -> new IllegalArgumentException("Product: " + productId + " does not exist"));
.orElseThrow(() -> new CreateOrderException("Product: " + productId + " does not exist"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

@Embeddable
public class PurchaseItems {
@ElementCollection
@ElementCollection(fetch = FetchType.EAGER)
@CollectionTable(
name = "purchase_items",
joinColumns = {@JoinColumn(name = "order_id", referencedColumnName = "id")})
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.leungcheng.spring_simple_backend.domain;

import static com.leungcheng.spring_simple_backend.testutil.CustomAssertions.assertBigDecimalEquals;
import static com.leungcheng.spring_simple_backend.testutil.DefaultBuilders.productBuilder;
import static com.leungcheng.spring_simple_backend.testutil.DefaultBuilders.userBuilder;

import java.math.BigDecimal;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class PrecisionTest {
private @Autowired ProductRepository productRepository;
private @Autowired UserRepository userRepository;

@Test
void shouldProductKeepPrecisionAfterSavingToRepository() {
Product product = productBuilder().price(new BigDecimal("123456.78912")).build();
productRepository.save(product);
Product savedProduct = productRepository.findById(product.getId()).orElseThrow();

assertBigDecimalEquals(product.getPrice(), savedProduct.getPrice());
}

@Test
void shouldUserKeepPrecisionAfterSavingToRepository() {
User user = userBuilder().balance(new BigDecimal("123456.78912")).build();
userRepository.save(user);
User savedUser = userRepository.findById(user.getId()).orElseThrow();

assertBigDecimalEquals(user.getBalance(), savedUser.getBalance());
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.leungcheng.spring_simple_backend.domain;

import static com.leungcheng.spring_simple_backend.testutil.DefaultBuilders.productBuilder;
import static org.junit.jupiter.api.Assertions.*;

import com.leungcheng.spring_simple_backend.validation.ObjectValidator;
Expand All @@ -8,14 +9,6 @@

class ProductTest {

private static Product.Builder productBuilder() {
return new Product.Builder()
.name("Default Product")
.price(new BigDecimal("0.1"))
.userId("user_01")
.quantity(1);
}

@Test
void shouldCreateProduct() {
Product product =
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,13 @@
package com.leungcheng.spring_simple_backend.domain;

import static com.leungcheng.spring_simple_backend.testutil.DefaultBuilders.userBuilder;
import static org.junit.jupiter.api.Assertions.*;

import com.leungcheng.spring_simple_backend.validation.ObjectValidator;
import java.math.BigDecimal;
import org.junit.jupiter.api.Test;

class UserTest {
private static User.Builder userBuilder() {
return new User.Builder()
.username("default_user")
.password("default_password")
.balance(new BigDecimal("1.0"));
}

@Test
void shouldCreateUser() {
User user =
Expand Down
Loading

0 comments on commit 5e06efc

Please sign in to comment.