# HG changeset patch # User Madhusudan C.S. # Date 1249305441 -7200 # Node ID 9921ac952f13ec1cc8133766d67c38905e50fe32 # Parent afd5368af75c4986db9593d42e73d87a973a0ce2 Added minimum age property to Program model. This will allow hosts to specify a minium age requirement for Students wanting to participate in a program. Reviewed and edited by: Lennard de Rijk diff -r afd5368af75c -r 9921ac952f13 app/soc/logic/cleaning.py --- a/app/soc/logic/cleaning.py Sun Aug 02 23:51:55 2009 +0200 +++ b/app/soc/logic/cleaning.py Mon Aug 03 15:17:21 2009 +0200 @@ -18,6 +18,7 @@ """ __authors__ = [ + '"Madhusudan.C.S" ', '"Todd Larsen" ', '"Sverre Rabbelier" ', '"Lennard de Rijk" ', @@ -53,6 +54,10 @@ DEF_NO_SUCH_DOCUMENT_MSG = ugettext( "There is no such document with that link ID under this entity.") +DEF_MUST_BE_ABOVE_AGE_LIMIT_FMT = ugettext( + "To sign up as a student for this program, you " + "must be at least %d years of age, as of %s.") + DEF_MUST_BE_ABOVE_LIMIT_FMT = ugettext( "Must be at least %d characters, it has %d characters.") @@ -556,6 +561,7 @@ return cleaned_data return wrapper + def validate_student_proposal(org_field, scope_field, student_logic, org_logic): """Validates the form of a student proposal. @@ -600,6 +606,7 @@ return cleaned_data return wrapper + def validate_student_project(org_field, mentor_field, student_field): """Validates the form of a student proposal. @@ -665,6 +672,58 @@ return wrapper + +def validate_student_age(birth_date_field, scope_field, + program_logic): + """Checks if the student has eligibility to sign up, given + by his birth_date given in field_name. + + Args: + birth_date_field: Field containing birth_date of student + scope_field: Field containing scope_path of the student entity + program_logic: Logic instance of the program + + Raises ValidationError if: + -The student's age is less than the minimum age required by the program + """ + + def wrapper(self): + """Wrapper method. + """ + + cleaned_data = self.cleaned_data + + birth_date = cleaned_data.get(birth_date_field) + program_key_name = cleaned_data.get(scope_field) + + if not birth_date or not program_key_name: + # nothing to check, field validator will find these errors + return cleaned_data + + # get the current program entity or bail out 404 + entity = program_logic.getFromKeyName(program_key_name) + + if not entity: + raise forms.ValidationError( + ugettext("No valid program found")) + + if entity.student_min_age and entity.student_min_age_as_of: + # only check if both the min_age and min_age_as_of are defined + min_year = entity.student_min_age_as_of.year - entity.student_min_age + min_date = entity.student_min_age_as_of.replace(year=min_year) + + if birth_date > min_date: + # this Student is not old enough + self._errors[birth_date_field] = ErrorList( + [DEF_MUST_BE_ABOVE_AGE_LIMIT_FMT %( + entity.student_min_age, + entity.student_min_age_as_of.strftime('%A, %B %d, %Y'))]) + del cleaned_data[birth_date_field] + + return cleaned_data + return wrapper + + def validate_document_acl(view, creating=False): """Validates that the document ACL settings are correct. """ @@ -722,6 +781,7 @@ return rights.hasMembership(roles, django_args) + def validate_access(self, view, rights, prefix, scope_path, field): """Validates that the user has access to the ACL for the specified fields. """ diff -r afd5368af75c -r 9921ac952f13 app/soc/models/program.py --- a/app/soc/models/program.py Sun Aug 02 23:51:55 2009 +0200 +++ b/app/soc/models/program.py Mon Aug 03 15:17:21 2009 +0200 @@ -111,6 +111,25 @@ slots_allocation = db.TextProperty(required=False, verbose_name=ugettext('the allocation of slots')) + #: Property that contains the minimum age of a student allowed to + #: participate + student_min_age = db.IntegerProperty( + required=False, verbose_name=ugettext('Student minimum age')) + student_min_age.group = ugettext('Contest Rules') + student_min_age.help_text = ugettext( + 'Minimum age of the student to sign-up in years.') + + #: Property that contains the date as of which above student + #: minimum age requirement holds. This is a DateTimeProperty because + #: programs might run in a different timezone then the Appengine Server + #: is running on. + student_min_age_as_of = db.DateProperty( + required=False, verbose_name=ugettext('Minimum age as of')) + student_min_age_as_of.group = ugettext('Contest Rules') + student_min_age_as_of.help_text = ugettext( + 'Date as of which the student minimum age requirement ' + 'should be reached.') + #: Required field storing the type of workflow this program has workflow = db.StringProperty(required=True, choices=['gsoc', 'ghop'], diff -r afd5368af75c -r 9921ac952f13 app/soc/modules/ghop/models/program.py --- a/app/soc/modules/ghop/models/program.py Sun Aug 02 23:51:55 2009 +0200 +++ b/app/soc/modules/ghop/models/program.py Mon Aug 03 15:17:21 2009 +0200 @@ -33,24 +33,6 @@ """GHOP Program model extends the basic Program model. """ - #: Property that contains the minimum age of a student allowed to - #: participate - student_min_age = db.IntegerProperty( - required=True, verbose_name=ugettext('Student minimum age')) - student_min_age.group = ugettext('Contest Rules') - student_min_age.help_text = ugettext( - 'Minimum age of the student to sign-up in years.') - - #: Property that contains the date as of which above student - #: minimum age requirement holds. This is a DateTimeProperty because - #: programs might run in a different timezone then the Appengine Server - #: is running on. - student_min_age_as_of = db.DateTimeProperty( - required=True, verbose_name=ugettext('Minimum age as of')) - student_min_age_as_of.group = ugettext('Contest Rules') - student_min_age_as_of.help_text = ugettext( - 'Date as of which the student minimum age requirement holds.') - #: Required property containing the number of Tasks Students can work #: on simultaneously. For GHOP it is 1 nr_simultaneous_tasks = db.IntegerProperty( diff -r afd5368af75c -r 9921ac952f13 app/soc/views/models/student.py --- a/app/soc/views/models/student.py Sun Aug 02 23:51:55 2009 +0200 +++ b/app/soc/views/models/student.py Mon Aug 03 15:17:21 2009 +0200 @@ -144,7 +144,9 @@ updated_fields = { 'link_id': forms.CharField(widget=forms.HiddenInput, required=True), - 'clean_link_id': cleaning.clean_user_is_current('link_id') + 'clean_link_id': cleaning.clean_user_is_current('link_id'), + 'clean': cleaning.validate_student_age( + 'birth_date', 'scope_path', self._logic.getScopeLogic().logic), } user_create_form = dynaform.extendDynaForm(