Skip to content

Commit

Permalink
Update dealer badge conversion logic for sellout
Browse files Browse the repository at this point in the history
Changes several things for dealer badge conversion to help avoid issues in a sellout situation:
- For dealers that will be offered discounted badges (that's all of them, for us), their badges are now non-transferable. We do this by adding an overridden price and locking badges with an overridden price from being transferable.
- Updates the email text based on requests and also adds information about the badge not being transferable.
- Actually gives dealers a real deadline for claiming their badges, after which unclaimed badges will be invalidated.
  • Loading branch information
kitsuta committed Jan 12, 2025
1 parent c808a8a commit a578cbe
Show file tree
Hide file tree
Showing 6 changed files with 34 additions and 10 deletions.
10 changes: 7 additions & 3 deletions uber/configspec.ini
Original file line number Diff line number Diff line change
Expand Up @@ -1086,18 +1086,22 @@ volunteer_checklist_open = string(default="%(shifts_created)s")
# Volunteers will be able to view shifts after this date.
shifts_created = string(default="")

# Dealer registration automatically opens on DEALER_REG_START. After DEALER_REG_DEADLINE
# all dealer registration are automatically waitlisted. After DEALER_REG_SHUTDOWN dealers
# can no longer even add themselves to the waitlist. Dealer payment reminder emails are
# Dealer registration automatically opens on DEALER_REG_START. After DEALER_REG_DEADLINE
# all dealer registration are automatically waitlisted. After DEALER_REG_SHUTDOWN dealers
# can no longer even add themselves to the waitlist. Dealer payment reminder emails are
# sent in the days and weeks leading up to DEALER_PAYMENT_DUE.
#
# If dealers get their badges converted to individual badges when declined, these badges
# will be invalidated after DEALER_BADGE_DEADLINE, if it is set.
#
# Leaving all of these blank will completely turn off dealer registration for your event.
#
dealer_reg_start = string(default="")
dealer_reg_deadline = string(default="")
dealer_reg_shutdown = string(default="")
dealer_payment_due = string(default="")
dealer_reg_public = string(default="%(dealer_reg_start)s")
dealer_badge_deadline = string(default="")

# These are similar to the dealer dates, but for Marketplace applications.
marketplace_reg_start = string(default="")
Expand Down
1 change: 1 addition & 0 deletions uber/models/attendee.py
Original file line number Diff line number Diff line change
Expand Up @@ -1399,6 +1399,7 @@ def is_inherently_transferable(self):
and not self.checked_in \
and (self.paid in [c.HAS_PAID, c.PAID_BY_GROUP] or self.in_promo_code_group) \
and self.badge_type in c.TRANSFERABLE_BADGE_TYPES \
and not self.overridden_price \
and not self.admin_account \
and not self.has_role_somewhere

Expand Down
2 changes: 2 additions & 0 deletions uber/site_sections/dealer_admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ def convert_dealer_badge(session, attendee, admin_note=''):
if attendee.paid not in [c.HAS_PAID, c.NEED_NOT_PAY]:
params['paid'] = c.NOT_PAID
params['badge_status'] = c.NEW_STATUS
params['overridden_price'] = c.get_attendee_price(attendee.registered_local)
attendee.can_transfer = False

receipt_items = ReceiptManager.auto_update_receipt(attendee, receipt, params)

Expand Down
2 changes: 0 additions & 2 deletions uber/site_sections/group_admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,8 +165,6 @@ def form(self, session, new_dealer='', message='', **params):
new_ribbon_type=group.new_ribbons,
badge_status=new_badge_status,
)
session.commit()
session.refresh(group)

if group.is_dealer and group.status == c.SHARED:
if group.table_shares:
Expand Down
17 changes: 17 additions & 0 deletions uber/tasks/registration.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,23 @@ def invalidate_at_door_badges():
session.commit()


@celery.schedule(timedelta(days=1))
def invalidate_dealer_badges():
if not c.DEALER_BADGE_DEADLINE or not c.AFTER_DEALER_BADGE_DEADLINE:
return

