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

Last change on this file since 6349 was 6349, checked in by uli, 13 years ago

Base further workflow stuff on hurry.workflow 0.11.

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