본문 바로가기
Clozet [프로젝트]

[프로젝트] 물품 장바구니,구매 예외처리하기

by ungyuun 2023. 10. 29.

상품을 등록할때 상품이 몇개있는지 재고를 등록한다. 이전에는 재고에 따른 구매 로직을 처리하지 않아 이번에 추가하였다. 장바구니로 등록, 구매창 이동, 장바구니에서 구매 선택, 물품 구매 에 예외처리를 해줘야하기때문에 공통 컴포넌트를 작성할 필요가 있었다.

 

 

const [isOpen, setIsOpen] = useState(false);
const [stock,setStock]=useState();

const onToggleModal = () => {
      setIsOpen((prev) => !prev);
};
    

{isOpen && (
	<StockModal stock={stock} onToggleModal={onToggleModal} />
)}

모달을 띄우기 위해, isOpen이 true일때 StockModal 컴포넌트를 화면에 렌더링한다.

 

import { Modal } from "antd";

const StockModal = ({stock,onToggleModal}) => {
    return(
        <Modal title="재고 부족 알림" visible={true} onOk={onToggleModal} onCancel={onToggleModal}>
            {stock.map((stocks,idx)=>(
                <div>
                    <div>{stocks.title} 제품의 {stocks.size} 사이즈는 재고부족입니다</div>
                    <div>남은재고 : {stocks.amount}</div>
                </div>
            ))}
        </Modal>
    )
}

export default StockModal;

 

모달 컴포넌트의 내용이다.

 

다음은 재고를 처리하여 구매, 장바구니 작업을 할수있는지 판별하는 주요 컴포넌트이다 

 

import axiosInstance from "../pages/common/AxiosInstance";

const CheckStock = (errorCallback,product,location) => {
    console.log(product)
    return new Promise((resolve, reject) => {
        axiosInstance.post(`${process.env.PUBLIC_URL}/cart/check`,product,{
            params: {
                pathname: location.pathname,
            },
            }).then((response) => {
                resolve();
            }).catch((error) => {
                errorCallback(error.response.data);
                reject(error);
            });
    })
}

export default CheckStock;

axios 요청을 보내고, 요청이 성공하면 다음 로직을 수행하는데, 요청이 실패하면 콜백함수로 재고가 없는 제품의 정보를 전달하고, 모달에 props를 넘겨 랜더링한다.

const errorCallback = (x) =>{
      setStock(x)
      setIsOpen(true)
    }

 

다음은 스프링부트에서 구현한 서버의 코드이다

 

@PostMapping("/check")
    public ResponseEntity<?> checkStock(@RequestBody List<CartDto> cartDtoList) throws Exception {

        List<CartDto> isNotStock= new ArrayList<>();
        try {
            for (CartDto cartDto : cartDtoList){
                CartDto notStock = productService.checkStock(cartDto);
                if (notStock != null) {
                    isNotStock.add(notStock);
                }
            }
            if (!isNotStock.isEmpty())
                return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(isNotStock);
            return new ResponseEntity<>(HttpStatus.OK);
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("잘못된 요청: " + e.getMessage());
        }
    }

 

받아온 상품의 정보와 상품의 재고를 비교한다. 구매하려는 물품이 재고의 개수보다 적은경우, 200코드를 리턴하지만, 구매하려는 물품이 재고의 개수보다 많은경우, 400에러와 문제있는 상품의 정보를 리턴한다. 

 

@Override
    public CartDto checkStock(CartDto cartDto) {

        Product product = productRepository.findByProdNo(cartDto.getProdNo());
        List<ProductDetail> productDetail = product.getProductDetail();
        for (ProductDetail detail : productDetail){
            if (detail.getAmount() < cartDto.getAmount()){
                cartDto.setAmount(detail.getAmount());
                return cartDto;
            }
        }
        return null;
    }

재고가 10개밖에 없는데 11개를 사려고하면  구매하려는 제품의 재고가 없다는 모달을 띄워주게된다.

 

 

성공적으로 장바구니에 들어간 모습이다.