backoffice: create/display user label from data fields (#33812)
This commit is contained in:
parent
b35f425223
commit
f14115483d
|
@ -2818,6 +2818,44 @@ def test_global_listing(pub):
|
|||
assert resp.body[resp.body.index('<tbody'):].count('<tr') == 0
|
||||
assert not 'form-title' in resp.body
|
||||
|
||||
def test_global_listing_user_label(pub):
|
||||
if not pub.is_using_postgresql():
|
||||
pytest.skip('this requires SQL')
|
||||
return
|
||||
|
||||
create_user(pub)
|
||||
FormDef.wipe()
|
||||
|
||||
from wcs.admin.settings import UserFieldsFormDef
|
||||
user_formdef = UserFieldsFormDef(pub)
|
||||
user_formdef.fields.append(fields.StringField(id='3', label='first_name', type='string'))
|
||||
user_formdef.fields.append(fields.StringField(id='4', label='last_name', type='string'))
|
||||
user_formdef.store()
|
||||
pub.cfg['users']['field_name'] = ['3', '4']
|
||||
pub.write_cfg()
|
||||
|
||||
formdef = FormDef()
|
||||
formdef.name = 'foobar'
|
||||
formdef.url_name = 'foobar'
|
||||
formdef.workflow_roles = {'_receiver': 1}
|
||||
formdef.fields = [
|
||||
fields.StringField(id='1', label='first_name',
|
||||
prefill={'type': 'user', 'value': '3'}),
|
||||
fields.StringField(id='2', label='last_name',
|
||||
prefill={'type': 'user', 'value': '4'}),
|
||||
]
|
||||
formdef.store()
|
||||
|
||||
formdata = formdef.data_class()()
|
||||
formdata.data = {'1': 'blah', '2': 'xxx'}
|
||||
formdata.just_created()
|
||||
formdata.store()
|
||||
formdata.jump_status('new')
|
||||
|
||||
app = login(get_app(pub))
|
||||
resp = app.get('/backoffice/management/').follow()
|
||||
resp = resp.click('Global View')
|
||||
assert '<td class="cell-user">blah xxx</td>' in resp.body
|
||||
|
||||
def test_management_views_with_no_formdefs(pub):
|
||||
if not pub.is_using_postgresql():
|
||||
|
|
|
@ -1618,3 +1618,60 @@ def test_string_filters(pub, variable_test_data):
|
|||
for mode in (None, 'lazy'):
|
||||
context = pub.substitutions.get_context_variables(mode=mode)
|
||||
assert tmpl.render(context) == ''
|
||||
|
||||
def test_user_label(pub):
|
||||
from wcs.admin.settings import UserFieldsFormDef
|
||||
user_formdef = UserFieldsFormDef(pub)
|
||||
user_formdef.fields.append(fields.StringField(id='3', label='first_name', type='string'))
|
||||
user_formdef.fields.append(fields.StringField(id='4', label='last_name', type='string'))
|
||||
user_formdef.store()
|
||||
pub.cfg['users']['field_name'] = ['3', '4']
|
||||
pub.write_cfg()
|
||||
|
||||
formdef = FormDef()
|
||||
formdef.name = 'foobar'
|
||||
formdef.url_name = 'foobar'
|
||||
formdef.fields = [
|
||||
fields.StringField(id='1', label='first_name',
|
||||
prefill={'type': 'user', 'value': '3'}),
|
||||
fields.StringField(id='2', label='last_name',
|
||||
prefill={'type': 'user', 'value': '4'}),
|
||||
]
|
||||
formdef.store()
|
||||
|
||||
user = pub.user_class()
|
||||
user.email = 'bar@localhost'
|
||||
user.store()
|
||||
|
||||
formdata = formdef.data_class()()
|
||||
formdata.data = {}
|
||||
formdata.user_id = user.id
|
||||
formdata.store()
|
||||
|
||||
assert str(formdef.data_class().get(formdata.id).user_id) == str(user.id)
|
||||
assert formdef.data_class().get(formdata.id).user_label is None
|
||||
assert formdef.data_class().get(formdata.id).get_user_label() == 'bar@localhost'
|
||||
|
||||
formdata = formdef.data_class()()
|
||||
formdata.data = {}
|
||||
formdata.store()
|
||||
|
||||
assert formdef.data_class().get(formdata.id).user_id is None
|
||||
assert formdef.data_class().get(formdata.id).user_label == ''
|
||||
assert formdef.data_class().get(formdata.id).get_user_label() == ''
|
||||
|
||||
formdata = formdef.data_class()()
|
||||
formdata.data = {'1': 'blah'}
|
||||
formdata.store()
|
||||
|
||||
assert formdef.data_class().get(formdata.id).user_id is None
|
||||
assert formdef.data_class().get(formdata.id).user_label == 'blah'
|
||||
assert formdef.data_class().get(formdata.id).get_user_label() == 'blah'
|
||||
|
||||
formdata = formdef.data_class()()
|
||||
formdata.data = {'1': 'blah', '2': 'xxx'}
|
||||
formdata.store()
|
||||
|
||||
assert formdef.data_class().get(formdata.id).user_id is None
|
||||
assert formdef.data_class().get(formdata.id).user_label == 'blah xxx'
|
||||
assert formdef.data_class().get(formdata.id).get_user_label() == 'blah xxx'
|
||||
|
|
|
@ -899,10 +899,10 @@ class ManagementDirectory(Directory):
|
|||
formdata.receipt_time)
|
||||
r += htmltext('<td class="cell-time">%s</td>') % misc.localstrftime(
|
||||
formdata.last_update_time)
|
||||
try:
|
||||
value = get_publisher().user_class.get(formdata.user_id).display_name
|
||||
value = formdata.get_user_label()
|
||||
if value:
|
||||
r += htmltext('<td class="cell-user">%s</td>') % value
|
||||
except:
|
||||
else:
|
||||
r += htmltext('<td class="cell-user cell-no-user">-</td>')
|
||||
r += htmltext('<td class="cell-status">%s</td>') % formdata.get_status_label()
|
||||
r += htmltext('</tr>\n')
|
||||
|
|
|
@ -29,6 +29,7 @@ from qommon import _
|
|||
from qommon.storage import StorableObject, Intersects, Contains
|
||||
import qommon.misc
|
||||
from qommon.evalutils import make_datetime
|
||||
from qommon.publisher import get_cfg
|
||||
from qommon.substitution import Substitutions, invalidate_substitution_cache
|
||||
from qommon.template import Template
|
||||
|
||||
|
@ -245,6 +246,7 @@ class FormData(StorableObject):
|
|||
id_display = None
|
||||
|
||||
user_id = None
|
||||
user_label = None # taken from data, for anonymous users
|
||||
receipt_time = None
|
||||
status = None
|
||||
anonymised = None
|
||||
|
@ -323,6 +325,12 @@ class FormData(StorableObject):
|
|||
self.user_id = None
|
||||
user = property(get_user, set_user)
|
||||
|
||||
def get_user_label(self):
|
||||
user = self.user
|
||||
if user:
|
||||
return user.get_display_name()
|
||||
return self.user_label
|
||||
|
||||
def has_empty_data(self):
|
||||
empty = True
|
||||
for key in self.data or {}:
|
||||
|
@ -386,7 +394,23 @@ class FormData(StorableObject):
|
|||
# only set id_display once as it may have been set automatically
|
||||
# by interpreting a webservice response.
|
||||
fields['id_display'] = self.formdef.get_display_id_format().strip()
|
||||
|
||||
changed = False
|
||||
|
||||
users_cfg = get_cfg('users', {})
|
||||
if not self.user_id and users_cfg and users_cfg.get('field_name'):
|
||||
field_name_values = users_cfg.get('field_name')
|
||||
form_user_data = {}
|
||||
for field in self.formdef.fields:
|
||||
if not hasattr(field, 'prefill'):
|
||||
continue
|
||||
if field.prefill and field.prefill.get('type') == 'user':
|
||||
form_user_data[field.prefill['value']] = self.data.get(field.id)
|
||||
user_label = ' '.join([form_user_data.get(x) for x in field_name_values if form_user_data.get(x)])
|
||||
if user_label != self.user_label:
|
||||
self.user_label = user_label
|
||||
changed = True
|
||||
|
||||
if any(fields.values()):
|
||||
context = self.get_substitution_variables()
|
||||
context['formdef_id'] = self.formdef.id
|
||||
|
@ -610,10 +634,7 @@ class FormData(StorableObject):
|
|||
if field.type == 'last_update_time':
|
||||
return qommon.misc.localstrftime(self.last_update_time)
|
||||
if field.type == 'user-label':
|
||||
try:
|
||||
return get_publisher().user_class.get(self.user_id).display_name
|
||||
except KeyError:
|
||||
return '-'
|
||||
return self.get_user_label() or '-'
|
||||
if field.type == 'status':
|
||||
return self.get_status_label()
|
||||
if field.type == 'submission_channel':
|
||||
|
@ -935,6 +956,7 @@ class FormData(StorableObject):
|
|||
|
||||
self.anonymised = datetime.datetime.now()
|
||||
self.user_id = None
|
||||
self.user_label = None
|
||||
self.editable_by = None
|
||||
self.workflow_data = None
|
||||
self.workflow_roles = None
|
||||
|
|
20
wcs/sql.py
20
wcs/sql.py
|
@ -403,7 +403,7 @@ def do_formdef_tables(formdef, conn=None, cur=None, rebuild_views=False, rebuild
|
|||
'actions_roles_array', 'backoffice_submission',
|
||||
'submission_context', 'submission_channel',
|
||||
'criticality_level', 'last_update_time',
|
||||
'digest'])
|
||||
'digest', 'user_label'])
|
||||
|
||||
# migrations
|
||||
if not 'fts' in existing_fields:
|
||||
|
@ -447,6 +447,9 @@ def do_formdef_tables(formdef, conn=None, cur=None, rebuild_views=False, rebuild
|
|||
if not 'digest' in existing_fields:
|
||||
cur.execute('''ALTER TABLE %s ADD COLUMN digest varchar''' % table_name)
|
||||
|
||||
if not 'user_label' in existing_fields:
|
||||
cur.execute('''ALTER TABLE %s ADD COLUMN user_label varchar''' % table_name)
|
||||
|
||||
# add new fields
|
||||
for field in formdef.get_all_fields():
|
||||
assert field.id is not None
|
||||
|
@ -733,7 +736,7 @@ def get_view_fields(formdef):
|
|||
view_fields.append(("int '%s'" % (formdef.id or 0), 'formdef_id'))
|
||||
for field in ('id', 'user_id', 'receipt_time', 'status',
|
||||
'id_display', 'submission_channel', 'backoffice_submission',
|
||||
'last_update_time', 'digest'):
|
||||
'last_update_time', 'digest', 'user_label'):
|
||||
view_fields.append((field, field))
|
||||
return view_fields
|
||||
|
||||
|
@ -1207,6 +1210,7 @@ class SqlFormData(SqlMixin, wcs.formdata.FormData):
|
|||
('criticality_level', 'int'),
|
||||
('last_update_time', 'timestamp'),
|
||||
('digest', 'varchar'),
|
||||
('user_label', 'varchar'),
|
||||
]
|
||||
|
||||
def __init__(self, id=None):
|
||||
|
@ -1363,12 +1367,14 @@ class SqlFormData(SqlMixin, wcs.formdata.FormData):
|
|||
if self.set_auto_fields():
|
||||
sql_statement = '''UPDATE %s
|
||||
SET id_display = %%(id_display)s,
|
||||
digest = %%(digest)s
|
||||
digest = %%(digest)s,
|
||||
user_label = %%(user_label)s
|
||||
WHERE id = %%(id)s''' % self._table_name
|
||||
cur.execute(sql_statement, {
|
||||
'id': self.id,
|
||||
'id_display': self.id_display,
|
||||
'digest': self.digest,
|
||||
'user_label': self.user_label,
|
||||
})
|
||||
|
||||
if self._evolution:
|
||||
|
@ -2168,7 +2174,7 @@ def get_yearly_totals(period_start=None, period_end=None, criterias=None):
|
|||
return result
|
||||
|
||||
|
||||
SQL_LEVEL = 30
|
||||
SQL_LEVEL = 31
|
||||
|
||||
def migrate_global_views(conn, cur):
|
||||
cur.execute('''SELECT COUNT(*) FROM information_schema.tables
|
||||
|
@ -2235,7 +2241,7 @@ def migrate():
|
|||
raise RuntimeError()
|
||||
if sql_level < 1: # 1: introduction of tracking_code table
|
||||
do_tracking_code_table()
|
||||
if sql_level < 27:
|
||||
if sql_level < 31:
|
||||
# 2: introduction of formdef_id in views
|
||||
# 5: add concerned_roles_array, is_at_endpoint and fts to views
|
||||
# 7: add backoffice_submission to tables
|
||||
|
@ -2251,6 +2257,7 @@ def migrate():
|
|||
# 22: rebuild views
|
||||
# 26: add digest to formdata
|
||||
# 27: add last_jump_datetime in evolutions tables
|
||||
# 31: add user_label to formdata
|
||||
migrate_views(conn, cur)
|
||||
if sql_level < 21:
|
||||
# 3: introduction of _structured for user fields
|
||||
|
@ -2270,13 +2277,14 @@ def migrate():
|
|||
# 21: (second part), store ascii_name of users
|
||||
# 23: (first part), use misc.simplify() over full text queries
|
||||
set_reindex('user', 'needed', conn=conn, cur=cur)
|
||||
if sql_level < 28:
|
||||
if sql_level < 31:
|
||||
# 17: store last_update_time in tables
|
||||
# 18: add user name to full-text search index
|
||||
# 21: (third part), add user ascii_names to full-text index
|
||||
# 23: (second part) use misc.simplify() over full text queries
|
||||
# 28: add display id and formdef name to full-text index
|
||||
# 29: add evolution parts to full-text index
|
||||
# 31: add user_label to formdata
|
||||
set_reindex('formdata', 'needed', conn=conn, cur=cur)
|
||||
if sql_level < 24:
|
||||
from wcs.formdef import FormDef
|
||||
|
|
Loading…
Reference in New Issue