def PlacefulWorkflowChain(ob, tool): """Monkey-patched by CMFPlacefulWorkflow to look for placeful workflow configurations. Goal: find a workflow chain in a policy Steps: 1. ask the object if it contains a policy 2. if it does, ask him for a chain 3. if there's no chain for the type the we loop on the parent 4. if the parent is the portal object or None we stop and ask portal_workflow """ if isinstance(ob, basestring): # We are not in an object, then we can only get default from # portal_workflow return ToolWorkflowChain(ob, tool) elif hasattr(aq_base(ob), 'getPortalTypeName'): portal_type = ob.getPortalTypeName() else: portal_type = None if portal_type is None or ob is None: return () # Inspired by implementation in CPSWorkflowTool.py of CPSCore 3.9.0 # Workflow needs to be determined by true containment not context # so we loop over the actual containers chain = None wfpolicyconfig = None current_ob = aq_inner(ob) # start_here is used to check 'In policy': We check it only in the # first folder start_here = True portal = aq_base(getToolByName(tool, 'portal_url').getPortalObject()) while chain is None and current_ob is not None: if base_hasattr(current_ob, WorkflowPolicyConfig_id): wfpolicyconfig = getattr(current_ob, WorkflowPolicyConfig_id) chain = wfpolicyconfig.getPlacefulChainFor(portal_type, start_here=start_here) if chain is not None: return chain elif aq_base(current_ob) is portal: break start_here = False current_ob = aq_inner(aq_parent(current_ob)) # fallback on the default mechanism return ToolWorkflowChain(ob, tool)
def SamplePrepTransitionEventHandler(instance, event): """Sample preparation is considered complete when the sampleprep workflow reaches a state which has no exit transitions. If the stateis state's ID is the same as any AnalysisRequest primary workflow ID, then the AnalysisRequest will be sent directly to that state. If the final state's ID is not found in the AR workflow, the AR will be transitioned to 'sample_received'. """ if not event.transition: # creation doesn't have a 'transition' return if not event.new_state.getTransitions(): # Is this the final (No exit transitions) state? workflow = ploneapi.portal.get_tool("portal_workflow") primary_wf_name = list(ToolWorkflowChain(instance, workflow))[0] primary_wf = workflow.getWorkflowById(primary_wf_name) primary_wf_states = primary_wf.states.keys() if event.new_state.id in primary_wf_states: # final state name matches review_state in primary workflow: dst_state = event.new_state.id else: # fallback state: dst_state = 'sample_received' changeWorkflowState(instance, primary_wf_name, dst_state)
def SamplePrepWorkflowChain(ob, wftool): """Responsible for inserting the optional sampling preparation workflow into the workflow chain for objects with ISamplePrepWorkflow This is only done if the object is in 'sample_prep' state in the primary workflow (review_state). """ # use catalog to retrieve review_state: getInfoFor causes recursion loop chain = list(ToolWorkflowChain(ob, wftool)) bc = ploneapi.portal.get_tool('bika_catalog') proxies = bc(UID=ob.UID()) if not proxies or proxies[0].review_state != 'sample_prep': return chain sampleprep_workflow = ob.getPreparationWorkflow() if sampleprep_workflow: chain.append(sampleprep_workflow) return tuple(chain)
def SamplePrepWorkflowChain(ob, wftool): """Responsible for inserting the optional sampling preparation workflow into the workflow chain for objects with ISamplePrepWorkflow This is only done if the object is in 'sample_prep' state in the primary workflow (review_state). """ # use catalog to retrieve review_state: getInfoFor causes recursion loop chain = list(ToolWorkflowChain(ob, wftool)) try: bc = getToolByName(ob, 'bika_catalog') except AttributeError: logger.warning(traceback.format_exc()) logger.warning( "Error getting 'bika_catalog' using 'getToolByName' with '{0}'" " as context.".format(ob)) return chain proxies = bc(UID=ob.UID()) if not proxies or proxies[0].review_state != 'sample_prep': return chain sampleprep_workflow = ob.getPreparationWorkflow() if sampleprep_workflow: chain.append(sampleprep_workflow) return tuple(chain)