source: main/waeup.kofa/trunk/src/waeup/kofa/students/workflow.py @ 16472

Last change on this file since 16472 was 15450, checked in by Henrik Bettermann, 6 years ago

Define alumni states (used in base packages).

  • Property svn:keywords set to Id
File size: 10.7 KB
Line 
1## $Id: workflow.py 15450 2019-06-04 07:01:04Z 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"""Workflow for students.
19"""
20import grok
21from datetime import datetime
22from zope.component import getUtility
23from hurry.workflow.workflow import Transition, WorkflowState, NullCondition
24from hurry.workflow.interfaces import IWorkflowState, IWorkflowTransitionEvent
25from waeup.kofa.interfaces import (
26    IObjectHistory, IKofaWorkflowInfo, IKofaUtils,
27    CREATED, ADMITTED, CLEARANCE, REQUESTED, CLEARED, PAID, RETURNING,
28    REGISTERED, VALIDATED, GRADUATED, TRANSREQ, TRANSVAL, TRANSREL,
29    IExtFileStore)
30from waeup.kofa.interfaces import MessageFactory as _
31from waeup.kofa.workflow import KofaWorkflow, KofaWorkflowInfo
32from waeup.kofa.students.interfaces import IStudent, IStudentsUtils
33from waeup.kofa.utils.helpers import get_current_principal
34
35
36IMPORTABLE_STATES = (ADMITTED, CLEARANCE, REQUESTED, CLEARED, PAID, RETURNING,
37    REGISTERED, VALIDATED, GRADUATED)
38
39FORBIDDEN_POSTGRAD_STATES = (RETURNING, REGISTERED, VALIDATED)
40
41ALUMNI_STATES = (GRADUATED, TRANSREQ, TRANSVAL, TRANSREL)
42
43REGISTRATION_TRANSITIONS = (
44    Transition(
45        transition_id = 'create',
46        title = _('Create student'),
47        source = None,
48        condition = NullCondition,
49        msg = _('Record created'),
50        destination = CREATED),
51
52    Transition(
53        transition_id = 'admit',
54        title = _('Admit student'),
55        msg = _('Admitted'),
56        source = CREATED,
57        destination = ADMITTED),
58
59    Transition(
60        transition_id = 'reset1',
61        title = _('Reset student'),
62        msg = _('Reset to initial state'),
63        source = ADMITTED,
64        destination = CREATED),
65
66    Transition(
67        transition_id = 'start_clearance',
68        title = _('Start clearance'),
69        msg = _('Clearance started'),
70        source = ADMITTED,
71        destination = CLEARANCE),
72
73    Transition(
74        transition_id = 'reset2',
75        title = _('Reset to admitted'),
76        msg = _("Reset to 'admitted'"),
77        source = CLEARANCE,
78        destination = ADMITTED),
79
80    Transition(
81        transition_id = 'request_clearance',
82        title = _('Request clearance'),
83        msg = _('Clearance requested'),
84        source = CLEARANCE,
85        destination = REQUESTED),
86
87    Transition(
88        transition_id = 'reset3',
89        title = _('Reset to clearance started'),
90        msg = _("Reset to 'clearance started'"),
91        source = REQUESTED,
92        destination = CLEARANCE),
93
94    Transition(
95        transition_id = 'clear',
96        title = _('Clear student'),
97        msg = _('Cleared'),
98        source = REQUESTED,
99        destination = CLEARED),
100
101    Transition(
102        transition_id = 'reset4',
103        title = _('Reset to clearance started'),
104        msg = _("Reset to 'clearance started'"),
105        source = CLEARED,
106        destination = CLEARANCE),
107
108    Transition(
109        transition_id = 'pay_first_school_fee',
110        title = _('Pay school fee'),
111        msg = _('First school fee payment made'),
112        source = CLEARED,
113        destination = PAID),
114
115    Transition(
116        transition_id = 'approve_first_school_fee',
117        title = _('Approve payment'),
118        msg = _('First school fee payment approved'),
119        source = CLEARED,
120        destination = PAID),
121
122    Transition(
123        transition_id = 'reset5',
124        title = _('Reset to cleared'),
125        msg = _("Reset to 'cleared'"),
126        source = PAID,
127        destination = CLEARED),
128
129    Transition(
130        transition_id = 'pay_school_fee',
131        title = _('Pay school fee'),
132        msg = _('School fee payment made'),
133        source = RETURNING,
134        destination = PAID),
135
136    Transition(
137        transition_id = 'pay_pg_fee',
138        title = _('Pay PG school fee'),
139        msg = _('PG school fee payment made'),
140        source = PAID,
141        destination = PAID),
142
143    Transition(
144        transition_id = 'approve_school_fee',
145        title = _('Approve school fee payment'),
146        msg = _('School fee payment approved'),
147        source = RETURNING,
148        destination = PAID),
149
150    Transition(
151        transition_id = 'approve_pg_fee',
152        title = _('Approve PG school fee payment'),
153        msg = _('PG school fee payment approved'),
154        source = PAID,
155        destination = PAID),
156
157    Transition(
158        transition_id = 'reset6',
159        title = _('Reset to returning'),
160        msg = _("Reset to 'returning'"),
161        source = PAID,
162        destination = RETURNING),
163
164    Transition(
165        transition_id = 'register_courses',
166        title = _('Register courses'),
167        msg = _('Courses registered'),
168        source = PAID,
169        destination = REGISTERED),
170
171    Transition(
172        transition_id = 'reset7',
173        title = _('Unregister courses'),
174        msg = _("Courses unregistered"),
175        source = REGISTERED,
176        destination = PAID),
177
178    Transition(
179        transition_id = 'validate_courses',
180        title = _('Validate courses'),
181        msg = _('Courses validated'),
182        source = REGISTERED,
183        destination = VALIDATED),
184
185    Transition(
186        transition_id = 'bypass_validation',
187        title = _('Return and bypass validation'),
188        msg = _("Course validation bypassed"),
189        source = REGISTERED,
190        destination = RETURNING),
191
192    Transition(
193        transition_id = 'reset8',
194        title = _('Reset to school fee paid'),
195        msg = _("Reset to 'school fee paid'"),
196        source = VALIDATED,
197        destination = PAID),
198
199    Transition(
200        transition_id = 'return',
201        title = _('Return'),
202        msg = _("Returned"),
203        source = VALIDATED,
204        destination = RETURNING),
205
206    Transition(
207        transition_id = 'reset9',
208        title = _('Reset to courses validated'),
209        msg = _("Reset to 'courses validated'"),
210        source = RETURNING,
211        destination = VALIDATED),
212
213    # There is no transition to graduated.
214
215    Transition(
216        transition_id = 'request_transcript',
217        title = _('Request transript'),
218        msg = _("Transcript requested"),
219        source = GRADUATED,
220        destination = TRANSREQ),
221
222    Transition(
223        transition_id = 'reset10',
224        title = _('Reject transcript request'),
225        msg = _("Transcript request rejected"),
226        source = TRANSREQ,
227        destination = GRADUATED),
228
229    Transition(
230        transition_id = 'validate_transcript',
231        title = _('Validate transcript'),
232        msg = _("Transcript validated"),
233        source = TRANSREQ,
234        destination = TRANSVAL),
235
236    Transition(
237        transition_id = 'release_transcript',
238        title = _('Release transcript'),
239        msg = _("Transcript released"),
240        source = TRANSVAL,
241        destination = TRANSREL),
242
243    Transition(
244        transition_id = 'reset11',
245        title = _('Reset to graduated'),
246        msg = _("Transcript process reset"),
247        source = TRANSREL,
248        destination = GRADUATED),
249    )
250
251
252IMPORTABLE_TRANSITIONS = [i.transition_id for i in REGISTRATION_TRANSITIONS]
253
254FORBIDDEN_POSTGRAD_TRANS = ['reset6', 'register_courses']
255
256registration_workflow = KofaWorkflow(REGISTRATION_TRANSITIONS)
257
258class RegistrationWorkflowState(WorkflowState, grok.Adapter):
259    """An adapter to adapt Student objects to workflow states.
260    """
261    grok.context(IStudent)
262    grok.provides(IWorkflowState)
263
264    state_key = 'wf.registration.state'
265    state_id = 'wf.registration.id'
266
267class RegistrationWorkflowInfo(KofaWorkflowInfo, grok.Adapter):
268    """Adapter to adapt Student objects to workflow info objects.
269    """
270    grok.context(IStudent)
271    grok.provides(IKofaWorkflowInfo)
272
273    def __init__(self, context):
274        self.context = context
275        self.wf = registration_workflow
276
277@grok.subscribe(IStudent, IWorkflowTransitionEvent)
278def handle_student_transition_event(obj, event):
279    """Append message to student history and log file when transition happened.
280
281    Lock and unlock clearance form.
282    Trigger actions after school fee payment.
283    """
284
285    msg = event.transition.user_data['msg']
286    history = IObjectHistory(obj)
287    history.addMessage(msg)
288    # School fee payment of returning students triggers the change of
289    # current session, current level, and current verdict
290    if event.transition.transition_id in (
291        'pay_school_fee', 'approve_school_fee'):
292        getUtility(IStudentsUtils).setReturningData(obj)
293    elif event.transition.transition_id in (
294        'pay_pg_fee', 'approve_pg_fee'):
295        new_session = obj['studycourse'].current_session + 1
296        obj['studycourse'].current_session = new_session
297    elif event.transition.transition_id == 'validate_courses':
298        current_level = obj['studycourse'].current_level
299        level_object = obj['studycourse'].get(str(current_level), None)
300        if level_object is not None:
301            user = get_current_principal()
302            if user is None:
303                usertitle = 'system'
304            else:
305                usertitle = getattr(user, 'public_name', None)
306                if not usertitle:
307                    usertitle = user.title
308            level_object.validated_by = usertitle
309            level_object.validation_date = datetime.utcnow()
310    elif event.transition.transition_id == 'clear':
311        obj.officer_comment = None
312    elif event.transition.transition_id == 'reset8':
313        current_level = obj['studycourse'].current_level
314        level_object = obj['studycourse'].get(str(current_level), None)
315        if level_object is not None:
316            level_object.validated_by = None
317            level_object.validation_date = None
318    elif event.transition.transition_id == 'reset11':
319        transcript_file = getUtility(IExtFileStore).getFileByContext(
320            obj, attr='final_transcript')
321        if transcript_file:
322            getUtility(IExtFileStore).deleteFileByContext(
323                obj, attr='final_transcript')
324        obj['studycourse'].transcript_comment = None
325        obj['studycourse'].transcript_signees = None
326    # In some tests we don't have a students container
327    try:
328        students_container = grok.getSite()['students']
329        students_container.logger.info('%s - %s' % (obj.student_id,msg))
330    except (TypeError, AttributeError):
331        pass
332    return
Note: See TracBrowser for help on using the repository browser.