0001-workflows-add-new-action-to-submit-the-current-formd.patch
tests/test_backoffice_pages.py | ||
---|---|---|
17 | 17 |
from wcs.qommon.http_request import HTTPRequest |
18 | 18 |
from wcs.roles import Role |
19 | 19 |
from wcs.workflows import (Workflow, CommentableWorkflowStatusItem, |
20 |
ChoiceWorkflowStatusItem, EditableWorkflowStatusItem) |
|
20 |
ChoiceWorkflowStatusItem, EditableWorkflowStatusItem, |
|
21 |
JumpOnSubmitWorkflowStatusItem) |
|
21 | 22 |
from wcs.wf.dispatch import DispatchWorkflowStatusItem |
22 | 23 |
from wcs.wf.wscall import WebserviceCallStatusItem |
24 |
from wcs.wf.register_comment import RegisterCommenterWorkflowStatusItem |
|
25 |
from wcs.wf.resubmit import ResubmitWorkflowStatusItem |
|
23 | 26 |
from wcs.categories import Category |
24 | 27 |
from wcs.formdef import FormDef |
25 | 28 |
from wcs import fields |
... | ... | |
1770 | 1773 |
assert 'Be warned this form is also being' in resp.body |
1771 | 1774 |
assert not '(unlock actions)' in resp.body |
1772 | 1775 |
assert len(resp.forms) == 1 |
1776 | ||
1777 |
def test_backoffice_resubmit(pub): |
|
1778 |
user = create_user(pub) |
|
1779 |
create_environment(pub) |
|
1780 | ||
1781 |
wf = Workflow(name='resubmit') |
|
1782 |
st1 = wf.add_status('Status1') |
|
1783 |
st2 = wf.add_status('Status2') |
|
1784 | ||
1785 |
resubmit = ResubmitWorkflowStatusItem() |
|
1786 |
resubmit.id = '_resubmit' |
|
1787 |
resubmit.by = [user.roles[0]] |
|
1788 |
st1.items.append(resubmit) |
|
1789 |
resubmit.parent = st1 |
|
1790 | ||
1791 |
jump = JumpOnSubmitWorkflowStatusItem() |
|
1792 |
jump.id = '_jump' |
|
1793 |
jump.status = st2.id |
|
1794 |
st1.items.append(jump) |
|
1795 |
jump.parent = st1 |
|
1796 | ||
1797 |
register_comment = RegisterCommenterWorkflowStatusItem() |
|
1798 |
register_comment.id = '_register' |
|
1799 |
register_comment.comment = '<p><a href="[resubmit_formdata_backoffice_url]">resubmitted</a></p>' |
|
1800 |
st2.items.append(register_comment) |
|
1801 |
register_comment.parent = st2 |
|
1802 | ||
1803 |
wf.store() |
|
1804 | ||
1805 |
formdef = FormDef.get_by_urlname('form-title') |
|
1806 |
formdef.fields[0].varname = 'foo' |
|
1807 |
formdef.workflow_id = wf.id |
|
1808 |
formdef.store() |
|
1809 | ||
1810 |
formdef2 = FormDef() |
|
1811 |
formdef2.name = 'form title bis' |
|
1812 |
formdef2.backoffice_submission_roles = user.roles[:] |
|
1813 |
formdef2.fields = [ |
|
1814 |
fields.StringField(id='2', label='1st field', type='string', varname='foo') |
|
1815 |
] |
|
1816 |
formdef2.store() |
|
1817 |
formdef2.data_class().wipe() |
|
1818 | ||
1819 |
formdata = formdef.data_class()() |
|
1820 |
formdata.just_created() |
|
1821 |
formdata.data= {'1': 'XXX'} |
|
1822 |
formdata.store() |
|
1823 | ||
1824 |
app = login(get_app(pub)) |
|
1825 |
resp = app.get(formdata.get_url(backoffice=True)) |
|
1826 |
resp.form['resubmit'].value = formdef2.id |
|
1827 |
resp = resp.form.submit('button_resubmit') |
|
1828 |
resp = resp.follow() |
|
1829 |
assert 'resubmitted' in resp.body |
|
1830 |
assert formdef2.data_class().select()[0].status == 'draft' |
|
1831 |
assert formdef2.data_class().select()[0].data == {'2': 'XXX'} |
|
1832 |
resp = resp.click('resubmitted') |
|
1833 |
resp = resp.follow() |
|
1834 |
resp = resp.follow() |
|
1835 |
assert resp.form['f2'].value == 'XXX' |
|
1836 |
assert 'Original form' in resp.body |
|
1837 |
assert formdata.get_url(backoffice=True) in resp.body |
tests/utilities.py | ||
---|---|---|
97 | 97 |
fd = file(os.path.join(pub.app_dir, 'site-options.cfg'), 'w') |
98 | 98 |
fd.write('[options]\n') |
99 | 99 |
fd.write('formdef-captcha-option = true\n') |
100 |
fd.write('workflow-resubmit-action = true\n') |
|
100 | 101 |
if sql_mode: |
101 | 102 |
fd.write('postgresql = true\n') |
102 | 103 |
conn = psycopg2.connect(user=os.environ['USER']) |
wcs/backoffice/management.py | ||
---|---|---|
1645 | 1645 |
if formdata.submission_context or formdata.submission_channel: |
1646 | 1646 |
extra_context = formdata.submission_context or {} |
1647 | 1647 |
r += htmltext('<div class="extra-context">') |
1648 |
if extra_context.get('orig_formdef_id'): |
|
1649 |
r += htmltext('<h3>%s</h3>') % _('Original form') |
|
1650 |
try: |
|
1651 |
formdata = FormDef.get(extra_context.get('orig_formdef_id') |
|
1652 |
).data_class().get(extra_context.get('orig_formdata_id')) |
|
1653 |
except KeyError: |
|
1654 |
r += htmltext('<p>%s</p>') % _('(deleted)') |
|
1655 |
else: |
|
1656 |
r += htmltext('<p><a href="%s">%s %s</a></p>') % ( |
|
1657 |
formdata.get_url(backoffice=True), |
|
1658 |
formdata.formdef.name, |
|
1659 |
formdata.get_display_id()) |
|
1648 | 1660 |
if formdata.submission_channel: |
1649 | 1661 |
r += htmltext('<h3>%s</h3>') % '%s: %s' % ( |
1650 | 1662 |
_('Channel'), formdata.get_submission_channel_label()) |
wcs/wf/resubmit.py | ||
---|---|---|
1 |
# w.c.s. - web application for online forms |
|
2 |
# Copyright (C) 2005-2016 Entr'ouvert |
|
3 |
# |
|
4 |
# This program is free software; you can redistribute it and/or modify |
|
5 |
# it under the terms of the GNU General Public License as published by |
|
6 |
# the Free Software Foundation; either version 2 of the License, or |
|
7 |
# (at your option) any later version. |
|
8 |
# |
|
9 |
# This program is distributed in the hope that it will be useful, |
|
10 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 |
# GNU General Public License for more details. |
|
13 |
# |
|
14 |
# You should have received a copy of the GNU General Public License |
|
15 |
# along with this program; if not, see <http://www.gnu.org/licenses/>. |
|
16 | ||
17 |
from quixote import get_publisher |
|
18 | ||
19 |
from wcs.workflows import WorkflowStatusItem, register_item_class |
|
20 |
from wcs.formdef import FormDef |
|
21 |
from wcs.qommon.form import (WidgetList, SingleSelectWidget, StringWidget, |
|
22 |
WysiwygTextWidget) |
|
23 | ||
24 | ||
25 |
class ResubmitWorkflowStatusItem(WorkflowStatusItem): |
|
26 |
description = N_('Resubmit') |
|
27 |
key = 'resubmit' |
|
28 |
endpoint = False |
|
29 |
waitpoint = True |
|
30 |
ok_in_global_action = False |
|
31 | ||
32 |
by = [] |
|
33 |
label = None |
|
34 |
backoffice_info_text = None |
|
35 | ||
36 |
@classmethod |
|
37 |
def is_available(cls): |
|
38 |
return get_publisher().has_site_option('workflow-resubmit-action') |
|
39 | ||
40 |
def render_as_line(self): |
|
41 |
if self.by: |
|
42 |
return _('Allow resubmit by %s') % self.render_list_of_roles(self.by) |
|
43 |
else: |
|
44 |
return _('Allow resubmit (not completed)') |
|
45 | ||
46 |
def fill_form(self, form, formdata, user): |
|
47 |
label = self.label |
|
48 |
if not label: |
|
49 |
label = _('Resubmit') |
|
50 |
list_forms = [(x.id, x.name, x.id) for x in FormDef.select(order_by='name') |
|
51 |
if x.backoffice_submission_roles] |
|
52 |
form.add(SingleSelectWidget, 'resubmit', title=_('Form'), |
|
53 |
required=True, options=list_forms) |
|
54 |
form.add_submit('button%s' % self.id, label) |
|
55 |
form.get_widget('button%s' % self.id).backoffice_info_text = self.backoffice_info_text |
|
56 | ||
57 |
def submit_form(self, form, formdata, user, evo): |
|
58 |
if form.get_submit() != 'button%s' % self.id: |
|
59 |
return |
|
60 |
formdef_id = form.get_widget('resubmit').parse() |
|
61 |
formdef = FormDef.get(formdef_id) |
|
62 |
new_formdata = formdef.data_class()() |
|
63 |
new_formdata.status = 'draft' |
|
64 |
new_formdata.user_id = formdata.user_id |
|
65 |
new_formdata.submission_context = formdata.submission_context |
|
66 |
new_formdata.submission_channel = formdata.submission_channel |
|
67 |
new_formdata.backoffice_submission = True |
|
68 |
if not new_formdata.submission_context: |
|
69 |
new_formdata.submission_context = {} |
|
70 |
new_formdata.submission_context['orig_formdef_id'] = formdata.formdef.id |
|
71 |
new_formdata.submission_context['orig_formdata_id'] = formdata.id |
|
72 |
new_formdata.data = {} |
|
73 | ||
74 |
field_dict = {} |
|
75 |
for field in formdata.formdef.fields: |
|
76 |
if not field.varname: |
|
77 |
continue |
|
78 |
field_dict['%s-%s' % (field.varname, field.type)] = field.id |
|
79 | ||
80 |
for field in formdef.fields: |
|
81 |
field_dict_key = '%s-%s' % (field.varname, field.type) |
|
82 |
orig_formdata_field_id = field_dict.get(field_dict_key) |
|
83 |
if orig_formdata_field_id is None: |
|
84 |
continue |
|
85 |
for suffix in ('', '_raw', '_structured'): |
|
86 |
old_key = '%s%s' % (orig_formdata_field_id, suffix) |
|
87 |
new_key = '%s%s' % (field.id, suffix) |
|
88 |
if not old_key in formdata.data: |
|
89 |
continue |
|
90 |
new_formdata.data[new_key] = formdata.data[old_key] |
|
91 | ||
92 |
new_formdata.store() |
|
93 | ||
94 |
workflow_data = {'resubmit_formdata_backoffice_url': new_formdata.get_url(backoffice=True)} |
|
95 |
formdata.update_workflow_data(workflow_data) |
|
96 |
formdata.store() |
|
97 | ||
98 |
def add_parameters_widgets(self, form, parameters, prefix='', formdef=None): |
|
99 |
if 'by' in parameters: |
|
100 |
form.add(WidgetList, '%sby' % prefix, title=_('By'), element_type=SingleSelectWidget, |
|
101 |
value=self.by, |
|
102 |
add_element_label=_('Add Role'), |
|
103 |
element_kwargs={'render_br': False, |
|
104 |
'options': [(None, '---', None)] + self.get_list_of_roles()}) |
|
105 |
if 'label' in parameters: |
|
106 |
form.add(StringWidget, '%slabel' % prefix, title=_('Button Label'), |
|
107 |
value=self.label or _('Resubmit')) |
|
108 |
if 'backoffice_info_text' in parameters: |
|
109 |
form.add(WysiwygTextWidget, '%sbackoffice_info_text' % prefix, |
|
110 |
title=_('Information Text for Backoffice'), |
|
111 |
value=self.backoffice_info_text) |
|
112 | ||
113 |
def get_parameters(self): |
|
114 |
return ('by', 'label', 'backoffice_info_text') |
|
115 | ||
116 |
register_item_class(ResubmitWorkflowStatusItem) |
wcs/workflows.py | ||
---|---|---|
1960 | 1960 |
import wf.register_comment |
1961 | 1961 |
import wf.anonymise |
1962 | 1962 |
import wf.export_to_model |
1963 |
import wf.resubmit |
|
1963 | 1964 | |
1964 | 1965 |
from wf.export_to_model import ExportToModel |
1965 |
- |