Skip to content

Commit

Permalink
feature: get products in clothingSales api (#155)
Browse files Browse the repository at this point in the history
* feature: get products in clothingSales api

* chore: update swagger docs

* chore: delete unused
  • Loading branch information
hyunihs authored Sep 13, 2024
1 parent a91d2ef commit 392a11a
Show file tree
Hide file tree
Showing 6 changed files with 114 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.example.repick.domain.clothingSales.service.BagService;
import com.example.repick.domain.clothingSales.service.BoxService;
import com.example.repick.domain.clothingSales.service.ClothingSalesService;
import com.example.repick.domain.clothingSales.dto.GetSalesProductsByClothingSales;
import com.example.repick.global.page.DateCondition;
import com.example.repick.global.page.PageCondition;
import com.example.repick.global.page.PageResponse;
Expand Down Expand Up @@ -69,8 +70,23 @@ public SuccessResponse<List<GetPendingClothingSales>> getPendingClothingSales()
옷μž₯ 정리 톡합 쑰회: 판맀 쀑인 옷μž₯, μ‹ μ²­ μ™„λ£ŒμΌ λ‚΄λ¦Όμ°¨μˆœμœΌλ‘œ μ •λ ¬λ˜μ–΄ 리슀트둜 λ°˜ν™˜ν•©λ‹ˆλ‹€.
""")
@GetMapping("/selling")
public SuccessResponse<List<GetSellingClothingSales>> getSellingClothingSales() {
return SuccessResponse.success(clothingSalesService.getSellingClothingSales());
public SuccessResponse<List<GetSellingClothingSales>> getSellingClothingSalesList() {
return SuccessResponse.success(clothingSalesService.getSellingClothingSalesList());
}

@Operation(summary = "옷μž₯ κ°œλ³„ 보기: 옷μž₯ 정보")
@GetMapping("/selling/{clothingSalesId}")
public SuccessResponse<GetSellingClothingSales> getSellingClothingSales(@PathVariable Long clothingSalesId) {
return SuccessResponse.success(clothingSalesService.getSellingClothingSales(clothingSalesId));
}

@Operation(summary = "옷μž₯ κ°œλ³„ 보기: 옷μž₯ μƒν’ˆ ν˜„ν™©",
description = """
productState: selling, confirm-pending, sold-out, selling-end
""")
@GetMapping("/products/{clothingSalesId}/{productState}")
public SuccessResponse<List<GetSalesProductsByClothingSales>> getProductsByClothingSales(@PathVariable Long clothingSalesId, @PathVariable String productState) {
return SuccessResponse.success(clothingSalesService.getProductsByClothingSales(clothingSalesId, productState));
}

@Operation(summary = "수거: μƒν’ˆ 보기", description = """
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.example.repick.domain.clothingSales.dto;

import com.example.repick.domain.product.entity.Product;
import io.swagger.v3.oas.annotations.media.Schema;

public record GetSalesProductsByClothingSales(
@Schema(description = "μƒν’ˆ ID") Long productId,
@Schema(description = "μƒν’ˆ λΈŒλžœλ“œ") String productBrand,
@Schema(description = "μƒν’ˆλͺ…") String productName,
@Schema(description = "μƒν’ˆ 이미지") String productImageUrl,
@Schema(description = "μƒν’ˆ 가격") Long productPrice,
@Schema(description = "μ •μ‚°κΈˆ") Long settlementAmount
) {
public static GetSalesProductsByClothingSales from(Product product) {
return new GetSalesProductsByClothingSales(
product.getId(),
product.getBrandName(),
product.getProductName(),
product.getThumbnailImageUrl(),
product.getPrice(),
product.getSettlement()
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import com.example.repick.domain.clothingSales.repository.ClothingSalesRepository;
import com.example.repick.domain.clothingSales.repository.ClothingSalesStateRepository;
import com.example.repick.domain.clothingSales.validator.ClothingSalesValidator;
import com.example.repick.domain.clothingSales.dto.GetSalesProductsByClothingSales;
import com.example.repick.domain.product.entity.Product;
import com.example.repick.domain.product.entity.ProductOrder;
import com.example.repick.domain.product.entity.ProductOrderState;
Expand Down Expand Up @@ -106,41 +107,85 @@ public Boolean updateProductPrice(List<PostProductPrice> postProductPriceList) {
return true;
}

public List<GetSellingClothingSales> getSellingClothingSales() {
public List<GetSellingClothingSales> getSellingClothingSalesList() {
User user = userRepository.findByProviderId(SecurityContextHolder.getContext().getAuthentication().getName())
.orElseThrow(() -> new CustomException(USER_NOT_FOUND));

List<GetSellingClothingSales> sellingClothingSalesList = new ArrayList<>();
List<ClothingSales> clothingSalesList = clothingSalesRepository.findByUserAndClothingSalesState(user, ClothingSalesStateType.SELLING);

for (ClothingSales clothingSales : clothingSalesList) {
List<Product> productList = clothingSales.getProductList();
if(productList.isEmpty()) {
continue;
}
int remainingSalesDays = (int) ChronoUnit.DAYS.between(LocalDate.now(), clothingSales.getSalesStartDate().toLocalDate().plusDays(90));
int sellingQuantity = 0;
int pendingQuantity = 0;
int soldQuantity = 0;
for (Product product : productList) {
if (product.getProductState().equals(ProductStateType.SELLING)) {
sellingQuantity++;
} else if (product.getProductState().equals(ProductStateType.SOLD_OUT)) {
ProductOrder productOrder = productOrderRepository.findFirstByProductIdOrderByCreatedDateDesc(product.getId())
.orElseThrow(() -> new CustomException(INVALID_PRODUCT_ID));
if (productOrder.isConfirmed()) {
soldQuantity++;
} else {
pendingQuantity++;
}
sellingClothingSalesList.add(getSellingClothingSalesInfo(clothingSales));
}
return sellingClothingSalesList;
}

public GetSellingClothingSales getSellingClothingSales(Long clothingSalesId) {
User user = userRepository.findByProviderId(SecurityContextHolder.getContext().getAuthentication().getName())
.orElseThrow(() -> new CustomException(USER_NOT_FOUND));

ClothingSales clothingSales = clothingSalesRepository.findById(clothingSalesId)
.orElseThrow(() -> new CustomException(INVALID_CLOTHING_SALES_ID));

if(!clothingSales.getUser().getId().equals(user.getId())){
throw new CustomException(INVALID_CLOTHING_SALES_ID);
}

return getSellingClothingSalesInfo(clothingSales);
}


private GetSellingClothingSales getSellingClothingSalesInfo(ClothingSales clothingSales) {
List<Product> productList = clothingSales.getProductList();
if(productList.isEmpty()) {
return GetSellingClothingSales.of(clothingSales, clothingSales.getSalesStartDate().format(DateTimeFormatter.ofPattern("yyyy.MM.dd")), 0, 0, 0, 0);
}

int remainingSalesDays = (int) ChronoUnit.DAYS.between(LocalDate.now(), clothingSales.getSalesStartDate().toLocalDate().plusDays(90));
int sellingQuantity = 0;
int pendingQuantity = 0;
int soldQuantity = 0;

for (Product product : productList) {
if (product.getProductState().equals(ProductStateType.SELLING)) {
sellingQuantity++;
} else if (product.getProductState().equals(ProductStateType.SOLD_OUT)) {
ProductOrder productOrder = productOrderRepository.findFirstByProductIdOrderByCreatedDateDesc(product.getId())
.orElseThrow(() -> new CustomException(INVALID_PRODUCT_ID));
if (productOrder.isConfirmed()) {
soldQuantity++;
} else {
pendingQuantity++;
}
}
sellingClothingSalesList.add(GetSellingClothingSales.of(clothingSales, clothingSales.getSalesStartDate().format(DateTimeFormatter.ofPattern("yyyy.MM.dd")), remainingSalesDays, sellingQuantity, pendingQuantity, soldQuantity));
}
return sellingClothingSalesList;
return GetSellingClothingSales.of(clothingSales, clothingSales.getSalesStartDate().format(DateTimeFormatter.ofPattern("yyyy.MM.dd")), remainingSalesDays, sellingQuantity, pendingQuantity, soldQuantity);
}


@Transactional(readOnly = true)
public List<GetSalesProductsByClothingSales> getProductsByClothingSales(Long clothingSalesId, String productState) {
if (productState.equals("confirm-pending") || productState.equals("sold-out")) {
List<Product> products = productRepository.findByClothingSalesIdAndProductState(clothingSalesId, ProductStateType.SOLD_OUT);
boolean isConfirmed = productState.equals("sold-out");
return products.stream()
.filter(product -> {
ProductOrder productOrder = productOrderRepository.findFirstByProductIdOrderByCreatedDateDesc(product.getId())
.orElseThrow(() -> new CustomException(PRODUCT_ORDER_NOT_FOUND));
return productOrder.isConfirmed() == isConfirmed;
})
.map(GetSalesProductsByClothingSales::from)
.collect(Collectors.toList());
} else {
ProductStateType productStateType = ProductStateType.fromEngValue(productState);
List<Product> products = productRepository.findByClothingSalesIdAndProductState(clothingSalesId, productStateType);
return products.stream()
.map(GetSalesProductsByClothingSales::from)
.collect(Collectors.toList());
}
}


public GetProductListByClothingSales getProductsByClothingSalesId(Long clothingSalesId) {
User user = userRepository.findByProviderId(SecurityContextHolder.getContext().getAuthentication().getName())
.orElseThrow(() -> new CustomException(USER_NOT_FOUND));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ public SuccessResponse<PageResponse<List<GetProductCountClothingSales>>> getProd
return SuccessResponse.success(productService.getProductCountByClothingSales(type, userId, pageCondition));
}

@Operation(summary = "μœ μ € μƒν’ˆ ν˜„ν™©",
@Operation(summary = "μœ μ € μƒν’ˆ ν˜„ν™© (Admin API)",
description = """
productState: selling, sold-out, rejected, selling-end, kg-sell
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.example.repick.domain.product.repository;

import com.example.repick.domain.product.entity.Product;
import com.example.repick.domain.product.entity.ProductStateType;
import jakarta.persistence.LockModeType;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Lock;
Expand All @@ -9,11 +10,9 @@
import java.util.List;

public interface ProductRepository extends JpaRepository<Product, Long>, ProductRepositoryCustom {

List<Product> findProductByUserIdAndClothingSalesCount(Long userId, Integer clothingSalesCount);
Integer countByUserIdAndClothingSalesCount(Long userId, Integer clothingSalesCount);

@Lock(LockModeType.PESSIMISTIC_WRITE)
@Query("SELECT p FROM Product p WHERE p.id IN :ids")
List<Product> findAllByIdWithLock(List<Long> ids);

List<Product> findByClothingSalesIdAndProductState(Long clothingSalesId, ProductStateType productStateType);
}
Original file line number Diff line number Diff line change
Expand Up @@ -482,6 +482,7 @@ public PageResponse<List<GetProductCountClothingSales>> getProductCountByClothin
return PageResponse.of(pages.getContent(), pages.getTotalPages(), pages.getTotalElements());
}

@Transactional(readOnly = true)
public PageResponse<List<?>> getProductsByUserClothingSales(Long clothingSalesId, String productState, Boolean isExpired, PageCondition pageCondition) {
Page<?> pages;
if (productState.equals("kg-sell")) { // kg λ§€μž… μƒν’ˆ(리젝, λ§Œλ£Œλ˜μ—ˆμ„ 경우 kg λ§€μž… κ°€λŠ₯)
Expand Down

0 comments on commit 392a11a

Please sign in to comment.