From d0884fb4ba14dd106baa888d6775f30495f92989 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20P=C3=A9ters?= <fpeters@entrouvert.com>
Date: Tue, 24 Sep 2019 17:59:07 +0200
Subject: [PATCH] admin: display and use card default workflow when setting
 workflow (#36413)

---
 tests/test_admin_pages.py | 37 +++++++++++++++++++++++++++++++++++++
 wcs/admin/forms.py        | 29 ++++++++++++++++-------------
 wcs/backoffice/cards.py   |  1 +
 wcs/formdef.py            |  3 ++-
 wcs/workflows.py          |  3 +++
 5 files changed, 59 insertions(+), 14 deletions(-)

diff --git a/tests/test_admin_pages.py b/tests/test_admin_pages.py
index 7ecd1c2d9..a45bd4ad9 100644
--- a/tests/test_admin_pages.py
+++ b/tests/test_admin_pages.py
@@ -5202,3 +5202,40 @@ def test_cards_duplicate(pub, studio):
     resp = resp.click('Duplicate')
     assert CardDef.get(2).name == 'card title (copy)'
     assert CardDef.get(2).disabled is False
+
+def test_card_workflow_change(pub, studio):
+    Workflow.wipe()
+    workflow = Workflow(name='Workflow Two')
+    workflow.add_status('plop')
+    workflow.store()
+
+    CardDef.wipe()
+    create_superuser(pub)
+    app = login(get_app(pub))
+    resp = app.get('/backoffice/cards/')
+    resp = resp.click('New Card')
+    resp.form['name'] = 'card title'
+    resp = resp.form.submit()
+    resp = resp.follow()
+    resp = resp.click(href='workflow', index=1)
+    assert resp.form['workflow_id'].options[0][2] == 'Default (cards)'
+    resp = resp.form.submit('submit').follow()
+    assert CardDef.select()[0].workflow_id is None
+
+    carddata = CardDef.select()[0].data_class()()
+    carddata.status = 'wf-recorded'
+    carddata.store()
+
+    resp = resp.click(href='workflow', index=1)
+    resp.form['workflow_id'] = '%s' % workflow.id
+    resp = resp.form.submit('submit')
+    assert resp.location == 'http://example.net/backoffice/cards/1/workflow-status-remapping?new=%s' % workflow.id
+    resp = resp.follow()
+    resp = resp.form.submit('submit').follow()
+
+    resp = resp.click(href='workflow', index=1)
+    resp.form['workflow_id'] = ''
+    resp = resp.form.submit('submit')
+    assert resp.location == 'http://example.net/backoffice/cards/1/workflow-status-remapping?new=%s' % '_carddef_default'
+    resp = resp.follow()
+    resp = resp.form.submit('submit').follow()
diff --git a/wcs/admin/forms.py b/wcs/admin/forms.py
index b1613f76d..fa94cd081 100644
--- a/wcs/admin/forms.py
+++ b/wcs/admin/forms.py
@@ -53,10 +53,6 @@ def get_categories():
     t = sorted([(misc.simplify(x.name), x.id, x.name, x.id) for x in Category.select()])
     return [x[1:] for x in t]
 
-def get_workflows(condition=lambda x: True):
-    t = sorted([(misc.simplify(x.name), x.id, x.name, x.id) for x in Workflow.select() if condition(x)])
-    return [x[1:] for x in t]
-
 
 class FormDefUI(object):
     formdef_class = FormDef
@@ -67,6 +63,12 @@ class FormDefUI(object):
     def get_categories(self):
         return get_categories()
 
+    @classmethod
+    def get_workflows(cls, condition=lambda x: True):
+        default_workflow = cls.formdef_class.get_default_workflow()
+        t = sorted([(misc.simplify(x.name), x.id, x.name, x.id) for x in Workflow.select() if condition(x)])
+        return [(None, default_workflow.name, '')] + [x[1:] for x in t]
+
     def new_form_ui(self):
         form = Form(enctype='multipart/form-data')
         if self.formdef:
@@ -80,11 +82,11 @@ class FormDefUI(object):
             form.add(SingleSelectWidget, 'category_id', title = _('Category'),
                     value = formdef.category_id,
                     options = [(None, '---', '')] + categories)
-        workflows = get_workflows()
-        if workflows:
-            form.add(SingleSelectWidget, 'workflow_id', title = _('Workflow'),
-                    value = formdef.workflow_id,
-                    options = [(None, _('Default Workflow'), '')] + workflows)
+        workflows = self.get_workflows()
+        if len(workflows) > 1:
+            form.add(SingleSelectWidget, 'workflow_id', title=_('Workflow'),
+                    value=formdef.workflow_id,
+                    options=workflows)
         form.add_submit('submit', _('Submit'))
         form.add_submit('cancel', _('Cancel'))
         return form
@@ -357,6 +359,7 @@ class FormDefPage(Directory):
     formdef_class = FormDef
     formdef_export_prefix = 'form'
     formdef_ui_class = FormDefUI
+    formdef_default_workflow = '_default'
 
     delete_message = N_('You are about to irrevocably delete this form.')
     delete_title = N_('Deleting Form:')
@@ -792,10 +795,10 @@ class FormDefPage(Directory):
 
     def workflow(self):
         form = Form(enctype='multipart/form-data')
-        workflows = get_workflows(condition=lambda x: x.possible_status)
+        workflows = self.formdef_ui_class.get_workflows(condition=lambda x: x.possible_status)
         form.add(SingleSelectWidget, 'workflow_id',
                         value=self.formdef.workflow_id,
-                        options = [(None, _('Default Workflow'), '')] + workflows)
+                        options=workflows)
         form.add_submit('submit', _('Submit'))
         form.add_submit('cancel', _('Cancel'))
         if form.get_widget('cancel').parse():
