Skip to content

Commit 824d7ae

Browse files
committed
Merge branch 'feature/ticket' into devdev
2 parents d5be9a2 + fed993d commit 824d7ae

File tree

10 files changed

+209
-43
lines changed

10 files changed

+209
-43
lines changed

program/migrations/0003_program.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Generated by Django 4.1.5 on 2023-05-24 13:39
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
dependencies = [
9+
('program', '0002_alter_proposal_options_and_more'),
10+
]
11+
12+
operations = [
13+
migrations.CreateModel(
14+
name='Program',
15+
fields=[
16+
('id', models.UUIDField(primary_key=True, serialize=False)),
17+
('host', models.CharField(max_length=100)),
18+
('title', models.CharField(max_length=100)),
19+
('short_desc', models.CharField(max_length=1000)),
20+
('desc', models.CharField(max_length=4000)),
21+
('room', models.CharField(blank=True, choices=[('101', '101'), ('102', '102'), ('103', '103'), ('104', '104'), ('105', '105'), ('201', '201'), ('202', '202'), ('203', '203')], max_length=15, null=True)),
22+
('capacity', models.IntegerField(blank=True, help_text='최대 참가 가능 인원 수', null=True)),
23+
('start_at', models.DateTimeField(blank=True, null=True)),
24+
('end_at', models.DateTimeField(blank=True, null=True)),
25+
('program_type', models.CharField(choices=[('CONFERENCE', '컨퍼런스'), ('TUTORIAL', '튜토리얼'), ('SPRINT', '스프린트')], max_length=30)),
26+
],
27+
),
28+
]

program/models.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,3 +95,45 @@ class Meta:
9595

9696
def __str__(self):
9797
return self.title
98+
99+
100+
CONFERENCE = "CONFERENCE"
101+
TUTORIAL = "TUTORIAL"
102+
SPRINT = "SPRINT"
103+
104+
105+
class Program(models.Model):
106+
id = models.UUIDField(primary_key=True)
107+
host = models.CharField(max_length=100) # TODO User로?
108+
title = models.CharField(max_length=100)
109+
short_desc = models.CharField(max_length=1000)
110+
desc = models.CharField(max_length=4000)
111+
room = models.CharField(
112+
max_length=15,
113+
null=True,
114+
blank=True,
115+
choices=(
116+
("101", "101"),
117+
("102", "102"),
118+
("103", "103"),
119+
("104", "104"),
120+
("105", "105"),
121+
("201", "201"),
122+
("202", "202"),
123+
("203", "203"), # TODO 2층 호실 추가 필요
124+
),
125+
)
126+
capacity = models.IntegerField(null=True, blank=True, help_text="최대 참가 가능 인원 수")
127+
start_at = models.DateTimeField(null=True, blank=True)
128+
end_at = models.DateTimeField(null=True, blank=True)
129+
program_type = models.CharField(
130+
max_length=30,
131+
choices=(
132+
(CONFERENCE, "컨퍼런스"),
133+
(TUTORIAL, "튜토리얼"),
134+
(SPRINT, "스프린트"),
135+
),
136+
)
137+
138+
def __str__(self):
139+
return self.title
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Generated by Django 4.1.5 on 2023-05-24 13:06
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
dependencies = [
9+
('ticket', '0003_ticket_remove_tickettype_code_and_more'),
10+
]
11+
12+
operations = [
13+
migrations.AlterField(
14+
model_name='tickettype',
15+
name='id',
16+
field=models.UUIDField(primary_key=True, serialize=False),
17+
),
18+
]
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Generated by Django 4.1.5 on 2023-05-24 13:07
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
dependencies = [
9+
('ticket', '0004_alter_tickettype_id'),
10+
]
11+
12+
operations = [
13+
migrations.AlterField(
14+
model_name='tickettype',
15+
name='day',
16+
field=models.CharField(choices=[('FRI', '금요일'), ('SAT', '토요일'), ('SUN', '일요일'), ('WEEKEND', '토/일요일')], max_length=10),
17+
),
18+
]
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Generated by Django 4.1.5 on 2023-05-24 13:39
2+
3+
from django.db import migrations, models
4+
import django.db.models.deletion
5+
6+
7+
class Migration(migrations.Migration):
8+
9+
dependencies = [
10+
('program', '0003_program'),
11+
('ticket', '0005_alter_tickettype_day'),
12+
]
13+
14+
operations = [
15+
migrations.AddField(
16+
model_name='tickettype',
17+
name='program',
18+
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.PROTECT, to='program.program'),
19+
),
20+
]

ticket/models.py

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,21 @@
99

1010

1111
class TicketType(models.Model):
12+
id = models.UUIDField(primary_key=True)
1213
name = models.CharField(max_length=100)
1314
price = models.IntegerField()
1415
min_price = models.IntegerField(null=True, blank=True)
1516
desc = models.TextField(max_length=1000)
1617
day = models.CharField(
1718
max_length=10,
1819
choices=(
20+
("FRI", "금요일"),
1921
("SAT", "토요일"),
2022
("SUN", "일요일"),
2123
("WEEKEND", "토/일요일"),
2224
),
2325
)
24-
# program = models.ForeignKey() # TODO
26+
program = models.ForeignKey("program.Program", on_delete=models.PROTECT, null=True)
2527
is_refundable = models.BooleanField(default=True)
2628

