<commit_before>"""
When an admin submits a form to create/edit an attendee/group/job/etc we usually want to perform some basic validations
on the data that was entered.  We put those validations here.  To make a validation for the Attendee model, you can
just write a function prefixed with "attendee_" like the "attendee_money" function below, which checks the values for
things like amount_paid and amount_extra.  That function should return None on success and an error string on failure.

In addition, you can define a set of required fields by suffixing the lower-cased model name with "_required", like
the "adminaccount_required" list below.  This should be a list of tuples where the first tuple element is the name of
the field, and the second is the name that should be displayed in the "XXX is a required field" error message.

To perform these validations, call the "check" method on the instance you're validating.  That method returns None
on success and a string error message on validation failure.
"""
from uber.common import *

# TODO: there are no unit tests for any of this :(


adminaccount_required = [('attendee', 'Attendee'), ('hashed','Password')]

def adminaccount_misc(account):
    if account.is_new:
        with Session() as session:
            if session.query(AdminAccount).filter_by(attendee_id=account.attendee_id).all():
                return 'That attendee already has an admin account'


event_required = [('name', 'Event Name')]

def event_overlaps(event, other_event_id=None):
    existing = {}
    for e in event.session.query(Event).filter(Event.location == event.location,
                                               Event.id != event.id,
                                               Event.id != other_event_id).all():
        for hh in e.half_hours:
            existing[hh] = e.name

    for hh in event.half_hours:
        if hh in existing:
            return '"{}" overlaps with the time/duration you specified for "{}"'.format(existing[hh], event.name)


group_required = [('name','Group Name')]

def group_paid(group):
    try:
        amount = int(float(group.amount_paid))
        if amount < 0 or amount > 2000:
            return 'Amount Paid must be a reasonable number'
    except:
        return "What you entered for Amount Paid ({}) isn't even a number".format(group.amount_paid)


def _invalid_phone_number(s):
    return s.startswith('+') or len(re.findall(r'\d', s)) != 10

def attendee_misc(attendee):
    if attendee.group_id and not attendee.first_name.strip() and not attendee.last_name.strip():
        return

    if not attendee.first_name or not attendee.last_name:
        return 'First Name and Last Name are required'
    elif attendee.placeholder:
        return

    if (AT_THE_CON and attendee.email and not re.match(EMAIL_RE, attendee.email)) or (not AT_THE_CON and not re.match(EMAIL_RE, attendee.email)):
        return 'Enter a valid email address'

    if not attendee.international and not AT_THE_CON:
        if not re.match(r'^\d{5}$', attendee.zip_code):
            return 'Enter a valid zip code'

        if _invalid_phone_number(attendee.ec_phone):
            return 'Enter a 10-digit emergency contact number'

        if attendee.cellphone and _invalid_phone_number(attendee.cellphone):
            return 'Invalid 10-digit cellphone number'

    if not attendee.no_cellphone and attendee.staffing and _invalid_phone_number(attendee.cellphone):
        return "10-digit cellphone number is required for volunteers (unless you don't own a cellphone)"
    if attendee.age_group == UNDER_18 and attendee.staffing and attendee.badge_type != STAFF_BADGE and PRE_CON:
        return "Attendees must be 18 years of age or older to volunteer"


def attendee_leadership(attendee):
    if attendee.session and not attendee.group_id:
        orig_group_id = attendee.orig_value_of('group_id')
        if orig_group_id and attendee.id == attendee.session.group(orig_group_id).leader_id:
            return 'You cannot remove the leader of a group from that group; make someone else the leader first'

def attendee_banned_volunteer(attendee):
    if (attendee.ribbon == VOLUNTEER_RIBBON or attendee.staffing) and attendee.full_name in BANNED_STAFFERS:
        return "We've declined to invite {} back as a volunteer, {}".format(attendee.full_name,
                'talk to Stops to override if necessary' if AT_THE_CON
            else 'email <EMAIL> if you believe this is in error')

def attendee_money(attendee):
    try:
        amount_paid = int(float(attendee.amount_paid))<commit_msg>Adds birthdate/age-group conversion and reg check<commit_after>"""
When an admin submits a form to create/edit an attendee/group/job/etc we usually want to perform some basic validations
on the data that was entered.  We put those validations here.  To make a validation for the Attendee model, you can
just write a function prefixed with "attendee_" like the "attendee_money" function below, which checks the values for
things like amount_paid and amount_extra.  That function should return None on success and an error string on failure.

In addition, you can define a set of required fields by suffixing the lower-cased model name with "_required", like
the "adminaccount_required" list below.  This should be a list of tuples where the first tuple element is the name of
the field, and the second is the name that should be displayed in the "XXX is a required field" error message.

To perform these validations, call the "check" method on the instance you're validating.  That method returns None
on success and a string error message on validation failure.
"""
from uber.common import *

