source: main/waeup.kofa/trunk/src/waeup/kofa/applicants/utils.py @ 17412

Last change on this file since 17412 was 17018, checked in by Henrik Bettermann, 2 years ago

Disable applicant balance payments in base package completely.

  • Property svn:keywords set to Id
File size: 6.4 KB
Line 
1## $Id: utils.py 17018 2022-07-10 11:47: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##
18"""General helper functions and utilities for the applicants section.
19"""
20
21from time import time
22from datetime import datetime
23import grok
24from zope.component import getUtility, createObject
25from zope.catalog.interfaces import ICatalog
26from waeup.kofa.interfaces import MessageFactory as _
27from waeup.kofa.applicants.interfaces import IApplicantsUtils
28from waeup.kofa.applicants.workflow import (INITIALIZED,
29    STARTED, PAID, ADMITTED, NOT_ADMITTED, SUBMITTED, CREATED, PROCESSED)
30
31class ApplicantsUtils(grok.GlobalUtility):
32    """A collection of parameters and methods subject to customization.
33    """
34    grok.implements(IApplicantsUtils)
35
36    #: A dictionary containing application type names, titles and
37    #: access code prefixes (meanwhile deprecated).
38    APP_TYPES_DICT = {
39      'app': ['General Studies', 'APP'],
40      'special': ['Special Application', 'SPE'],
41      }
42
43    #: A dictionary which maps widget names to headlines.
44    #: The headline is rendered in forms and on pdf slips above the
45    #: respective display or input widget.
46    SEPARATORS_DICT = {
47      'form.applicant_id': _(u'Base Data'),
48      'form.course1': _(u'Desired Study Courses'),
49      'form.notice': _(u'Application Process Data'),
50      'form.referees': _(u'Referees (automatically invited by email '
51                          'after final submission of this form)'),
52      }
53
54    #: A tuple of tuple of file names to be uploaded by applicants and copied
55    #: over to the students section.
56    ADDITIONAL_FILES = (('Test File','testfile'),)
57   
58    # A list of states which enable balance payments (not used in base package)
59    BALANCE_PAYMENT_STATES = ()
60
61    def setPaymentDetails(self, container, payment, applicant):
62        """Set the payment data of an applicant.
63        In contrast to its `StudentsUtils` counterpart, the payment ticket
64        must exist and is an argument of this method.
65        """
66        timestamp = ("%d" % int(time()*10000))[1:]
67        payment.p_id = "p%s" % timestamp
68        payment.p_item = container.title
69        if container.year:
70            payment.p_session = container.year
71        else:
72            payment.p_session = datetime.now().year
73        payment.amount_auth = 0.0
74        if applicant.special:
75            if applicant.special_application:
76                try:
77                    session_config = grok.getSite()['configuration'][
78                        str(payment.p_session)]
79                except KeyError:
80                    return _(u'Session configuration object is not available.')   
81                fee_name = applicant.special_application + '_fee'
82                payment.amount_auth = getattr(session_config, fee_name, None)
83                payment.p_category = applicant.special_application
84            if payment.amount_auth in (0.0, None):
85                return _('Amount could not be determined. Have you saved the form?')
86            return
87        payment.p_category = 'application'
88        container_fee = container.application_fee
89        if not container_fee:
90            return _('Amount could not be determined.')
91        payment.amount_auth = container_fee
92        return
93
94    def setBalanceDetails(self, applicant, category, balance_amount):
95        """Create a balance payment ticket and set the payment data
96        as selected by the applicant.
97        """
98        if applicant.state not in self.BALANCE_PAYMENT_STATES:
99            return _('Wrong state.'), None
100        p_item = u'Balance'
101        amount = balance_amount
102        if amount in (0.0, None) or amount < 0:
103            return _('Amount must be greater than 0.'), None
104        payment = createObject(u'waeup.ApplicantOnlinePayment')
105        timestamp = ("%d" % int(time()*10000))[1:]
106        payment.p_id = "p%s" % timestamp
107        payment.p_category = category
108        payment.p_item = p_item
109        if applicant.__parent__.year:
110            payment.p_session = applicant.__parent__.year
111        else:
112            payment.p_session = datetime.now().year
113        payment.amount_auth = amount
114        return None, payment
115
116    def getApplicantsStatistics(self, container):
117        """Count applicants in applicants containers.
118        """
119        state_stats = {INITIALIZED:0, STARTED:0, PAID:0, SUBMITTED:0,
120            ADMITTED:0, NOT_ADMITTED:0, CREATED:0, PROCESSED:0}
121        cat = getUtility(ICatalog, name='applicants_catalog')
122        code = container.code
123        for state in state_stats:
124            if state == 'initialized':
125                results = cat.searchResults(
126                                state=(state, state),
127                                container_code=(code + '+', code + '+'))
128                state_stats[state] = len(results)
129            else:
130                results = cat.searchResults(
131                    state=(state, state),
132                    container_code=(code + '+', code + '-'))
133                state_stats[state] = len(results)
134        return state_stats, None
135
136    def sortCertificates(self, context, resultset):
137        """Sort already filtered certificates in `AppCatCertificateSource`.
138        Display also current course even if certificate in the academic
139        section has been removed.
140        """
141        resultlist = sorted(resultset, key=lambda value: value.code)
142        curr_course = context.course1
143        if curr_course is not None and curr_course not in resultlist:
144            resultlist = [curr_course,] + resultlist
145        return resultlist
146
147    def getCertTitle(self, context, value):
148        """Compose the titles in `AppCatCertificateSource`.
149        """
150        return "%s - %s" % (value.code, value.title)
151
152    def isPictureEditable(self, container):
153        """False if applicants are not allowed to edit uploaded pictures.
154        """
155        return container.with_picture
Note: See TracBrowser for help on using the repository browser.