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

Last change on this file since 6345 was 6339, checked in by uli, 14 years ago

Maintain history of objects in a separate component, similar to workflows, instead of storing everything with the object core object.

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