Skip to content

Commit 1d104f3

Browse files
committed
fix: 상품 카테고리에서 명시적으로 상품이 티켓인지 결정 여부를 설정할 수 있게 수정
1 parent b4e9135 commit 1d104f3

7 files changed

Lines changed: 49 additions & 4 deletions

File tree

app/admin_api/serializers/shop/products.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ class CategoryAdminSerializer(BaseAbstractSerializer, JsonSchemaSerializer, Nest
2121

2222
class Meta:
2323
model = Category
24-
fields = COMMON_ADMIN_FIELDS + ("group", "name", "priority")
24+
fields = COMMON_ADMIN_FIELDS + ("group", "name", "priority", "is_ticket")
2525
# group 은 NestedFieldSpec.parent_fk_name 으로 부모 인스턴스에서 주입되므로 입력 시 생략 가능.
2626
# validators=[] — auto UniqueTogetherValidator(group, name) 가 group 누락 시 required 로 막음.
2727
# DB unique constraint(uq__cat__grp_nm) 가 여전히 enforce.

app/shop/conftest.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ def staff_client(staff_user) -> APIClient:
114114
def product(db) -> Product:
115115
# category_group / category 는 Product 의 FK 체인을 만들기 위한 중간 단계 — 직접 참조하는 테스트가 생기는 시점에 별도 fixture 로 분리.
116116
category_group = CategoryGroup.objects.create(name="기본")
117-
category = Category.objects.create(group=category_group, name="티켓")
117+
category = Category.objects.create(group=category_group, name="티켓", is_ticket=True)
118118
return Product.objects.create(
119119
category=category,
120120
name="파이콘 한국 2026 티켓",

app/shop/order/serializers/dto.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ class Meta:
6565
model = OrderProductRelation
6666

6767
def get_scancode_url(self, obj: OrderProductRelation) -> str | None:
68-
if "티켓" not in obj.product.category.name:
68+
if not obj.product.category.is_ticket:
6969
return None
7070

7171
return urljoin(settings.BACKEND_DOMAIN, obj.scancode_path)

app/shop/order/test/serializers_test.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,27 @@ def test_order_product_relation_dto_scancode_url_none_for_non_ticket_category(cu
4545
}
4646

4747

48+
@override_settings(BACKEND_DOMAIN=_TEST_BACKEND_DOMAIN)
49+
@pytest.mark.django_db
50+
def test_order_product_relation_dto_scancode_url_follows_is_ticket_not_name(customer_user):
51+
# 노출 여부는 Category.is_ticket 으로만 결정된다 — 이름의 "티켓" 포함 여부와 무관.
52+
group = CategoryGroup.objects.create(name="기타")
53+
named_ticket_flag_off = Category.objects.create(group=group, name="옛 티켓", is_ticket=False)
54+
unnamed_flag_on = Category.objects.create(group=group, name="입장권", is_ticket=True)
55+
56+
flag_off_product = Product.objects.create(category=named_ticket_flag_off, name="옛 티켓", price=5000)
57+
flag_on_product = Product.objects.create(category=unnamed_flag_on, name="입장권", price=5000)
58+
order = Order.objects.create(user=customer_user, name="주문")
59+
flag_off_opr = OrderProductRelation.objects.create(order=order, product=flag_off_product, price=5000)
60+
flag_on_opr = OrderProductRelation.objects.create(order=order, product=flag_on_product, price=5000)
61+
62+
assert OrderProductRelationDto(instance=flag_off_opr).data["scancode_url"] is None
63+
assert (
64+
OrderProductRelationDto(instance=flag_on_opr).data["scancode_url"]
65+
== f"{_TEST_BACKEND_DOMAIN}{flag_on_opr.scancode_path}"
66+
)
67+
68+
4869
@override_settings(BACKEND_DOMAIN=_TEST_BACKEND_DOMAIN)
4970
@pytest.mark.django_db
5071
def test_order_dto_includes_scancode_url_and_nested_payload(product, order_factory):
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Generated by Django 6.0.5 on 2026-06-03 08:47
2+
3+
from django.db import migrations, models
4+
5+
6+
def _backfill_is_ticket(apps, schema_editor) -> None:
7+
Category = apps.get_model("product", "Category")
8+
Category.objects.filter(name__contains="티켓").update(is_ticket=True)
9+
10+
11+
class Migration(migrations.Migration):
12+
atomic = True
13+
dependencies = [("product", "0005_historicaloptiongroup_orderable_ends_at_and_more")]
14+
operations = [
15+
migrations.AddField(model_name="category", name="is_ticket", field=models.BooleanField(default=False)),
16+
migrations.AddField(
17+
model_name="historicalcategory",
18+
name="is_ticket",
19+
field=models.BooleanField(default=False),
20+
),
21+
migrations.RunPython(_backfill_is_ticket, migrations.RunPython.noop),
22+
]

app/shop/product/models.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ class Category(BaseAbstractModel):
3737
name = models.CharField(max_length=100)
3838
priority = models.IntegerField(default=0)
3939

40+
is_ticket = models.BooleanField(default=False)
41+
4042
history = HistoricalRecords()
4143

4244
class Meta:

app/shop/test/e2e_purchase_flow_test.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,7 @@ def test_cart_get_reflects_added_products_for_e2e_setup(customer_client, custome
330330
"status": OrderProductRelation.OrderProductStatus.pending,
331331
"price": 25000,
332332
"donation_price": 0,
333-
# 카테고리 "티셔츠" — "티켓" 미포함 → scancode_url None.
333+
# 카테고리 "티셔츠" — is_ticket=False → scancode_url None.
334334
"not_refundable_reason": NotRefundableErrorMessages.ORDER_NOT_REFUNDABLE,
335335
"scancode_url": None,
336336
},

0 commit comments

Comments
 (0)