From 415c3d48c2addd719348f65a951937a71a89b809 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20P=C3=A9ters?= <fpeters@entrouvert.com>
Date: Mon, 13 Jul 2020 19:55:27 +0200
Subject: [PATCH] backoffice: add filtering on submission agent id (#45081)

---
 tests/test_backoffice_pages.py | 49 ++++++++++++++++++++++++++++++++++
 wcs/backoffice/management.py   | 17 +++++++++++-
 2 files changed, 65 insertions(+), 1 deletion(-)

diff --git a/tests/test_backoffice_pages.py b/tests/test_backoffice_pages.py
index 9bd3f0aac..c5f9b3f73 100644
--- a/tests/test_backoffice_pages.py
+++ b/tests/test_backoffice_pages.py
@@ -1174,6 +1174,55 @@ def test_backoffice_user_filter(pub):
     assert resp.text.count('>userB<') == 0
 
 
+def test_backoffice_submission_agent_filter(pub):
+    pub.user_class.wipe()
+    user = create_superuser(pub)
+    create_environment(pub)
+    formdef = FormDef.get_by_urlname('form-title')
+    formdef.backoffice_submission_roles = user.roles
+    formdef.store()
+
+    user1 = pub.user_class(name='userA')
+    user1.store()
+    user2 = pub.user_class(name='userB')
+    user2.store()
+
+    for i, formdata in enumerate(formdef.data_class().select()):
+        formdata.submission_agent_id = str(user1.id if i < 10 else user2.id)
+        formdata.status = 'wf-new'
+        formdata.store()
+
+    app = login(get_app(pub))
+    resp = app.get('/backoffice/management/form-title/?limit=100')
+    # enable submission-agent column
+    resp.forms['listing-settings']['submission_agent'].checked = True
+    resp = resp.forms['listing-settings'].submit()
+    assert resp.text.count('>userA<') > 0
+    assert resp.text.count('>userB<') > 0
+    # check the filter is hidden
+    assert resp.pyquery.find('li[hidden] input[name=filter-submission-agent]')
+
+    base_url = resp.request.url
+    resp = app.get(base_url + '&filter-submission-agent=on&filter-submission-agent-value=%s' % user1.id)
+    assert resp.text.count('>userA<') > 0
+    assert resp.text.count('>userB<') == 0
+    assert resp.text.count('<tr') == 11
+    assert resp.pyquery.find('input[value=userA]')  # displayed in sidebar
+    # check it persits on filter changes
+    resp = resp.forms['listing-settings'].submit()
+    assert resp.text.count('>userA<') > 0
+    assert resp.text.count('>userB<') == 0
+    assert resp.text.count('<tr') == 11
+
+    resp = app.get(base_url + '&filter-submission-agent=on&filter-submission-agent-value=%s' % user2.id)
+    assert resp.text.count('>userA<') == 0
+    assert resp.text.count('>userB<') > 0
+    assert resp.text.count('<tr') == 42
+
+    resp = app.get('/backoffice/management/form-title/?limit=100&filter-submission-agent=on&filter-submission-agent-value=%s' % user2.id)
+    assert resp.text.count('<tr') == 42
+
+
 def test_backoffice_csv(pub):
     create_superuser(pub)
     create_environment(pub)
diff --git a/wcs/backoffice/management.py b/wcs/backoffice/management.py
index 52e05a2ac..5b6a1ae5d 100644
--- a/wcs/backoffice/management.py
+++ b/wcs/backoffice/management.py
@@ -1171,7 +1171,8 @@ class FormPage(Directory):
                 cls=misc.JSONEncoder)
 
     def get_filterable_field_types(self):
-        types = ['string', 'email', 'item', 'bool', 'items', 'period-date', 'user-id']
+        types = ['string', 'email', 'item', 'bool', 'items', 'period-date',
+                'user-id', 'submission-agent-id']
         if get_publisher().is_using_postgresql():
             types.append('date')
         return types
@@ -1184,6 +1185,7 @@ class FormPage(Directory):
             FakeField('start', 'period-date', _('Start')),
             FakeField('end', 'period-date', _('End')),
             FakeField('user', 'user-id', _('User'), addable=False),
+            FakeField('submission-agent', 'submission-agent-id', _('Submission Agent'), addable=False),
         ]
         default_filters = self.get_default_filters(mode)
 
@@ -1281,6 +1283,16 @@ class FormPage(Directory):
                     widget._parsed = True  # make sure value is not replaced by request query
                     r += widget.render()
 
+            elif filter_field.type == 'submission-agent-id':
+                r += HiddenWidget(filter_field_key, value=filter_field_value).render()
+                if filter_field_value:
+                    filtered_user = get_publisher().user_class.get(filter_field_value, ignore_errors=True)
+                    widget = StringWidget('_' + filter_field_key, title=filter_field.label,
+                            value=filtered_user.display_name if filtered_user else _('Unknown'),
+                            readonly=True, render_br=False)
+                    widget._parsed = True  # make sure value is not replaced by request query
+                    r += widget.render()
+
             elif filter_field.type in ('item', 'items'):
                 filter_field.required = False
 
@@ -1571,6 +1583,7 @@ class FormPage(Directory):
             FakeField('start-mtime', 'period-date', _('Start (modification time)')),
             FakeField('end-mtime', 'period-date', _('End (modification time)')),
             FakeField('user', 'user-id', _('User')),
+            FakeField('submission-agent', 'submission-agent-id', _('Submission Agent')),
         ]
         criterias = []
 
@@ -1633,6 +1646,8 @@ class FormPage(Directory):
                 criterias[-1]._label = '%s: %s' % (filter_field.label, filter_field_value)
             elif filter_field.type == 'user-id':
                 criterias.append(Equal('user_id', filter_field_value))
+            elif filter_field.type == 'submission-agent-id':
+                criterias.append(Equal('submission_agent_id', filter_field_value))
             elif filter_field.type in ('item', 'items') and filter_field_value not in (None, 'None'):
                 if filter_field.type == 'item':
                     criterias.append(Equal('f%s' % filter_field.id, filter_field_value))
-- 
2.27.0

