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) admin_id = cherrypy.session.get('account_id') admin_name = session.admin_attendee().full_name already_queued = 0 for id in attendee_ids: existing_import = session.query(ApiJob).filter(ApiJob.job_name == "attendee_import", ApiJob.query == id, ApiJob.cancelled == None, ApiJob.errors == '').count() if existing_import: already_queued += 1 else: session.add(ApiJob( admin_id = admin_id, admin_name = admin_name, job_name = "attendee_import", target_server = target_server, api_token = api_token, query = id, json_data = {'badge_type': badge_type, 'admin_notes': admin_notes, 'full': True} )) session.commit() attendee_count = len(attendee_ids) - already_queued badge_label = c.BADGES[int(badge_type)].lower() if len(attendee_ids) > 100: query = '' # Clear very large queries to prevent 502 errors 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}.{queued}'.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, queued='' if not already_queued else '{} badges are already queued for import.'.format(already_queued), ) )
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 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 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 _decline_and_convert_dealer_group(session, group, status=c.DECLINED): """ Deletes the waitlisted dealer group and converts all of the group members to the appropriate badge type. Unassigned, unpaid badges will be deleted. """ admin_note = 'Converted badge from waitlisted {} "{}".'.format(c.DEALER_REG_TERM, group.name) group.status = status if not group.is_unpaid: group.tables = 0 for attendee in group.attendees: attendee.append_admin_note(admin_note) attendee.ribbon = remove_opt(attendee.ribbon_ints, c.DEALER_RIBBON) return 'Group {} status removed'.format(c.DEALER_TERM) message = ['Group declined'] emails_failed = 0 emails_sent = 0 badges_converted = 0 for attendee in list(group.attendees): if _is_dealer_convertible(attendee): attendee.badge_status = c.INVALID_STATUS if not attendee.is_unassigned: new_attendee = Attendee() for attr in c.UNTRANSFERABLE_ATTRS: setattr(new_attendee, attr, getattr(attendee, attr)) new_attendee.overridden_price = attendee.base_badge_price - c.GROUP_DISCOUNT new_attendee.base_badge_price = attendee.base_badge_price new_attendee.append_admin_note(admin_note) session.add(new_attendee) try: send_email.delay( c.MARKETPLACE_EMAIL, new_attendee.email, 'Do you still want to come to {}?'.format(c.EVENT_NAME), render('emails/dealers/badge_converted.html', { 'attendee': new_attendee, 'group': group}, encoding=None), format='html', model=attendee.to_dict('id')) emails_sent += 1 except Exception: emails_failed += 1 badges_converted += 1 else: if attendee.paid not in [c.HAS_PAID, c.NEED_NOT_PAY]: attendee.paid = c.NOT_PAID attendee.append_admin_note(admin_note) attendee.ribbon = remove_opt(attendee.ribbon_ints, c.DEALER_RIBBON) for count, template in [ (badges_converted, '{} badge{} converted'), (emails_sent, '{} email{} sent'), (emails_failed, '{} email{} failed to send')]: if count > 0: message.append(template.format(count, pluralize(count))) return ', '.join(message)
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 _decline_and_convert_dealer_group(session, group, delete_when_able=False): """ Deletes the waitlisted dealer group and converts all of the group members to the appropriate badge type. Unassigned, unpaid badges will be deleted. """ admin_note = 'Converted badge from waitlisted dealer group "{}".'.format( group.name) if not group.is_unpaid: group.tables = 0 for attendee in group.attendees: attendee.append_admin_note(admin_note) attendee.ribbon = remove_opt(attendee.ribbon_ints, c.DEALER_RIBBON) return 'Group dealer status removed' message = ['Group declined'] emails_failed = 0 emails_sent = 0 badges_converted = 0 badges_deleted = 0 group.leader = None for attendee in list(group.attendees): if (delete_when_able or attendee.is_unassigned ) and _is_attendee_disentangled(attendee): session.delete(attendee) badges_deleted += 1 else: if _is_dealer_convertible(attendee): attendee.badge_status = c.NEW_STATUS try: send_email.delay( c.REGDESK_EMAIL, attendee.email, 'Do you still want to come to {}?'.format( c.EVENT_NAME), render('emails/dealers/badge_converted.html', { 'attendee': attendee, 'group': group }, encoding=None), format='html', model=attendee.to_dict('id')) emails_sent += 1 except Exception: emails_failed += 1 badges_converted += 1 if attendee.paid not in [c.HAS_PAID, c.NEED_NOT_PAY]: attendee.paid = c.NOT_PAID attendee.append_admin_note(admin_note) attendee.ribbon = remove_opt(attendee.ribbon_ints, c.DEALER_RIBBON) group.attendees.remove(attendee) session.delete(group) for count, template in [(badges_converted, '{} badge{} converted'), (emails_sent, '{} email{} sent'), (emails_failed, '{} email{} failed to send'), (badges_deleted, '{} badge{} deleted')]: if count > 0: message.append(template.format(count, pluralize(count))) return ', '.join(message)
def confirm_attendees(self, session, badge_type, admin_notes, target_server, api_token, query, attendee_ids): if cherrypy.request.method != 'POST': raise HTTPRedirect('attendees?target_server={}&api_token={}&query={}', target_server, api_token, query) target_url, target_host, remote_api_token = _format_import_params(target_server, api_token) results = {} try: uri = '{}/jsonrpc/'.format(target_url) service = ServerProxy(uri=uri, extra_headers={'X-Auth-Token': remote_api_token}) results = service.attendee.export(query=','.join(listify(attendee_ids)), full=True) except Exception as ex: raise HTTPRedirect( '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( '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 _decline_and_convert_dealer_group(session, group, status=c.DECLINED): """ Deletes the waitlisted dealer group and converts all of the group members to the appropriate badge type. Unassigned, unpaid badges will be deleted. """ admin_note = 'Converted badge from waitlisted dealer group "{}".'.format(group.name) group.status = status if not group.is_unpaid: group.tables = 0 for attendee in group.attendees: attendee.append_admin_note(admin_note) attendee.ribbon = remove_opt(attendee.ribbon_ints, c.DEALER_RIBBON) return 'Group dealer status removed' message = ['Group declined'] emails_failed = 0 emails_sent = 0 badges_converted = 0 for attendee in list(group.attendees): if _is_dealer_convertible(attendee): attendee.badge_status = c.INVALID_STATUS if not attendee.is_unassigned: new_attendee = Attendee() for attr in c.UNTRANSFERABLE_ATTRS: setattr(new_attendee, attr, getattr(attendee, attr)) new_attendee.overridden_price = attendee.overridden_price new_attendee.base_badge_price = attendee.base_badge_price new_attendee.append_admin_note(admin_note) session.add(new_attendee) try: send_email.delay( c.MARKETPLACE_EMAIL, new_attendee.email, 'Do you still want to come to {}?'.format(c.EVENT_NAME), render('emails/dealers/badge_converted.html', { 'attendee': new_attendee, 'group': group}, encoding=None), format='html', model=attendee.to_dict('id')) emails_sent += 1 except Exception: emails_failed += 1 badges_converted += 1 else: if attendee.paid not in [c.HAS_PAID, c.NEED_NOT_PAY]: attendee.paid = c.NOT_PAID attendee.append_admin_note(admin_note) attendee.ribbon = remove_opt(attendee.ribbon_ints, c.DEALER_RIBBON) for count, template in [ (badges_converted, '{} badge{} converted'), (emails_sent, '{} email{} sent'), (emails_failed, '{} email{} failed to send')]: if count > 0: message.append(template.format(count, pluralize(count))) return ', '.join(message)