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 %}