workflow: allow to send generated docs in backoffice field (#19188)
This commit is contained in:
parent
eb586a7cfa
commit
2b193960e9
|
@ -19,7 +19,8 @@ from quixote.http_request import Upload as QuixoteUpload
|
|||
from wcs.qommon.form import UploadedFile
|
||||
from wcs.qommon.ident.password_accounts import PasswordAccount
|
||||
from wcs.formdef import FormDef
|
||||
from wcs.workflows import Workflow, EditableWorkflowStatusItem, DisplayMessageWorkflowStatusItem
|
||||
from wcs.workflows import (Workflow, EditableWorkflowStatusItem,
|
||||
DisplayMessageWorkflowStatusItem, WorkflowBackofficeFieldsFormDef)
|
||||
from wcs.wf.export_to_model import ExportToModel, transform_to_pdf
|
||||
from wcs.wf.jump import JumpWorkflowStatusItem
|
||||
from wcs.wf.attachment import AddAttachmentWorkflowStatusItem
|
||||
|
@ -2551,6 +2552,70 @@ def test_formdata_generated_document_non_interactive(pub):
|
|||
assert formdef.data_class().count() == 1
|
||||
assert formdef.data_class().select()[0].status == 'wf-st2'
|
||||
|
||||
def test_formdata_generated_document_to_backoffice_field(pub):
|
||||
create_user_and_admin(pub)
|
||||
wf = Workflow(name='status')
|
||||
wf.backoffice_fields_formdef = WorkflowBackofficeFieldsFormDef(wf)
|
||||
wf.backoffice_fields_formdef.fields = [
|
||||
fields.FileField(id='bo1', label='bo field 1', type='file'),
|
||||
fields.StringField(id='bo2', label='bo field 2', type='string'),
|
||||
]
|
||||
|
||||
st1 = wf.add_status('Status1', 'st1')
|
||||
export_to = ExportToModel()
|
||||
export_to.method = 'non-interactive'
|
||||
template_filename = os.path.join(os.path.dirname(__file__), 'template.odt')
|
||||
template = open(template_filename).read()
|
||||
upload = QuixoteUpload('/foo/template.odt', content_type='application/octet-stream')
|
||||
upload.fp = StringIO.StringIO()
|
||||
upload.fp.write(template)
|
||||
upload.fp.seek(0)
|
||||
export_to.model_file = UploadedFile(pub.app_dir, None, upload)
|
||||
export_to.id = '_export_to'
|
||||
export_to.attach_to_history = True
|
||||
export_to.backoffice_filefield_id = 'bo1'
|
||||
st1.items.append(export_to)
|
||||
export_to.parent = st1
|
||||
|
||||
assert export_to.get_backoffice_filefield_options() == [('bo1', 'bo field 1', 'bo1')]
|
||||
|
||||
jump = JumpWorkflowStatusItem()
|
||||
jump.status = 'st2'
|
||||
st1.items.append(jump)
|
||||
jump.parent = st1
|
||||
wf.add_status('Status2', 'st2')
|
||||
wf.store()
|
||||
|
||||
formdef = create_formdef()
|
||||
formdef.workflow_id = wf.id
|
||||
formdef.fields = [fields.TextField(id='0', label='comment', type='text', varname='comment')]
|
||||
formdef.store()
|
||||
formdef.data_class().wipe()
|
||||
|
||||
resp = login(get_app(pub), username='foo', password='foo').get('/test/')
|
||||
resp.form['f0'] = 'Hello\n\nWorld.'
|
||||
resp = resp.forms[0].submit('submit')
|
||||
assert 'Check values then click submit.' in resp.body
|
||||
resp = resp.forms[0].submit('submit')
|
||||
assert resp.status_int == 302
|
||||
resp = resp.follow()
|
||||
assert 'The form has been recorded' in resp.body
|
||||
|
||||
# get the two generated files from backoffice: in backoffice fields
|
||||
# (export_to.backoffice_filefield_id), and in history (export_to.attach_to_history)
|
||||
for index in (0, 1):
|
||||
resp = login(get_app(pub), username='admin', password='admin').get(
|
||||
'/backoffice/management/test/1/')
|
||||
resp = resp.click('template.odt', index=index)
|
||||
assert resp.location.endswith('/template.odt')
|
||||
resp = resp.follow()
|
||||
assert resp.content_type == 'application/octet-stream'
|
||||
with open(os.path.join(os.path.dirname(__file__), 'template-out.odt')) as f:
|
||||
assert_equal_zip(StringIO.StringIO(resp.body), f)
|
||||
|
||||
assert formdef.data_class().count() == 1
|
||||
assert formdef.data_class().select()[0].status == 'wf-st2'
|
||||
|
||||
def test_formdata_form_file_download(pub):
|
||||
create_user(pub)
|
||||
wf = Workflow(name='status')
|
||||
|
|
|
@ -2131,6 +2131,70 @@ def test_export_to_model_image(pub):
|
|||
# check the original image has been left
|
||||
assert zinfo.file_size == 580
|
||||
|
||||
def test_export_to_model_backoffice_field(pub):
|
||||
wf = Workflow(name='email with attachments')
|
||||
wf.backoffice_fields_formdef = WorkflowBackofficeFieldsFormDef(wf)
|
||||
wf.backoffice_fields_formdef.fields = [
|
||||
FileField(id='bo1', label='bo field 1', type='file', varname='backoffice_file1'),
|
||||
]
|
||||
st1 = wf.add_status('Status1')
|
||||
wf.store()
|
||||
formdef = FormDef()
|
||||
formdef.name = 'foo-export-to-bofile'
|
||||
formdef.fields = [
|
||||
StringField(id='1', label='String', type='string', varname='string'),
|
||||
]
|
||||
formdef.workflow_id = wf.id
|
||||
formdef.store()
|
||||
formdata = formdef.data_class()()
|
||||
formdata.data = {}
|
||||
formdata.just_created()
|
||||
formdata.store()
|
||||
pub.substitutions.feed(formdata)
|
||||
|
||||
item = ExportToModel()
|
||||
item.method = 'non-interactive'
|
||||
template_filename = os.path.join(os.path.dirname(__file__), 'template.odt')
|
||||
template = open(template_filename).read()
|
||||
upload = QuixoteUpload('/foo/template.odt', content_type='application/octet-stream')
|
||||
upload.fp = StringIO.StringIO()
|
||||
upload.fp.write(template)
|
||||
upload.fp.seek(0)
|
||||
item.model_file = UploadedFile(pub.app_dir, None, upload)
|
||||
item.parent = st1
|
||||
item.backoffice_filefield_id = 'bo1'
|
||||
item.perform(formdata)
|
||||
|
||||
assert 'bo1' in formdata.data
|
||||
fbo1 = formdata.data['bo1']
|
||||
assert fbo1.base_filename == 'template.odt'
|
||||
assert fbo1.content_type == 'application/octet-stream'
|
||||
zfile = zipfile.ZipFile(fbo1.get_file())
|
||||
assert 'foo-export-to-bofile' in zfile.read('content.xml')
|
||||
|
||||
# no more 'bo1' backoffice field: do nothing
|
||||
formdata = formdef.data_class()()
|
||||
formdata.data = {}
|
||||
formdata.just_created()
|
||||
formdata.store()
|
||||
pub.substitutions.feed(formdata)
|
||||
# id is not bo1:
|
||||
wf.backoffice_fields_formdef.fields = [
|
||||
FileField(id='bo2', label='bo field 2', type='file'),
|
||||
]
|
||||
item.perform(formdata)
|
||||
assert formdata.data == {}
|
||||
# field is not a field file:
|
||||
wf.backoffice_fields_formdef.fields = [
|
||||
StringField(id='bo1', label='bo field 1', type='string'),
|
||||
]
|
||||
item.perform(formdata)
|
||||
assert formdata.data == {}
|
||||
# no field at all:
|
||||
wf.backoffice_fields_formdef.fields = []
|
||||
item.perform(formdata)
|
||||
assert formdata.data == {}
|
||||
|
||||
def test_global_timeouts(pub):
|
||||
FormDef.wipe()
|
||||
Workflow.wipe()
|
||||
|
|
|
@ -34,7 +34,7 @@ from qommon import ezt
|
|||
from qommon.form import (SingleSelectWidget, WidgetList, CheckboxWidget,
|
||||
StringWidget, UploadWidget, WysiwygTextWidget, Upload,
|
||||
UploadedFile, UploadValidationError, VarnameWidget,
|
||||
RadiobuttonsWidget)
|
||||
RadiobuttonsWidget, PicklableUpload)
|
||||
from qommon.errors import PublishError
|
||||
import qommon
|
||||
|
||||
|
@ -212,6 +212,7 @@ class ExportToModel(WorkflowStatusItem):
|
|||
convert_to_pdf = False
|
||||
push_to_portfolio = False
|
||||
method = 'interactive'
|
||||
backoffice_filefield_id = None
|
||||
|
||||
def render_as_line(self):
|
||||
if self.model_file:
|
||||
|
@ -276,13 +277,20 @@ class ExportToModel(WorkflowStatusItem):
|
|||
|
||||
def get_parameters(self):
|
||||
parameters = ('method', 'by', 'label', 'model_file', 'attach_to_history',
|
||||
'backoffice_info_text', 'varname')
|
||||
'backoffice_info_text', 'varname', 'backoffice_filefield_id')
|
||||
if transform_to_pdf is not None:
|
||||
parameters += ('convert_to_pdf',)
|
||||
if has_portfolio():
|
||||
parameters += ('push_to_portfolio',)
|
||||
return parameters
|
||||
|
||||
def get_backoffice_filefield_options(self):
|
||||
options = []
|
||||
for field in self.parent.parent.get_backoffice_fields():
|
||||
if field.key == 'file':
|
||||
options.append((field.id, field.label, field.id))
|
||||
return options
|
||||
|
||||
def add_parameters_widgets(self, form, parameters, prefix='',
|
||||
formdef=None):
|
||||
methods = collections.OrderedDict(
|
||||
|
@ -322,6 +330,13 @@ class ExportToModel(WorkflowStatusItem):
|
|||
form.add(CheckboxWidget, '%sconvert_to_pdf' % prefix,
|
||||
title=_('Convert generated file to PDF'),
|
||||
value=self.convert_to_pdf)
|
||||
if 'backoffice_filefield_id' in parameters:
|
||||
options = self.get_backoffice_filefield_options()
|
||||
if options:
|
||||
form.add(SingleSelectWidget, '%sbackoffice_filefield_id' % prefix,
|
||||
title=_('Store in a backoffice file field'),
|
||||
value=self.backoffice_filefield_id,
|
||||
options=[(None, '---', None)] + options)
|
||||
if 'attach_to_history' in parameters:
|
||||
form.add(CheckboxWidget, '%sattach_to_history' % prefix,
|
||||
title=_('Attach generated file to the form history'),
|
||||
|
@ -516,6 +531,15 @@ class ExportToModel(WorkflowStatusItem):
|
|||
return
|
||||
self.perform_real(formdata, formdata.evolution[-1])
|
||||
|
||||
def store_in_backoffice_filefield(self, formdata, filename, content_type, content):
|
||||
filefield = [x for x in self.parent.parent.get_backoffice_fields()
|
||||
if x.id == self.backoffice_filefield_id and x.key == 'file']
|
||||
if filefield:
|
||||
upload = PicklableUpload(filename, content_type)
|
||||
upload.receive([content])
|
||||
formdata.data[self.backoffice_filefield_id] = upload
|
||||
formdata.store()
|
||||
|
||||
def perform_real(self, formdata, evo):
|
||||
outstream = self.apply_template_to_formdata(formdata)
|
||||
filename = self.model_file.base_filename
|
||||
|
@ -532,5 +556,12 @@ class ExportToModel(WorkflowStatusItem):
|
|||
content_type=content_type,
|
||||
varname=self.varname))
|
||||
formdata.store()
|
||||
if self.backoffice_filefield_id:
|
||||
outstream.seek(0)
|
||||
self.store_in_backoffice_filefield(
|
||||
formdata,
|
||||
filename,
|
||||
content_type,
|
||||
outstream.read())
|
||||
|
||||
register_item_class(ExportToModel)
|
||||
|
|
Loading…
Reference in New Issue