2729
def __str__(self):
@@ -30,12 +32,18 @@ def __str__(self):
3032
@property
3133
def buyable(self) -> bool:
3234
"""잔여 수량이 있는지"""
35+
if self.day == "FRI":
36+
ticket_count = Ticket.objects.filter(
37+
models.Q(ticket_type=self) & models.Q(is_refunded=False)
38+
).count()
39+
return ticket_count < self.program.capacity
40+
3341
sat_ticket_count = Ticket.objects.filter(
34-
models.Q(ticket_type__day="SAT") & models.Q(ticket_type__day="WEEKEND")
35-
).count()
42+
models.Q(ticket_type__day="SAT") | models.Q(ticket_type__day="WEEKEND")
43+
).filter(is_refunded=False).count()
3644
sun_ticket_count = Ticket.objects.filter(
37-
models.Q(ticket_type__day="SUN") & models.Q(ticket_type__day="WEEKEND")
38-
).count()
45+
models.Q(ticket_type__day="SUN") | models.Q(ticket_type__day="WEEKEND")
46+
).filter(is_refunded=False).count()
3947

4048
can_buy_sat_ticket = sat_ticket_count < config.CONFERENCE_PARTICIPANT_COUNT_SAT
4149
can_buy_sun_ticket = sun_ticket_count < config.CONFERENCE_PARTICIPANT_COUNT_SUN
@@ -54,6 +62,9 @@ def can_coexist(self, other: TicketType) -> bool:
5462
return True
5563
if self.day == "SUN" and other.day == "SAT":
5664
return True
65+
if self.day == "FRI" or other.day == "FRI":
66+
# TODO program의 시간이 겹치는지 확인?
67+
return True
5768

5869
return False
5970

ticket/requests.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,14 +57,14 @@ def __init__(self, request: HttpRequest, **kwargs):
5757

5858

5959
@dataclass(init=False)
60-
class CheckConferenceTicketTypeBuyableRequest:
60+
class CheckTicketTypeBuyableRequest:
6161
@dataclass
6262
class Querystring:
6363
username: Optional[str] = None
6464

6565
@dataclass
6666
class MatchInfo:
67-
ticket_type_code: str
67+
ticket_type_id: str
6868

6969
@dataclass
7070
class Data:
@@ -74,14 +74,14 @@ def __init__(self, request: HttpRequest, **kwargs):
7474
try:
7575
self.querystring = jsons.load(
7676
_extract_querystring(request),
77-
CheckConferenceTicketTypeBuyableRequest.Querystring,
77+
CheckTicketTypeBuyableRequest.Querystring,
7878
)
7979
self.match_info = jsons.load(
80-
kwargs, CheckConferenceTicketTypeBuyableRequest.MatchInfo
80+
kwargs, CheckTicketTypeBuyableRequest.MatchInfo
8181
)
8282
self.data = jsons.load(
8383
json.loads(request.body) if request.body else dict(),
84-
CheckConferenceTicketTypeBuyableRequest.Data,
84+
CheckTicketTypeBuyableRequest.Data,
8585
)
8686
except Exception as e:
8787
raise RequestParsingException() from e

ticket/urls.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@
33
from . import views
44

55
urlpatterns = [
6-
path("conference-ticket-types", views.get__get_conference_ticket_types),
6+
path("conference-ticket-types", views.get__get_ticket_types),
77
re_path(
8-
r"^conference-ticket-types/(?P<ticket_type_code>\w+)/check",
9-
views.get__check_conference_ticket_type_buyable,
8+
r"^conference-ticket-types/(?P<ticket_type_id>\w+)/check",
9+
views.get__check_ticket_type_buyable,
1010
),
11-
path("conference-tickets", views.post__add_conference_ticket),
11+
path("conference-tickets", views.post__add_ticket),
1212
path("list", views.get__ticket_list, name="ticket-list"),
1313
path("<int:item_id>", views.TicketDetailView.as_view(), name="ticket-detail"),
1414
path("success", views.ticket_success, name="page-ticket-success"),

ticket/view_models.py

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,47 @@
11
from dataclasses import asdict, dataclass
2-
from typing import Optional
2+
from datetime import datetime
3+
from typing import Optional, Union
34

5+
from program.models import CONFERENCE, TUTORIAL, SPRINT
46
from .models import TicketType
57

68

79
@dataclass(init=False)
8-
class ConferenceTicketTypeViewModel:
9-
code: str
10+
class TicketTypeViewModel:
11+
@dataclass
12+
class Program:
13+
title: str
14+
short_desc: str
15+
start_at: datetime
16+
end_at: datetime
17+
program_type: str # type: Union[CONFERENCE, TUTORIAL, SPRINT]
18+
19+
id: str
1020
name: str
1121
price: int
1222
min_price: Optional[int]
1323
desc: str
14-
day: str
24+
day: str # choice
25+
program: Program
26+
is_refundable: bool
27+
is_buyable: property # type: bool
1528

1629
def __init__(self, model: TicketType):
17-
self.code = model.code
30+
self.id = model.id
1831
self.name = model.name
1932
self.price = model.price
2033
self.min_price = model.min_price
2134
self.desc = model.desc
2235
self.day = model.day
36+
self.program = TicketTypeViewModel.Program(
37+
title=model.program.title,
38+
short_desc=model.program.short_desc,
39+
start_at=model.program.start_at,
40+
end_at=model.program.end_at,
41+
program_type=model.program.program_type,
42+
)
43+
self.is_refundable = model.is_refundable
44+
self.is_buyable = model.buyable
2345

2446
def to_dict(self):
2547
return asdict(self)

0 commit comments

Comments
 (0)