diff --git a/build.gradle b/build.gradle index 470b3681..d16e3748 100644 --- a/build.gradle +++ b/build.gradle @@ -64,7 +64,7 @@ dependencies { testImplementation 'org.springframework.boot:spring-boot-starter-test' testImplementation 'de.flapdoodle.embed:de.flapdoodle.embed.mongo' testImplementation 'org.mockito:mockito-core:4.8.0' - implementation 'io.github.lotteon-maven:blooming-blooms-utils:202312271442' + implementation 'io.github.lotteon-maven:blooming-blooms-utils:202312280417' testImplementation 'com.github.tomakehurst:wiremock:2.27.2' } diff --git a/src/main/java/kr/bb/product/domain/product/adapter/out/mongo/ProductCommandRepository.java b/src/main/java/kr/bb/product/domain/product/adapter/out/mongo/ProductCommandRepository.java index e4672691..00ef7c66 100644 --- a/src/main/java/kr/bb/product/domain/product/adapter/out/mongo/ProductCommandRepository.java +++ b/src/main/java/kr/bb/product/domain/product/adapter/out/mongo/ProductCommandRepository.java @@ -6,7 +6,9 @@ import kr.bb.product.domain.product.application.port.out.ProductCommandOutPort; import kr.bb.product.domain.product.entity.Product; import kr.bb.product.domain.product.entity.ProductSaleStatus; +import kr.bb.product.domain.product.mapper.ProductCommand.ProductUpdate; import kr.bb.product.domain.product.mapper.ProductCommand.UpdateSubscriptionProduct; +import kr.bb.product.domain.tag.entity.Tag; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.data.mongodb.core.BulkOperations; @@ -67,19 +69,25 @@ public void updateProductSaleCount(List newOrderEvent) { } @Override - public void updateProductSaleStatus(Product product) { + public void updateProductSaleStatus(String productId, ProductUpdate productRequestData) { mongoTemplate.updateFirst( - Query.query(Criteria.where("_id").is(product.getProductId())), - Update.update("is_deleted", true) - .set("product_sale_status", ProductSaleStatus.DISCONTINUED), + Query.query(Criteria.where("_id").is(productId)), + Update.update("is_deleted", true).set("product_sale_status", ProductSaleStatus.DELETED), Product.class); } @Override - public void updateProductSaleStatus(Product product, ProductSaleStatus productSaleStatus) { + public void updateProductSaleStatus( + String productId, ProductUpdate productRequestData, List tags) { mongoTemplate.updateFirst( - Query.query(Criteria.where("_id").is(product.getProductId())), - Update.update("product_sale_status", productSaleStatus), + Query.query(Criteria.where("_id").is(productId)), + Update.update("product_sale_status", productRequestData.getProductSaleStatus()) + .set("tag", tags) + .set("product_summary", productRequestData.getProductSummary()) + .set("product_price", productRequestData.getProductPrice()) + .set("product_thumbnail", productRequestData.getProductThumbnail()) + .set("product_name", productRequestData.getProductName()) + .set("product_description_image", productRequestData.getProductDescriptionImage()), Product.class); } } diff --git a/src/main/java/kr/bb/product/domain/product/adapter/out/mongo/ProductMongoRepository.java b/src/main/java/kr/bb/product/domain/product/adapter/out/mongo/ProductMongoRepository.java index 5f1eca6d..b5b1e492 100644 --- a/src/main/java/kr/bb/product/domain/product/adapter/out/mongo/ProductMongoRepository.java +++ b/src/main/java/kr/bb/product/domain/product/adapter/out/mongo/ProductMongoRepository.java @@ -3,8 +3,6 @@ import java.util.List; import java.util.Optional; import kr.bb.product.domain.product.entity.Product; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; import org.springframework.data.mongodb.repository.MongoRepository; import org.springframework.data.mongodb.repository.Query; @@ -12,13 +10,6 @@ public interface ProductMongoRepository extends MongoRepository @Query("{ '_id' : ?0 }") Optional findByProductId(String productId); - @Query( - "{ 'category.categoryId' : ?0, 'product_sale_status' : 'SALE', 'is_subscription' : false }") - Page findByCategoryId(Long categoryId, Pageable pageable); - - @Query("{ 'tag.tagId' : ?0, 'product_sale_status' : 'SALE', 'is_subscription' : false}") - Page findProductsByTagId(Long tagId, Pageable pageable); - @Query("{'store_id': ?0}") List findProductByStoreId(Long storeId); diff --git a/src/main/java/kr/bb/product/domain/product/adapter/out/mongo/ProductQueryRepository.java b/src/main/java/kr/bb/product/domain/product/adapter/out/mongo/ProductQueryRepository.java index 89386312..973fe6d4 100644 --- a/src/main/java/kr/bb/product/domain/product/adapter/out/mongo/ProductQueryRepository.java +++ b/src/main/java/kr/bb/product/domain/product/adapter/out/mongo/ProductQueryRepository.java @@ -10,7 +10,6 @@ import kr.bb.product.domain.product.entity.ProductSaleStatus; import kr.bb.product.domain.product.mapper.ProductCommand; import kr.bb.product.domain.product.mapper.ProductCommand.SelectOption; -import kr.bb.product.exception.errors.ProductNotFoundException; import lombok.AccessLevel; import lombok.AllArgsConstructor; import lombok.Builder; @@ -93,7 +92,7 @@ public Page findProductsByCategory(Long categoryId, Long storeId, Pagea Query query = new Query(); if (storeId != null) query.addCriteria(Criteria.where("store_id").is(storeId)); query.addCriteria(Criteria.where("category.categoryId").is(categoryId)); - query.addCriteria(Criteria.where("product_sale_status").is(ProductSaleStatus.SALE)); + query.addCriteria(Criteria.where("product_sale_status").ne(ProductSaleStatus.DELETED)); query.with(pageable); List products = mongoTemplate.find(query, Product.class); return PageableExecutionUtils.getPage( @@ -107,7 +106,7 @@ public Page findProductsByTag(Long tagId, Long categoryId, Pageable pag Query query = new Query(); query.addCriteria(Criteria.where("tag.tagId").is(tagId)); if (categoryId != null) query.addCriteria(Criteria.where("category.categoryId").is(categoryId)); - query.addCriteria(Criteria.where("product_sale_status").is(ProductSaleStatus.SALE)); + query.addCriteria(Criteria.where("product_sale_status").ne(ProductSaleStatus.DELETED)); query.with(pageable); List products = mongoTemplate.find(query, Product.class); @@ -119,9 +118,7 @@ public Page findProductsByTag(Long tagId, Long categoryId, Pageable pag @Override public Product findByProductId(String productId) { - return productMongoRepository - .findByProductId(productId) - .orElseThrow(ProductNotFoundException::new); + return mongoTemplate.findOne(Query.query(Criteria.where("_id").is(productId)), Product.class); } @Override diff --git a/src/main/java/kr/bb/product/domain/product/application/port/in/ProductCommandInputPort.java b/src/main/java/kr/bb/product/domain/product/application/port/in/ProductCommandInputPort.java index 9a5e675d..9b3d2506 100644 --- a/src/main/java/kr/bb/product/domain/product/application/port/in/ProductCommandInputPort.java +++ b/src/main/java/kr/bb/product/domain/product/application/port/in/ProductCommandInputPort.java @@ -10,7 +10,6 @@ import kr.bb.product.domain.product.application.port.out.ProductCommandOutPort; import kr.bb.product.domain.product.application.port.out.ProductQueryOutPort; import kr.bb.product.domain.product.application.usecase.ProductCommandUseCase; -import kr.bb.product.domain.product.entity.Product; import kr.bb.product.domain.product.entity.ProductSaleStatus; import kr.bb.product.domain.product.infrastructure.message.ProductSQSPublisher; import kr.bb.product.domain.product.mapper.ProductCommand; @@ -54,8 +53,8 @@ private List getFlowers( } @NotNull - private List getTags(ProductCommand.ProductRegister productRequestData) { - return tagRepository.findAllById(productRequestData.getProductTag()); + private List getTags(List productRequestData) { + return tagRepository.findAllById(productRequestData); } private Category getCategory(ProductCommand.ProductRegister productRequestData) { @@ -72,18 +71,19 @@ private Category getCategory(ProductCommand.ProductRegister productRequestData) */ @Override @Transactional - public void updateProductSaleStatus( + public void updateProduct( String productId, ProductCommand.ProductUpdate productRequestData) { - Product product = productQueryOutPort.findByProductId(productId); + List tags = getTags(productRequestData.getProductTag()); + if (productRequestData.getProductSaleStatus().equals(ProductSaleStatus.DELETED)) { - productCommandOutPort.updateProductSaleStatus(product); + productCommandOutPort.updateProductSaleStatus(productId, productRequestData); } else if (productRequestData.getProductSaleStatus().equals(ProductSaleStatus.SALE)) { // sqs 재입고 알림 조회 요청 publishMessageToSQS.publishProductResaleNotificationCheckQueue( - productId, product.getProductName()); - productCommandOutPort.updateProductSaleStatus(product, productRequestData.getProductSaleStatus()); + productId, productRequestData.getProductName()); + productCommandOutPort.updateProductSaleStatus(productId, productRequestData, tags); } else { - productCommandOutPort.updateProductSaleStatus(product, productRequestData.getProductSaleStatus()); + productCommandOutPort.updateProductSaleStatus(productId, productRequestData, tags); } } @@ -96,7 +96,7 @@ public void updateProductSaleStatus( @Transactional public void createProduct(ProductCommand.ProductRegister productRequestData) { Category category = getCategory(productRequestData); - List tags = getTags(productRequestData); + List tags = getTags(productRequestData.getProductTag()); ProductFlowersRequestData representativeFlower = productRequestData.getRepresentativeFlower(); List flowers = getFlowers(productRequestData, representativeFlower); diff --git a/src/main/java/kr/bb/product/domain/product/application/port/in/ProductQueryInputPort.java b/src/main/java/kr/bb/product/domain/product/application/port/in/ProductQueryInputPort.java index d658c712..3d6c4180 100644 --- a/src/main/java/kr/bb/product/domain/product/application/port/in/ProductQueryInputPort.java +++ b/src/main/java/kr/bb/product/domain/product/application/port/in/ProductQueryInputPort.java @@ -75,7 +75,8 @@ private static Pageable getPageable(Pageable pageable, ProductCommand.SortOption return PageRequest.of( pageable.getPageNumber(), pageable.getPageSize(), - Sort.by(direction, sortOption.getSortOption())); + Sort.by(Direction.DESC, "product_sale_status") + .and(Sort.by(direction, sortOption.getSortOption()))); } private static List getProduct(Page byCategory) { diff --git a/src/main/java/kr/bb/product/domain/product/application/port/out/ProductCommandOutPort.java b/src/main/java/kr/bb/product/domain/product/application/port/out/ProductCommandOutPort.java index 1c47ffb0..51eadf6c 100644 --- a/src/main/java/kr/bb/product/domain/product/application/port/out/ProductCommandOutPort.java +++ b/src/main/java/kr/bb/product/domain/product/application/port/out/ProductCommandOutPort.java @@ -4,8 +4,9 @@ import bloomingblooms.domain.review.ReviewRegisterEvent; import java.util.List; import kr.bb.product.domain.product.entity.Product; -import kr.bb.product.domain.product.entity.ProductSaleStatus; import kr.bb.product.domain.product.mapper.ProductCommand; +import kr.bb.product.domain.product.mapper.ProductCommand.ProductUpdate; +import kr.bb.product.domain.tag.entity.Tag; public interface ProductCommandOutPort { void createProduct(Product product); @@ -16,7 +17,7 @@ public interface ProductCommandOutPort { void updateProductSaleCount(List newOrderEvent); - void updateProductSaleStatus(Product product); + void updateProductSaleStatus(String productId, ProductUpdate productRequestData); - void updateProductSaleStatus(Product product, ProductSaleStatus productSaleStatus); + void updateProductSaleStatus(String productId, ProductUpdate productRequestData, List tags); } diff --git a/src/main/java/kr/bb/product/domain/product/application/usecase/ProductCommandUseCase.java b/src/main/java/kr/bb/product/domain/product/application/usecase/ProductCommandUseCase.java index b3b00dea..2d28ef11 100644 --- a/src/main/java/kr/bb/product/domain/product/application/usecase/ProductCommandUseCase.java +++ b/src/main/java/kr/bb/product/domain/product/application/usecase/ProductCommandUseCase.java @@ -6,7 +6,7 @@ import kr.bb.product.domain.product.mapper.ProductCommand; public interface ProductCommandUseCase { - void updateProductSaleStatus(String productId, ProductCommand.ProductUpdate productRequestData); + void updateProduct(String productId, ProductCommand.ProductUpdate productRequestData); void createProduct(ProductCommand.ProductRegister productRequestData); diff --git a/src/main/java/kr/bb/product/domain/product/infrastructure/http/api/ProductRestController.java b/src/main/java/kr/bb/product/domain/product/infrastructure/http/api/ProductRestController.java index 22c48163..1bac9cfe 100644 --- a/src/main/java/kr/bb/product/domain/product/infrastructure/http/api/ProductRestController.java +++ b/src/main/java/kr/bb/product/domain/product/infrastructure/http/api/ProductRestController.java @@ -150,7 +150,7 @@ public void createProduct( public void updateProductSaleStatus( @PathVariable String productId, @RequestBody ProductCommand.ProductUpdate productRequestData) { - productCommandUseCase.updateProductSaleStatus(productId, productRequestData); + productCommandUseCase.updateProduct(productId, productRequestData); } /** diff --git a/src/main/java/kr/bb/product/domain/product/mapper/ProductCommand.java b/src/main/java/kr/bb/product/domain/product/mapper/ProductCommand.java index c79bb00f..7f067b26 100644 --- a/src/main/java/kr/bb/product/domain/product/mapper/ProductCommand.java +++ b/src/main/java/kr/bb/product/domain/product/mapper/ProductCommand.java @@ -233,10 +233,7 @@ public static class ProductUpdate { private String productThumbnail; private Long productPrice; private ProductSaleStatus productSaleStatus; - private Long categoryId; private List productTag; - private ProductFlowersRequestData representativeFlower; - private List flowers; } @Getter diff --git a/src/test/java/kr/bb/product/domain/product/application/port/in/ProductCommandInputPortTest.java b/src/test/java/kr/bb/product/domain/product/application/port/in/ProductCommandInputPortTest.java index 412f8e7c..66e8af17 100644 --- a/src/test/java/kr/bb/product/domain/product/application/port/in/ProductCommandInputPortTest.java +++ b/src/test/java/kr/bb/product/domain/product/application/port/in/ProductCommandInputPortTest.java @@ -3,14 +3,13 @@ import static org.assertj.core.api.AssertionsForClassTypes.assertThat; import static org.junit.jupiter.api.Assertions.*; -import com.amazonaws.services.sqs.model.AmazonSQSException; import java.util.List; import kr.bb.product.domain.product.adapter.out.mongo.ProductMongoRepository; import kr.bb.product.domain.product.entity.Product; +import kr.bb.product.domain.product.entity.ProductSaleStatus; import kr.bb.product.domain.product.mapper.ProductCommand; import kr.bb.product.domain.product.mapper.ProductCommand.ProductUpdate; import kr.bb.product.domain.product.mapper.ProductCommand.SubscriptionProduct; -import kr.bb.product.domain.product.entity.ProductSaleStatus; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -92,21 +91,23 @@ void updateSubscriptionProduct() { @Test @DisplayName("상품 판매 상태 수정") void updateProductSaleStatus() { + productMongoRepository.deleteAll(); Product save = productMongoRepository.save( Product.builder() .productId("123") - .productSaleStatus(ProductSaleStatus.DISCONTINUED) + .productSaleStatus(ProductSaleStatus.SALE) .productName("name") .build()); ProductUpdate name = ProductUpdate.builder() - .productSaleStatus(ProductSaleStatus.SALE) - .productName("name") + .productSaleStatus(ProductSaleStatus.DISCONTINUED) + .productName("name1") + .productTag(List.of(1L)) .build(); - assertThrows( - AmazonSQSException.class, - () -> productCommandInputPort.updateProductSaleStatus("123", name)); + productCommandInputPort.updateProduct("123", name); + Product product = productMongoRepository.findByProductId("123").get(); + assertThat(product.getProductName()).isEqualTo(name.getProductName()); } } diff --git a/src/test/java/kr/bb/product/domain/product/application/port/in/ProductStoreInputPortTest.java b/src/test/java/kr/bb/product/domain/product/application/port/in/ProductStoreInputPortTest.java index b194511e..beecc06b 100644 --- a/src/test/java/kr/bb/product/domain/product/application/port/in/ProductStoreInputPortTest.java +++ b/src/test/java/kr/bb/product/domain/product/application/port/in/ProductStoreInputPortTest.java @@ -1,7 +1,9 @@ package kr.bb.product.domain.product.application.port.in; import static org.assertj.core.api.AssertionsForClassTypes.assertThat; +import static org.junit.jupiter.api.Assertions.assertThrows; +import com.amazonaws.services.sqs.model.AmazonSQSException; import java.util.ArrayList; import java.util.List; import kr.bb.product.domain.flower.mapper.FlowerCommand.ProductFlowersRequestData; @@ -10,6 +12,7 @@ import kr.bb.product.domain.product.entity.Product; import kr.bb.product.domain.product.entity.ProductSaleStatus; import kr.bb.product.domain.product.mapper.ProductCommand; +import kr.bb.product.domain.product.mapper.ProductCommand.ProductUpdate; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -62,12 +65,8 @@ private ProductCommand.ProductUpdate updateProductDiscontinued() { list.add(ProductFlowersRequestData.builder().flowerId(2L).flowerCount(2L).build()); return ProductCommand.ProductUpdate.builder() - .categoryId(1L) .productTag(tagList) .productSaleStatus(ProductSaleStatus.DISCONTINUED) - .representativeFlower( - ProductFlowersRequestData.builder().flowerCount(3L).flowerId(1L).build()) - .flowers(list) .productName("Example Product") .productSummary("Product Summary") .productDescriptionImage("image") @@ -88,12 +87,8 @@ private ProductCommand.ProductUpdate updateProductDeleted() { list.add(ProductFlowersRequestData.builder().flowerId(2L).flowerCount(2L).build()); return ProductCommand.ProductUpdate.builder() - .categoryId(1L) .productTag(tagList) .productSaleStatus(ProductSaleStatus.DELETED) - .representativeFlower( - ProductFlowersRequestData.builder().flowerCount(3L).flowerId(1L).build()) - .flowers(list) .productName("Example Product") .productSummary("Product Summary") .productDescriptionImage("image") @@ -131,7 +126,7 @@ void updateProductSaleStatusDeleted() { Product product = createProduct(); // Act - productStoreInputPort.updateProductSaleStatus(product.getProductId(), productRequestData); + productStoreInputPort.updateProduct(product.getProductId(), productRequestData); Product byProductId = productQueryOutPort.findByProductId(product.getProductId()); assertThat(byProductId.getProductSaleStatus()).isEqualTo(ProductSaleStatus.DISCONTINUED); } @@ -144,12 +139,30 @@ void updateProductSaleStatusNotDeleted() { Product product = createProduct(); // Act - productStoreInputPort.updateProductSaleStatus(product.getProductId(), productRequestData); + productStoreInputPort.updateProduct(product.getProductId(), productRequestData); Product byProductId = productQueryOutPort.findByProductId(product.getProductId()); - assertThat(byProductId.getProductSaleStatus()).isEqualTo(ProductSaleStatus.DISCONTINUED); + assertThat(byProductId.getProductSaleStatus()).isEqualTo(ProductSaleStatus.DELETED); assertThat(byProductId.getIsDeleted()).isEqualTo(true); } + @Test + @DisplayName("Update product sale status - ProductSaleStatus SALE") + void updateProductSaleStatusSALE() { + // Arrange + + ProductUpdate build = + ProductUpdate.builder() + .productTag(List.of(1L)) + .productSaleStatus(ProductSaleStatus.SALE) + .build(); + Product product = createProduct(); + + // Act + assertThrows( + AmazonSQSException.class, + () -> productStoreInputPort.updateProduct(product.getProductId(), build)); + } + private Product createProduct() { // Create and return a mock Product object productStoreInputPort.createProduct(getProductRequestData());