Added minimum age property to Program model.
authorMadhusudan C.S. <madhusudancs@gmail.com>
Mon, 03 Aug 2009 15:17:21 +0200
changeset 2716 9921ac952f13
parent 2715 afd5368af75c
child 2717 fdde098394a7
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
app/soc/logic/cleaning.py
app/soc/models/program.py
app/soc/modules/ghop/models/program.py
app/soc/views/models/student.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" <madhusudancs@gmail.com>',
     '"Todd Larsen" <tlarsen@google.com>',
     '"Sverre Rabbelier" <sverre@rabbelier.nl>',
     '"Lennard de Rijk" <ljvderijk@gmail.com>',
@@ -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.
   """
--- 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'],
--- 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(
--- 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(