Ignore:
Timestamp:
20 Apr 2012, 10:01:49 (13 years ago)
Author:
uli
Message:

Reduce redundancy and try to check more correctly for set values in
StudentsProcessor?.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • main/waeup.kofa/trunk/src/waeup/kofa/students/batching.py

    r8225 r8232  
    9191
    9292    def getLocator(self, row):
    93         if row.get('student_id',None):
     93        if row.get('student_id',None) not in (None, IGNORE_MARKER):
    9494            return 'student_id'
    95         elif row.get('reg_number',None):
     95        elif row.get('reg_number',None) not in (None, IGNORE_MARKER):
    9696            return 'reg_number'
    97         elif row.get('matric_number',None):
     97        elif row.get('matric_number',None) not in (None, IGNORE_MARKER):
    9898            return 'matric_number'
    9999        else:
     
    155155
    156156        # Remove student_id from row if empty
    157         if row.has_key('student_id') and row['student_id'] is None:
     157        if row.has_key('student_id') and row['student_id'] in (
     158            None, IGNORE_MARKER):
    158159            row.pop('student_id')
    159160
    160161        # Update password
    161         passwd = row.get('password', '')
    162         if passwd:
     162        passwd = row.get('password', IGNORE_MARKER)
     163        if passwd not in ('', IGNORE_MARKER):
    163164            IUserAccount(obj).setPassword(passwd)
    164165            row.pop('password')
    165166
    166167        # Update registration state
    167         if 'reg_state' in row.keys():
     168        if 'reg_state' in row.keys(): # and row['reg_state'] not in (IGNORE_MARKER, ''):
    168169            value = row['reg_state']
    169170            IWorkflowState(obj).setState(value)
     
    225226        return errs, inv_errs, conv_dict
    226227
    227 class StudentStudyCourseProcessor(BatchProcessor):
    228     """A batch processor for IStudentStudyCourse objects.
    229     """
    230     grok.implements(IBatchProcessor)
    231     grok.provides(IBatchProcessor)
    232     grok.context(Interface)
    233     util_name = 'studycourseupdater'
    234     grok.name(util_name)
    235 
    236     name = u'StudentStudyCourse Processor (update only)'
    237     iface = IStudentStudyCourse
    238     factory_name = 'waeup.StudentStudyCourse'
    239 
    240     location_fields = []
     228
     229class StudentProcessorBase(BatchProcessor):
     230    """A base for student subitem processor.
     231
     232    Helps reducing redundancy.
     233    """
     234    grok.baseclass()
     235
     236    #: required fields beside 'student_id', 'reg_number' and 'matric_number'
     237    additional_fields = []
     238
     239    #: header fields additional required
     240    additional_headers = []
    241241
    242242    @property
    243243    def available_fields(self):
    244         return sorted(list(set(
    245             ['student_id','reg_number','matric_number'] + getFields(
     244        fields = ['student_id','reg_number','matric_number'
     245                  ] + self.additional_fields
     246        return sorted(list(set(fields + getFields(
    246247                self.iface).keys())))
    247248
     
    252253                "Need at least columns student_id " +
    253254                "or reg_number or matric_number for import!")
     255        for name in self.additional_headers:
     256            if not name in headerfields:
     257                raise FatalCSVError(
     258                    "Need %s for import!" % name)
     259
    254260        # Check for fields to be ignored...
    255261        not_ignored_fields = [x for x in headerfields
     
    260266        return True
    261267
    262     def getParent(self, row, site):
     268    def _getStudent(self, row, site):
    263269        NON_VALUES = ['', IGNORE_MARKER]
    264270        if not 'students' in site.keys():
     
    285291
    286292    def parentsExist(self, row, site):
     293        result = self.getParent(row, site) is not None
    287294        return self.getParent(row, site) is not None
    288295
    289296    def entryExists(self, row, site):
    290297        return self.getEntry(row, site) is not None
     298
     299    def checkConversion(self, row, mode='ignore'):
     300        """Validates all values in row.
     301        """
     302        converter = IObjectConverter(self.iface)
     303        errs, inv_errs, conv_dict =  converter.fromStringDict(
     304            row, self.factory_name, mode=mode)
     305        return errs, inv_errs, conv_dict
     306
     307
     308class StudentStudyCourseProcessor(StudentProcessorBase):
     309    """A batch processor for IStudentStudyCourse objects.
     310    """
     311    grok.implements(IBatchProcessor)
     312    grok.provides(IBatchProcessor)
     313    grok.context(Interface)
     314    util_name = 'studycourseupdater'
     315    grok.name(util_name)
     316
     317    name = u'StudentStudyCourse Processor (update only)'
     318    iface = IStudentStudyCourse
     319    factory_name = 'waeup.StudentStudyCourse'
     320
     321    location_fields = []
     322    additional_fields = []
     323
     324    def getParent(self, row, site):
     325        return self._getStudent(row, site)
    291326
    292327    def getEntry(self, row, site):
     
    312347        """Validates all values in row.
    313348        """
    314         converter = IObjectConverter(self.iface)
    315         errs, inv_errs, conv_dict =  converter.fromStringDict(
    316             row, self.factory_name, mode=mode)
     349        errs, inv_errs, conv_dict = super(
     350            StudentStudyCourseProcessor, self).checkConversion(row, mode=mode)
    317351        # We have to check if current_level is in range of certificate.
    318352        if conv_dict.has_key('certificate'):
     
    323357        return errs, inv_errs, conv_dict
    324358
    325 class StudentStudyLevelProcessor(BatchProcessor):
     359class StudentStudyLevelProcessor(StudentProcessorBase):
    326360    """A batch processor for IStudentStudyLevel objects.
    327361    """
     
    337371
    338372    location_fields = []
    339 
    340     @property
    341     def available_fields(self):
    342         return sorted(list(set(
    343             ['student_id','reg_number','matric_number','level'] + getFields(
    344                 self.iface).keys())))
    345 
    346     def checkHeaders(self, headerfields, mode='ignore'):
    347         if not 'reg_number' in headerfields and not 'student_id' \
    348             in headerfields and not 'matric_number' in headerfields:
    349             raise FatalCSVError(
    350                 "Need at least columns student_id " +
    351                 "or reg_number or matric_number for import!")
    352         if not 'level' in headerfields:
    353             raise FatalCSVError(
    354                 "Need level for import!")
    355         # Check for fields to be ignored...
    356         not_ignored_fields = [x for x in headerfields
    357                               if not x.startswith('--')]
    358         if len(set(not_ignored_fields)) < len(not_ignored_fields):
    359             raise FatalCSVError(
    360                 "Double headers: each column name may only appear once.")
    361         return True
     373    additional_fields = ['level']
     374    additional_headers = ['level']
    362375
    363376    def getParent(self, row, site):
    364         if not 'students' in site.keys():
    365             return None
    366         if 'student_id' in row.keys() and row['student_id']:
    367             if row['student_id'] in site['students']:
    368                 student = site['students'][row['student_id']]
    369                 return student['studycourse']
    370         elif 'reg_number' in row.keys() and row['reg_number']:
    371             reg_number = row['reg_number']
    372             cat = queryUtility(ICatalog, name='students_catalog')
    373             results = list(
    374                 cat.searchResults(reg_number=(reg_number, reg_number)))
    375             if results:
    376                 return results[0]['studycourse']
    377         elif 'matric_number' in row.keys() and row['matric_number']:
    378             matric_number = row['matric_number']
    379             cat = queryUtility(ICatalog, name='students_catalog')
    380             results = list(
    381                 cat.searchResults(matric_number=(matric_number, matric_number)))
    382             if results:
    383                 return results[0]['studycourse']
    384         return None
    385 
    386     def parentsExist(self, row, site):
    387         return self.getParent(row, site) is not None
    388 
    389     def entryExists(self, row, site):
    390         return self.getEntry(row, site) is not None
     377        student = self._getStudent(row, site)
     378        if student is None:
     379            return None
     380        return student['studycourse']
    391381
    392382    def getEntry(self, row, site):
     
    405395        """Validates all values in row.
    406396        """
    407         converter = IObjectConverter(self.iface)
    408         errs, inv_errs, conv_dict =  converter.fromStringDict(
    409             row, self.factory_name, mode=mode)
     397        errs, inv_errs, conv_dict = super(
     398            StudentStudyLevelProcessor, self).checkConversion(row, mode=mode)
     399
    410400        # We have to check if level is a valid integer.
    411401        # This is not done by the converter.
     
    418408        return errs, inv_errs, conv_dict
    419409
    420 class CourseTicketProcessor(BatchProcessor):
     410class CourseTicketProcessor(StudentProcessorBase):
    421411    """A batch processor for ICourseTicket objects.
    422412    """
     
    432422
    433423    location_fields = []
    434 
    435     @property
    436     def available_fields(self):
    437         return sorted(list(set(
    438             ['student_id','reg_number','matric_number','level',
    439              'code'] + getFields(self.iface).keys())))
    440 
    441     def checkHeaders(self, headerfields, mode='ignore'):
    442         if not 'reg_number' in headerfields and not 'student_id' \
    443             in headerfields and not 'matric_number' in headerfields:
    444             raise FatalCSVError(
    445                 "Need at least columns student_id " +
    446                 "or reg_number or matric_number for import!")
    447         if not 'level' in headerfields:
    448             raise FatalCSVError(
    449                 "Need level for import!")
    450         if not 'code' in headerfields:
    451             raise FatalCSVError(
    452                 "Need code for import!")
    453         # Check for fields to be ignored...
    454         not_ignored_fields = [x for x in headerfields
    455                               if not x.startswith('--')]
    456         if len(set(not_ignored_fields)) < len(not_ignored_fields):
    457             raise FatalCSVError(
    458                 "Double headers: each column name may only appear once.")
    459         return True
     424    additional_fields = ['level', 'code']
     425    additional_headers = ['level', 'code']
    460426
    461427    def getParent(self, row, site):
    462         if not 'students' in site.keys():
    463             return None
    464         if 'student_id' in row.keys() and row['student_id']:
    465             if row['student_id'] in site['students']:
    466                 student = site['students'][row['student_id']]
    467                 return student['studycourse'].get(row['level'])
    468         elif 'reg_number' in row.keys() and row['reg_number']:
    469             reg_number = row['reg_number']
    470             cat = queryUtility(ICatalog, name='students_catalog')
    471             results = list(
    472                 cat.searchResults(reg_number=(reg_number, reg_number)))
    473             if results:
    474                 return results[0]['studycourse'].get(row['level'])
    475         elif 'matric_number' in row.keys() and row['matric_number']:
    476             matric_number = row['matric_number']
    477             cat = queryUtility(ICatalog, name='students_catalog')
    478             results = list(
    479                 cat.searchResults(matric_number=(matric_number, matric_number)))
    480             if results:
    481                 return results[0]['studycourse'].get(row['level'])
    482         return None
    483 
    484     def parentsExist(self, row, site):
    485         return self.getParent(row, site) is not None
    486 
    487     def entryExists(self, row, site):
    488         return self.getEntry(row, site) is not None
     428        student = self._getStudent(row, site)
     429        if student is None:
     430            return None
     431        return student['studycourse'].get(row['level'])
    489432
    490433    def getEntry(self, row, site):
     
    510453        """Validates all values in row.
    511454        """
    512         converter = IObjectConverter(self.iface)
    513         errs, inv_errs, conv_dict =  converter.fromStringDict(
    514             row, self.factory_name, mode=mode)
     455        errs, inv_errs, conv_dict = super(
     456            CourseTicketProcessor, self).checkConversion(row, mode=mode)
     457
    515458        # We have to check if course really exists.
    516459        # This is not done by the converter.
     
    522465        return errs, inv_errs, conv_dict
    523466
    524 class StudentOnlinePaymentProcessor(BatchProcessor):
     467class StudentOnlinePaymentProcessor(StudentProcessorBase):
    525468    """A batch processor for IStudentOnlinePayment objects.
    526469    """
     
    536479
    537480    location_fields = []
    538 
    539     @property
    540     def available_fields(self):
    541         return sorted(list(set(
    542             ['student_id','reg_number','matric_number','p_id'] + getFields(
    543                 self.iface).keys())))
    544 
    545     def checkHeaders(self, headerfields, mode='ignore'):
    546         if not 'reg_number' in headerfields and not 'student_id' \
    547             in headerfields and not 'matric_number' in headerfields:
    548             raise FatalCSVError(
    549                 "Need at least columns student_id " +
    550                 "or reg_number or matric_number for import!")
    551         if not 'p_id' in headerfields:
    552             raise FatalCSVError(
    553                 "Need p_id for import!")
    554         # Check for fields to be ignored...
    555         not_ignored_fields = [x for x in headerfields
    556                               if not x.startswith('--')]
    557         if len(set(not_ignored_fields)) < len(not_ignored_fields):
    558             raise FatalCSVError(
    559                 "Double headers: each column name may only appear once.")
    560         return True
     481    additional_fields = ['p_id']
     482    additional_headers = ['p_id']
     483
     484    def parentsExist(self, row, site):
     485        result = self.getParent(row, site) is not None
     486        return self.getParent(row, site) is not None
    561487
    562488    def getParent(self, row, site):
    563         if not 'students' in site.keys():
    564             return None
    565         if 'student_id' in row.keys() and row['student_id']:
    566             if row['student_id'] in site['students']:
    567                 student = site['students'][row['student_id']]
    568                 return student['payments']
    569         elif 'reg_number' in row.keys() and row['reg_number']:
    570             reg_number = row['reg_number']
    571             cat = queryUtility(ICatalog, name='students_catalog')
    572             results = list(
    573                 cat.searchResults(reg_number=(reg_number, reg_number)))
    574             if results:
    575                 return results[0]['payments']
    576         elif 'matric_number' in row.keys() and row['matric_number']:
    577             matric_number = row['matric_number']
    578             cat = queryUtility(ICatalog, name='students_catalog')
    579             results = list(
    580                 cat.searchResults(matric_number=(matric_number, matric_number)))
    581             if results:
    582                 return results[0]['payments']
    583         return None
    584 
    585     def parentsExist(self, row, site):
    586         return self.getParent(row, site) is not None
    587 
    588     def entryExists(self, row, site):
    589         return self.getEntry(row, site) is not None
     489        student = self._getStudent(row, site)
     490        if student is None:
     491            return None
     492        return student['payments']
    590493
    591494    def getEntry(self, row, site):
     
    618521        """Validates all values in row.
    619522        """
    620         converter = IObjectConverter(self.iface)
    621         errs, inv_errs, conv_dict =  converter.fromStringDict(
    622             row, self.factory_name, mode=mode)
     523        errs, inv_errs, conv_dict = super(
     524            StudentOnlinePaymentProcessor, self).checkConversion(row, mode=mode)
     525
    623526        # We have to check p_id.
    624527        p_id = row['p_id'].strip('#')
     
    646549    factory_name = 'waeup.StudentStudyCourse'
    647550
    648     @property
    649     def available_fields(self):
    650         return sorted(list(set(
    651             ['student_id','reg_number','matric_number',
    652                 'current_session', 'current_level'] + getFields(
    653                 self.iface).keys())))
     551    additional_fields = ['current_session', 'current_level']
    654552
    655553    def checkUpdateRequirements(self, obj, row, site):
     
    685583        notify(grok.ObjectModifiedEvent(obj.__parent__))
    686584        return
    687 
    688     def checkConversion(self, row, mode='ignore'):
    689         """Validates all values in row.
    690         """
    691         converter = IObjectConverter(self.iface)
    692         errs, inv_errs, conv_dict =  converter.fromStringDict(
    693             row, self.factory_name, mode=mode)
    694         return errs, inv_errs, conv_dict
Note: See TracChangeset for help on using the changeset viewer.