def test_dept_head_ribbon_label_from_dept_membership(): with Session() as session: a = Attendee() session.add(a) a.presave_adjustments() assert a.ribbon_labels == [] a.dept_memberships = [DeptMembership(is_dept_head=True)] a.presave_adjustments() assert a.ribbon_labels == ['Department Head'] a.presave_adjustments() assert a.ribbon_labels == ['Department Head'] a.badge_type = c.ATTENDEE_BADGE a.staffing = True a.ribbon = '{}'.format(c.DEALER_RIBBON) a.presave_adjustments() assert set(a.ribbon_labels) == set(['Department Head', 'Shopkeep']) a.presave_adjustments() assert set(a.ribbon_labels) == set(['Department Head', 'Shopkeep']) a.dept_memberships = [DeptMembership(is_dept_head=False)] a.presave_adjustments() assert set(a.ribbon_labels) == set(['Department Head', 'Shopkeep']) a.presave_adjustments() assert set(a.ribbon_labels) == set(['Department Head', 'Shopkeep']) session.expunge_all()
def test_must_contact(): dept1 = Department(name='Dept1', description='Dept1') dept2 = Department(name='Dept2', description='Dept2') poc_dept1 = Attendee( paid=c.NEED_NOT_PAY, first_name='Poc', last_name='Dept1') poc_dept2 = Attendee( paid=c.NEED_NOT_PAY, first_name='Poc', last_name='Dept2') poc_both = Attendee( paid=c.NEED_NOT_PAY, first_name='Poc', last_name='Both') poc_dept1.dept_memberships = [DeptMembership( department=dept1, is_poc=True)] poc_dept2.dept_memberships = [DeptMembership( department=dept2, is_poc=True)] poc_both.dept_memberships = [ DeptMembership( department=dept1, is_poc=True), DeptMembership( department=dept2, is_poc=True)] start_time = datetime.now(tz=pytz.UTC) job1 = Job( name='Job1', description='Job1', start_time=start_time, duration=1, weight=1, slots=1, department=dept1) job2 = Job( name='Job2', description='Job2', start_time=start_time, duration=1, weight=1, slots=1, department=dept2) volunteer = Attendee(paid=c.HAS_PAID, first_name='V', last_name='One') job1.shifts = [Shift(attendee=volunteer, job=job1)] job2.shifts = [Shift(attendee=volunteer, job=job2)] with Session() as session: session.add_all([ dept1, dept2, poc_dept1, poc_dept2, poc_both, job1, job2, volunteer]) session.commit() assert volunteer.must_contact == '(Dept1) Poc Both / Poc Dept1<br/>(Dept2) Poc Both / Poc Dept2'
def requests(self, session, department_id=None, requested_any=False, message='', **params): if not department_id: raise HTTPRedirect('index') department = session.query(Department).get(department_id) if cherrypy.request.method == 'POST': attendee_ids = [s for s in params.get('attendee_ids', []) if s] if attendee_ids: attendee_count = len(attendee_ids) for attendee_id in attendee_ids: session.add( DeptMembership(department_id=department_id, attendee_id=attendee_id)) raise HTTPRedirect( 'form?id={}&message={}', department_id, '{} volunteer{}!'.format( attendee_count, pluralize(attendee_count, ' added as a new member', 's added as new members'))) raise HTTPRedirect('form?id={}', department_id) return { 'department': department, 'message': message, 'requested_any': requested_any }
def new(self, session, message='', **params): if params.get('id'): raise HTTPRedirect('form?id={}', params['id']) department = session.department(params, bools=Department.all_bools, checkgroups=Department.all_checkgroups) if cherrypy.request.method == 'POST': message = check_dept_admin(session) if not message: message = check(department) if not message: attendee = session.admin_attendee() has_email = bool(attendee.email) department.memberships = [ DeptMembership(attendee=attendee, is_dept_head=True, is_poc=has_email, is_checklist_admin=has_email) ] session.add(department) raise HTTPRedirect('form?id={}', department.id) return {'department': department, 'message': message}
def test_unpaid_dept_head(self, dept): dept_membership = DeptMembership( department=dept, is_dept_head=True) a = Attendee(dept_memberships=[dept_membership]) a._staffing_adjustments() assert a.paid == c.NEED_NOT_PAY
def test_dept_head_invariants(self, dept): dept_membership = DeptMembership( department=dept, is_dept_head=True) a = Attendee(dept_memberships=[dept_membership]) a._staffing_adjustments() assert a.staffing assert a.badge_type == c.STAFF_BADGE
def test_restricted_in_correct_trusted_dept(self, session): session.staff_two.dept_memberships = [ DeptMembership(department=session.dept_arcade, dept_roles=session.job_six.required_roles) ] session.commit() error = session.assign(session.staff_two.id, session.job_six.id) assert not error
def test_is_not_transferable_trusted(monkeypatch, dept, trusted_role): monkeypatch.setattr(Attendee, 'is_new', False) with Session() as session: attendee = Attendee(paid=c.HAS_PAID) dept_membership = DeptMembership(attendee=attendee, department=dept, dept_roles=[trusted_role]) session.add_all([attendee, dept, trusted_role, dept_membership]) session.flush() assert not attendee.is_transferable
def test_staffing_still_trusted_assigned(self, dept, shiftless_dept): """ After applying staffing adjustements: Any depts you are both trusted and assigned to should remain unchanged """ a = Attendee(staffing=True) dept_memberships = [ DeptMembership(attendee=a, attendee_id=a.id, department=dept, department_id=dept.id, is_dept_head=True), DeptMembership(attendee=a, attendee_id=a.id, department=shiftless_dept, department_id=shiftless_dept.id, dept_roles=[DeptRole()]) ] a.assigned_depts = [dept, shiftless_dept] a.dept_memberships_with_role = dept_memberships a._staffing_adjustments() assert a.assigned_to(dept) and a.trusted_in(dept) assert a.assigned_to(shiftless_dept) and a.trusted_in(shiftless_dept)
def test_has_role_somewhere(dept, trusted_role): with Session() as session: attendee = Attendee(paid=c.HAS_PAID) dept_membership = DeptMembership(attendee=attendee, department=dept, dept_roles=[trusted_role]) session.add_all([attendee, dept, trusted_role, dept_membership]) session.flush() assert attendee.has_role_somewhere dept_membership.dept_roles = [] session.flush() session.refresh(attendee) assert not attendee.has_role_somewhere
def test_basic(self, dept, trusted_role): a = Attendee( staffing=True, requested_depts=[dept], ribbon=c.VOLUNTEER_RIBBON, shifts=[Shift()]) a.dept_memberships = [DeptMembership( attendee=a, department=dept, dept_roles=[trusted_role])] a.assigned_depts = [dept] a.unset_volunteering() assert not a.staffing assert not a.has_role_somewhere assert not a.requested_depts assert not a.dept_memberships assert not a.shifts assert a.ribbon == ''
def assign_member(self, session, department_id, attendee_id, message=''): if cherrypy.request.method == 'POST': membership = session.query(DeptMembership) \ .filter_by( department_id=department_id, attendee_id=attendee_id) \ .order_by(DeptMembership.id) \ .options(subqueryload(DeptMembership.attendee)) \ .first() if membership: message = '{} is already a member of this ' \ 'department'.format(membership.attendee.full_name) else: session.add( DeptMembership(department_id=department_id, attendee_id=attendee_id)) attendee = session.query(Attendee).get(attendee_id) message = '{} successfully added as a member of this ' \ 'department'.format(attendee.full_name) raise HTTPRedirect('form?id={}&message={}', department_id, message) raise HTTPRedirect('form?id={}', department_id)
def import_attendee(attendee_import_job): from uber.models import Attendee, DeptMembership, DeptMembershipRequest from functools import partial with uber.models.Session() as session: service, message, target_url = get_api_service_from_server(attendee_import_job.target_server, attendee_import_job.api_token) attendee_import_job.queued = datetime.now() session.commit() errors = [] badge_type = int(attendee_import_job.json_data.get('badge_type', 0)) extra_admin_notes = attendee_import_job.json_data.get('admin_notes', '') if not badge_type: errors.append("ERROR: Attendee does not have a badge type.") elif badge_type not in c.BADGES: errors.append("ERROR: Attendee badge type not recognized: " + str(badge_type)) try: results = service.attendee.export(attendee_import_job.query, True) except Exception as ex: errors.append(str(ex)) else: num_attendees = len(results.get('attendees', [])) if num_attendees != 1: errors.append("ERROR: We expected one attendee for this query, but got " + str(num_attendees) + " instead.") if errors: attendee_import_job.errors += "; {}".format("; ".join(errors)) if attendee_import_job.errors else "; ".join(errors) session.commit() return attendee_to_import = results.get('attendees', [])[0] badge_label = c.BADGES[badge_type].lower() if badge_type in [c.STAFF_BADGE, c.CONTRACTOR_BADGE]: paid = c.NEED_NOT_PAY else: paid = c.UNPAID import_from_url = '{}/registration/form?id={}\n\n'.format(attendee_import_job.target_server, attendee_to_import['id']) new_admin_notes = '{}\n\n'.format(extra_admin_notes) if extra_admin_notes else '' old_admin_notes = 'Old Admin Notes:\n{}\n'.format(attendee_to_import['admin_notes']) if attendee_to_import['admin_notes'] else '' attendee_to_import.update({ 'badge_type': badge_type, 'badge_status': c.IMPORTED_STATUS, 'paid': paid, 'placeholder': True, 'requested_hotel_info': True, 'admin_notes': 'Imported {} from {}{}{}'.format( badge_label, import_from_url, new_admin_notes, old_admin_notes), 'past_years': attendee_to_import['all_years'], }) if attendee_to_import['shirt'] not in c.SHIRT_OPTS: del attendee_to_import['shirt'] del attendee_to_import['id'] del attendee_to_import['all_years'] if badge_type != c.STAFF_BADGE: attendee = Attendee().apply(attendee_to_import, restricted=False) else: assigned_depts = {attendee_to_import[0]: attendee_to_import[1] for attendee_to_import in map(partial(TaskUtils._guess_dept, session), attendee_to_import.pop('assigned_depts', {}).items()) if attendee_to_import} checklist_admin_depts = attendee_to_import.pop('checklist_admin_depts', {}) dept_head_depts = attendee_to_import.pop('dept_head_depts', {}) poc_depts = attendee_to_import.pop('poc_depts', {}) requested_depts = attendee_to_import.pop('requested_depts', {}) attendee_to_import.update({ 'staffing': True, 'ribbon': str(c.DEPT_HEAD_RIBBON) if dept_head_depts else '', }) attendee = Attendee().apply(attendee_to_import, restricted=False) for id, dept in assigned_depts.items(): attendee.dept_memberships.append(DeptMembership( department=dept, attendee=attendee, is_checklist_admin=bool(id in checklist_admin_depts), is_dept_head=bool(id in dept_head_depts), is_poc=bool(id in poc_depts), )) requested_anywhere = requested_depts.pop('All', False) requested_depts = {d[0]: d[1] for d in map(partial(TaskUtils._guess_dept, session), requested_depts.items()) if d} if requested_anywhere: attendee.dept_membership_requests.append(DeptMembershipRequest(attendee=attendee)) for id, dept in requested_depts.items(): attendee.dept_membership_requests.append(DeptMembershipRequest( department=dept, attendee=attendee, )) session.add(attendee) try: session.commit() except Exception as ex: attendee_import_job.errors += "; {}".format(str(ex)) if attendee_import_job.errors else str(ex) session.rollback() else: attendee_import_job.completed = datetime.now()
def confirm_staff(self, session, target_server, api_token, query, attendee_ids): if cherrypy.request.method != 'POST': raise HTTPRedirect('staff?target_server={}&api_token={}&query={}', target_server, api_token, query) target_url = _server_to_url(target_server) results = {} try: uri = '{}/jsonrpc/'.format(target_url) service = ServerProxy( uri=uri, extra_headers={'X-Auth-Token': api_token.strip()}) results = service.attendee.export(query=','.join( listify(attendee_ids)), full=True) except Exception as ex: raise HTTPRedirect( 'staff?target_server={}&api_token={}&query={}&message={}', target_server, api_token, query, str(ex)) depts = {} def _guess_dept(id_name): id, name = id_name if id in depts: return (id, depts[id]) dept = session.query(Department).filter( or_( Department.id == id, Department.normalized_name == Department.normalize_name(name))).first() if dept: depts[id] = dept return (id, dept) return None attendees = results.get('attendees', []) for d in attendees: import_from_url = '{}/registration/form?id={}'.format( target_url, d['id']) old_admin_notes = '\n\nOld Admin Notes:\n{}'.format( d['admin_notes']) if d['admin_notes'] else '' assigned_depts = { d[0]: d[1] for d in map(_guess_dept, d.pop('assigned_depts', {}).items()) if d } checklist_admin_depts = d.pop('checklist_admin_depts', {}) dept_head_depts = d.pop('dept_head_depts', {}) poc_depts = d.pop('poc_depts', {}) requested_depts = d.pop('requested_depts', {}) d.update({ 'badge_type': c.STAFF_BADGE, 'paid': c.NEED_NOT_PAY, 'placeholder': True, 'staffing': True, 'requested_hotel_info': True, 'admin_notes': 'Imported staff from {}{}'.format(import_from_url, old_admin_notes), 'ribbon': str(c.DEPT_HEAD_RIBBON) if dept_head_depts else '', 'past_years': d['all_years'], }) del d['id'] del d['all_years'] attendee = Attendee().apply(d, restricted=False) for id, dept in assigned_depts.items(): attendee.dept_memberships.append( DeptMembership( department=dept, attendee=attendee, is_checklist_admin=bool(id in checklist_admin_depts), is_dept_head=bool(id in dept_head_depts), is_poc=bool(id in poc_depts), )) requested_anywhere = requested_depts.pop('All', False) requested_depts = { d[0]: d[1] for d in map(_guess_dept, requested_depts.items()) if d } if requested_anywhere: attendee.dept_membership_requests.append( DeptMembershipRequest(attendee=attendee)) for id, dept in requested_depts.items(): attendee.dept_membership_requests.append( DeptMembershipRequest( department=dept, attendee=attendee, )) session.add(attendee) attendee_count = len(attendees) raise HTTPRedirect( 'staff?target_server={}&api_token={}&query={}&message={}', target_server, api_token, query, '{} attendee{} imported'.format(attendee_count, pluralize(attendee_count)))
def confirm_import_attendees(self, session, badge_type, admin_notes, target_server, api_token, query, attendee_ids): if cherrypy.request.method != 'POST': raise HTTPRedirect( 'import_attendees?target_server={}&api_token={}&query={}', target_server, api_token, query) service, message, target_url = get_api_service_from_server( target_server, api_token) try: results = service.attendee.export(query=','.join( listify(attendee_ids)), full=True) except Exception as ex: raise HTTPRedirect( 'import_attendees?target_server={}&api_token={}&query={}&message={}', target_server, remote_api_token, query, str(ex)) depts = {} def _guess_dept(id_name): id, name = id_name if id in depts: return (id, depts[id]) dept = session.query(Department).filter( or_( Department.id == id, Department.normalized_name == Department.normalize_name(name))).first() if dept: depts[id] = dept return (id, dept) return None badge_type = int(badge_type) badge_label = c.BADGES[badge_type].lower() attendees = results.get('attendees', []) for d in attendees: import_from_url = '{}/registration/form?id={}\n\n'.format( target_url, d['id']) new_admin_notes = '{}\n\n'.format( admin_notes) if admin_notes else '' old_admin_notes = 'Old Admin Notes:\n{}\n'.format( d['admin_notes']) if d['admin_notes'] else '' d.update({ 'badge_type': badge_type, 'badge_status': c.NEW_STATUS, 'paid': c.NEED_NOT_PAY, 'placeholder': True, 'requested_hotel_info': True, 'admin_notes': 'Imported {} from {}{}{}'.format(badge_label, import_from_url, new_admin_notes, old_admin_notes), 'past_years': d['all_years'], }) del d['id'] del d['all_years'] if badge_type != c.STAFF_BADGE: attendee = Attendee().apply(d, restricted=False) else: assigned_depts = { d[0]: d[1] for d in map(_guess_dept, d.pop('assigned_depts', {}).items()) if d } checklist_admin_depts = d.pop('checklist_admin_depts', {}) dept_head_depts = d.pop('dept_head_depts', {}) poc_depts = d.pop('poc_depts', {}) requested_depts = d.pop('requested_depts', {}) d.update({ 'staffing': True, 'ribbon': str(c.DEPT_HEAD_RIBBON) if dept_head_depts else '', }) attendee = Attendee().apply(d, restricted=False) for id, dept in assigned_depts.items(): attendee.dept_memberships.append( DeptMembership( department=dept, attendee=attendee, is_checklist_admin=bool( id in checklist_admin_depts), is_dept_head=bool(id in dept_head_depts), is_poc=bool(id in poc_depts), )) requested_anywhere = requested_depts.pop('All', False) requested_depts = { d[0]: d[1] for d in map(_guess_dept, requested_depts.items()) if d } if requested_anywhere: attendee.dept_membership_requests.append( DeptMembershipRequest(attendee=attendee)) for id, dept in requested_depts.items(): attendee.dept_membership_requests.append( DeptMembershipRequest( department=dept, attendee=attendee, )) session.add(attendee) attendee_count = len(attendees) raise HTTPRedirect( 'import_attendees?target_server={}&api_token={}&query={}&message={}', target_server, api_token, query, '{count} attendee{s} imported with {a}{badge_label} badge{s}'. format( count=attendee_count, s=pluralize(attendee_count), a=pluralize( attendee_count, singular='an ' if badge_label.startswith('a') else 'a ', plural=''), badge_label=badge_label, ))
def test_is_dept_head(): assert not Attendee().is_dept_head dept_membership = DeptMembership(is_dept_head=True) assert Attendee(dept_memberships=[dept_membership]).is_dept_head
def init_db(request): if os.path.exists(TEST_DB_FILE): os.remove(TEST_DB_FILE) patch_session(Session, request) initialize_db(modify_tables=True) register_session_listeners() with Session() as session: session.add( Attendee(placeholder=True, first_name='Regular', last_name='Volunteer', ribbon=c.VOLUNTEER_RIBBON, staffing=True)) session.add( Attendee(placeholder=True, first_name='Regular', last_name='Attendee')) d_arcade_trusted_dept_role = DeptRole(name='Trusted', description='Trusted in Arcade') d_arcade = Department(name='Arcade', description='Arcade', dept_roles=[d_arcade_trusted_dept_role]) d_console_trusted_dept_role = DeptRole( name='Trusted', description='Trusted in Console') d_console = Department(name='Console', description='Console', dept_roles=[d_console_trusted_dept_role]) session.add_all([ d_arcade, d_arcade_trusted_dept_role, d_console, d_console_trusted_dept_role ]) assigned_depts = { 'One': [d_arcade], 'Two': [d_console], 'Three': [d_arcade, d_console], 'Four': [d_arcade, d_console], 'Five': [] } trusted_depts = { 'One': [], 'Two': [], 'Three': [], 'Four': [d_arcade, d_console], 'Five': [] } for name in ['One', 'Two', 'Three', 'Four', 'Five']: dept_memberships = [] for dept in assigned_depts[name]: is_trusted = dept in trusted_depts[name] dept_memberships.append( DeptMembership( department_id=dept.id, dept_roles=(dept.dept_roles if is_trusted else []))) session.add_all(dept_memberships) session.add( Attendee(placeholder=True, first_name=name, last_name=name, paid=c.NEED_NOT_PAY, badge_type=c.STAFF_BADGE, dept_memberships=dept_memberships)) session.add( Attendee(placeholder=True, first_name=name, last_name=name, paid=c.NEED_NOT_PAY, badge_type=c.SUPPORTER_BADGE)) session.commit() session.add( WatchList(first_names='Banned, Alias, Nickname', last_name='Attendee', email='*****@*****.**', birthdate=date(1980, 7, 10), action='Action', reason='Reason')) session.add( Job(name='Job One', start_time=c.EPOCH, slots=1, weight=1, duration=2, department=d_arcade, extra15=True)) session.add( Job(name='Job Two', start_time=c.EPOCH + timedelta(hours=1), slots=1, weight=1, duration=2, department=d_arcade)) session.add( Job(name='Job Three', start_time=c.EPOCH + timedelta(hours=2), slots=1, weight=1, duration=2, department=d_arcade)) session.add( Job(name='Job Four', start_time=c.EPOCH, slots=2, weight=1, duration=2, department=d_console, extra15=True)) session.add( Job(name='Job Five', start_time=c.EPOCH + timedelta(hours=2), slots=1, weight=1, duration=2, department=d_console)) session.add( Job(name='Job Six', start_time=c.EPOCH, slots=1, weight=1, duration=2, department=d_console, required_roles=[d_console_trusted_dept_role])) session.add( PromoCode(code='ten percent off', discount=10, discount_type=PromoCode._PERCENT_DISCOUNT)) session.add( PromoCode(code='ten dollars off', discount=10, discount_type=PromoCode._FIXED_DISCOUNT)) session.add( PromoCode(code='ten dollar badge', discount=10, discount_type=PromoCode._FIXED_PRICE)) session.add(PromoCode(code='free badge', discount=0, uses_allowed=100)) session.commit()