Projet

Général

Profil

0002-workflow-allow-to-send-generated-docs-in-backoffice-.patch

Thomas Noël, 07 octobre 2017 15:38

Télécharger (10,6 ko)

Voir les différences:

Subject: [PATCH 2/2] workflow: allow to send generated docs in backoffice
 field (#19188)

 tests/test_form_pages.py  | 67 ++++++++++++++++++++++++++++++++++++++++++++++-
 tests/test_workflows.py   | 64 ++++++++++++++++++++++++++++++++++++++++++++
 wcs/wf/export_to_model.py | 35 +++++++++++++++++++++++--
 3 files changed, 163 insertions(+), 3 deletions(-)
tests/test_form_pages.py
19 19
from wcs.qommon.form import UploadedFile
20 20
from wcs.qommon.ident.password_accounts import PasswordAccount
21 21
from wcs.formdef import FormDef
22
from wcs.workflows import Workflow, EditableWorkflowStatusItem, DisplayMessageWorkflowStatusItem
22
from wcs.workflows import (Workflow, EditableWorkflowStatusItem,
23
        DisplayMessageWorkflowStatusItem, WorkflowBackofficeFieldsFormDef)
23 24
from wcs.wf.export_to_model import ExportToModel, transform_to_pdf
24 25
from wcs.wf.jump import JumpWorkflowStatusItem
25 26
from wcs.wf.attachment import AddAttachmentWorkflowStatusItem
......
2551 2552
    assert formdef.data_class().count() == 1
2552 2553
    assert formdef.data_class().select()[0].status == 'wf-st2'
2553 2554

  
2555
def test_formdata_generated_document_to_backoffice_field(pub):
2556
    create_user_and_admin(pub)
2557
    wf = Workflow(name='status')
2558
    wf.backoffice_fields_formdef = WorkflowBackofficeFieldsFormDef(wf)
2559
    wf.backoffice_fields_formdef.fields = [
2560
        fields.FileField(id='bo1', label='bo field 1', type='file'),
2561
        fields.StringField(id='bo2', label='bo field 2', type='string'),
2562
    ]
2563

  
2564
    st1 = wf.add_status('Status1', 'st1')
2565
    export_to = ExportToModel()
2566
    export_to.method = 'non-interactive'
2567
    template_filename = os.path.join(os.path.dirname(__file__), 'template.odt')
2568
    template = open(template_filename).read()
2569
    upload = QuixoteUpload('/foo/template.odt', content_type='application/octet-stream')
2570
    upload.fp = StringIO.StringIO()
2571
    upload.fp.write(template)
2572
    upload.fp.seek(0)
2573
    export_to.model_file = UploadedFile(pub.app_dir, None, upload)
2574
    export_to.id = '_export_to'
2575
    export_to.attach_to_history = True
2576
    export_to.backoffice_filefield_id = 'bo1'
2577
    st1.items.append(export_to)
2578
    export_to.parent = st1
2579

  
2580
    assert export_to.get_backoffice_filefield_options() == [('bo1', 'bo field 1', 'bo1')]
2581

  
2582
    jump = JumpWorkflowStatusItem()
2583
    jump.status = 'st2'
2584
    st1.items.append(jump)
2585
    jump.parent = st1
2586
    wf.add_status('Status2', 'st2')
2587
    wf.store()
2588

  
2589
    formdef = create_formdef()
2590
    formdef.workflow_id = wf.id
2591
    formdef.fields = [fields.TextField(id='0', label='comment', type='text', varname='comment')]
2592
    formdef.store()
2593
    formdef.data_class().wipe()
2594

  
2595
    resp = login(get_app(pub), username='foo', password='foo').get('/test/')
2596
    resp.form['f0'] = 'Hello\n\nWorld.'
2597
    resp = resp.forms[0].submit('submit')
2598
    assert 'Check values then click submit.' in resp.body
2599
    resp = resp.forms[0].submit('submit')
2600
    assert resp.status_int == 302
2601
    resp = resp.follow()
2602
    assert 'The form has been recorded' in resp.body
2603

  
2604
    # get the two generated files from backoffice: in backoffice fields
2605
    # (export_to.backoffice_filefield_id), and in history (export_to.attach_to_history)
2606
    for index in (0, 1):
2607
        resp = login(get_app(pub), username='admin', password='admin').get(
2608
                '/backoffice/management/test/1/')
2609
        resp = resp.click('template.odt', index=index)
2610
        assert resp.location.endswith('/template.odt')
2611
        resp = resp.follow()
2612
        assert resp.content_type == 'application/octet-stream'
2613
        with open(os.path.join(os.path.dirname(__file__), 'template-out.odt')) as f:
2614
            assert_equal_zip(StringIO.StringIO(resp.body), f)
2615

  
2616
    assert formdef.data_class().count() == 1
2617
    assert formdef.data_class().select()[0].status == 'wf-st2'
2618

  
2554 2619
def test_formdata_form_file_download(pub):
2555 2620
    create_user(pub)
2556 2621
    wf = Workflow(name='status')
tests/test_workflows.py
2124 2124
        # check the original image has been left
2125 2125
        assert zinfo.file_size == 580
2126 2126

  
2127
def test_export_to_model_backoffice_field(pub):
2128
    wf = Workflow(name='email with attachments')
2129
    wf.backoffice_fields_formdef = WorkflowBackofficeFieldsFormDef(wf)
2130
    wf.backoffice_fields_formdef.fields = [
2131
        FileField(id='bo1', label='bo field 1', type='file', varname='backoffice_file1'),
2132
    ]
2133
    st1 = wf.add_status('Status1')
2134
    wf.store()
2135
    formdef = FormDef()
2136
    formdef.name = 'foo-export-to-bofile'
2137
    formdef.fields = [
2138
        StringField(id='1', label='String', type='string', varname='string'),
2139
    ]
2140
    formdef.workflow_id = wf.id
2141
    formdef.store()
2142
    formdata = formdef.data_class()()
2143
    formdata.data = {}
2144
    formdata.just_created()
2145
    formdata.store()
2146
    pub.substitutions.feed(formdata)
2147

  
2148
    item = ExportToModel()
2149
    item.method = 'non-interactive'
2150
    template_filename = os.path.join(os.path.dirname(__file__), 'template.odt')
2151
    template = open(template_filename).read()
2152
    upload = QuixoteUpload('/foo/template.odt', content_type='application/octet-stream')
2153
    upload.fp = StringIO.StringIO()
2154
    upload.fp.write(template)
2155
    upload.fp.seek(0)
2156
    item.model_file = UploadedFile(pub.app_dir, None, upload)
2157
    item.parent = st1
2158
    item.backoffice_filefield_id = 'bo1'
2159
    item.perform(formdata)
2160

  
2161
    assert 'bo1' in formdata.data
2162
    fbo1 = formdata.data['bo1']
2163
    assert fbo1.base_filename == 'template.odt'
2164
    assert fbo1.content_type == 'application/octet-stream'
2165
    zfile = zipfile.ZipFile(fbo1.get_file())
2166
    assert 'foo-export-to-bofile' in zfile.read('content.xml')
2167

  
2168
    # no more 'bo1' backoffice field: do nothing
2169
    formdata = formdef.data_class()()
2170
    formdata.data = {}
2171
    formdata.just_created()
2172
    formdata.store()
2173
    pub.substitutions.feed(formdata)
2174
    # id is not bo1:
2175
    wf.backoffice_fields_formdef.fields = [
2176
        FileField(id='bo2', label='bo field 2', type='file'),
2177
    ]
2178
    item.perform(formdata)
2179
    assert formdata.data == {}
2180
    # field is not a field file:
2181
    wf.backoffice_fields_formdef.fields = [
2182
        StringField(id='bo1', label='bo field 1', type='string'),
2183
    ]
2184
    item.perform(formdata)
2185
    assert formdata.data == {}
2186
    # no field at all:
2187
    wf.backoffice_fields_formdef.fields = []
2188
    item.perform(formdata)
2189
    assert formdata.data == {}
2190

  
2127 2191
def test_global_timeouts(pub):
2128 2192
    FormDef.wipe()
2129 2193
    Workflow.wipe()
wcs/wf/export_to_model.py
34 34
from qommon.form import (SingleSelectWidget, WidgetList, CheckboxWidget,
35 35
                         StringWidget, UploadWidget, WysiwygTextWidget, Upload,
36 36
                         UploadedFile, UploadValidationError, VarnameWidget,
37
                         RadiobuttonsWidget)
37
                         RadiobuttonsWidget, PicklableUpload)
