Merge branch 'ticket-testing' into 'master'
Update inventory for 2018 See merge request LCA2018/symposion_app!49
This commit is contained in:
commit
2c2fb35557
2 changed files with 160 additions and 77 deletions
|
@ -14,7 +14,7 @@ docker exec symposion ./manage.py create_review_permissions
|
||||||
docker exec symposion ./manage.py loaddata ./fixtures/miniconf-fixtures/*.json
|
docker exec symposion ./manage.py loaddata ./fixtures/miniconf-fixtures/*.json
|
||||||
if [ -e ./symposion-fixtures ]; then
|
if [ -e ./symposion-fixtures ]; then
|
||||||
pushd ./symposion-fixtures
|
pushd ./symposion-fixtures
|
||||||
./load_data_local.sh
|
./load_chunks_local.sh
|
||||||
popd
|
popd
|
||||||
else
|
else
|
||||||
docker exec -it symposion ./manage.py createsuperuser --username root --email root@example.com
|
docker exec -it symposion ./manage.py createsuperuser --username root --email root@example.com
|
||||||
|
|
|
@ -46,6 +46,11 @@ class Command(BaseCommand):
|
||||||
("name", ),
|
("name", ),
|
||||||
name="Can see unpublished products",
|
name="Can see unpublished products",
|
||||||
)
|
)
|
||||||
|
self.group_prepurchase = self.find_or_make(
|
||||||
|
Group,
|
||||||
|
("name", ),
|
||||||
|
name="Pre-purchase",
|
||||||
|
)
|
||||||
|
|
||||||
def populate_inventory(self):
|
def populate_inventory(self):
|
||||||
# Categories
|
# Categories
|
||||||
|
@ -56,7 +61,7 @@ class Command(BaseCommand):
|
||||||
name="Ticket",
|
name="Ticket",
|
||||||
description="Each type of ticket has different included products. "
|
description="Each type of ticket has different included products. "
|
||||||
"For details of what products are included, see our "
|
"For details of what products are included, see our "
|
||||||
"[LINK]registration details page.[/LINK]",
|
"<a href='https://lca2018.org/attend'>registration page</a>",
|
||||||
required=True,
|
required=True,
|
||||||
render_type=inv.Category.RENDER_TYPE_RADIO,
|
render_type=inv.Category.RENDER_TYPE_RADIO,
|
||||||
limit_per_user=1,
|
limit_per_user=1,
|
||||||
|
@ -67,7 +72,7 @@ class Command(BaseCommand):
|
||||||
("name",),
|
("name",),
|
||||||
name="Penguin Dinner Ticket",
|
name="Penguin Dinner Ticket",
|
||||||
description="Tickets to our conference dinner on the evening of "
|
description="Tickets to our conference dinner on the evening of "
|
||||||
"Wednesday 18 January. All attendees may purchase "
|
"Wednesday 24 January. All attendees may purchase "
|
||||||
"seats at the dinner, even if a dinner ticket is not "
|
"seats at the dinner, even if a dinner ticket is not "
|
||||||
"included in your conference ticket price.",
|
"included in your conference ticket price.",
|
||||||
required=False,
|
required=False,
|
||||||
|
@ -80,20 +85,20 @@ class Command(BaseCommand):
|
||||||
("name",),
|
("name",),
|
||||||
name="Speakers' Dinner Ticket",
|
name="Speakers' Dinner Ticket",
|
||||||
description="Tickets to our exclusive Speakers' Dinner on the "
|
description="Tickets to our exclusive Speakers' Dinner on the "
|
||||||
"evening of Tuesday 17 January. You may purchase up "
|
"evening of Tuesday 23 January. You may purchase up "
|
||||||
"to 5 tickets in total, for significant others, and "
|
"to 5 tickets in total, for significant others and "
|
||||||
"family members.",
|
"family members.",
|
||||||
required=False,
|
required=False,
|
||||||
render_type=inv.Category.RENDER_TYPE_QUANTITY,
|
render_type=inv.Category.RENDER_TYPE_QUANTITY,
|
||||||
limit_per_user=5,
|
limit_per_user=5,
|
||||||
order=20,
|
order=20,
|
||||||
)
|
)
|
||||||
self.pdns_breakfast = self.find_or_make(
|
self.pdns_category = self.find_or_make(
|
||||||
inv.Category,
|
inv.Category,
|
||||||
("name",),
|
("name",),
|
||||||
name="Opening Reception Breakfast Ticket",
|
name="Professional Delegates Networking Session Ticket",
|
||||||
description="Tickets to our Opening Reception Breakfast. This "
|
description="Tickets to our Professional Delegates Networking session."
|
||||||
"event will be held on the morning of Monday 16 "
|
"This event will be held on the evening of Thursday 25th "
|
||||||
"January, and is restricted to Professional Ticket "
|
"January, and is restricted to Professional Ticket "
|
||||||
"holders, speakers, miniconf organisers, and invited "
|
"holders, speakers, miniconf organisers, and invited "
|
||||||
"guests.",
|
"guests.",
|
||||||
|
@ -106,31 +111,31 @@ class Command(BaseCommand):
|
||||||
inv.Category,
|
inv.Category,
|
||||||
("name",),
|
("name",),
|
||||||
name="T-Shirt",
|
name="T-Shirt",
|
||||||
description="Commemorative conference t-shirts, featuring secret "
|
description="Commemorative conference t-shirts, featuring the"
|
||||||
"linux.conf.au 2017 artwork.",
|
"linux.conf.au 2018 artwork.",
|
||||||
required=False,
|
required=False,
|
||||||
render_type=inv.Category.RENDER_TYPE_ITEM_QUANTITY,
|
render_type=inv.Category.RENDER_TYPE_ITEM_QUANTITY,
|
||||||
order=40,
|
order=40,
|
||||||
)
|
)
|
||||||
self.accommodation = self.find_or_make(
|
# self.accommodation = self.find_or_make(
|
||||||
inv.Category,
|
# inv.Category,
|
||||||
("name",),
|
# ("name",),
|
||||||
name="Accommodation at University of Tasmania",
|
# name="Accommodation at University of Tasmania",
|
||||||
description="Accommodation at the University of Tasmania colleges "
|
# description="Accommodation at the University of Tasmania colleges "
|
||||||
"and apartments. You can come back and book your "
|
# "and apartments. You can come back and book your "
|
||||||
"accommodation at a later date, provided rooms remain "
|
# "accommodation at a later date, provided rooms remain "
|
||||||
"available. Rooms may only be booked from Sunday 15 "
|
# "available. Rooms may only be booked from Sunday 15 "
|
||||||
"January--Saturday 21 January. If you wish to stay "
|
# "January--Saturday 21 January. If you wish to stay "
|
||||||
"for only a part of the 6-day period, you must book "
|
# "for only a part of the 6-day period, you must book "
|
||||||
"accommodation for the full 6-day period. Rooms at "
|
# "accommodation for the full 6-day period. Rooms at "
|
||||||
"other hotels, including Wrest Point can be booked "
|
# "other hotels, including Wrest Point can be booked "
|
||||||
"elsewhere. For full details, see [LINK]our "
|
# "elsewhere. For full details, see [LINK]our "
|
||||||
"accommodation page.[/LINK]",
|
# "accommodation page.[/LINK]",
|
||||||
required=False,
|
# required=False,
|
||||||
render_type=inv.Category.RENDER_TYPE_RADIO,
|
# render_type=inv.Category.RENDER_TYPE_RADIO,
|
||||||
limit_per_user=1,
|
# limit_per_user=1,
|
||||||
order=50,
|
# order=50,
|
||||||
)
|
# )
|
||||||
self.extras = self.find_or_make(
|
self.extras = self.find_or_make(
|
||||||
inv.Category,
|
inv.Category,
|
||||||
("name",),
|
("name",),
|
||||||
|
@ -176,7 +181,7 @@ class Command(BaseCommand):
|
||||||
("name", "category",),
|
("name", "category",),
|
||||||
category=self.ticket,
|
category=self.ticket,
|
||||||
name="Student",
|
name="Student",
|
||||||
price=Decimal("160.00"),
|
price=Decimal("149.00"),
|
||||||
reservation_duration=hours(24),
|
reservation_duration=hours(24),
|
||||||
order=30,
|
order=30,
|
||||||
)
|
)
|
||||||
|
@ -270,7 +275,7 @@ class Command(BaseCommand):
|
||||||
("name", "category",),
|
("name", "category",),
|
||||||
category=self.penguin_dinner,
|
category=self.penguin_dinner,
|
||||||
name="Child",
|
name="Child",
|
||||||
description="Includes a child's meal and soft drink service.",
|
description="Children 14 and under. Includes a child's meal and soft drink service.",
|
||||||
price=Decimal("50.00"),
|
price=Decimal("50.00"),
|
||||||
reservation_duration=hours(1),
|
reservation_duration=hours(1),
|
||||||
order=20,
|
order=20,
|
||||||
|
@ -303,7 +308,7 @@ class Command(BaseCommand):
|
||||||
("name", "category",),
|
("name", "category",),
|
||||||
category=self.speakers_dinner_ticket,
|
category=self.speakers_dinner_ticket,
|
||||||
name="Child",
|
name="Child",
|
||||||
description="Includes a child's meal and soft drink service.",
|
description="Children 14 and under. Includes a child's meal and soft drink service.",
|
||||||
price=Decimal("60.00"),
|
price=Decimal("60.00"),
|
||||||
reservation_duration=hours(1),
|
reservation_duration=hours(1),
|
||||||
order=20,
|
order=20,
|
||||||
|
@ -320,12 +325,12 @@ class Command(BaseCommand):
|
||||||
order=30,
|
order=30,
|
||||||
)
|
)
|
||||||
|
|
||||||
# PDNS breakfast
|
# PDNS
|
||||||
|
|
||||||
self.pdns = self.find_or_make(
|
self.pdns = self.find_or_make(
|
||||||
inv.Product,
|
inv.Product,
|
||||||
("name", "category",),
|
("name", "category",),
|
||||||
category=self.pdns_breakfast,
|
category=self.pdns_category,
|
||||||
name="Conference Attendee",
|
name="Conference Attendee",
|
||||||
price=Decimal("00.00"),
|
price=Decimal("00.00"),
|
||||||
reservation_duration=hours(1),
|
reservation_duration=hours(1),
|
||||||
|
@ -333,19 +338,19 @@ class Command(BaseCommand):
|
||||||
order=10,
|
order=10,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Accommodation
|
# # Accommodation
|
||||||
|
|
||||||
self.accommodation_week = self.find_or_make(
|
# self.accommodation_week = self.find_or_make(
|
||||||
inv.Product,
|
# inv.Product,
|
||||||
("name", "category",),
|
# ("name", "category",),
|
||||||
category=self.accommodation,
|
# category=self.accommodation,
|
||||||
name="Single Bedroom with Shared Bathrooms, includes full "
|
# name="Single Bedroom with Shared Bathrooms, includes full "
|
||||||
"breakfast, Sunday 15 January 2017--Saturday 21 January 2017",
|
# "breakfast, Sunday 15 January 2017--Saturday 21 January 2017",
|
||||||
price=Decimal("396.00"),
|
# price=Decimal("396.00"),
|
||||||
reservation_duration=hours(24),
|
# reservation_duration=hours(24),
|
||||||
limit_per_user=1,
|
# limit_per_user=1,
|
||||||
order=10,
|
# order=10,
|
||||||
)
|
# )
|
||||||
|
|
||||||
# Extras
|
# Extras
|
||||||
|
|
||||||
|
@ -367,14 +372,10 @@ class Command(BaseCommand):
|
||||||
"Men's/Straight Cut Size",
|
"Men's/Straight Cut Size",
|
||||||
("S", "M", "L", "XL", "2XL", "3XL", "5XL"),
|
("S", "M", "L", "XL", "2XL", "3XL", "5XL"),
|
||||||
),
|
),
|
||||||
"womens_classic": ShirtGroup(
|
"womens": ShirtGroup(
|
||||||
"Women's Classic Fit",
|
"Women's Classic Fit",
|
||||||
("XS", "S", "M", "L", "XL", "2XL"),
|
("XS", "S", "M", "L", "XL", "2XL"),
|
||||||
),
|
),
|
||||||
"womens_semi": ShirtGroup(
|
|
||||||
"Women's Semi-Fitted",
|
|
||||||
("S", "M", "L", "XL", "2XL"),
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self.shirts = {}
|
self.shirts = {}
|
||||||
|
@ -408,6 +409,23 @@ class Command(BaseCommand):
|
||||||
hide_voucher_products.products.set([
|
hide_voucher_products.products.set([
|
||||||
self.ticket_media,
|
self.ticket_media,
|
||||||
self.ticket_sponsor,
|
self.ticket_sponsor,
|
||||||
|
self.ticket_miniconfs_mt,
|
||||||
|
self.ticket_miniconfs_mon,
|
||||||
|
self.ticket_miniconfs_tue,
|
||||||
|
])
|
||||||
|
|
||||||
|
hide_all_tickets = self.find_or_make(
|
||||||
|
cond.GroupMemberFlag,
|
||||||
|
("description", ),
|
||||||
|
description="Can pre-purchase tickets",
|
||||||
|
condition=cond.FlagBase.ENABLE_IF_TRUE,
|
||||||
|
)
|
||||||
|
hide_all_tickets.group.set([self.group_prepurchase])
|
||||||
|
hide_all_tickets.products.set([
|
||||||
|
self.ticket_fairy,
|
||||||
|
self.ticket_professional,
|
||||||
|
self.ticket_hobbyist,
|
||||||
|
self.ticket_student,
|
||||||
])
|
])
|
||||||
|
|
||||||
# Set limits.
|
# Set limits.
|
||||||
|
@ -416,7 +434,7 @@ class Command(BaseCommand):
|
||||||
("description", ),
|
("description", ),
|
||||||
description="Public ticket cap",
|
description="Public ticket cap",
|
||||||
condition=cond.FlagBase.DISABLE_IF_FALSE,
|
condition=cond.FlagBase.DISABLE_IF_FALSE,
|
||||||
limit=450,
|
limit=600,
|
||||||
)
|
)
|
||||||
public_ticket_cap.products.set([
|
public_ticket_cap.products.set([
|
||||||
self.ticket_fairy,
|
self.ticket_fairy,
|
||||||
|
@ -425,27 +443,71 @@ class Command(BaseCommand):
|
||||||
self.ticket_student,
|
self.ticket_student,
|
||||||
])
|
])
|
||||||
|
|
||||||
non_public_ticket_cap = self.find_or_make(
|
student_ticket_cap = self.find_or_make(
|
||||||
cond.TimeOrStockLimitFlag,
|
cond.TimeOrStockLimitFlag,
|
||||||
("description", ),
|
("description", ),
|
||||||
description="Non-public ticket cap",
|
description="Student ticket cap",
|
||||||
condition=cond.FlagBase.DISABLE_IF_FALSE,
|
condition=cond.FlagBase.DISABLE_IF_FALSE,
|
||||||
limit=450,
|
limit=100,
|
||||||
)
|
)
|
||||||
non_public_ticket_cap.products.set([
|
public_ticket_cap.products.set([
|
||||||
self.ticket_speaker,
|
self.ticket_fairy,
|
||||||
|
self.ticket_professional,
|
||||||
|
self.ticket_hobbyist,
|
||||||
|
self.ticket_student,
|
||||||
|
])
|
||||||
|
|
||||||
|
sponsor_ticket_cap = self.find_or_make(
|
||||||
|
cond.TimeOrStockLimitFlag,
|
||||||
|
("description", ),
|
||||||
|
description="Reserved for sponsors",
|
||||||
|
condition=cond.FlagBase.DISABLE_IF_FALSE,
|
||||||
|
limit=70,
|
||||||
|
)
|
||||||
|
sponsor_ticket_cap.products.set([
|
||||||
self.ticket_sponsor,
|
self.ticket_sponsor,
|
||||||
self.ticket_media,
|
])
|
||||||
|
|
||||||
|
volunteer_ticket_cap = self.find_or_make(
|
||||||
|
cond.TimeOrStockLimitFlag,
|
||||||
|
("description", ),
|
||||||
|
description="Reserrved for volunteers and organizers",
|
||||||
|
condition=cond.FlagBase.DISABLE_IF_FALSE,
|
||||||
|
limit=62,
|
||||||
|
)
|
||||||
|
volunteer_ticket_cap.products.set([
|
||||||
self.ticket_team,
|
self.ticket_team,
|
||||||
self.ticket_volunteer,
|
self.ticket_volunteer,
|
||||||
])
|
])
|
||||||
|
|
||||||
|
media_ticket_cap = self.find_or_make(
|
||||||
|
cond.TimeOrStockLimitFlag,
|
||||||
|
("description", ),
|
||||||
|
description="Reserved for media",
|
||||||
|
condition=cond.FlagBase.DISABLE_IF_FALSE,
|
||||||
|
limit=10,
|
||||||
|
)
|
||||||
|
media_ticket_cap.products.set([
|
||||||
|
self.ticket_media,
|
||||||
|
])
|
||||||
|
|
||||||
|
speaker_ticket_cap = self.find_or_make(
|
||||||
|
cond.TimeOrStockLimitFlag,
|
||||||
|
("description", ),
|
||||||
|
description="Reserved for speakers (and miniconf organisers)",
|
||||||
|
condition=cond.FlagBase.DISABLE_IF_FALSE,
|
||||||
|
limit=104,
|
||||||
|
)
|
||||||
|
speaker_ticket_cap.products.set([
|
||||||
|
self.ticket_speaker,
|
||||||
|
])
|
||||||
|
|
||||||
penguin_dinner_cap = self.find_or_make(
|
penguin_dinner_cap = self.find_or_make(
|
||||||
cond.TimeOrStockLimitFlag,
|
cond.TimeOrStockLimitFlag,
|
||||||
("description", ),
|
("description", ),
|
||||||
description="Penguin dinner ticket cap",
|
description="Penguin dinner ticket cap",
|
||||||
condition=cond.FlagBase.DISABLE_IF_FALSE,
|
condition=cond.FlagBase.DISABLE_IF_FALSE,
|
||||||
limit=450,
|
limit=900,
|
||||||
)
|
)
|
||||||
penguin_dinner_cap.categories.set([
|
penguin_dinner_cap.categories.set([
|
||||||
self.penguin_dinner,
|
self.penguin_dinner,
|
||||||
|
@ -456,7 +518,7 @@ class Command(BaseCommand):
|
||||||
("description", ),
|
("description", ),
|
||||||
description="Speakers dinner ticket cap",
|
description="Speakers dinner ticket cap",
|
||||||
condition=cond.FlagBase.DISABLE_IF_FALSE,
|
condition=cond.FlagBase.DISABLE_IF_FALSE,
|
||||||
limit=150,
|
limit=135,
|
||||||
)
|
)
|
||||||
speakers_dinner_cap.categories.set([
|
speakers_dinner_cap.categories.set([
|
||||||
self.speakers_dinner_ticket,
|
self.speakers_dinner_ticket,
|
||||||
|
@ -465,12 +527,12 @@ class Command(BaseCommand):
|
||||||
pdns_cap = self.find_or_make(
|
pdns_cap = self.find_or_make(
|
||||||
cond.TimeOrStockLimitFlag,
|
cond.TimeOrStockLimitFlag,
|
||||||
("description", ),
|
("description", ),
|
||||||
description="PDNS breakfast ticket cap",
|
description="PDNS ticket cap",
|
||||||
condition=cond.FlagBase.DISABLE_IF_FALSE,
|
condition=cond.FlagBase.DISABLE_IF_FALSE,
|
||||||
limit=400,
|
limit=400,
|
||||||
)
|
)
|
||||||
pdns_cap.categories.set([
|
pdns_cap.categories.set([
|
||||||
self.pdns_breakfast,
|
self.pdns_category,
|
||||||
])
|
])
|
||||||
|
|
||||||
# Volunteer tickets are for volunteers only
|
# Volunteer tickets are for volunteers only
|
||||||
|
@ -535,7 +597,7 @@ class Command(BaseCommand):
|
||||||
self.ticket_media,
|
self.ticket_media,
|
||||||
self.ticket_sponsor,
|
self.ticket_sponsor,
|
||||||
])
|
])
|
||||||
pdns_by_ticket.categories.set([self.pdns_breakfast, ])
|
pdns_by_ticket.categories.set([self.pdns_category, ])
|
||||||
|
|
||||||
# They are available to speakers
|
# They are available to speakers
|
||||||
pdns_by_speaker = self.find_or_make(
|
pdns_by_speaker = self.find_or_make(
|
||||||
|
@ -548,7 +610,7 @@ class Command(BaseCommand):
|
||||||
|
|
||||||
)
|
)
|
||||||
pdns_by_speaker.proposal_kind.set(self.main_conference_proposals)
|
pdns_by_speaker.proposal_kind.set(self.main_conference_proposals)
|
||||||
pdns_by_speaker.categories.set([self.pdns_breakfast, ])
|
pdns_by_speaker.categories.set([self.pdns_category, ])
|
||||||
|
|
||||||
# They are available to staff
|
# They are available to staff
|
||||||
pdns_by_staff = self.find_or_make(
|
pdns_by_staff = self.find_or_make(
|
||||||
|
@ -556,13 +618,26 @@ class Command(BaseCommand):
|
||||||
("description", ),
|
("description", ),
|
||||||
description="PDNS available to staff",
|
description="PDNS available to staff",
|
||||||
condition=cond.FlagBase.ENABLE_IF_TRUE,
|
condition=cond.FlagBase.ENABLE_IF_TRUE,
|
||||||
|
|
||||||
)
|
)
|
||||||
pdns_by_staff.group.set([
|
pdns_by_staff.group.set([
|
||||||
self.group_team,
|
self.group_team,
|
||||||
self.group_volunteers,
|
self.group_volunteers,
|
||||||
])
|
])
|
||||||
pdns_by_staff.categories.set([self.pdns_breakfast, ])
|
pdns_by_staff.categories.set([self.pdns_category, ])
|
||||||
|
|
||||||
|
#Don't allow people to get anything if they don't have a ticket first
|
||||||
|
needs_a_ticket = self.find_or_make(
|
||||||
|
cond.CategoryFlag,
|
||||||
|
("description", ),
|
||||||
|
description="GottaGettaTicketFirst",
|
||||||
|
condition=cond.FlagBase.ENABLE_IF_TRUE,
|
||||||
|
enabling_category = self.ticket
|
||||||
|
)
|
||||||
|
needs_a_ticket.categories.set([
|
||||||
|
self.extras,
|
||||||
|
self.t_shirt,
|
||||||
|
self.penguin_dinner,
|
||||||
|
])
|
||||||
|
|
||||||
def populate_discounts(self):
|
def populate_discounts(self):
|
||||||
|
|
||||||
|
@ -583,14 +658,6 @@ class Command(BaseCommand):
|
||||||
price=Decimal("150.00"),
|
price=Decimal("150.00"),
|
||||||
quantity=1, # Per user
|
quantity=1, # Per user
|
||||||
)
|
)
|
||||||
self.find_or_make(
|
|
||||||
cond.DiscountForProduct,
|
|
||||||
("discount", "product"),
|
|
||||||
discount=discount,
|
|
||||||
product=self.ticket_hobbyist,
|
|
||||||
price=Decimal("100.00"),
|
|
||||||
quantity=1, # Per user
|
|
||||||
)
|
|
||||||
|
|
||||||
def free_category(parent_discount, category, quantity=1):
|
def free_category(parent_discount, category, quantity=1):
|
||||||
self.find_or_make(
|
self.find_or_make(
|
||||||
|
@ -603,12 +670,28 @@ class Command(BaseCommand):
|
||||||
)
|
)
|
||||||
|
|
||||||
# Early Bird Discount (general public)
|
# Early Bird Discount (general public)
|
||||||
|
early_bird_hobbyist_discount = self.find_or_make(
|
||||||
|
cond.TimeOrStockLimitDiscount,
|
||||||
|
("description", ),
|
||||||
|
description="Early Bird Hobbyist",
|
||||||
|
end_time=datetime(year=2017, month=11, day=1),
|
||||||
|
limit=150, # Across all users
|
||||||
|
)
|
||||||
|
self.find_or_make(
|
||||||
|
cond.DiscountForProduct,
|
||||||
|
("discount", "product"),
|
||||||
|
discount=early_bird_hobbyist_discount,
|
||||||
|
product=self.ticket_hobbyist,
|
||||||
|
price=Decimal("100.00"),
|
||||||
|
quantity=1, # Per user
|
||||||
|
)
|
||||||
|
|
||||||
early_bird = self.find_or_make(
|
early_bird = self.find_or_make(
|
||||||
cond.TimeOrStockLimitDiscount,
|
cond.TimeOrStockLimitDiscount,
|
||||||
("description", ),
|
("description", ),
|
||||||
description="Early Bird",
|
description="Early Bird",
|
||||||
end_time=datetime(year=2016, month=11, day=1),
|
end_time=datetime(year=2017, month=11, day=1),
|
||||||
limit=165, # Across all users
|
limit=200, # Across professionals and hobbyists
|
||||||
)
|
)
|
||||||
add_early_birds(early_bird)
|
add_early_birds(early_bird)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue