Projet

Général

Profil

0001-backoffice-create-display-user-label-from-data-field.patch

Frédéric Péters, 08 juin 2019 14:42

Télécharger (12,7 ko)

Voir les différences:

Subject: [PATCH] backoffice: create/display user label from data fields
 (#33812)

 tests/test_backoffice_pages.py | 38 +++++++++++++++++++++++
 tests/test_formdata.py         | 57 ++++++++++++++++++++++++++++++++++
 wcs/backoffice/management.py   |  6 ++--
 wcs/formdata.py                | 30 +++++++++++++++---
 wcs/sql.py                     | 20 ++++++++----
 5 files changed, 138 insertions(+), 13 deletions(-)
tests/test_backoffice_pages.py
2826 2826
    assert resp.body[resp.body.index('<tbody'):].count('<tr') == 0
2827 2827
    assert not 'form-title' in resp.body
2828 2828

  
2829
def test_global_listing_user_label(pub):
2830
    if not pub.is_using_postgresql():
2831
        pytest.skip('this requires SQL')
2832
        return
2833

  
2834
    create_user(pub)
2835
    FormDef.wipe()
2836

  
2837
    from wcs.admin.settings import UserFieldsFormDef
2838
    user_formdef = UserFieldsFormDef(pub)
2839
    user_formdef.fields.append(fields.StringField(id='3', label='first_name', type='string'))
2840
    user_formdef.fields.append(fields.StringField(id='4', label='last_name', type='string'))
2841
    user_formdef.store()
2842
    pub.cfg['users']['field_name'] = ['3', '4']
2843
    pub.write_cfg()
2844

  
2845
    formdef = FormDef()
2846
    formdef.name = 'foobar'
2847
    formdef.url_name = 'foobar'
2848
    formdef.workflow_roles = {'_receiver': 1}
2849
    formdef.fields = [
2850
        fields.StringField(id='1', label='first_name',
2851
        prefill={'type': 'user', 'value': '3'}),
2852
        fields.StringField(id='2', label='last_name',
2853
        prefill={'type': 'user', 'value': '4'}),
2854
    ]
2855
    formdef.store()
2856

  
2857
    formdata = formdef.data_class()()
2858
    formdata.data = {'1': 'blah', '2': 'xxx'}
2859
    formdata.just_created()
2860
    formdata.store()
2861
    formdata.jump_status('new')
2862

  
2863
    app = login(get_app(pub))
2864
    resp = app.get('/backoffice/management/').follow()
2865
    resp = resp.click('Global View')
2866
    assert '<td class="cell-user">blah xxx</td>' in resp.body
2829 2867

  
2830 2868
def test_management_views_with_no_formdefs(pub):
2831 2869
    if not pub.is_using_postgresql():
tests/test_formdata.py
1618 1618
    for mode in (None, 'lazy'):
1619 1619
        context = pub.substitutions.get_context_variables(mode=mode)
1620 1620
        assert tmpl.render(context) == ''
1621

  
1622
def test_user_label(pub):
1623
    from wcs.admin.settings import UserFieldsFormDef
1624
    user_formdef = UserFieldsFormDef(pub)
1625
    user_formdef.fields.append(fields.StringField(id='3', label='first_name', type='string'))
1626
    user_formdef.fields.append(fields.StringField(id='4', label='last_name', type='string'))
1627
    user_formdef.store()
1628
    pub.cfg['users']['field_name'] = ['3', '4']
1629
    pub.write_cfg()
1630

  
1631
    formdef = FormDef()
1632
    formdef.name = 'foobar'
1633
    formdef.url_name = 'foobar'
1634
    formdef.fields = [
1635
        fields.StringField(id='1', label='first_name',
1636
        prefill={'type': 'user', 'value': '3'}),
1637
        fields.StringField(id='2', label='last_name',
1638
        prefill={'type': 'user', 'value': '4'}),
1639
    ]
1640
    formdef.store()
1641

  
1642
    user = pub.user_class()
1643
    user.email = 'bar@localhost'
1644
    user.store()
1645

  
1646
    formdata = formdef.data_class()()
1647
    formdata.data = {}
1648
    formdata.user_id = user.id
1649
    formdata.store()
1650

  
1651
    assert str(formdef.data_class().get(formdata.id).user_id) == str(user.id)
1652
    assert formdef.data_class().get(formdata.id).user_label is None
1653
    assert formdef.data_class().get(formdata.id).get_user_label() == 'bar@localhost'
1654

  
1655
    formdata = formdef.data_class()()
1656
    formdata.data = {}
1657
    formdata.store()
1658

  
1659
    assert formdef.data_class().get(formdata.id).user_id is None
1660
    assert formdef.data_class().get(formdata.id).user_label == ''
1661
    assert formdef.data_class().get(formdata.id).get_user_label() == ''
1662

  
1663
    formdata = formdef.data_class()()
1664
    formdata.data = {'1': 'blah'}
1665
    formdata.store()
1666

  
1667
    assert formdef.data_class().get(formdata.id).user_id is None
1668
    assert formdef.data_class().get(formdata.id).user_label == 'blah'
1669
    assert formdef.data_class().get(formdata.id).get_user_label() == 'blah'
1670

  
1671
    formdata = formdef.data_class()()
1672
    formdata.data = {'1': 'blah', '2': 'xxx'}
1673
    formdata.store()
1674

  
1675
    assert formdef.data_class().get(formdata.id).user_id is None
1676
    assert formdef.data_class().get(formdata.id).user_label == 'blah xxx'
1677
    assert formdef.data_class().get(formdata.id).get_user_label() == 'blah xxx'
wcs/backoffice/management.py
903 903
                    formdata.receipt_time)
