source: main/waeup.sirp/trunk/src/waeup/sirp/applicants/workflow.py @ 6326

Last change on this file since 6326 was 6323, checked in by Henrik Bettermann, 13 years ago

Replace reserved term 'messages' by 'msgs'.

  • Property svn:keywords set to Id
File size: 5.8 KB
Line 
1"""Workflow for applicants.
2"""
3import grok
4from datetime import datetime
5from hurry.workflow.workflow import (
6    Transition, Workflow, WorkflowVersions, WorkflowInfo, WorkflowState,
7    NullCondition)
8from hurry.workflow.interfaces import (
9    IWorkflow, IWorkflowState, IWorkflowInfo, IWorkflowVersions,
10    InvalidTransitionError, IWorkflowTransitionEvent)
11from waeup.sirp.applicants.interfaces import IApplicantBaseData
12
13
14INITIALIZED = 'initialized'
15STARTED = 'started'
16SUBMITTED = 'submitted'
17ADMITTED = 'admitted'
18NOT_ADMITTED = 'not admitted'
19CREATED = 'created'
20
21def create_workflow():
22    init_transition = Transition(
23        transition_id = 'init',
24        title = 'Initialize application',
25        source = None,
26        condition = NullCondition,
27        msg = 'appplication process initialized',
28        destination = INITIALIZED)
29
30    start_transition = Transition(
31        transition_id = 'start',
32        title = 'Start application',
33        msg = 'appplication process started',
34        source = INITIALIZED,
35        destination = STARTED)
36
37    submit_transition = Transition(
38        transition_id = 'submit',
39        title = 'Submit application',
40        msg = 'appplication record submitted',
41        source = STARTED,
42        destination = SUBMITTED)
43
44    admit_transition = Transition(
45        transition_id = 'admit',
46        title = 'Admit applicant',
47        msg = 'appplicant admitted',
48        source = SUBMITTED,
49        destination = ADMITTED)
50
51    refuse1_transition = Transition(
52        transition_id = 'refuse1',
53        title = 'Refuse application',
54        msg = 'appplication refused',
55        source = SUBMITTED,
56        destination = NOT_ADMITTED)
57
58    refuse2_transition = Transition(
59        transition_id = 'refuse2',
60        title = 'Refuse application',
61        msg = 'appplication refused',
62        source = ADMITTED,
63        destination = NOT_ADMITTED)
64
65    create_transition = Transition(
66        transition_id = 'create',
67        title = 'Create student record',
68        msg = 'student record created',
69        source = ADMITTED,
70        destination = CREATED)
71
72    reset1_transition = Transition(
73        transition_id = 'reset1',
74        title = 'Reset application',
75        msg = 'appplication record reset',
76        source = SUBMITTED,
77        destination = STARTED)
78
79    reset2_transition = Transition(
80        transition_id = 'reset2',
81        title = 'Reset application',
82        msg = 'appplication record reset',
83        source = ADMITTED,
84        destination = STARTED)
85
86    reset3_transition = Transition(
87        transition_id = 'reset3',
88        title = 'Reset application',
89        msg = 'appplication record reset',
90        source = NOT_ADMITTED,
91        destination = STARTED)
92
93    reset4_transition = Transition(
94        transition_id = 'reset4',
95        title = 'Reset application',
96        msg = 'appplication record reset',
97        source = CREATED,
98        destination = STARTED)
99
100    return [init_transition, start_transition, submit_transition,
101            admit_transition, create_transition, refuse1_transition,
102            refuse2_transition, reset1_transition, reset2_transition,
103            reset3_transition, reset4_transition]
104
105
106class ApplicationWorkflow(Workflow):
107    """A hurry.workflow Workflow with more appropriate error messages.
108    """
109    grok.provides(IWorkflow)
110    def __init__(self):
111        super(Workflow, self).__init__()
112        self.refresh(create_workflow())
113
114    def getTransition(self, source, transition_id):
115        transition = self._id_transitions[transition_id]
116        if transition.source != source:
117            raise InvalidTransitionError(
118                "Transition '%s' requires '%s' as source state (is: '%s')" % (
119                    transition_id, transition.source, source))
120        return transition
121
122
123class ApplicationWorkflowNullVersions(WorkflowVersions):
124    """A workflow versions manager that does not handle versions.
125
126    Sounds odd, but the default implementation of
127    :class:`hurry.workflow.workflow.WorkflowVersions` is a base
128    implementation that raises :exc:`NotImplemented` exceptions for
129    most of the methods defined below.
130
131    If we want to register a versionless workflow, an utility
132    implementing IWorkflowVersions is looked up nevertheless by
133    WorkflowInfo and WorkflowState components so we **have** to
134    provide workflow versions, even if we do not support versioned
135    workflows.
136
137    This implementation returns empty result sets for any requests,
138    but does not raise :exc:`NotImplemented`.
139    """
140    def getVersions(self, state, id):
141        return []
142
143    def getVersionsWithAutomaticTransitions(self):
144        return []
145
146    def hasVersion(self, id, state):
147        return False
148
149    def hasVersionId(self, id):
150        return False
151
152# Register global utilities for workflows and workflow versions...
153grok.global_utility(ApplicationWorkflow, IWorkflow)
154grok.global_utility(ApplicationWorkflowNullVersions, IWorkflowVersions)
155
156class ApplicationState(grok.Adapter, WorkflowState):
157    """An adapter to adapt Applicant objects to workflow states.
158    """
159    grok.context(IApplicantBaseData)
160    grok.provides(IWorkflowState)
161
162class ApplicationInfo(grok.Adapter, WorkflowInfo):
163    """Adapter to adapt Applicant objects to workflow info objects.
164    """
165    grok.context(IApplicantBaseData)
166    grok.provides(IWorkflowInfo)
167
168
169@grok.subscribe(IApplicantBaseData, IWorkflowTransitionEvent)
170def handle_applicant_transition_event(obj, event):
171    """Append message to applicant when transition happened.
172    """
173    timestamp = datetime.now().strftime("%d/%m/%Y %H:%M:%S")
174    # XXX: We should not store HTML code but simple messages.
175    msg = '%s - %s (new state: %s)' % (
176        timestamp, event.transition.user_data['msg'], event.destination)
177    msgs = getattr(obj, 'msgs', None)
178    if msgs:
179        msgs += '<br />'
180        msgs += msg
181    else:
182        msgs = msg
183    obj.msgs = msgs
184    return
Note: See TracBrowser for help on using the repository browser.