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

Last change on this file since 10613 was 10530, checked in by Henrik Bettermann, 11 years ago

Add waeup.local.DepartmentOfficer? to local_roles of Certificates.

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