source: main/waeup.kofa/trunk/src/waeup/kofa/applicants/container.py @ 17860

Last change on this file since 17860 was 16134, checked in by Henrik Bettermann, 4 years ago

Ease customization.

  • Property svn:keywords set to Id
File size: 5.1 KB
RevLine 
[5649]1## $Id: container.py 16134 2020-06-28 18:01:52Z henrik $
[6077]2##
[6478]3## Copyright (C) 2011 Uli Fouquet & Henrik Bettermann
[5649]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.
[6077]8##
[5649]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.
[6077]13##
[5649]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"""
[5676]19Containers for university applicants.
[5649]20"""
[7260]21from random import SystemRandom as r
[5649]22import grok
[8665]23import pytz
24from datetime import datetime
[10655]25import zope.location.location
[13077]26from zope.component import getUtility, ComponentLookupError
[6280]27from zope.component.factory import Factory
28from zope.component.interfaces import IFactory
[13217]29from zope.catalog.interfaces import ICatalog
[7847]30from waeup.kofa.interfaces import MessageFactory as _
[7811]31from waeup.kofa.applicants.interfaces import (
[8645]32    IApplicantsContainer, IApplicantsContainerAdd, IApplicant,
33    IApplicantsUtils)
[7811]34from waeup.kofa.utils.helpers import attrs_to_fields
[10655]35from waeup.kofa.utils.batching import VirtualExportJobContainer
[5649]36
[7260]37def generate_applicant_id(container=None):
38    if container is not None:
[8540]39        key = r().randint(99999,1000000)
[8543]40        while str(key) in container.keys():
[8540]41            key = r().randint(99999,1000000)
42        return u"%s_%d" % (container.code, key)
[7260]43    else:
44        # In some tests we don't use containers
45        return u"xxx_1234"
46
[10655]47class VirtualApplicantsExportJobContainer(VirtualExportJobContainer):
[15501]48    """A virtual export job container for applicants container.
[10655]49    """
50
[5676]51class ApplicantsContainer(grok.Container):
52    """An applicants container contains university applicants.
[5649]53    """
[6069]54    grok.implements(IApplicantsContainer,IApplicantsContainerAdd)
[5649]55
[7903]56    description_dict = {}
[6077]57
[13570]58    local_roles = [
59        'waeup.local.ApplicationsManager',
60        ]
[6184]61
[16133]62    @property
63    def picture_editable(self):
[16134]64        try:
65            return getUtility(IApplicantsUtils).isPictureEditable(self)
66        except ComponentLookupError:  # happens in unit tests
67            return
[16133]68
[7240]69    def addApplicant(self, applicant):
70        """Add an applicant.
71        """
[8008]72        if not IApplicant.providedBy(applicant):
[7240]73            raise TypeError(
[8008]74                'ApplicantsContainers contain only IApplicant instances')
[8290]75        if applicant.applicant_id is None:
76            applicant_id = generate_applicant_id(container=self)
77            applicant.applicant_id = applicant_id
[7240]78        self[applicant.application_number] = applicant
79        return
80
[8563]81    @property
[13217]82    def counts(self):
83        total = len(self)
84        code = self.code + '+'
85        cat = getUtility(ICatalog, name='applicants_catalog')
86        results = list(
87           cat.searchResults(container_code=(code, code)))
88        return len(self), len(results)
89
90    @property
91    def first_unused(self):
92        code = self.code + '-'
93        cat = getUtility(ICatalog, name='applicants_catalog')
94        results = list(
95           cat.searchResults(container_code=(code, code)))
96        if results:
97            return results[0]
98        return
99
100    @property
[8643]101    def statistics(self):
[13077]102        try:
103          statistics = getUtility(
104              IApplicantsUtils).getApplicantsStatistics(self)
105        except ComponentLookupError:  # happens in unit tests
106            return
107        return statistics
[8643]108
[8665]109    @property
110    def expired(self):
111        # Check if application has started ...
112        if not self.startdate or (
113            self.startdate > datetime.now(pytz.utc)):
114            return True
115        # ... or ended
116        if not self.enddate or (
117            self.enddate < datetime.now(pytz.utc)):
118            return True
119        return False
120
[9531]121    def writeLogMessage(self, view, message):
122        ob_class = view.__implemented__.__name__.replace('waeup.kofa.','')
123        self.__parent__.logger.info(
124            '%s - %s - %s' % (ob_class, self.code, message))
125        return
[8665]126
[10655]127    def traverse(self, name):
[13077]128        """Deliver virtual export container.
[10655]129        """
130        if name == 'exports':
[15517]131            # create a virtual exports container and return it
132            container = VirtualApplicantsExportJobContainer()
[10655]133            zope.location.location.located(container, self, 'exports')
134            return container
135        return None
136
[6072]137ApplicantsContainer = attrs_to_fields(ApplicantsContainer)
[6077]138
[8008]139# ApplicantsContainers must be importable. So we need a factory.
140class ApplicantsContainerFactory(grok.GlobalUtility):
141    """A factory for student online payments.
[5821]142    """
[8008]143    grok.implements(IFactory)
144    grok.name(u'waeup.ApplicantsContainer')
145    title = u"Create a new container for applicants.",
146    description = u"This factory instantiates new IApplicantsContainer instances."
[5821]147
[8008]148    def __call__(self, *args, **kw):
149        return ApplicantsContainer()
[6280]150
[8008]151    def getInterfaces(self):
152        return implementedBy(ApplicantsContainer)
Note: See TracBrowser for help on using the repository browser.