16 # import standard library |
16 # import standard library |
17 from datetime import datetime |
17 from datetime import datetime |
18 |
18 |
19 # import interfaces |
19 # import interfaces |
20 from pyams_workflow.interfaces import IWorkflowVersions, IWorkflowManagedContent, VersionError, IWorkflowState, \ |
20 from pyams_workflow.interfaces import IWorkflowVersions, IWorkflowManagedContent, VersionError, IWorkflowState, \ |
21 IWorkflowVersion, IWorkflowStateHistoryItem, IWorkflowTransitionEvent, IWorkflowVersionTransitionEvent |
21 IWorkflowVersion, IWorkflowStateHistoryItem, IWorkflowTransitionEvent, IWorkflowVersionTransitionEvent, IWorkflow |
22 from zope.annotation.interfaces import IAnnotations |
22 from zope.annotation.interfaces import IAnnotations |
|
23 from zope.location.interfaces import ISublocations |
23 from zope.traversing.interfaces import ITraversable |
24 from zope.traversing.interfaces import ITraversable |
24 |
25 |
25 # import packages |
26 # import packages |
26 from persistent import Persistent |
27 from persistent import Persistent |
27 from persistent.list import PersistentList |
28 from persistent.list import PersistentList |
28 from persistent.mapping import PersistentMapping |
29 from persistent.mapping import PersistentMapping |
29 from pyams_utils.adapter import adapter_config, ContextAdapter |
30 from pyams_utils.adapter import adapter_config, ContextAdapter |
30 from pyams_utils.request import check_request |
31 from pyams_utils.registry import get_utility |
|
32 from pyams_utils.request import check_request, query_request |
31 from pyams_utils.traversing import get_parent |
33 from pyams_utils.traversing import get_parent |
32 from pyramid.events import subscriber |
34 from pyramid.events import subscriber |
33 from pyramid.threadlocal import get_current_registry |
35 from pyramid.threadlocal import get_current_registry |
34 from zope.container.folder import Folder |
36 from zope.container.folder import Folder |
35 from zope.interface import implementer, alsoProvides |
37 from zope.interface import implementer, alsoProvides |
58 @implementer(IWorkflowState) |
60 @implementer(IWorkflowState) |
59 class WorkflowVersionState(Persistent): |
61 class WorkflowVersionState(Persistent): |
60 """Workflow managed content version object""" |
62 """Workflow managed content version object""" |
61 |
63 |
62 version_id = None |
64 version_id = None |
63 state = None |
65 _state = None |
|
66 _state_date = FieldProperty(IWorkflowState['state_date']) |
|
67 _state_principal = FieldProperty(IWorkflowState['state_principal']) |
64 |
68 |
65 def __init__(self): |
69 def __init__(self): |
66 self.history = PersistentList() |
70 self.history = PersistentList() |
|
71 |
|
72 @property |
|
73 def state(self): |
|
74 return self._state |
|
75 |
|
76 @state.setter |
|
77 def state(self, value): |
|
78 self._state = value |
|
79 self._state_date = datetime.utcnow() |
|
80 request = query_request() |
|
81 if request is not None: |
|
82 self._state_principal = request.principal.id |
|
83 |
|
84 @property |
|
85 def state_date(self): |
|
86 return self._state_date |
|
87 |
|
88 @property |
|
89 def state_principal(self): |
|
90 return self._state_principal |
67 |
91 |
68 |
92 |
69 @subscriber(IWorkflowTransitionEvent) |
93 @subscriber(IWorkflowTransitionEvent) |
70 def handle_workflow_transition(event): |
94 def handle_workflow_transition(event): |
71 """Handle workflow transition""" |
95 """Handle workflow transition""" |
72 if IWorkflowVersionTransitionEvent.providedBy(event): |
96 if IWorkflowVersionTransitionEvent.providedBy(event): |
73 return |
97 return |
|
98 workflow = event.workflow |
74 request = check_request() |
99 request = check_request() |
|
100 translate = request.localizer.translate |
75 item = WorkflowHistoryItem(date=datetime.utcnow(), |
101 item = WorkflowHistoryItem(date=datetime.utcnow(), |
76 source_state=event.source, |
102 source_state=translate(workflow.states.getTerm(event.source).title) |
77 target_state=event.destination, |
103 if event.source else None, |
78 transition=event.transition.title, |
104 target_state=translate(workflow.states.getTerm(event.destination).title), |
|
105 transition=translate(event.transition.title), |
79 principal=request.principal.id, |
106 principal=request.principal.id, |
80 comment=event.comment) |
107 comment=event.comment) |
81 IWorkflowState(event.object).history.append(item) |
108 IWorkflowState(event.object).history.append(item) |
82 |
109 |
83 |
110 |
84 @subscriber(IWorkflowVersionTransitionEvent) |
111 @subscriber(IWorkflowVersionTransitionEvent) |
85 def handle_workflow_version_transition(event): |
112 def handle_workflow_version_transition(event): |
86 """Handle workflow version transition""" |
113 """Handle workflow version transition""" |
|
114 workflow = event.workflow |
87 request = check_request() |
115 request = check_request() |
|
116 translate = request.localizer.translate |
88 item = WorkflowHistoryItem(date=datetime.utcnow(), |
117 item = WorkflowHistoryItem(date=datetime.utcnow(), |
89 source_version=IWorkflowState(event.old_object).version_id, |
118 source_version=IWorkflowState(event.old_object).version_id, |
90 source_state=event.source, |
119 source_state=translate(workflow.states.getTerm(event.source).title), |
91 target_state=event.destination, |
120 target_state=translate(workflow.states.getTerm(event.destination).title), |
92 transition=event.transition.title, |
121 transition=translate(event.transition.title), |
93 principal=request.principal.id, |
122 principal=request.principal.id, |
94 comment=event.comment) |
123 comment=event.comment) |
95 IWorkflowState(event.object).history.append(item) |
124 IWorkflowState(event.object).history.append(item) |
96 |
125 |
97 |
126 |
191 def has_version(self, state): |
220 def has_version(self, state): |
192 if state is None: |
221 if state is None: |
193 state = '__none__' |
222 state = '__none__' |
194 return bool(self.versions_by_state.get(state, ())) |
223 return bool(self.versions_by_state.get(state, ())) |
195 |
224 |
196 def remove_version(self, version_id): |
225 def remove_version(self, version_id, state='deleted', comment=None): |
197 if str(version_id) not in self: |
226 if str(version_id) not in self: |
198 pass |
227 return |
|
228 # update version state |
|
229 version = self[str(version_id)] |
|
230 wf_state = IWorkflowState(version) |
|
231 if comment: |
|
232 request = check_request() |
|
233 translate = request.localizer.translate |
|
234 workflow = get_utility(IWorkflow, name=get_parent(self, IWorkflowManagedContent).workflow_name) |
|
235 item = WorkflowHistoryItem(date=datetime.utcnow(), |
|
236 source_version=wf_state.version_id, |
|
237 source_state=translate(workflow.states.getTerm(wf_state.state).title), |
|
238 target_state=translate(workflow.states.getTerm(state).title), |
|
239 principal=request.principal.id, |
|
240 comment=comment) |
|
241 wf_state.history.append(item) |
|
242 wf_state.state = state |
|
243 # remove given version |
199 state = self.state_by_version[version_id] |
244 state = self.state_by_version[version_id] |
200 versions = self.versions_by_state[state] |
245 versions = self.versions_by_state[state] |
201 versions.remove(version_id) |
246 versions.remove(version_id) |
202 if versions: |
247 if versions: |
203 self.versions_by_state[state] = versions |
248 self.versions_by_state[state] = versions |