38 38
from qommon.errors import PublishError
39 39
import qommon
40 40

  
......
212 212
    convert_to_pdf = False
213 213
    push_to_portfolio = False
214 214
    method = 'interactive'
215
    backoffice_filefield_id = None
215 216

  
216 217
    def render_as_line(self):
217 218
        if self.model_file:
......
276 277

  
277 278
    def get_parameters(self):
278 279
        parameters = ('method', 'by', 'label', 'model_file', 'attach_to_history',
279
                'backoffice_info_text', 'varname')
280
                'backoffice_info_text', 'varname', 'backoffice_filefield_id')
280 281
        if transform_to_pdf is not None:
281 282
            parameters += ('convert_to_pdf',)
282 283
        if has_portfolio():
283 284
            parameters += ('push_to_portfolio',)
284 285
        return parameters
285 286

  
287
    def get_backoffice_filefield_options(self):
288
        options = []
289
        for field in self.parent.parent.get_backoffice_fields():
290
            if field.key == 'file':
291
                options.append((field.id, field.label, field.id))
292
        return options
293

  
286 294
    def add_parameters_widgets(self, form, parameters, prefix='',
287 295
                               formdef=None):
288 296
        methods = collections.OrderedDict(
......
322 330
            form.add(CheckboxWidget, '%sconvert_to_pdf' % prefix,
323 331
                     title=_('Convert generated file to PDF'),
324 332
                     value=self.convert_to_pdf)
333
        if 'backoffice_filefield_id' in parameters:
334
            options = self.get_backoffice_filefield_options()
335
            if options:
336
                form.add(SingleSelectWidget, '%sbackoffice_filefield_id' % prefix,
337
                         title=_('Store in a backoffice file field'),
338
                         value=self.backoffice_filefield_id,
339
                         options=[(None, '---', None)] + options)
325 340
        if 'attach_to_history' in parameters:
326 341
            form.add(CheckboxWidget, '%sattach_to_history' % prefix,
327 342
                     title=_('Attach generated file to the form history'),
......
516 531
            return
517 532
        self.perform_real(formdata, formdata.evolution[-1])
518 533

  
534
    def store_in_backoffice_filefield(self, formdata, filename, content_type, content):
535
        filefield = [x for x in self.parent.parent.get_backoffice_fields()
536
                        if x.id == self.backoffice_filefield_id and x.key == 'file']
537
        if filefield:
538
            upload = PicklableUpload(filename, content_type)
539
            upload.receive([content])
540
            formdata.data[self.backoffice_filefield_id] = upload
541
            formdata.store()
542

  
519 543
    def perform_real(self, formdata, evo):
520 544
        outstream = self.apply_template_to_formdata(formdata)
521 545
        filename = self.model_file.base_filename
......
532 556
                content_type=content_type,
533 557
                varname=self.varname))
534 558
            formdata.store()
559
        if self.backoffice_filefield_id:
560
            outstream.seek(0)
561
            self.store_in_backoffice_filefield(
562
                formdata,
563
                filename,
564
                content_type,
565
                outstream.read())
535 566

  
536 567
register_item_class(ExportToModel)
537
-