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

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

Rename delCertCourse. This method can delete more than one certificate course.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 7.5 KB
Line 
1## $Id: certificate.py 9826 2013-01-05 14:07:47Z 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##
18"""Kofa certificates
19"""
20import grok
21from zope.event import notify
22from zope.catalog.interfaces import ICatalog
23from zope.intid.interfaces import IIntIds
24from zope.schema import getFields
25from zope.component import getUtility
26from zope.component.interfaces import IFactory, ComponentLookupError
27from zope.interface import implementedBy
28from waeup.kofa.interfaces import IKofaPluggable
29from waeup.kofa.university.interfaces import (
30    ICertificate, ICertificateAdd, ICertificateCourse)
31from waeup.kofa.university.vocabularies import course_levels
32
33class Certificate(grok.Container):
34    """A certificate.
35    """
36    grok.implements(ICertificate, ICertificateAdd)
37
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        ]
46
47    def __init__(self, code=u'NA', title=u'Unnamed Certificate',
48                 study_mode=None, start_level=None,
49                 end_level=None, application_category=None,
50                 school_fee_1=None, school_fee_2=None,
51                 school_fee_3=None, school_fee_4=None):
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
59        self.school_fee_1 = school_fee_1
60        self.school_fee_2 = school_fee_2
61        self.school_fee_3 = school_fee_3
62        self.school_fee_4 = school_fee_4
63
64    def longtitle(self):
65        return "%s (%s)" % (self.title,self.code)
66
67    def addCertCourse(self, course, level=100, mandatory=True):
68        """Add a certificate course.
69        """
70        code = "%s_%s" % (course.code, level)
71        self[code] = CertificateCourse(course, level, mandatory)
72        self[code].__parent__ = self
73        self[code].__name__ = code
74        self._p_changed = True
75
76    def delCertCourses(self, code, level=None):
77        """Delete certificate courses.
78
79        We might have more than one certificate course for a course.
80        If level is not provided all certificate courses referring
81        to the same course will be deleted.
82        """
83        keys = list(self.keys()) # create list copy
84        for key in keys:
85            if self[key].getCourseCode() != code:
86                continue
87            if level is not None and str(self[key].level) != str(level):
88                # found a course with correct key but wrong level...
89                continue
90            del self[key]
91            self._p_changed = True
92        return
93
94    def moveCertificate(self, fac, dep):
95        self.moved = True
96        cert = self
97        del self.__parent__[cert.code]
98        grok.getSite()['faculties'][fac][dep].certificates[cert.code] = cert
99        self.__parent__._p_changed = True
100        cat = getUtility(ICatalog, name='students_catalog')
101        results = cat.searchResults(certcode=(cert.code, cert.code))
102        for student in results:
103            notify(grok.ObjectModifiedEvent(student))
104            student.__parent__.logger.info(
105                '%s - Certificate moved' % student.__name__)
106
107        return
108
109class CertificateFactory(grok.GlobalUtility):
110    """A factory for certificates.
111    """
112    grok.implements(IFactory)
113    grok.name(u'waeup.Certificate')
114    title = u"Create a new certificate.",
115    description = u"This factory instantiates new certificate instances."
116
117    def __call__(self, *args, **kw):
118        return Certificate(*args, **kw)
119
120    def getInterfaces(self):
121        return implementedBy(Certificate)
122
123class CertificateCourse(grok.Model):
124    grok.implements(ICertificateCourse)
125
126    def __init__(self, course=None, level=100, mandatory=True):
127        self.course = course
128        self.level = level
129        self.mandatory = mandatory
130
131    def getCourseCode(self):
132        """Get code of a course.
133        """
134        return self.course.code
135
136    def longtitle(self):
137        return "%s in level %s" % (self.course.code,
138                   course_levels.getTerm(self.level).title)
139
140class CertificateCourseFactory(grok.GlobalUtility):
141    """A factory for certificate courses.
142    """
143    grok.implements(IFactory)
144    grok.name(u'waeup.CertificateCourse')
145    title = u"Create a new certificate course.",
146    description = u"This factory instantiates new certificate courses."
147
148    def __call__(self, *args, **kw):
149        return CertificateCourse(*args, **kw)
150
151    def getInterfaces(self):
152        return implementedBy(CertificateCourse)
153
154@grok.subscribe(ICertificate, grok.IObjectRemovedEvent)
155def handle_certificate_removed(certificate, event):
156    """If a certificate is deleted, we make sure that also referrers to
157    student studycourse objects are removed.
158    """
159    # Do not remove referrer if certificate is going to move
160    if getattr(certificate, 'moved', False):
161        return
162
163    code = certificate.code
164
165    # Find all student studycourses that refer to given certificate...
166    try:
167        cat = getUtility(ICatalog, name='students_catalog')
168    except ComponentLookupError:
169        # catalog not available. This might happen during tests.
170        return
171
172    results = cat.searchResults(certcode=(code, code))
173    for student in results:
174        # Remove that referrer...
175        studycourse = student['studycourse']
176        studycourse.certificate = None
177        notify(grok.ObjectModifiedEvent(student))
178        student.__parent__.logger.info(
179            'ObjectRemovedEvent - %s - removed: certificate' % student.__name__)
180    return
181
182class CertificatesPlugin(grok.GlobalUtility):
183    """A plugin that updates certificates.
184    """
185
186    grok.implements(IKofaPluggable)
187    grok.name('certificates')
188
189    deprecated_attributes = []
190
191    def setup(self, site, name, logger):
192        return
193
194    def update(self, site, name, logger):
195        cat = getUtility(ICatalog, name='certificates_catalog')
196        results = cat.apply({'code':(None,None)})
197        uidutil = getUtility(IIntIds, context=cat)
198        items = getFields(ICertificate).items()
199        for r in results:
200            o = uidutil.getObject(r)
201            # Add new attributes
202            for i in items:
203                if not hasattr(o,i[0]):
204                    setattr(o,i[0],i[1].missing_value)
205                    logger.info(
206                        'CertificatesPlugin: %s attribute %s added.' % (
207                        o.code,i[0]))
208            # Remove deprecated attributes
209            for i in self.deprecated_attributes:
210                try:
211                    delattr(o,i)
212                    logger.info(
213                        'CertificatesPlugin: %s attribute %s deleted.' % (
214                        o.code,i))
215                except AttributeError:
216                    pass
217        return
Note: See TracBrowser for help on using the repository browser.