904 904
            r += htmltext('<td class="cell-time">%s</td>') % misc.localstrftime(
905 905
                    formdata.last_update_time)
906
            try:
907
                value = get_publisher().user_class.get(formdata.user_id).display_name
906
            value = formdata.get_user_label()
907
            if value:
908 908
                r += htmltext('<td class="cell-user">%s</td>') % value
909
            except:
909
            else:
910 910
                r += htmltext('<td class="cell-user cell-no-user">-</td>')
911 911
            r += htmltext('<td class="cell-status">%s</td>') % formdata.get_status_label()
912 912
            r += htmltext('</tr>\n')
wcs/formdata.py
29 29
from qommon.storage import StorableObject, Intersects, Contains
30 30
import qommon.misc
31 31
from qommon.evalutils import make_datetime
32
from qommon.publisher import get_cfg
32 33
from qommon.substitution import Substitutions, invalidate_substitution_cache
33 34
from qommon.template import Template
34 35

  
......
245 246
    id_display = None
246 247

  
247 248
    user_id = None
249
    user_label = None  # taken from data, for anonymous users
248 250
    receipt_time = None
249 251
    status = None
250 252
    anonymised = None
......
323 325
            self.user_id = None
324 326
    user = property(get_user, set_user)
325 327

  
328
    def get_user_label(self):
329
        user = self.user
330
        if user:
331
            return user.get_display_name()
332
        return self.user_label
333

  
326 334
    def has_empty_data(self):
327 335
        empty = True
328 336
        for key in self.data or {}:
......
386 394
            # only set id_display once as it may have been set automatically
387 395
            # by interpreting a webservice response.
388 396
            fields['id_display'] = self.formdef.get_display_id_format().strip()
397

  
389 398
        changed = False
399

  
400
        users_cfg = get_cfg('users', {})
401
        if not self.user_id and users_cfg and users_cfg.get('field_name'):
402
            field_name_values = users_cfg.get('field_name')
403
            form_user_data = {}
404
            for field in self.formdef.fields:
405
                if not hasattr(field, 'prefill'):
406
                    continue
407
                if field.prefill and field.prefill.get('type') == 'user':
408
                    form_user_data[field.prefill['value']] = self.data.get(field.id)
409
            user_label = ' '.join([form_user_data.get(x) for x in field_name_values if form_user_data.get(x)])
410
            if user_label != self.user_label:
411
                self.user_label = user_label
412
                changed = True
413

  
390 414
        if any(fields.values()):
391 415
            context = self.get_substitution_variables()
392 416
            context['formdef_id'] = self.formdef.id
......
610 634
        if field.type == 'last_update_time':
611 635
            return qommon.misc.localstrftime(self.last_update_time)
612 636
        if field.type == 'user-label':
613
            try:
614
                return get_publisher().user_class.get(self.user_id).display_name
615
            except KeyError:
616
                return '-'
637
            return self.get_user_label() or '-'
617 638
        if field.type == 'status':
618 639
            return self.get_status_label()
619 640
        if field.type == 'submission_channel':
......
932 953

  
933 954
        self.anonymised = datetime.datetime.now()
