|
7 | 7 | from rest_framework import serializers |
8 | 8 | from shop.product.models import Option, OptionGroup, Product |
9 | 9 |
|
| 10 | +# product 인당 한도(product_max_quantity_per_user)는 "이 유저가 이 상품(티켓)을 몇 개 살 수 있나" 축이라, |
| 11 | +# 옵션/그룹 인스턴스 개수(max_quantity_per_product 축, 1 OPR 아래 다수 OPOR)를 제한하지 않는다. |
| 12 | +# breakdown 에는 참고용으로 남기되 leftover_stock_per_user(= binding min) 계산에서는 제외한다. |
| 13 | +_LEFTOVER_PER_USER_EXCLUDED_KEYS = frozenset({"product_max_quantity_per_user"}) |
| 14 | + |
10 | 15 |
|
11 | 16 | def _min_ignoring_none(values: Iterable[int | None]) -> int | None: |
12 | 17 | return min(finite) if (finite := [v for v in values if v is not None]) else None |
13 | 18 |
|
14 | 19 |
|
| 20 | +def _leftover_stock_per_user(info: dict[str, int | None]) -> int | None: |
| 21 | + return _min_ignoring_none(v for k, v in info.items() if k not in _LEFTOVER_PER_USER_EXCLUDED_KEYS) |
| 22 | + |
| 23 | + |
15 | 24 | @dataclass(frozen=True) |
16 | 25 | class StockContext: |
17 | 26 | """Product 페이지에 등장하는 모든 product / option / group 의 점유 수량을 단일 stage 에서 prefetch 한 결과""" |
@@ -115,7 +124,7 @@ def get_leftover_stock_info(self, option: Option) -> dict[str, int | None]: |
115 | 124 | return self.context.get("stock_context", _EMPTY_STOCK_CONTEXT).option_leftover_info(option) |
116 | 125 |
|
117 | 126 | def get_leftover_stock_per_user(self, option: Option) -> int | None: |
118 | | - return _min_ignoring_none(self.get_leftover_stock_info(option).values()) |
| 127 | + return _leftover_stock_per_user(self.get_leftover_stock_info(option)) |
119 | 128 |
|
120 | 129 |
|
121 | 130 | class OptionGroupDto(serializers.ModelSerializer): |
@@ -148,7 +157,7 @@ def get_leftover_stock_info(self, group: OptionGroup) -> dict[str, int | None]: |
148 | 157 | return self.context.get("stock_context", _EMPTY_STOCK_CONTEXT).option_group_leftover_info(group) |
149 | 158 |
|
150 | 159 | def get_leftover_stock_per_user(self, group: OptionGroup) -> int | None: |
151 | | - return _min_ignoring_none(self.get_leftover_stock_info(group).values()) |
| 160 | + return _leftover_stock_per_user(self.get_leftover_stock_info(group)) |
152 | 161 |
|
153 | 162 |
|
154 | 163 | class ProductDto(serializers.ModelSerializer): |
|
0 commit comments