source: main/waeup.kofa/trunk/src/waeup/kofa/university/certificate.py @ 9342

Last change on this file since 9342 was 9341, checked in by Henrik Bettermann, 12 years ago

Add moveCertificate. The new method is not yet used in any view or batch processor.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 7.4 KB
RevLine 
[7195]1## $Id: certificate.py 9341 2012-10-16 04:31:16Z henrik $
2##
3## Copyright (C) 2011 Uli Fouquet & Henrik Bettermann
4## This program is free software; you can redistribute it and/or modify
5## it under the terms of the GNU General Public License as published by
6## the Free Software Foundation; either version 2 of the License, or
7## (at your option) any later version.
8##
9## This program is distributed in the hope that it will be useful,
10## but WITHOUT ANY WARRANTY; without even the implied warranty of
11## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12## GNU General Public License for more details.
13##
14## You should have received a copy of the GNU General Public License
15## along with this program; if not, write to the Free Software
16## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17##
[7819]18"""Kofa certificates
[4789]19"""
20import grok
[7209]21from zope.event import notify
[6296]22from zope.catalog.interfaces import ICatalog
[8299]23from zope.intid.interfaces import IIntIds
24from zope.schema import getFields
[4789]25from zope.component import getUtility
26from zope.component.interfaces import IFactory, ComponentLookupError
27from zope.interface import implementedBy
[8299]28from waeup.kofa.interfaces import IKofaPluggable
[7811]29from waeup.kofa.university.interfaces import (
[7207]30    ICertificate, ICertificateAdd, ICertificateCourse)
[7811]31from waeup.kofa.university.vocabularies import course_levels
[4789]32
33class Certificate(grok.Container):
34    """A certificate.
35    """
[5953]36    grok.implements(ICertificate, ICertificateAdd)
[4789]37
[8993]38    local_roles = [
39        'waeup.local.CourseAdviser100',
40        'waeup.local.CourseAdviser200',
41        'waeup.local.CourseAdviser300',
42        'waeup.local.CourseAdviser400',
43        'waeup.local.CourseAdviser500',
44        'waeup.local.CourseAdviser600',
45        ]
[7334]46
[4789]47    def __init__(self, code=u'NA', title=u'Unnamed Certificate',
[4993]48                 study_mode=None, start_level=None,
[8299]49                 end_level=None, application_category=None,
[8967]50                 school_fee_1=None, school_fee_2=None,
51                 school_fee_3=None, school_fee_4=None):
[4789]52        super(Certificate, self).__init__()
53        self.code = code
54        self.title = title
55        self.study_mode = study_mode
56        self.start_level = start_level
57        self.end_level = end_level
58        self.application_category = application_category
[8299]59        self.school_fee_1 = school_fee_1
60        self.school_fee_2 = school_fee_2
[8967]61        self.school_fee_3 = school_fee_3
62        self.school_fee_4 = school_fee_4
[4789]63
[6008]64    def longtitle(self):
[7349]65        return "%s (%s)" % (self.title,self.code)
66
[8920]67    def addCertCourse(self, course, level=100, mandatory=True):
68        """Add a certificate course.
[4789]69        """
70        code = "%s_%s" % (course.code, level)
[7665]71        self[code] = CertificateCourse(course, level, mandatory)
[4789]72        self[code].__parent__ = self
73        self[code].__name__ = code
74        self._p_changed = True
75
[8920]76    def delCertCourse(self, code, level=None):
77        """Delete a certificate course denoted by its code.
[4789]78        """
[6980]79        keys = list(self.keys()) # create list copy
80        for key in keys:
[4789]81            if self[key].getCourseCode() != code:
82                continue
83            if level is not None and str(self[key].level) != str(level):
84                # found a course with correct key but wrong level...
85                continue
86            del self[key]
87            self._p_changed = True
88        return
89
[9341]90    def moveCertificate(self, fac, dep):
91        self.moved = True
92        cert = self
93        del self.__parent__[cert.code]
94        grok.getSite()['faculties'][fac][dep].certificates[cert.code] = cert
95        self.__parent__._p_changed = True
96        cat = getUtility(ICatalog, name='students_catalog')
97        results = cat.searchResults(certcode=(cert.code, cert.code))
98        for student in results:
99            notify(grok.ObjectModifiedEvent(student))
100            student.__parent__.logger.info(
101                '%s - Certificate moved' % student.__name__)
102
103        return
104
[4789]105class CertificateFactory(grok.GlobalUtility):
106    """A factory for certificates.
107    """
108    grok.implements(IFactory)
109    grok.name(u'waeup.Certificate')
110    title = u"Create a new certificate.",
111    description = u"This factory instantiates new certificate instances."
112
113    def __call__(self, *args, **kw):
114        return Certificate(*args, **kw)
115
116    def getInterfaces(self):
117        return implementedBy(Certificate)
118
119class CertificateCourse(grok.Model):
120    grok.implements(ICertificateCourse)
121
[7665]122    def __init__(self, course=None, level=100, mandatory=True):
[4789]123        self.course = course
124        self.level = level
[7665]125        self.mandatory = mandatory
[4789]126
127    def getCourseCode(self):
128        """Get code of a course.
129        """
130        return self.course.code
[7349]131
[6008]132    def longtitle(self):
133        return "%s in level %s" % (self.course.code,
[7349]134                   course_levels.getTerm(self.level).title)
135
[4789]136class CertificateCourseFactory(grok.GlobalUtility):
137    """A factory for certificate courses.
138    """
139    grok.implements(IFactory)
140    grok.name(u'waeup.CertificateCourse')
141    title = u"Create a new certificate course.",
142    description = u"This factory instantiates new certificate courses."
143
144    def __call__(self, *args, **kw):
145        return CertificateCourse(*args, **kw)
146
147    def getInterfaces(self):
148        return implementedBy(CertificateCourse)
[7209]149
150@grok.subscribe(ICertificate, grok.IObjectRemovedEvent)
151def handle_certificate_removed(certificate, event):
152    """If a certificate is deleted, we make sure that also referrers to
153    student studycourse objects are removed.
154    """
[9341]155    # Do not remove referrer if certificate is going to move
156    if getattr(certificate, 'moved', False):
157        return
158
[7209]159    code = certificate.code
160
161    # Find all student studycourses that refer to given certificate...
162    try:
163        cat = getUtility(ICatalog, name='students_catalog')
164    except ComponentLookupError:
165        # catalog not available. This might happen during tests.
166        return
167
168    results = cat.searchResults(certcode=(code, code))
169    for student in results:
170        # Remove that referrer...
171        studycourse = student['studycourse']
172        studycourse.certificate = None
173        notify(grok.ObjectModifiedEvent(student))
[8737]174        student.__parent__.logger.info(
175            'ObjectRemovedEvent - %s - removed: certificate' % student.__name__)
[7349]176    return
[8299]177
178class CertificatesPlugin(grok.GlobalUtility):
179    """A plugin that updates certificates.
180    """
181
182    grok.implements(IKofaPluggable)
183    grok.name('certificates')
184
[8310]185    deprecated_attributes = []
186
[8299]187    def setup(self, site, name, logger):
188        return
189
190    def update(self, site, name, logger):
191        cat = getUtility(ICatalog, name='certificates_catalog')
192        results = cat.apply({'code':(None,None)})
193        uidutil = getUtility(IIntIds, context=cat)
194        items = getFields(ICertificate).items()
195        for r in results:
196            o = uidutil.getObject(r)
[8310]197            # Add new attributes
[8299]198            for i in items:
[8310]199                if not hasattr(o,i[0]):
[8299]200                    setattr(o,i[0],i[1].missing_value)
201                    logger.info(
202                        'CertificatesPlugin: %s attribute %s added.' % (
203                        o.code,i[0]))
[8310]204            # Remove deprecated attributes
205            for i in self.deprecated_attributes:
206                try:
207                    delattr(o,i)
208                    logger.info(
209                        'CertificatesPlugin: %s attribute %s deleted.' % (
210                        o.code,i))
211                except AttributeError:
212                    pass
[8299]213        return
Note: See TracBrowser for help on using the repository browser.