From 04dfcd89c8b828ccf55f263eb1b112e91e2ef513 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20P=C3=A9ters?= <fpeters@entrouvert.com>
Date: Wed, 27 May 2020 09:23:54 +0200
Subject: [PATCH] misc: record parent object class (#43361)

---
 tests/test_form_pages.py  |  2 ++
 tests/test_formdata.py    |  1 +
 wcs/formdata.py           | 19 +++++++++++++++++++
 wcs/variables.py          | 11 +----------
 wcs/wf/create_formdata.py |  1 +
 wcs/wf/resubmit.py        |  1 +
 6 files changed, 25 insertions(+), 10 deletions(-)

diff --git a/tests/test_form_pages.py b/tests/test_form_pages.py
index 08076ecc9..106803683 100644
--- a/tests/test_form_pages.py
+++ b/tests/test_form_pages.py
@@ -7799,6 +7799,7 @@ def test_create_formdata_anonymous_draft(create_formdata):
     assert target_formdata.data.get('1').get_content() == b'foobar'
     assert target_formdata.status == 'draft'
     assert target_formdata.submission_context == {
+        'orig_object_type': 'formdef',
         'orig_formdata_id': str(create_formdata['source_formdef'].data_class().select()[0].id),
         'orig_formdef_id': str(create_formdata['source_formdef'].id),
     }
@@ -7850,6 +7851,7 @@ def test_create_formdata_anonymous_submitted(create_formdata):
     assert target_formdata.data.get('1').get_content() == b'foobar'
     assert target_formdata.status == 'wf-new'
     assert target_formdata.submission_context == {
+        'orig_object_type': 'formdef',
         'orig_formdata_id': str(create_formdata['source_formdef'].data_class().select()[0].id),
         'orig_formdef_id': str(create_formdata['source_formdef'].id),
     }
diff --git a/tests/test_formdata.py b/tests/test_formdata.py
index c917823ef..9f1b0b8d2 100644
--- a/tests/test_formdata.py
+++ b/tests/test_formdata.py
@@ -2019,6 +2019,7 @@ def test_form_parent(pub):
     child = formdef.data_class()()
     child.data = {'0': 'world'}
     child.submission_context = {
+        'orig_object_type': 'formdef',
         'orig_formdef_id': formdef.id,
         'orig_formdata_id': parent.id,
     }
diff --git a/wcs/formdata.py b/wcs/formdata.py
index 68f85701d..13b446f49 100644
--- a/wcs/formdata.py
+++ b/wcs/formdata.py
@@ -358,6 +358,25 @@ class FormData(StorableObject):
     def get_submission_channel_label(self):
         return self.get_submission_channels().get(self.submission_channel) or _('Web')
 
+    def get_parent(self):
+        if not self.submission_context:
+            return None
+        object_type = self.submission_context.get('orig_object_type', 'formdef')
+        objectdef_id = self.submission_context.get('orig_formdef_id')
+        objectdata_id = self.submission_context.get('orig_formdata_id')
+        if not (object_type and objectdef_id and objectdata_id):
+            return None
+        if object_type == 'carddef':
+            from .carddef import CardDef
+            objectdef_class = CardDef
+        else:
+            from .formdef import FormDef
+            objectdef_class = FormDef
+        try:
+            return objectdef_class.get(objectdef_id).data_class().get(objectdata_id)
+        except KeyError:
+            return None
+
     def just_created(self):
         self.receipt_time = time.localtime()
         self.status = 'wf-%s' % self.formdef.workflow.possible_status[0].id
diff --git a/wcs/variables.py b/wcs/variables.py
index e7ce623c7..1c6797f9b 100644
--- a/wcs/variables.py
+++ b/wcs/variables.py
@@ -412,16 +412,7 @@ class LazyFormData(LazyFormDef):
 
     @property
     def parent(self):
-        if not self._formdata.submission_context:
-            return None
-        if 'orig_formdef_id' not in self._formdata.submission_context:
-            return None
-        if 'orig_formdata_id' not in self._formdata.submission_context:
-            return None
-        formdef = FormDef.get(self._formdata.submission_context['orig_formdef_id'], ignore_errors=True)
-        if formdef is None:
-            return None
-        formdata = formdef.data_class().get(self._formdata.submission_context['orig_formdata_id'], ignore_errors=True)
+        formdata = self._formdata.get_parent()
         if formdata is None:
             return None
         return formdata.get_substitution_variables()
diff --git a/wcs/wf/create_formdata.py b/wcs/wf/create_formdata.py
index 2e0d5b3db..db3e91c91 100644
--- a/wcs/wf/create_formdata.py
+++ b/wcs/wf/create_formdata.py
@@ -323,6 +323,7 @@ class CreateFormdataWorkflowStatusItem(WorkflowStatusItem):
         if self.backoffice_submission and get_request() and get_request().user is not None:
             new_formdata.submission_context['agent_id'] = str(get_request().user.id)
 
+        new_formdata.submission_context['orig_object_type'] = formdata.formdef.xml_root_node
         new_formdata.submission_context['orig_formdef_id'] = str(formdata.formdef.id)
         new_formdata.submission_context['orig_formdata_id'] = str(formdata.id)
         new_formdata.data = {}
diff --git a/wcs/wf/resubmit.py b/wcs/wf/resubmit.py
index 4b771c34c..d69e7de72 100644
--- a/wcs/wf/resubmit.py
+++ b/wcs/wf/resubmit.py
@@ -80,6 +80,7 @@ class ResubmitWorkflowStatusItem(WorkflowStatusItem):
         new_formdata.backoffice_submission = get_request().is_in_backoffice()
         if not new_formdata.submission_context:
             new_formdata.submission_context = {}
+        new_formdata.submission_context['orig_object_type'] = formdata.formdef.xml_root_node
         new_formdata.submission_context['orig_formdef_id'] = formdata.formdef.id
         new_formdata.submission_context['orig_formdata_id'] = formdata.id
         new_formdata.data = {}
-- 
2.27.0.rc2