# TODO: there are no unit tests for any of this :(


adminaccount_required = [('attendee', 'Attendee'), ('hashed','Password')]

def adminaccount_misc(account):
    if account.is_new:
        with Session() as session:
            if session.query(AdminAccount).filter_by(attendee_id=account.attendee_id).all():
                return 'That attendee already has an admin account'


event_required = [('name', 'Event Name')]

def event_overlaps(event, other_event_id=None):
    existing = {}
    for e in event.session.query(Event).filter(Event.location == event.location,
                                               Event.id != event.id,
                                               Event.id != other_event_id).all():
        for hh in e.half_hours:
            existing[hh] = e.name

    for hh in event.half_hours:
        if hh in existing:
            return '"{}" overlaps with the time/duration you specified for "{}"'.format(existing[hh], event.name)


group_required = [('name','Group Name')]

def group_paid(group):
    try:
        amount = int(float(group.amount_paid))
        if amount < 0 or amount > 2000:
            return 'Amount Paid must be a reasonable number'
    except:
        return "What you entered for Amount Paid ({}) isn't even a number".format(group.amount_paid)


def _invalid_phone_number(s):
    return s.startswith('+') or len(re.findall(r'\d', s)) != 10

def attendee_misc(attendee):
    if attendee.group_id and not attendee.first_name.strip() and not attendee.last_name.strip():
        return

    if not attendee.first_name or not attendee.last_name:
        return 'First Name and Last Name are required'
    elif attendee.placeholder:
        return

    if (AT_THE_CON and attendee.email and not re.match(EMAIL_RE, attendee.email)) or (not AT_THE_CON and not re.match(EMAIL_RE, attendee.email)):
        return 'Enter a valid email address'

    if not attendee.international and not AT_THE_CON:
        if not re.match(r'^\d{5}$', attendee.zip_code):
            return 'Enter a valid zip code'

        if _invalid_phone_number(attendee.ec_phone):
            return 'Enter a 10-digit emergency contact number'

        if attendee.cellphone and _invalid_phone_number(attendee.cellphone):
            return 'Invalid 10-digit cellphone number'

    if not attendee.no_cellphone and attendee.staffing and _invalid_phone_number(attendee.cellphone):
        return "10-digit cellphone number is required for volunteers (unless you don't own a cellphone)"
    if attendee.age_group == UNDER_18 and attendee.staffing and attendee.badge_type != STAFF_BADGE and PRE_CON:
        return "Attendees must be 18 years of age or older to volunteer"
        
    if COLLECT_EXACT_BIRTHDATE and attendee.birthdate:
        if attendee.birthdate == "Click to select":
            return "Please enter your birthdate."
        print(attendee.birthdate)
        attendee.birthdate = EVENT_TIMEZONE.localize(datetime.strptime(attendee.birthdate,"%m/%d/%Y"))
        with Session() as session:
            for age_group in AGE_GROUP_OPTS: # This section needs to be rewritten when we can make the database relational.
                age_groups = session.query(AgeGroup)
                current_age_group = age_groups.filter(AgeGroup.desc == age_group[1]).first()
                if current_age_group:
                    birthdate_range = State.get_age_group_date(current_age_group)
                    print(birthdate_range)
                    if birthdate_range[0] <= attendee.birthdate <= birthdate_range[1]:
                        if not current_age_group.can_register:
                            return "Attendees cannot be " + current_age_group.desc + "."
                        else:
                            attendee.age_group = age_group[0]


def attendee_leadership(attendee):
    if attendee.session and not attendee.group_id:
        orig_group_id = attendee.orig_value_of('group_id')
        if orig_group_id and attendee.id == attendee.session.group(orig_group_id).leader_id:
            return 'You cannot remove the leader of a group from that group; make someone else the leader first'

def attendee_banned_volunteer(attendee):
    if (attendee.ribbon == VOLUNTEER_RIBBON or attendee.staffing) and attendee.full_name in BANNED_STAFFERS:
        return "We've declined to invite {} back as a volunteer, {}".format(attendee.full_name,
                'talk to Stops to override if necessary' if AT_THE_CON
            else 'email <EMAIL> if you believe this is in error')

def attendee_money(attendee):
    try:
        amount_paid = int(float(attendee.amount_paid))
{'fraction_non_alphanumeric': 0.08017492711370262, 'fraction_numerical': 0.003887269193391642, 'mean_word_length': 3.0563657863618445, 'pattern_counts': {'":': 1, '<': 9, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5963355', 'n_tokens_mistral': 3034, 'n_tokens_neox': 2901, 'n_words': 1036}