From b1a905bf98fd18cefaeb0a5f602051b0d91be70d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Laur=C3=A9line=20Gu=C3=A9rin?= <zebuline@entrouvert.com>
Date: Tue, 13 Sep 2022 11:01:20 +0200
Subject: [PATCH] api: add backoffice agent info in formdata result (#68753)

---
 tests/api/test_formdata.py   | 52 +++++++++++++++++++++++++++++++++++-
 wcs/backoffice/management.py | 10 ++++---
 wcs/formdata.py              |  9 +++++++
 3 files changed, 67 insertions(+), 4 deletions(-)

diff --git a/tests/api/test_formdata.py b/tests/api/test_formdata.py
index 8e9fd51cf..5cf8f4350 100644
--- a/tests/api/test_formdata.py
+++ b/tests/api/test_formdata.py
@@ -206,7 +206,7 @@ def test_formdata(pub, local_user):
     ]
     assert resp.json['workflow']['status']['name'] == 'New'
     assert resp.json['workflow']['real_status']['name'] == 'New'
-    assert resp.json['submission']['channel'] == 'web'
+    assert resp.json['submission'] == {'backoffice': False, 'channel': 'web'}
     assert resp.json['geolocations']['base']['lon'] == 10
     assert resp.json['geolocations']['base']['lat'] == -12
 
@@ -284,6 +284,56 @@ def test_formdata_user_fields(pub, local_user):
     }
 
 
+def test_formdata_submission_fields(pub, local_user):
+    agent = pub.user_class(name='agent')
+    agent.store()
+
+    pub.role_class.wipe()
+    role = pub.role_class(name='test')
+    role.id = '123'
+    role.store()
+    local_user.roles = [role.id]
+    local_user.store()
+
+    user_formdef = UserFieldsFormDef(pub)
+    user_formdef.fields = [
+        fields.StringField(id='3', label='test', type='string', varname='var1'),
+        fields.StringField(id='9', label='noop', type='string', varname='var2'),
+        fields.StringField(id='42', label='no varname', type='string'),
+    ]
+    user_formdef.store()
+    local_user.form_data = {'3': 'toto', '9': 'nono'}
+    local_user.store()
+
+    FormDef.wipe()
+    formdef = FormDef()
+    formdef.name = 'test'
+    formdef.workflow_roles = {'_receiver': role.id}
+    formdef.store()
+
+    formdef.data_class().wipe()
+    formdata = formdef.data_class()()
+    formdata.user_id = local_user.id
+    formdata.submission_agent_id = agent.id
+    formdata.just_created()
+    formdata.store()
+
+    resp = get_app(pub).get(sign_uri('/api/forms/test/list', user=local_user))
+    assert 'submission' not in resp.json[0]
+    resp = get_app(pub).get(sign_uri('/api/forms/test/list?full=on', user=local_user))
+    assert resp.json[0]['submission'] == {
+        'backoffice': False,
+        'channel': 'web',
+        'agent': {'id': agent.id, 'name': 'agent'},
+    }
+    resp = get_app(pub).get(sign_uri('/api/forms/test/%s/' % formdata.id, user=local_user))
+    assert resp.json['submission'] == {
+        'backoffice': False,
+        'channel': 'web',
+        'agent': {'id': agent.id, 'name': 'agent'},
+    }
+
+
 def test_formdata_backoffice_fields(pub, local_user):
     test_formdata(pub, local_user)
     Workflow.wipe()
diff --git a/wcs/backoffice/management.py b/wcs/backoffice/management.py
index ea2cb1344..76474317b 100644
--- a/wcs/backoffice/management.py
+++ b/wcs/backoffice/management.py
@@ -4281,11 +4281,15 @@ class JsonFileExportAfterJob(CsvExportAfterJob):
         formdef = self.kwargs['formdef_class'].get(self.kwargs['formdef_id'])
         prefetched_users = None
         prefetched_roles = None
+        user_ids = list(
+            set(
+                [x.user_id for x in items if x.user_id]
+                + [x.submission_agent_id for x in items if x.submission_agent_id]
+            )
+        )
         prefetched_users = {
             str(x.id): x
-            for x in get_publisher().user_class.get_ids(
-                [x.user_id for x in items if x.user_id], ignore_errors=True
-            )
+            for x in get_publisher().user_class.get_ids(user_ids, ignore_errors=True)
             if x is not None
         }
         if include_roles:
diff --git a/wcs/formdata.py b/wcs/formdata.py
index c7ca85c4e..0e31cdfd9 100644
--- a/wcs/formdata.py
+++ b/wcs/formdata.py
@@ -1434,6 +1434,15 @@ class FormData(StorableObject):
             'backoffice': self.backoffice_submission,
             'channel': self.submission_channel or 'web',
         }
+        try:
+            if prefetched_users is not None:
+                agent = prefetched_users.get(str(self.submission_agent_id))
+            else:
+                agent = get_publisher().user_class.get(self.submission_agent_id)
+        except KeyError:
+            agent = None
+        if agent:
+            data['submission']['agent'] = agent.get_json_export_dict()
         parent = self.get_parent()
         if parent:
             data['submission']['parent'] = {
-- 
2.35.1

