Updated workflow history management
authorThierry Florac <thierry.florac@onf.fr>
Mon, 11 Sep 2017 14:27:28 +0200
changeset 36 a84e933260c6
parent 35 c879fc48d6b1
child 37 2b8636f18d39
Updated workflow history management
src/pyams_workflow/content.py
src/pyams_workflow/versions.py
--- a/src/pyams_workflow/content.py	Mon Sep 11 14:25:27 2017 +0200
+++ b/src/pyams_workflow/content.py	Mon Sep 11 14:27:28 2017 +0200
@@ -128,10 +128,10 @@
 
     @property
     def push_end_date_index(self):
-        value = self.push_end_date
+        value = self.push_end_date or self.publication_expiration_date
         if value is None:
             value = datetime(9999, 12, 31, 11, 59, 59, 999999, GMT)
-        return value
+        return gmtime(value)
 
     @property
     def publication_expiration_date(self):
@@ -159,18 +159,14 @@
         if (parent is not None) and not IWorkflowPublicationInfo(parent).is_published():
             return False
         # associated workflow?
-        wf_name = IWorkflowManagedContent(self.__parent__).workflow_name
-        if not wf_name:
-            return True
-        # published state(s) in workflow?
-        workflow = query_utility(IWorkflow, name=wf_name)
+        workflow = IWorkflow(self.__parent__, None)
         if (workflow is None) or not workflow.published_states:
             return False
         # check content versions
         versions = IWorkflowVersions(self.__parent__)
         if not (versions or versions.get_versions(workflow.published_states)):
             return False
-        now = datetime.utcnow()
+        now = tztime(datetime.utcnow())
         return (self.publication_effective_date is not None) and \
                (self.publication_effective_date <= now) and \
                ((self.publication_expiration_date is None) or
@@ -213,12 +209,13 @@
     request = check_request()
     translate = request.localizer.translate
     source_state = IWorkflowState(event.source)
+    item = WorkflowHistoryItem(date=datetime.utcnow(),
+                               principal=request.principal.id,
+                               comment=translate(_("Clone created from version {source} (in « {state} » state)")).format(
+                                   source=source_state.version_id,
+                                   state=translate(IWorkflow(event.source).get_state_label(source_state.state))))
     target_state = IWorkflowState(event.object)
-    item = WorkflowHistoryItem(date=datetime.utcnow(),
-                               source_state=source_state.state,
-                               principal=request.principal.id,
-                               comment=translate(_("Clone created from version {source}")).format(
-                                   source=source_state.version_id))
+    target_state.history.clear()
     target_state.history.append(item)
 
 
--- a/src/pyams_workflow/versions.py	Mon Sep 11 14:25:27 2017 +0200
+++ b/src/pyams_workflow/versions.py	Mon Sep 11 14:27:28 2017 +0200
@@ -17,6 +17,7 @@
 from datetime import datetime
 
 # import interfaces
+from pyams_security.interfaces import IPrincipalInfo
 from pyams_workflow.interfaces import IWorkflowVersions, IWorkflowManagedContent, VersionError, IWorkflowState, \
     IWorkflowVersion, IWorkflowStateHistoryItem, IWorkflowTransitionEvent, IWorkflowVersionTransitionEvent, IWorkflow
 from zope.annotation.interfaces import IAnnotations
@@ -91,22 +92,28 @@
     def state_principal(self):
         return self._state_principal
 
+    @state_principal.setter
+    def state_principal(self, value):
+        self._state_principal = value.id if IPrincipalInfo.providedBy(value) else value
+
+    def get_first_state_date(self, states):
+        for item in self.history:
+            if item.target_state in states:
+                return item.date
+        return None
+
 
 @subscriber(IWorkflowTransitionEvent)
 def handle_workflow_transition(event):
     """Handle workflow transition"""
     if IWorkflowVersionTransitionEvent.providedBy(event):
         return
-    workflow = event.workflow
-    request = check_request()
-    translate = request.localizer.translate
+    principal = event.principal
     item = WorkflowHistoryItem(date=datetime.utcnow(),
-                               source_state=translate(workflow.states.getTerm(event.source).title)
-                                            if event.source else None,
-                               target_state=translate(workflow.states.getTerm(event.destination).title),
+                               source_state=event.source,
+                               target_state=event.destination,
                                transition_id=event.transition.transition_id,
-                               transition=translate(event.transition.title),
-                               principal=request.principal.id,
+                               principal=principal.id if IPrincipalInfo.providedBy(principal) else principal,
                                comment=event.comment)
     IWorkflowState(event.object).history.append(item)
 
@@ -114,16 +121,13 @@
 @subscriber(IWorkflowVersionTransitionEvent)
 def handle_workflow_version_transition(event):
     """Handle workflow version transition"""
-    workflow = event.workflow
-    request = check_request()
-    translate = request.localizer.translate
+    principal = event.principal
     item = WorkflowHistoryItem(date=datetime.utcnow(),
                                source_version=IWorkflowState(event.old_object).version_id,
-                               source_state=translate(workflow.states.getTerm(event.source).title),
-                               target_state=translate(workflow.states.getTerm(event.destination).title),
+                               source_state=event.source,
+                               target_state=event.destination,
                                transition_id=event.transition.transition_id,
-                               transition=translate(event.transition.title),
-                               principal=request.principal.id,
+                               principal=principal.id if IPrincipalInfo.providedBy(principal) else principal,
                                comment=event.comment)
     IWorkflowState(event.object).history.append(item)
 
@@ -183,7 +187,7 @@
             result = result[:count]
         return result
 
-    def add_version(self, content, state):
+    def add_version(self, content, state, principal=None):
         self.last_version_id += 1
         version_id = self.last_version_id
         # init version state
@@ -191,6 +195,8 @@
         wf_state = IWorkflowState(content)
         wf_state.version_id = version_id
         wf_state.state = state
+        if principal is not None:
+            wf_state.state_principal = principal
         # store new version
         if state is None:
             state = '__none__'
@@ -201,12 +207,14 @@
         self.versions_by_state[state] = versions
         return version_id
 
-    def set_state(self, version_id, state):
+    def set_state(self, version_id, state, principal=None):
         # update version state
         version = self[str(version_id)]
         wf_state = IWorkflowState(version)
         wf_state.version_id = version_id
         wf_state.state = state
+        if principal is not None:
+            wf_state.state_principal = principal
         # update versions/states mapping
         if state is None:
             state = '__none__'
@@ -233,7 +241,7 @@
                 return True
         return False
 
-    def remove_version(self, version_id, state='deleted', comment=None):
+    def remove_version(self, version_id, state='deleted', comment=None, principal=None):
         if str(version_id) not in self:
             return
         # update version state
@@ -251,6 +259,8 @@
                                        comment=comment)
             wf_state.history.append(item)
         wf_state.state = state
+        if principal is not None:
+            wf_state.state_principal = principal
         # remove given version
         state = self.state_by_version[version_id]
         versions = self.versions_by_state[state]