Patrick Downey
Patrick Downey

Reputation: 965

Plone/Workflow- Why is portal_workflow tool's getStatusOf returning None?

I'm trying to get the workflow state of a dexterity content type (my.product.my_object)

My workflow 'my_object_workflow' has three states: draft pending_approval approved

In my browserview, I am trying to get the status of my_objects. I query portal_catalog for my_objects.

my_objects = api.portal.get_tool(name='portal_catalog').searchResults(
                                           {'portal_type':'my.product.my_object',
                                             ...
                                           })

I get the brains and then iterate through the list and attempt to print the state with the portal_workflow tool.:

wf_tool = api.portal.get_tool(name='portal_workflow')

for m_obj in my_objects:
    print wf_tool.getStatusOf('my_object_workflow',m_obj.getObject())

Unfortunately, rather than printing the state of the object, it prints None instead.

I could use m_obj['review_state'] instead since m_obj is a brain, but I'd prefer to use the portal_workflow tool.

What could cause this to happen? Am I misunderstand what getStatusOf is actually for?

I am using Plone 4.3

Upvotes: 2

Views: 161

Answers (1)

Mathias
Mathias

Reputation: 6839

To solve your problem you need to know what getStatusOfis actually doing. There are several possible cases to get None if getStatusOf is called.

First take a look at the implementation (Products.CMFCore.WorkflowTool):

def getStatusOf(self, wf_id, ob):
    """ Get the last element of a workflow history for a given workflow.
    """
    wfh = self.getHistoryOf(wf_id, ob)
    if wfh:
        return wfh[-1]
    return None

def getHistoryOf(self, wf_id, ob):
    """ Get the history of an object for a given workflow.
    """
    if hasattr(aq_base(ob), 'workflow_history'):
        wfh = ob.workflow_history
        return wfh.get(wf_id, None)
    return ()

getStatusOf gets the last entry of list stored in the workflow_history attribute.

The workflow_history is a persistent Dict:

  • The keys are the workflow id's - In your case my_object_workflow
  • The values are the workflow transitions (List of transitions)

Why your brain metadata has the wrong value?

Usually this happens if you manipulate/change the workflow and you forget to update the catalog.


Why calling getStatusOf is None?

This usually happens if you change the workflow and the workflow_history storage for the new workflow is empty or not yet initialized.


How can I avoid this problem if I change the workflow configuration for my type?

IMHO this is not an easy task. You need to be avare of several things.

I personally use ftw.upgrade to introduce a new workflow for my type.

Go thru the Workflow Chain Updater section of Readme or check out the implementation

You have to do the following steps manually or use ftw.upgrade if you have changed the workflow for your type:

  • Set state of every object to the initial state of the new workflow
  • Migrate the workflow history from the old to the new workflow
  • If you remove the workflow from a specific type you need to reset the permissions manually for each affected object.
  • Keep the catalog up to date.

Upvotes: 3

Related Questions