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

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

Add BalancePaymentAddFormPage which can only be opened by managers.
No button is provided in base package.

  • Property svn:keywords set to Id
File size: 6.3 KB
Line 
1## $Id: utils.py 17016 2022-07-10 08:40:43Z 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    def setPaymentDetails(self, container, payment, applicant):
59        """Set the payment data of an applicant.
60        In contrast to its `StudentsUtils` counterpart, the payment ticket
61        must exist and is an argument of this method.
62        """
63        timestamp = ("%d" % int(time()*10000))[1:]
64        payment.p_id = "p%s" % timestamp
65        payment.p_item = container.title
66        if container.year:
67            payment.p_session = container.year
68        else:
69            payment.p_session = datetime.now().year
70        payment.amount_auth = 0.0
71        if applicant.special:
72            if applicant.special_application:
73                try:
74                    session_config = grok.getSite()['configuration'][
75                        str(payment.p_session)]
76                except KeyError:
77                    return _(u'Session configuration object is not available.')   
78                fee_name = applicant.special_application + '_fee'
79                payment.amount_auth = getattr(session_config, fee_name, None)
80                payment.p_category = applicant.special_application
81            if payment.amount_auth in (0.0, None):
82                return _('Amount could not be determined. Have you saved the form?')
83            return
84        payment.p_category = 'application'
85        container_fee = container.application_fee
86        if not container_fee:
87            return _('Amount could not be determined.')
88        payment.amount_auth = container_fee
89        return
90
91    def setBalanceDetails(self, applicant, category, balance_amount):
92        """Create a balance payment ticket and set the payment data
93        as selected by the applicant.
94        """
95        if applicant.state not in (PAID, ADMITTED, SUBMITTED, PROCESSED):
96            return _('Wrong state.'), None
97        p_item = u'Balance'
98        amount = balance_amount
99        if amount in (0.0, None) or amount < 0:
100            return _('Amount must be greater than 0.'), None
101        payment = createObject(u'waeup.ApplicantOnlinePayment')
102        timestamp = ("%d" % int(time()*10000))[1:]
103        payment.p_id = "p%s" % timestamp
104        payment.p_category = category
105        payment.p_item = p_item
106        if applicant.__parent__.year:
107            payment.p_session = applicant.__parent__.year
108        else:
109            payment.p_session = datetime.now().year
110        payment.amount_auth = amount
111        return None, payment
112
113    def getApplicantsStatistics(self, container):
114        """Count applicants in applicants containers.
115        """
116        state_stats = {INITIALIZED:0, STARTED:0, PAID:0, SUBMITTED:0,
117            ADMITTED:0, NOT_ADMITTED:0, CREATED:0, PROCESSED:0}
118        cat = getUtility(ICatalog, name='applicants_catalog')
119        code = container.code
120        for state in state_stats:
121            if state == 'initialized':
122                results = cat.searchResults(
123                                state=(state, state),
124                                container_code=(code + '+', code + '+'))
125                state_stats[state] = len(results)
126            else:
127                results = cat.searchResults(
128                    state=(state, state),
129                    container_code=(code + '+', code + '-'))
130                state_stats[state] = len(results)
131        return state_stats, None
132
133    def sortCertificates(self, context, resultset):
134        """Sort already filtered certificates in `AppCatCertificateSource`.
135        Display also current course even if certificate in the academic
136        section has been removed.
137        """
138        resultlist = sorted(resultset, key=lambda value: value.code)
139        curr_course = context.course1
140        if curr_course is not None and curr_course not in resultlist:
141            resultlist = [curr_course,] + resultlist
142        return resultlist
143
144    def getCertTitle(self, context, value):
145        """Compose the titles in `AppCatCertificateSource`.
146        """
147        return "%s - %s" % (value.code, value.title)
148
149    def isPictureEditable(self, container):
150        """False if applicants are not allowed to edit uploaded pictures.
151        """
152        return container.with_picture
Note: See TracBrowser for help on using the repository browser.