source: main/waeup.ikoba/trunk/src/waeup/ikoba/customers/workflow.py @ 12145

Last change on this file since 12145 was 12145, checked in by Henrik Bettermann, 10 years ago

Undo the approval of contract and raise an exception if contract
does not meet the requirements for approval.

  • Property svn:keywords set to Id
File size: 8.1 KB
Line 
1## $Id: workflow.py 12145 2014-12-04 18:11:12Z henrik $
2##
3## Copyright (C) 2014 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 customers.
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 (
25    IWorkflowState, IWorkflowTransitionEvent, InvalidTransitionError)
26from waeup.ikoba.interfaces import (
27    IObjectHistory, IIkobaWorkflowInfo, IIkobaUtils,
28    STARTED, CREATED, REQUESTED, APPROVED,
29    SUBMITTED, VERIFIED, REJECTED, EXPIRED)
30from waeup.ikoba.interfaces import MessageFactory as _
31from waeup.ikoba.workflow import (
32    IkobaWorkflow, IkobaWorkflowInfo)
33from waeup.ikoba.customers.interfaces import (
34    ICustomer, ICustomersUtils,
35    IContract)
36from waeup.ikoba.utils.helpers import get_current_principal
37from waeup.ikoba.documents.workflow import VERIFICATION_TRANSITIONS
38
39# Customer workflow
40
41IMPORTABLE_REGISTRATION_STATES = (STARTED, REQUESTED, APPROVED)
42
43REGISTRATION_TRANSITIONS = (
44    Transition(
45        transition_id = 'create',
46        title = _('Create customer'),
47        source = None,
48        condition = NullCondition,
49        msg = _('Customer record created'),
50        destination = CREATED),
51
52    Transition(
53        transition_id = 'start',
54        title = _('Start registration'),
55        source = CREATED,
56        condition = NullCondition,
57        msg = _('Customer registration started'),
58        destination = STARTED),
59
60    Transition(
61        transition_id = 'request',
62        title = _('Request registration'),
63        msg = _('Customer registration requested'),
64        source = STARTED,
65        destination = REQUESTED),
66
67    Transition(
68        transition_id = 'approve',
69        title = _('Approve customer'),
70        msg = _('Customer registration approved'),
71        source = REQUESTED,
72        destination = APPROVED),
73
74    Transition(
75        transition_id = 'reject',
76        title = _('Reject customer'),
77        msg = _('Customer registration rejected'),
78        source = REQUESTED,
79        destination = STARTED),
80
81    Transition(
82        transition_id = 'reset1',
83        title = _('Reset customer'),
84        msg = _('Reset to initial customer state'),
85        source = APPROVED,
86        destination = STARTED),
87
88    Transition(
89        transition_id = 'reset2',
90        title = _('Reset to requested'),
91        msg = _("Reset to 'requested'"),
92        source = APPROVED,
93        destination = REQUESTED),
94
95    Transition(
96        transition_id = 'reset3',
97        title = _('Reset customer'),
98        msg = _("Reset to initial state"),
99        source = REQUESTED,
100        destination = STARTED),
101
102    )
103
104
105IMPORTABLE_REGISTRATION_TRANSITIONS = [i.transition_id for i in REGISTRATION_TRANSITIONS]
106
107registration_workflow = IkobaWorkflow(REGISTRATION_TRANSITIONS)
108
109
110class RegistrationWorkflowState(WorkflowState, grok.Adapter):
111    """An adapter to adapt Customer objects to workflow states.
112    """
113    grok.context(ICustomer)
114    grok.provides(IWorkflowState)
115
116    state_key = 'wf.registration.state'
117    state_id = 'wf.registration.id'
118
119
120class RegistrationWorkflowInfo(IkobaWorkflowInfo, grok.Adapter):
121    """Adapter to adapt Customer objects to workflow info objects.
122    """
123    grok.context(ICustomer)
124    grok.provides(IIkobaWorkflowInfo)
125
126    def __init__(self, context):
127        self.context = context
128        self.wf = registration_workflow
129
130
131@grok.subscribe(ICustomer, IWorkflowTransitionEvent)
132def handle_customer_transition_event(obj, event):
133    """Append message to customer history and log file when transition happened.
134    """
135
136    msg = event.transition.user_data['msg']
137    history = IObjectHistory(obj)
138    history.addMessage(msg)
139    try:
140        customers_container = grok.getSite()['customers']
141        customers_container.logger.info('%s - %s' % (obj.customer_id,msg))
142    except (TypeError, AttributeError):
143        pass
144    return
145
146# Contract workflow (the same as verification workflow)
147
148IMPORTABLE_CONTRACT_STATES = (CREATED, SUBMITTED, APPROVED, REJECTED, EXPIRED)
149
150CONTRACT_TRANSITIONS = (
151    Transition(
152        transition_id = 'create',
153        title = _('Create contract record'),
154        source = None,
155        condition = NullCondition,
156        msg = _('Contract record created'),
157        destination = CREATED),
158
159    Transition(
160        transition_id = 'submit',
161        title = _('Submit for approval'),
162        msg = _('Submitted for approval'),
163        source = CREATED,
164        destination = SUBMITTED),
165
166    Transition(
167        transition_id = 'approve',
168        title = _('Approve'),
169        msg = _('Approved'),
170        source = SUBMITTED,
171        destination = APPROVED),
172
173    Transition(
174        transition_id = 'reject',
175        title = _('Reject'),
176        msg = _('REJECTED'),
177        source = SUBMITTED,
178        destination = REJECTED),
179
180    Transition(
181        transition_id = 'reset1',
182        title = _('Reset to initial state'),
183        msg = _('Reset to initial state'),
184        source = REJECTED,
185        destination = CREATED),
186
187    Transition(
188        transition_id = 'reset2',
189        title = _('Reset to initial state'),
190        msg = _('Reset to initial state'),
191        source = APPROVED,
192        destination = CREATED),
193
194    Transition(
195        transition_id = 'reset3',
196        title = _('Reset to initial state'),
197        msg = _('Reset to initial state'),
198        source = SUBMITTED,
199        destination = CREATED),
200
201    Transition(
202        transition_id = 'expire',
203        title = _('Set to expired'),
204        msg = _('Set to expired'),
205        source = APPROVED,
206        destination = EXPIRED),
207
208    Transition(
209        transition_id = 'reset4',
210        title = _('Reset to initial state'),
211        msg = _('Reset to initial state'),
212        source = EXPIRED,
213        destination = CREATED),
214    )
215
216
217IMPORTABLE_CONTRACT_TRANSITIONS = [
218    i.transition_id for i in REGISTRATION_TRANSITIONS]
219
220contract_workflow = IkobaWorkflow(CONTRACT_TRANSITIONS)
221
222class ContractWorkflowState(WorkflowState, grok.Adapter):
223    """An adapter to adapt Contract objects to workflow states.
224    """
225    grok.context(IContract)
226    grok.provides(IWorkflowState)
227
228    state_key = 'wf.contract.state'
229    state_id = 'wf.contract.id'
230
231class ContractWorkflowInfo(IkobaWorkflowInfo, grok.Adapter):
232    """Adapter to adapt Contract objects to workflow info objects.
233    """
234    grok.context(IContract)
235    grok.provides(IIkobaWorkflowInfo)
236
237    def __init__(self, context):
238        self.context = context
239        self.wf = contract_workflow
240
241@grok.subscribe(IContract, IWorkflowTransitionEvent)
242def handle_contract_transition_event(obj, event):
243    """Append message to contract history and log file, also update
244    last_transition_date when transition happened.
245
246    Undo the approval of contract and raise an exception if contract
247    does not meet the requirements for approval.
248    """
249    if event.transition.destination == APPROVED:
250        if not obj.is_approvable:
251            # Undo transition and raise an exception.
252            IWorkflowState(obj).setState(event.transition.source)
253            raise InvalidTransitionError(
254                "Documents must be verified first.")
255    msg = event.transition.user_data['msg']
256    history = IObjectHistory(obj)
257    history.addMessage(msg)
258    obj.last_transition_date = datetime.utcnow()
259    try:
260        customers_container = grok.getSite()['customers']
261        customers_container.logger.info('%s - %s' % (obj.customer_id,msg))
262    except (TypeError, AttributeError):
263        pass
264    return
Note: See TracBrowser for help on using the repository browser.