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

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

Add copyright header.

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