Skip to content

Commit

Permalink
Update how pending badges work
Browse files Browse the repository at this point in the history
Fixes https://magfest.atlassian.net/browse/MAGDEV-1331 by adding a new setting that makes ALL non-registration-admin badges pending. Also updates under what circumstances you can change the badge status to both accommodate this change (so you can't just immediately set the badge status from Pending to New) and to better manage how we handle badges on the watchlist.
  • Loading branch information
kitsuta committed Oct 10, 2024
1 parent 2a11592 commit 9f23c4a
Show file tree
Hide file tree
Showing 9 changed files with 58 additions and 31 deletions.
5 changes: 3 additions & 2 deletions uber/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -541,8 +541,9 @@ def FORMATTED_BADGE_TYPES(self):
if c.AT_THE_CON and self.ONE_DAYS_ENABLED and self.ONE_DAY_BADGE_AVAILABLE:
badge_types.append({
'name': 'Single Day',
'desc': 'Can be upgrated to a weekend badge later.',
'value': c.ONE_DAY_BADGE
'desc': 'Can be upgraded to a weekend badge later.',
'value': c.ONE_DAY_BADGE,
'price': c.ONEDAY_BADGE_PRICE
})
badge_types.append({
'name': 'Attendee',
Expand Down
5 changes: 5 additions & 0 deletions uber/configspec.ini
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,11 @@ dealer_editable_status_list = string_list(default=list("Pending Approval", "Wait
# As above, but this controls whether dealer groups can cancel their own applications
dealer_cancellable_status_list = string_list(default=list("Pending Approval", "Waitlisted"))

# If True, admins who don't have full access to /registration/ can only create badges
# in Pending status. These badges get put into a list that admins with /registration/
# access must review and approve before those individuals will receive any emails.
admin_badges_need_approval = boolean(default=False)

# By default, staff/volunteers are only allowed to work shifts in a maximum of
# three different departments. Historically, we've found that working in too
# many different departments can spread people too thin and cause burn out,
Expand Down
19 changes: 16 additions & 3 deletions uber/menu.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,13 +115,11 @@ def get_external_schedule_menu_name():

MenuItem(name='People', submenu=[
MenuItem(name='Attendees', href='../registration/'),
MenuItem(name='Pending Badges', href='../registration/pending_badges'),
MenuItem(name='Promo Code Groups', href='../registration/promo_code_groups'),
MenuItem(name='Groups', href='../group_admin/'),
MenuItem(name='Dealers', href='../group_admin/#dealers', access_override='dealer_admin'),
MenuItem(name='Guests', href='../group_admin/#guests', access_override='guest_admin'),
MenuItem(name='Bands', href='../group_admin/#bands', access_override='band_admin'),
MenuItem(name='MIVS', href='../group_admin/#mivs', access_override='mivs_admin'),

]),

MenuItem(name='Schedule', submenu=[
Expand All @@ -136,11 +134,26 @@ def get_external_schedule_menu_name():
])


if c.MIVS_ENABLED:
c.MENU['People'].append_menu_item(MenuItem(name='MIVS', href='../group_admin/#mivs',
access_override='mivs_admin'), position=5)


if c.GROUPS_ENABLED:
c.MENU['People'].append_menu_item(MenuItem(name='Promo Code Groups',
href='../registration/promo_code_groups'), position=2)


if c.ATTENDEE_ACCOUNTS_ENABLED:
c.MENU['People'].append_menu_item(MenuItem(name='Attendee Accounts',
href='../reg_admin/attendee_accounts'), position=1)


if c.ADMIN_BADGES_NEED_APPROVAL:
c.MENU['People'].append_menu_item(MenuItem(name='Pending Badges',
href='../registration/pending_badges'), position=1)


if c.ATTRACTIONS_ENABLED:
c.MENU['Schedule'].append_menu_item(MenuItem(name='Attractions', href='../attractions_admin/'))

Expand Down
11 changes: 0 additions & 11 deletions uber/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -804,17 +804,6 @@ def admin_attendee_max_access(self, attendee, read_only=True):
return max([admin.max_level_access(section,
read_only=read_only) for section in attendee.access_sections])

def admin_can_create_attendee(self, attendee):
admin = self.current_admin_account()
if not admin:
return

if admin.full_registration_admin:
return True

return admin.full_shifts_admin if attendee.badge_type == c.STAFF_BADGE else \
self.admin_attendee_max_access(attendee) >= AccessGroup.DEPT

def viewable_groups(self):
from uber.models import Group, GuestGroup
admin = self.current_admin_account()
Expand Down
14 changes: 14 additions & 0 deletions uber/models/attendee.py
Original file line number Diff line number Diff line change
Expand Up @@ -752,6 +752,20 @@ def admin_write_access(self):
from uber.models import Session
with Session() as session:
return session.admin_attendee_max_access(self, read_only=False)

@property
def cannot_edit_badge_status_reason(self):
full_reg_admin = False
from uber.models import Session
with Session() as session:
full_reg_admin = bool(session.current_admin_account().full_registration_admin)
if c.ADMIN_BADGES_NEED_APPROVAL and not full_reg_admin and self.badge_status == c.PENDING_STATUS:
return "This badge must be approved by an admin."
if self.badge_status == c.WATCHED_STATUS and not c.HAS_SECURITY_ADMIN_ACCESS:
return "Please escalate this case to someone with access to the watchlist."
if c.AT_THE_CON and not c.HAS_REG_ADMIN_ACCESS:
return "Altering the badge status is disabled during the event. The system will update it automatically."
return ''

@property
def ribbon_and_or_badge(self):
Expand Down
8 changes: 4 additions & 4 deletions uber/site_sections/group_admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,10 +139,10 @@ def form(self, session, new_dealer='', message='', **params):
group.auto_recalc = False

if group.is_new or group.badges != group_info_form.badges.data:
test_permissions = Attendee(badge_type=group.new_badge_type, ribbon=group.new_ribbons,
paid=c.PAID_BY_GROUP)
new_badge_status = c.PENDING_STATUS if not session.admin_can_create_attendee(test_permissions)\
else c.NEW_STATUS
if c.ADMIN_BADGES_NEED_APPROVAL and not session.current_admin_account().full_registration_admin:
new_badge_status = c.PENDING_STATUS
else:
new_badge_status = c.NEW_STATUS
message = session.assign_badges(
group,
group_info_form.badges.data or int(bool(group.leader_first_name)),
Expand Down
10 changes: 6 additions & 4 deletions uber/site_sections/registration.py
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,11 @@ def form(self, session, message='', return_to='', **params):
message = save_attendee(session, attendee, params)

if not message:
message = '{} has been saved.'.format(attendee.full_name)
message = '{} has been saved'.format(attendee.full_name)
if attendee.is_new and c.ADMIN_BADGES_NEED_APPROVAL and not session.current_admin_account().full_registration_admin:
attendee.badge_status = c.PENDING_STATUS
message += ' as a pending badge'

stay_on_form = params.get('save_return_to_search', False) is False
session.add(attendee)
session.commit()
Expand Down Expand Up @@ -1424,9 +1428,7 @@ def update_attendee(self, session, message='', success=False, **params):
success = True
message = '{} has been saved'.format(attendee.full_name)

if (attendee.is_new or attendee.badge_type != attendee.orig_value_of('badge_type')
or attendee.group_id != attendee.orig_value_of('group_id'))\
and not session.admin_can_create_attendee(attendee):
if attendee.is_new and c.ADMIN_BADGES_NEED_APPROVAL and not session.current_admin_account().full_registration_admin:
attendee.badge_status = c.PENDING_STATUS
message += ' as a pending badge'

Expand Down
5 changes: 2 additions & 3 deletions uber/templates/forms/attendee/admin_badge_flags.html
Original file line number Diff line number Diff line change
Expand Up @@ -126,11 +126,10 @@


{% block badge_info %}
{% set admin_can_change_status = not c.AT_THE_CON or c.HAS_REG_ADMIN_ACCESS or c.HAS_SECURITY_ADMIN_ACCESS %}
<div class="row g-sm-3">
<div class="col-12 col-sm-4">{{ form_macros.form_input(badge_flags.badge_status,
help_text='' if admin_can_change_status else "Altering the badge status is disabled during the event. The system will update it automatically.",
disabled=not admin_can_change_status) }}</div>
admin_text=attendee.cannot_edit_badge_status_reason,
disabled=(attendee.cannot_edit_badge_status_reason != '')) }}</div>
<div class="col-12 col-sm-4">{{ form_macros.form_input(badge_flags.badge_type) }}</div>
<div class="col-12 col-sm-4">{{ form_macros.form_input(badge_flags.badge_num,
extra_field=form_macros.toggle_checkbox(badge_flags.no_badge_num, [badge_flags.badge_num], hide_on_checked=True, prop="readonly", checked=not attendee.badge_num)) }}</div>
Expand Down
12 changes: 8 additions & 4 deletions uber/templates/registration/pending_badges.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{% extends "base.html" %}{% set admin_area=True %}
{% block title %}Panelist Badges{% endblock %}}
{% block title %}Pending Badges{% endblock %}
{% block content %}
<script>
var hideRows = function (id) {
Expand All @@ -17,14 +17,16 @@
};
</script>

<h3>Pending badges</h3>
<div class="card card-body">
<h3>Pending Badges</h3>

The following is a list of badges that have been submitted for creation.

<table class="table table-striped">
<thead>
<tr>
<th>Name</th>
<th>Group</th>
<th>Email</th>
<th>Badge Type</th>
<th>Ribbons</th>
Expand All @@ -38,19 +40,21 @@ <h3>Pending badges</h3>
{% for badge in pending_badges %}
<tr id="{{ badge.id }}">
<td>
<a href="#attendee_form?id={{ badge.id }}" target="_blank">{{ badge.full_name }}</a>
<a href="#attendee_form?id={{ badge.id }}">{{ badge.full_name }}</a>
{% if badge.legal_name %}(Name on Photo ID: {{ badge.legal_name }}){% endif %}
</td>
<td>{{ badge.group.name if badge.group else '' }}</td>
<td>{{ badge.email|email_to_link }}</td>
<td>{{ badge.badge_type_label }}</td>
<td>{{ badge.ribbon_labels|join(", ") }}</td>
<td>{{ "Need Not Pay" if badge.paid == c.NEED_NOT_PAY else badge.badge_cost }}</td>
<td>{{ "Need Not Pay" if badge.paid == c.NEED_NOT_PAY else badge.badge_cost|format_currency }}</td>
<td>{{ badge.created_info.who }}</td>
<td>{{ badge.admin_notes }}</td>
<td><button class="btn btn-primary" onClick="approve('{{ badge.id }}')">Approve Badge</button></td>
</tr>
{% endfor %}
</tbody>
</table>
</div>

{% endblock %}

0 comments on commit 9f23c4a

Please sign in to comment.