with Session() as session:
pending_badges = session.query(Attendee).filter(Attendee.admin_notes.contains('Converted badge'),
Attendee.placeholder,
Attendee.paid == c.NOT_PAID,
Attendee.badge_status != c.INVALID_STATUS)
for badge in pending_badges:
badge.badge_status = c.INVALID_STATUS
session.add(badge)

session.commit()


@celery.schedule(timedelta(days=1))
def email_pending_attendees():
if c.REMAINING_BADGES < int(c.BADGES_LEFT_ALERTS[0]) or not c.PRE_CON:
Expand Down
12 changes: 7 additions & 5 deletions uber/templates/emails/dealers/badge_converted.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,22 @@

<br/><br/>
{% if group.status not in [c.CANCELLED, c.DECLINED] %}
I am sorry to inform you that only a few spaces opened up for the waitlist, and unfortunately your group ({{ group.name }}) did not make it into the {{ c.EVENT_NAME }} {{ c.DEALER_LOC_TERM }} this year, which is why your application is now being declined. Please try again next year.
I am sorry to inform you that only a few spaces opened up for the waitlist, and unfortunately your group ({{ group.name }}) did not make it into the {{ c.EVENT_NAME }} {{ c.DEALER_LOC_TERM }} this year, which is why your application is now being declined.

<br/><br/>We hope you'll still want to come to {{ c.EVENT_NAME }}!
<br/><br/>If you would still like to attend {{ c.EVENT_NAME }} as an attendee,
{% else %}
Although your group ({{ group.name }}) {{ 'cancelled their ' + c.DEALER_APP_TERM if group.status == c.CANCELLED else 'was declined' }}, we think you may still want to come and enjoy all that {{ c.EVENT_NAME }} has to offer!
Although your group ({{ group.name }}) {{ 'cancelled their ' + c.DEALER_APP_TERM if group.status == c.CANCELLED else 'was declined' }}, we think you may still want to come and enjoy all that {{ c.EVENT_NAME }} has to offer! Therefore,
{% endif %}
Therefore, we have reserved a badge for you{% if c.PRICE_BUMPS and attendee.badge_cost and attendee.badge_cost < c.BADGE_PRICE %} for {{ attendee.badge_cost|format_currency }}, which was the price of registration when you first applied{% endif %}.
we have reserved a badge for you{% if c.PRICE_BUMPS and attendee.badge_cost and attendee.badge_cost < c.BADGE_PRICE %} for {{ attendee.badge_cost|format_currency }}, which was the price of registration when you first applied{% endif %}.
{% if other_badges > 0 %}Attendee badges were also reserved for the {{ (other_badges ~ ' other people') if other_badges > 1 else 'other person' }} in your group who had a valid name and email. {% endif %}
{% if group.unregistered_badges > 0 %}All unassigned badges were dropped.{% endif %}

<br/><br/>Please note: You are choosing to accept or decline an ATTENDEE badge at the price it would have been had you bought it instead of applying for the {{ c.DEALER_LOC_TERM }}.
<strong>You were not accepted as {{ c.DEALER_INDEFINITE_TERM }}, and will not have space in the {{ c.DEALER_LOC_TERM }}.</strong>

{% if c.TRANSFERABLE_BADGE_TYPES %}<br/><br/>Additionally, this badge is reserved for only you and thus <strong>cannot be transferred</strong> to anyone else at any time.{% endif %}

<br/><br/>Please go ahead and confirm or decline <a href="{{ c.URL_BASE }}/preregistration/confirm?id={{ attendee.id }}">your registration</a>. We hope to see you this year!
<br/><br/>Please go ahead and confirm or decline <a href="{{ c.URL_BASE }}/preregistration/confirm?id={{ attendee.id }}">your registration</a>. All badges not confirmed by {{ c.DEALER_BADGE_DEADLINE|datetime_local("%A, %B %e") }} will be dropped automatically. We hope to see you this year!

<br/><br/>-----

Expand Down

0 comments on commit a578cbe

Please sign in to comment.