@@ -814,7 +817,7 @@ class FormDefPage(Directory):
             if self.formdef.data_class().keys():
                 # there are existing formdata, status will have to be mapped
                 if workflow_id is None:
-                    workflow_id = '_default'
+                    workflow_id = self.formdef_default_workflow
                 return redirect('workflow-status-remapping?new=%s' % workflow_id)
             self.formdef.workflow_id = workflow_id
             self.formdef.store()
@@ -853,7 +856,7 @@ class FormDefPage(Directory):
             get_logger().info('admin - form "%s", workflow is now "%s" (was "%s")' % (
                 self.formdef.name, new_workflow.name, self.formdef.workflow.name))
             self.workflow_status_remapping_submit(form)
-            if new_workflow.id == '_default':
+            if new_workflow.id == self.formdef_default_workflow:
                 self.formdef.workflow_id = None
             else:
                 self.formdef.workflow_id = new_workflow.id
diff --git a/wcs/backoffice/cards.py b/wcs/backoffice/cards.py
index bab1ce572..1f18a686a 100644
--- a/wcs/backoffice/cards.py
+++ b/wcs/backoffice/cards.py
@@ -42,6 +42,7 @@ class CardDefPage(FormDefPage):
     formdef_class = CardDef
     formdef_export_prefix = 'card'
     formdef_ui_class = CardDefUI
+    formdef_default_workflow = '_carddef_default'
 
     delete_message = N_('You are about to irrevocably delete this card.')
     delete_title = N_('Deleting Card:')
diff --git a/wcs/formdef.py b/wcs/formdef.py
index 014e62853..665e495a3 100644
--- a/wcs/formdef.py
+++ b/wcs/formdef.py
@@ -416,7 +416,8 @@ class FormDef(StorableObject):
         else:
             return self.get_default_workflow()
 
-    def get_default_workflow(self):
+    @classmethod
+    def get_default_workflow(cls):
         from wcs.workflows import Workflow
         return Workflow.get_default_workflow()
 
diff --git a/wcs/workflows.py b/wcs/workflows.py
index 210507b8e..e79fdf7b1 100644
--- a/wcs/workflows.py
+++ b/wcs/workflows.py
@@ -364,6 +364,9 @@ class Workflow(StorableObject):
     def get(cls, id, ignore_errors=False, ignore_migration=False):
         if id == '_default':
             return cls.get_default_workflow()
+        elif id == '_carddef_default':
+            from wcs.carddef import CardDef
+            return CardDef.get_default_workflow()
         return super(Workflow, cls).get (id, ignore_errors=ignore_errors,
                                   ignore_migration=ignore_migration)
 
-- 
2.23.0