934 955
        self.user_id = None
956
        self.user_label = None
935 957
        self.editable_by = None
936 958
        self.workflow_data = None
937 959
        self.workflow_roles = None
wcs/sql.py
403 403
        'actions_roles_array', 'backoffice_submission',
404 404
        'submission_context', 'submission_channel',
405 405
        'criticality_level', 'last_update_time',
406
        'digest'])
406
        'digest', 'user_label'])
407 407

  
408 408
    # migrations
409 409
    if not 'fts' in existing_fields:
......
447 447
    if not 'digest' in existing_fields:
448 448
        cur.execute('''ALTER TABLE %s ADD COLUMN digest varchar''' % table_name)
449 449

  
450
    if not 'user_label' in existing_fields:
451
        cur.execute('''ALTER TABLE %s ADD COLUMN user_label varchar''' % table_name)
452

  
450 453
    # add new fields
451 454
    for field in formdef.get_all_fields():
452 455
        assert field.id is not None
......
733 736
    view_fields.append(("int '%s'" % (formdef.id or 0), 'formdef_id'))
734 737
    for field in ('id', 'user_id', 'receipt_time', 'status',
735 738
            'id_display', 'submission_channel', 'backoffice_submission',
736
            'last_update_time', 'digest'):
739
            'last_update_time', 'digest', 'user_label'):
737 740
        view_fields.append((field, field))
738 741
    return view_fields
739 742

  
......
1207 1210
        ('criticality_level', 'int'),
1208 1211
        ('last_update_time', 'timestamp'),
1209 1212
        ('digest', 'varchar'),
1213
        ('user_label', 'varchar'),
1210 1214
    ]
1211 1215

  
1212 1216
    def __init__(self, id=None):
......
1363 1367
        if self.set_auto_fields():
1364 1368
            sql_statement = '''UPDATE %s
1365 1369
                                  SET id_display = %%(id_display)s,
1366
                                      digest = %%(digest)s
1370
                                      digest = %%(digest)s,
1371
                                      user_label = %%(user_label)s
1367 1372
                                WHERE id = %%(id)s''' % self._table_name
1368 1373
            cur.execute(sql_statement, {
1369 1374
                'id': self.id,
1370 1375
                'id_display': self.id_display,
1371 1376
                'digest': self.digest,
1377
                'user_label': self.user_label,
1372 1378
            })
1373 1379

  
1374 1380
        if self._evolution:
......
2168 2174
    return result
2169 2175

  
2170 2176

  
2171
SQL_LEVEL = 30
2177
SQL_LEVEL = 31
2172 2178

  
2173 2179
def migrate_global_views(conn, cur):
2174 2180
    cur.execute('''SELECT COUNT(*) FROM information_schema.tables
......
2235 2241
        raise RuntimeError()
2236 2242
    if sql_level < 1: # 1: introduction of tracking_code table
2237 2243
        do_tracking_code_table()
2238
    if sql_level < 27:
2244
    if sql_level < 31:
2239 2245
        # 2: introduction of formdef_id in views
2240 2246
        # 5: add concerned_roles_array, is_at_endpoint and fts to views
2241 2247
        # 7: add backoffice_submission to tables
......
2251 2257
        # 22: rebuild views
2252 2258
        # 26: add digest to formdata
2253 2259
        # 27: add last_jump_datetime in evolutions tables
2260
        # 31: add user_label to formdata
2254 2261
        migrate_views(conn, cur)
2255 2262
    if sql_level < 21:
2256 2263
        # 3: introduction of _structured for user fields
......
2270 2277
        # 21: (second part), store ascii_name of users
2271 2278
        # 23: (first part), use misc.simplify() over full text queries
2272 2279
        set_reindex('user', 'needed', conn=conn, cur=cur)
2273
    if sql_level < 28:
2280
    if sql_level < 31:
2274 2281
        # 17: store last_update_time in tables
2275 2282
        # 18: add user name to full-text search index
2276 2283
        # 21: (third part), add user ascii_names to full-text index
2277 2284
        # 23: (second part) use misc.simplify() over full text queries
2278 2285
        # 28: add display id and formdef name to full-text index
2279 2286
        # 29: add evolution parts to full-text index
2287
        # 31: add user_label to formdata
2280 2288
        set_reindex('formdata', 'needed', conn=conn, cur=cur)
2281 2289
    if sql_level < 24:
2282 2290
        from wcs.formdef import FormDef
2283
-