From 9f23c4a8bc58ae46ca1e0ba4f454017ceae8f915 Mon Sep 17 00:00:00 2001 From: Victoria Earl Date: Thu, 10 Oct 2024 18:39:03 -0400 Subject: [PATCH] Update how pending badges work 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. --- uber/config.py | 5 +++-- uber/configspec.ini | 5 +++++ uber/menu.py | 19 ++++++++++++++++--- uber/models/__init__.py | 11 ----------- uber/models/attendee.py | 14 ++++++++++++++ uber/site_sections/group_admin.py | 8 ++++---- uber/site_sections/registration.py | 10 ++++++---- .../forms/attendee/admin_badge_flags.html | 5 ++--- .../registration/pending_badges.html | 12 ++++++++---- 9 files changed, 58 insertions(+), 31 deletions(-) diff --git a/uber/config.py b/uber/config.py index a2b48ee7d..ac322b9b2 100644 --- a/uber/config.py +++ b/uber/config.py @@ -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', diff --git a/uber/configspec.ini b/uber/configspec.ini index 3f4854df5..505d5b1cb 100644 --- a/uber/configspec.ini +++ b/uber/configspec.ini @@ -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, diff --git a/uber/menu.py b/uber/menu.py index 7631b1421..fcc80858b 100644 --- a/uber/menu.py +++ b/uber/menu.py @@ -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=[ @@ -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/')) diff --git a/uber/models/__init__.py b/uber/models/__init__.py index 7b2248b5a..67de7712d 100644 --- a/uber/models/__init__.py +++ b/uber/models/__init__.py @@ -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() diff --git a/uber/models/attendee.py b/uber/models/attendee.py index bdd530bfc..db5a73c73 100644 --- a/uber/models/attendee.py +++ b/uber/models/attendee.py @@ -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): diff --git a/uber/site_sections/group_admin.py b/uber/site_sections/group_admin.py index 894a1b46f..4fff46583 100644 --- a/uber/site_sections/group_admin.py +++ b/uber/site_sections/group_admin.py @@ -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)), diff --git a/uber/site_sections/registration.py b/uber/site_sections/registration.py index 6fd444ad7..da760b94c 100644 --- a/uber/site_sections/registration.py +++ b/uber/site_sections/registration.py @@ -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() @@ -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' diff --git a/uber/templates/forms/attendee/admin_badge_flags.html b/uber/templates/forms/attendee/admin_badge_flags.html index 07be22362..d31524ce9 100644 --- a/uber/templates/forms/attendee/admin_badge_flags.html +++ b/uber/templates/forms/attendee/admin_badge_flags.html @@ -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 %}
{{ 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) }}
+ admin_text=attendee.cannot_edit_badge_status_reason, + disabled=(attendee.cannot_edit_badge_status_reason != '')) }}
{{ form_macros.form_input(badge_flags.badge_type) }}
{{ 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)) }}
diff --git a/uber/templates/registration/pending_badges.html b/uber/templates/registration/pending_badges.html index e048a1eb6..1b930651f 100644 --- a/uber/templates/registration/pending_badges.html +++ b/uber/templates/registration/pending_badges.html @@ -1,5 +1,5 @@ {% extends "base.html" %}{% set admin_area=True %} -{% block title %}Panelist Badges{% endblock %}} +{% block title %}Pending Badges{% endblock %} {% block content %} -

Pending badges

+
+

Pending Badges

The following is a list of badges that have been submitted for creation. @@ -25,6 +26,7 @@

Pending badges

Name + Group Email Badge Type Ribbons @@ -38,13 +40,14 @@

Pending badges

{% for badge in pending_badges %} - {{ badge.full_name }} + {{ badge.full_name }} {% if badge.legal_name %}(Name on Photo ID: {{ badge.legal_name }}){% endif %} + {{ badge.group.name if badge.group else '' }} {{ badge.email|email_to_link }} {{ badge.badge_type_label }} {{ badge.ribbon_labels|join(", ") }} - {{ "Need Not Pay" if badge.paid == c.NEED_NOT_PAY else badge.badge_cost }} + {{ "Need Not Pay" if badge.paid == c.NEED_NOT_PAY else badge.badge_cost|format_currency }} {{ badge.created_info.who }} {{ badge.admin_notes }} @@ -52,5 +55,6 @@

Pending badges

{% endfor %} +
{% endblock %}