workflows: pass caller to external workflow action context (#43700)

This commit is contained in:
Frédéric Péters 2020-06-29 20:25:18 +02:00
parent eef03c0a56
commit c17f11f88e
2 changed files with 85 additions and 0 deletions

View File

@ -5040,6 +5040,81 @@ def test_call_external_workflow_with_parent_object(pub):
assert card.data['bo0'] == '1' # got called
def test_call_external_workflow_use_caller_variable(pub):
FormDef.wipe()
CardDef.wipe()
LoggedError.wipe()
# carddef workflow, with global action to set a value in a backoffice field
carddef_wf = Workflow(name='Carddef Workflow')
carddef_wf.backoffice_fields_formdef = WorkflowBackofficeFieldsFormDef(carddef_wf)
carddef_wf.backoffice_fields_formdef.fields = [
StringField(id='bo0', varname='bo', type='string', label='bo variable'),
]
global_action = carddef_wf.add_global_action('Update')
global_action.append_item('set-backoffice-fields')
setbo = global_action.items[0]
setbo.fields = [{'field_id': 'bo0',
'value': '{{ caller_form_var_email }}'}]
trigger = global_action.append_trigger('webservice')
trigger.identifier = 'update'
carddef_wf.store()
# associated carddef
carddef = CardDef()
carddef.name = 'Data'
carddef.fields = [
StringField(id='0', label='string', varname='card_string'),
]
carddef.workflow = carddef_wf
carddef.store()
# and sample carddata
carddata = carddef.data_class()()
carddata.data = {'0': 'Text'}
carddata.store()
# formdef workflow that will trigger the global action
wf = Workflow(name='External actions')
wf.add_status('Action')
update_global_action = wf.add_global_action('Update linked object data')
update_action = update_global_action.append_item('external_workflow_global_action')
update_action.slug = 'carddef:%s' % carddef.url_name
update_action.trigger_id = 'action:update'
wf.store()
# associated formdef
formdef = FormDef()
formdef.name = 'External action form'
formdef.fields = [EmailField(id='1', label='Email', varname='email')]
formdef.workflow = wf
formdef.store()
# and formdata
formdata = formdef.data_class()()
formdata.data = {'1': 'foo@example.com'}
formdata.store()
formdata.just_created()
formdata.perform_workflow()
# run, against no parent
perform_items([update_action], formdata)
card = carddef.data_class().get(carddata.id)
assert 'bo0' not in card.data # not called
# appropriate parent
formdata.submission_context = {
'orig_object_type': 'carddef',
'orig_formdata_id': str(carddata.id),
'orig_formdef_id': str(carddef.id),
}
formdata.store()
perform_items([update_action], formdata)
card = carddef.data_class().get(carddata.id)
assert card.data['bo0'] == 'foo@example.com' # got called
def test_edit_carddata_with_data_sourced_object(pub):
FormDef.wipe()
CardDef.wipe()

View File

@ -155,12 +155,22 @@ class ExternalWorkflowGlobalAction(WorkflowStatusItem):
LoggedError.record(_('No trigger with id "%s" found in workflow') % self.trigger_id)
return
class CallerSource:
def __init__(self, formdata):
self.formdata = formdata
def get_substitution_variables(self):
return {'caller_form': self.formdata.get_substitution_variables(minimal=True)['form']}
caller_source = CallerSource(formdata)
for target_data in self.iter_target_datas(formdata, objectdef):
with get_publisher().substitutions.temporary_feed(target_data):
get_publisher().substitutions.reset()
get_publisher().substitutions.feed(get_publisher())
get_publisher().substitutions.feed(target_data.formdef)
get_publisher().substitutions.feed(target_data)
get_publisher().substitutions.feed(caller_source)
perform_items(trigger.parent.items, target_data)