-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #4 from KBTG-Kampus-ClassNest-SE-Java/story-4
Story 4
- Loading branch information
Showing
12 changed files
with
291 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,29 @@ | ||
package com.kampus.kbazaar.cart; | ||
|
||
import com.kampus.kbazaar.product.Product; | ||
import jakarta.persistence.*; | ||
import jakarta.validation.constraints.NotBlank; | ||
import jakarta.validation.constraints.NotEmpty; | ||
import jakarta.validation.constraints.Positive; | ||
import lombok.Data; | ||
|
||
@Entity(name = "cart") | ||
@Data | ||
public class Cart { | ||
private int userID; | ||
@Id | ||
@GeneratedValue(strategy = GenerationType.IDENTITY) | ||
private Long id; | ||
|
||
private Product[] products; | ||
@NotBlank @NotEmpty private String username; | ||
|
||
public Cart(int userID, Product[] products) { | ||
this.userID = userID; | ||
this.products = products; | ||
@NotBlank @NotEmpty private String sku; | ||
|
||
@Positive private int quantity; | ||
|
||
public Cart() {} | ||
|
||
public Cart(String username, String sku, int quantity) { | ||
this.username = username; | ||
this.sku = sku; | ||
this.quantity = quantity; | ||
} | ||
} |
17 changes: 17 additions & 0 deletions
17
kbazaar/src/main/java/com/kampus/kbazaar/cart/CartController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,31 @@ | ||
package com.kampus.kbazaar.cart; | ||
|
||
import jakarta.validation.Valid; | ||
import org.springframework.http.HttpStatus; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.web.bind.annotation.*; | ||
|
||
@RestController | ||
@RequestMapping("/api/v1") | ||
public class CartController { | ||
|
||
private final CartService cartService; | ||
|
||
public CartController(CartService cartService) { | ||
this.cartService = cartService; | ||
} | ||
|
||
@GetMapping("/carts") | ||
public ResponseEntity getCart() { // NOSONAR | ||
return ResponseEntity.ok().build(); | ||
} | ||
|
||
@PostMapping("/carts/{username}/items") | ||
public ResponseEntity<CartResponse> addCart( | ||
@PathVariable("username") String userName, | ||
@RequestBody @Valid CartRequest cartRequest) { | ||
|
||
CartResponse cartResponse = cartService.addCart(userName, cartRequest); | ||
return ResponseEntity.status(HttpStatus.CREATED).body(cartResponse); | ||
} | ||
} |
13 changes: 13 additions & 0 deletions
13
kbazaar/src/main/java/com/kampus/kbazaar/cart/CartRepository.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package com.kampus.kbazaar.cart; | ||
|
||
import java.util.List; | ||
import java.util.Optional; | ||
import org.springframework.data.jpa.repository.JpaRepository; | ||
import org.springframework.stereotype.Repository; | ||
|
||
@Repository | ||
public interface CartRepository extends JpaRepository<Cart, Long> { | ||
Optional<Cart> findByUsernameAndSku(String username, String sku); | ||
|
||
List<Cart> findAllByUsername(String username); | ||
} |
5 changes: 5 additions & 0 deletions
5
kbazaar/src/main/java/com/kampus/kbazaar/cart/CartRequest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
package com.kampus.kbazaar.cart; | ||
|
||
import jakarta.validation.constraints.*; | ||
|
||
public record CartRequest(@NotEmpty String productSku, @Positive int quantity) {} |
11 changes: 11 additions & 0 deletions
11
kbazaar/src/main/java/com/kampus/kbazaar/cart/CartResponse.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package com.kampus.kbazaar.cart; | ||
|
||
import com.kampus.kbazaar.product.ProductResponseWithDiscount; | ||
import java.math.BigDecimal; | ||
import java.util.List; | ||
|
||
public record CartResponse( | ||
String username, | ||
List<ProductResponseWithDiscount> products, | ||
BigDecimal totalPrice, | ||
int totalDiscount) {} |
87 changes: 87 additions & 0 deletions
87
kbazaar/src/main/java/com/kampus/kbazaar/cart/CartService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
package com.kampus.kbazaar.cart; | ||
|
||
import com.kampus.kbazaar.product.Product; | ||
import com.kampus.kbazaar.product.ProductResponse; | ||
import com.kampus.kbazaar.product.ProductResponseWithDiscount; | ||
import com.kampus.kbazaar.product.ProductService; | ||
import com.kampus.kbazaar.shopper.ShopperResponse; | ||
import com.kampus.kbazaar.shopper.ShopperService; | ||
import jakarta.transaction.Transactional; | ||
import java.math.BigDecimal; | ||
import java.util.ArrayList; | ||
import java.util.List; | ||
import java.util.Optional; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.stereotype.Service; | ||
|
||
@Service | ||
public class CartService { | ||
|
||
private final CartRepository cartRepository; | ||
private final ShopperService shopperService; | ||
private final ProductService productService; | ||
|
||
@Autowired | ||
public CartService( | ||
CartRepository cartRepository, | ||
ShopperService shopperService, | ||
ProductService productService) { | ||
this.cartRepository = cartRepository; | ||
this.shopperService = shopperService; | ||
this.productService = productService; | ||
} | ||
|
||
@Transactional | ||
public CartResponse addCart(String userName, CartRequest cartRequest) { | ||
ShopperResponse shopperResponse = shopperService.getByUsername(userName); | ||
ProductResponse productResponse = productService.getBySku(cartRequest.productSku()); | ||
|
||
Optional<Cart> cartOptional = | ||
cartRepository.findByUsernameAndSku( | ||
shopperResponse.username(), productResponse.sku()); | ||
|
||
if (cartOptional.isEmpty()) { | ||
cartRepository.save( | ||
new Cart( | ||
shopperResponse.username(), | ||
productResponse.sku(), | ||
cartRequest.quantity())); | ||
} else { | ||
Cart cart = cartOptional.get(); | ||
cart.setQuantity(cartRequest.quantity()); | ||
cartRepository.save(cart); | ||
} | ||
|
||
List<ProductResponseWithDiscount> productList = new ArrayList<>(); | ||
BigDecimal totalPrice = BigDecimal.ZERO; | ||
|
||
List<Cart> cartList = cartRepository.findAllByUsername(userName); | ||
|
||
for (Cart cart : cartList) { | ||
ProductResponse productServiceBySku = productService.getBySku(cart.getSku()); | ||
Product p = | ||
new Product( | ||
productServiceBySku.id(), | ||
productServiceBySku.name(), | ||
productServiceBySku.sku(), | ||
productServiceBySku.price(), | ||
cart.getQuantity()); | ||
BigDecimal finalPrice = | ||
productServiceBySku.price().multiply(new BigDecimal(cart.getQuantity())); | ||
productList.add( | ||
new ProductResponseWithDiscount( | ||
p.getName(), | ||
p.getSku(), | ||
p.getPrice(), | ||
cart.getQuantity(), | ||
0, | ||
finalPrice)); | ||
|
||
BigDecimal total = | ||
productServiceBySku.price().multiply(new BigDecimal(cart.getQuantity())); | ||
totalPrice = totalPrice.add(total); | ||
} | ||
|
||
return new CartResponse(userName, productList, totalPrice, 0); | ||
} | ||
} |
11 changes: 11 additions & 0 deletions
11
kbazaar/src/main/java/com/kampus/kbazaar/product/ProductResponseWithDiscount.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package com.kampus.kbazaar.product; | ||
|
||
import java.math.BigDecimal; | ||
|
||
public record ProductResponseWithDiscount( | ||
String name, | ||
String sku, | ||
BigDecimal price, | ||
int quantity, | ||
int discount, | ||
BigDecimal finalPrice) {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
-- Smartphones | ||
INSERT INTO cart (username, sku, quantity) VALUES ('GeekChic','MOBILE-APPLE-IPHONE-12-PRO', 1) ON CONFLICT DO NOTHING; | ||
|
||
INSERT INTO cart (username, sku, quantity) VALUES ('GeekChic','BEV-COCA-COLA', 1) ON CONFLICT DO NOTHING; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
DROP TABLE IF EXISTS cart; | ||
|
||
CREATE TABLE IF NOT EXISTS cart ( | ||
id SERIAL PRIMARY KEY, | ||
username VARCHAR(255) NOT NULL, | ||
sku VARCHAR(255) NOT NULL, | ||
quantity INT NOT NULL | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
75 changes: 75 additions & 0 deletions
75
kbazaar/src/test/java/com/kampus/kbazaar/cart/CartServiceTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
package com.kampus.kbazaar.cart; | ||
|
||
import static org.mockito.ArgumentMatchers.*; | ||
import static org.mockito.Mockito.*; | ||
|
||
import com.kampus.kbazaar.product.ProductResponse; | ||
import com.kampus.kbazaar.product.ProductService; | ||
import com.kampus.kbazaar.shopper.ShopperResponse; | ||
import com.kampus.kbazaar.shopper.ShopperService; | ||
import java.math.BigDecimal; | ||
import java.util.List; | ||
import java.util.Optional; | ||
import org.junit.jupiter.api.Assertions; | ||
import org.junit.jupiter.api.Test; | ||
import org.junit.jupiter.api.extension.ExtendWith; | ||
import org.mockito.InjectMocks; | ||
import org.mockito.Mock; | ||
import org.mockito.junit.jupiter.MockitoExtension; | ||
|
||
@ExtendWith(MockitoExtension.class) | ||
public class CartServiceTest { | ||
@InjectMocks private CartService cartService; | ||
@Mock private CartRepository cartRepository; | ||
@Mock private ShopperService shopperService; | ||
@Mock private ProductService productService; | ||
|
||
@Test | ||
public void addNewCartSuccess() { | ||
CartRequest cartRequest = new CartRequest("MOBILE-LG-VELVET", 6); | ||
String userName = "GeekChic"; | ||
String sku = "MOBILE-LG-VELVET"; | ||
|
||
Cart cart = new Cart(userName, sku, 6); | ||
ProductResponse productResponse = | ||
new ProductResponse(1L, "apple", sku, new BigDecimal("1000"), 10); | ||
|
||
when(cartRepository.findByUsernameAndSku(any(), any())).thenReturn(Optional.empty()); | ||
when(shopperService.getByUsername(userName)) | ||
.thenReturn(new ShopperResponse(1L, userName, "email")); | ||
when(productService.getBySku(sku)).thenReturn(productResponse); | ||
when(cartRepository.save(any())).thenReturn(cart); | ||
when(cartRepository.findAllByUsername(userName)).thenReturn(List.of(cart)); | ||
|
||
CartResponse cartResponse = cartService.addCart(userName, cartRequest); | ||
|
||
Assertions.assertEquals(cartResponse.totalPrice(), new BigDecimal("6000")); | ||
Assertions.assertEquals(userName, cartResponse.username()); | ||
Assertions.assertEquals(sku, cartResponse.products().get(0).sku()); | ||
|
||
verify(cartRepository, times(1)).save(any()); | ||
} | ||
|
||
@Test | ||
public void updateOldCartSuccess() { | ||
CartRequest cartRequest = new CartRequest("MOBILE-LG-VELVET", 6); | ||
String userName = "GeekChic"; | ||
String sku = "MOBILE-LG-VELVET"; | ||
|
||
Cart cart = new Cart(userName, sku, 1); | ||
ProductResponse productResponse = | ||
new ProductResponse(1L, "apple", sku, new BigDecimal("1000"), 1); | ||
|
||
when(cartRepository.findByUsernameAndSku(any(), any())).thenReturn(Optional.of(cart)); | ||
when(shopperService.getByUsername(userName)) | ||
.thenReturn(new ShopperResponse(1L, userName, "email")); | ||
when(productService.getBySku(sku)).thenReturn(productResponse); | ||
when(cartRepository.save(any())).thenReturn(cart); | ||
when(cartRepository.findAllByUsername(userName)).thenReturn(List.of(cart)); | ||
|
||
CartResponse cartResponse = cartService.addCart(userName, cartRequest); | ||
|
||
Assertions.assertEquals(cartResponse.totalPrice(), new BigDecimal("6000")); | ||
verify(cartRepository, times(1)).save(any()); | ||
} | ||
} |