source: main/waeup.kofa/trunk/src/waeup/kofa/students/payments.py @ 12986

Last change on this file since 12986 was 12889, checked in by Henrik Bettermann, 10 years ago

Bypass school fee payment activation code creation if student is allowed
to proceed to next session.

  • Property svn:keywords set to Id
File size: 7.6 KB
Line 
1## $Id: payments.py 12889 2015-04-27 08:14:31Z 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"""
19Student payment components.
20"""
21import grok
22from zope.component.interfaces import IFactory
23from zope.interface import implementedBy
24from zope.schema.interfaces import ConstraintNotSatisfied
25from hurry.workflow.interfaces import IWorkflowInfo
26from waeup.kofa.interfaces import MessageFactory as _
27from waeup.kofa.students.interfaces import (
28    IStudentPaymentsContainer, IStudentNavigation, IStudentOnlinePayment)
29from waeup.kofa.students.workflow import CLEARED, RETURNING, PAID
30from waeup.kofa.payments import PaymentsContainer, OnlinePayment
31from waeup.kofa.payments.interfaces import IPayer
32from waeup.kofa.utils.helpers import attrs_to_fields
33from waeup.kofa.accesscodes import create_accesscode
34
35class StudentPaymentsContainer(PaymentsContainer):
36    """This is a container for student payments.
37    """
38    grok.implements(IStudentPaymentsContainer, IStudentNavigation)
39    grok.provides(IStudentPaymentsContainer)
40
41    def __init__(self):
42        super(StudentPaymentsContainer, self).__init__()
43        return
44
45    @property
46    def student(self):
47        return self.__parent__
48
49    def writeLogMessage(self, view, message):
50        return self.__parent__.writeLogMessage(view, message)
51
52StudentPaymentsContainer = attrs_to_fields(StudentPaymentsContainer)
53
54class StudentOnlinePayment(OnlinePayment):
55    """This is an online payment.
56    """
57    grok.implements(IStudentOnlinePayment, IStudentNavigation)
58    grok.provides(IStudentOnlinePayment)
59
60    def __init__(self):
61        super(StudentOnlinePayment, self).__init__()
62        return
63
64    @property
65    def student(self):
66        try:
67            return self.__parent__.__parent__
68        except AttributeError:
69            return None
70
71    def writeLogMessage(self, view, message):
72        return self.__parent__.__parent__.writeLogMessage(view, message)
73
74    def _redeemTicket(self):
75        student = self.student
76        if self.p_category == 'clearance':
77            # Create CLR access code
78            pin, error = create_accesscode(
79                'CLR',0,self.amount_auth,student.student_id)
80            if error:
81                return error
82            self.ac = pin
83        elif self.p_category in ('schoolfee', 'schoolfee_1'):
84            # Bypass activation code creation if next session
85            # can be started directly.
86            if student['studycourse'].next_session_allowed:
87                try:
88                    if student.state == CLEARED:
89                        IWorkflowInfo(student).fireTransition(
90                            'pay_first_school_fee')
91                        return None
92                    elif student.state == RETURNING:
93                        IWorkflowInfo(student).fireTransition(
94                            'pay_school_fee')
95                        return None
96                    elif student.state == PAID:
97                        IWorkflowInfo(student).fireTransition(
98                            'pay_pg_fee')
99                        return None
100                except ConstraintNotSatisfied:
101                    pass
102            # Create SFE access code
103            pin, error = create_accesscode(
104                'SFE',0,self.amount_auth,student.student_id)
105            if error:
106                return error
107            self.ac = pin
108        elif self.p_category == 'bed_allocation':
109            # Create HOS access code
110            pin, error = create_accesscode(
111                'HOS',0,self.amount_auth,student.student_id)
112            if error:
113                return error
114            self.ac = pin
115        elif self.p_category == 'transcript':
116            # Create TSC access code
117            pin, error = create_accesscode(
118                'TSC',0,self.amount_auth,student.student_id)
119            if error:
120                return error
121            self.ac = pin
122        return None
123
124    def doAfterStudentPayment(self):
125        """Process student after payment was made.
126        """
127        if self.p_current:
128            error = self._redeemTicket()
129            if error is not None:
130                return 'danger', error, error
131        log = 'successful %s payment: %s' % (self.p_category, self.p_id)
132        msg = _('Successful payment')
133        flashtype = 'success'
134        return flashtype, msg, log
135
136    def doAfterStudentPaymentApproval(self):
137        """Process student after payment was approved.
138        """
139        if self.p_current:
140            error = self._redeemTicket()
141            if error is not None:
142                return 'danger', error, error
143        log = '%s payment approved: %s' % (self.p_category, self.p_id)
144        msg = _('Payment approved.')
145        flashtype = 'success'
146        return flashtype, msg, log
147
148    def approveStudentPayment(self):
149        """Approve payment and process student.
150        """
151        if self.p_state == 'paid':
152            return 'warning', _('This ticket has already been paid.'), None
153        self.approve()
154        return self.doAfterStudentPaymentApproval()
155
156
157StudentOnlinePayment = attrs_to_fields(
158    StudentOnlinePayment, omit=['display_item'])
159
160class Payer(grok.Adapter):
161    """An adapter to publish student data through a simple webservice.
162    """
163    grok.context(IStudentOnlinePayment)
164    grok.implements(IPayer)
165
166    @property
167    def display_fullname(self):
168        "Name of  payer"
169        return self.context.student.display_fullname
170
171    @property
172    def id(self):
173        "Id of payer"
174        return self.context.student.student_id
175
176    @property
177    def matric_number(self):
178        "Matric number or reg number of payer"
179        return self.context.student.matric_number
180
181    @property
182    def reg_number(self):
183        "Reg number or reg number of payer"
184        return self.context.student.reg_number
185
186    @property
187    def faculty(self):
188        "Faculty of payer"
189        return self.context.student.faccode
190
191    @property
192    def department(self):
193        "Department of payer"
194        return self.context.student.depcode
195
196    @property
197    def email(self):
198        "Email of payer"
199        return self.context.student.email
200
201    @property
202    def phone(self):
203        "Phone number of payer"
204        return self.context.student.phone
205
206    @property
207    def current_mode(self):
208        "Current study mode of payer"
209        return self.context.student.current_mode
210
211    @property
212    def current_level(self):
213        "Current level of payer"
214        return self.context.student.current_level
215
216# Student online payments must be importable. So we might need a factory.
217class StudentOnlinePaymentFactory(grok.GlobalUtility):
218    """A factory for student online payments.
219    """
220    grok.implements(IFactory)
221    grok.name(u'waeup.StudentOnlinePayment')
222    title = u"Create a new online payment.",
223    description = u"This factory instantiates new online payment instances."
224
225    def __call__(self, *args, **kw):
226        return StudentOnlinePayment()
227
228    def getInterfaces(self):
229        return implementedBy(StudentOnlinePayment)
Note: See TracBrowser for help on using the repository browser.