0001-misc-load-drafts-from-the-form-URL-with-trailing-sla.patch
tests/test_api.py | ||
---|---|---|
1459 | 1459 |
assert len(resp.json['data']) == 2 |
1460 | 1460 | |
1461 | 1461 |
draft_formdata = [x for x in resp.json['data'] if x['status'] == 'Draft'][0] |
1462 |
assert draft_formdata.get('url')[-1] != '/' |
|
1463 | 1462 | |
1464 | 1463 |
formdata = formdef.data_class()() |
1465 | 1464 |
formdata.data = {'0': 'foo@localhost', '1': 'xyy'} |
... | ... | |
2595 | 2594 | |
2596 | 2595 |
resp = get_app(pub).get(sign_url('/api/code/%s?orig=coucou' % code.id, '1234'), status=200) |
2597 | 2596 |
assert resp.json['err'] == 0 |
2598 |
assert resp.json['url'] == 'http://example.net/test/%s' % formdata.id |
|
2597 |
assert resp.json['url'] == 'http://example.net/test/%s/' % formdata.id
|
|
2599 | 2598 |
assert resp.json['load_url'] == 'http://example.net/code/%s/load' % code.id |
2600 | 2599 | |
2601 | 2600 |
formdef.enable_tracking_codes = False |
tests/test_backoffice_pages.py | ||
---|---|---|
2072 | 2072 |
return resp.json['data']['id'] |
2073 | 2073 | |
2074 | 2074 |
resp = app.get('/backoffice/management/form-title/%s/' % post_formdata()) |
2075 |
resp = resp.follow() # -> /backoffice/submission/form-title/XXX |
|
2075 |
resp = resp.follow() # -> /backoffice/submission/form-title/XXX/
|
|
2076 | 2076 |
resp = resp.follow() # -> /backoffice/submission/form-title/?mt=XYZ |
2077 | 2077 | |
2078 | 2078 |
# second page should be shown |
... | ... | |
2085 | 2085 |
formdef.store() |
2086 | 2086 | |
2087 | 2087 |
resp = app.get('/backoffice/management/form-title/%s/' % post_formdata()) |
2088 |
resp = resp.follow() # -> /backoffice/submission/form-title/XXX |
|
2088 |
resp = resp.follow() # -> /backoffice/submission/form-title/XXX/
|
|
2089 | 2089 |
resp = resp.follow() # -> /backoffice/submission/form-title/?mt=XYZ |
2090 | 2090 | |
2091 | 2091 |
pq = resp.pyquery.remove_namespaces() |
... | ... | |
2152 | 2152 | |
2153 | 2153 |
resp = app.get('/backoffice/submission/') |
2154 | 2154 |
assert 'Submission to complete' in resp.text |
2155 |
resp1 = app.get('/backoffice/submission/form-title/%s' % formdata.id) |
|
2155 |
resp1 = app.get('/backoffice/submission/form-title/%s/' % formdata.id)
|
|
2156 | 2156 |
resp1 = resp1.follow() |
2157 |
resp2 = app.get('/backoffice/submission/form-title/%s' % formdata.id) |
|
2157 |
resp2 = app.get('/backoffice/submission/form-title/%s/' % formdata.id)
|
|
2158 | 2158 |
resp2 = resp2.follow() |
2159 |
resp3 = app.get('/backoffice/submission/form-title/%s' % formdata.id) |
|
2159 |
resp3 = app.get('/backoffice/submission/form-title/%s/' % formdata.id)
|
|
2160 | 2160 |
resp3 = resp3.follow() |
2161 | 2161 | |
2162 | 2162 |
resp1.form['f1'] = 'foo' |
... | ... | |
2196 | 2196 |
assert formdef.data_class().get(formdata.id).data['1'] == 'foo' |
2197 | 2197 | |
2198 | 2198 |
# try again, very late. |
2199 |
resp4 = app.get('/backoffice/submission/form-title/%s' % formdata.id) |
|
2199 |
resp4 = app.get('/backoffice/submission/form-title/%s/' % formdata.id)
|
|
2200 | 2200 |
resp4 = resp4.follow() |
2201 | 2201 |
assert 'This form has already been submitted.' in resp4.text |
2202 | 2202 | |
... | ... | |
2343 | 2343 | |
2344 | 2344 |
# check it can also be accessed using its final URL |
2345 | 2345 |
resp2 = app.get('/backoffice/management/%s/%s/' % (formdef.url_name, formdata_no)) |
2346 |
assert resp2.location == 'http://example.net/backoffice/submission/%s/%s' % ( |
|
2346 |
assert resp2.location == 'http://example.net/backoffice/submission/%s/%s/' % (
|
|
2347 | 2347 |
formdef.url_name, formdata_no) |
2348 | 2348 | |
2349 | 2349 |
resp = resp.click('#%s' % formdata_no) |
... | ... | |
2595 | 2595 |
assert resp.form['f1'].value == '' |
2596 | 2596 | |
2597 | 2597 |
# restore a draft |
2598 |
resp = app.get('/backoffice/submission/form-title/%s' % formdata.id) |
|
2598 |
resp = app.get('/backoffice/submission/form-title/%s/' % formdata.id)
|
|
2599 | 2599 |
resp = resp.follow() |
2600 | 2600 |
# and check it got prefilled with the user from context |
2601 | 2601 |
assert resp.form['f1'].value == 'other@example.net' |
2602 | 2602 | |
2603 | 2603 |
# restore another, without user id |
2604 |
resp = app.get('/backoffice/submission/form-title/%s' % formdata2.id) |
|
2604 |
resp = app.get('/backoffice/submission/form-title/%s/' % formdata2.id)
|
|
2605 | 2605 |
resp = resp.follow() |
2606 | 2606 |
# and check it was not prefilled |
2607 | 2607 |
assert resp.form['f1'].value == '' |
... | ... | |
2642 | 2642 |
assert resp.form['f1'].value == '' |
2643 | 2643 | |
2644 | 2644 |
# restore a draft |
2645 |
resp = app.get('/backoffice/submission/form-title/%s' % formdata.id) |
|
2645 |
resp = app.get('/backoffice/submission/form-title/%s/' % formdata.id)
|
|
2646 | 2646 |
resp = resp.follow() |
2647 | 2647 |
# and check it got prefilled with the user from context |
2648 | 2648 |
assert resp.form['f1'].value == 'other@example.net' |
2649 | 2649 | |
2650 | 2650 |
# restore another, without user id |
2651 |
resp = app.get('/backoffice/submission/form-title/%s' % formdata2.id) |
|
2651 |
resp = app.get('/backoffice/submission/form-title/%s/' % formdata2.id)
|
|
2652 | 2652 |
resp = resp.follow() |
2653 | 2653 |
# and check it was not prefilled |
2654 | 2654 |
assert resp.form['f1'].value == '' |
... | ... | |
2700 | 2700 |
assert resp.form['f5'].value == '' |
2701 | 2701 | |
2702 | 2702 |
# restore a draft |
2703 |
resp = app.get('/backoffice/submission/form-title/%s' % formdata.id) |
|
2703 |
resp = app.get('/backoffice/submission/form-title/%s/' % formdata.id)
|
|
2704 | 2704 |
resp = resp.follow() |
2705 | 2705 |
resp = resp.form.submit('submit') |
2706 | 2706 |
# and check it got prefilled with the user from context |
2707 | 2707 |
assert resp.form['f5'].value == 'other@example.net' |
2708 | 2708 | |
2709 | 2709 |
# restore another, without user id |
2710 |
resp = app.get('/backoffice/submission/form-title/%s' % formdata2.id) |
|
2710 |
resp = app.get('/backoffice/submission/form-title/%s/' % formdata2.id)
|
|
2711 | 2711 |
resp = resp.follow() |
2712 | 2712 |
resp = resp.form.submit('submit') |
2713 | 2713 |
# and check it was not prefilled |
... | ... | |
2719 | 2719 |
formdata.page_no = 0 |
2720 | 2720 |
formdata.user_id = other_user.id |
2721 | 2721 |
formdata.store() |
2722 |
resp = app.get('/backoffice/submission/form-title/%s' % formdata.id) |
|
2722 |
resp = app.get('/backoffice/submission/form-title/%s/' % formdata.id)
|
|
2723 | 2723 |
resp = resp.follow() |
2724 | 2724 |
resp.form['f1'] = 'Hello' |
2725 | 2725 |
resp_autosave = app.post('/backoffice/submission/form-title/autosave', params=resp.form.submit_fields()) |
... | ... | |
2827 | 2827 |
formdata.backoffice_submission = True |
2828 | 2828 |
formdata.store() |
2829 | 2829 | |
2830 |
resp = app.get('/backoffice/submission/form-title/%s' % formdata.id) |
|
2830 |
resp = app.get('/backoffice/submission/form-title/%s/' % formdata.id)
|
|
2831 | 2831 |
resp = resp.follow() |
2832 | 2832 |
resp.form['f1'].value = 'PLOP' |
2833 | 2833 |
resp.form['f10'].value = 'bar' |
... | ... | |
2901 | 2901 |
resp = app.get('/backoffice/submission/form-title/?NameID=%s&channel=mail' % local_user.name_identifiers[0]) |
2902 | 2902 |
assert resp.location.startswith('http://example.net/backoffice/submission/form-title/') |
2903 | 2903 | |
2904 |
formdata_no = resp.location.split('/')[-1]
|
|
2904 |
formdata_no = resp.location.split('/')[-2]
|
|
2905 | 2905 |
formdata = formdef.data_class().get(formdata_no) |
2906 | 2906 |
assert formdata.user_id == str(local_user.id) |
2907 | 2907 |
assert formdata.submission_channel == 'mail' |
tests/test_form_pages.py | ||
---|---|---|
175 | 175 |
assert '<a href="test/%s"' % draft.id in resp |
176 | 176 |
resp = app.get('/test/%s' % formdata.id) |
177 | 177 |
resp.status_int = 200 |
178 |
resp = app.get('/test/%s' % draft.id, status=302) |
|
178 |
resp = app.get('/test/%s/' % draft.id, status=302)
|
|
179 | 179 |
resp = resp.follow(status=200) |
180 | 180 | |
181 | 181 |
# disable formdef: formdatas are still visible and accessible, drafts are not |
... | ... | |
186 | 186 |
assert '<a href="test/%s/"' % formdata.id in resp |
187 | 187 |
assert not 'Draft' in resp |
188 | 188 |
assert not '<a href="test/%s"' % draft.id in resp |
189 |
resp = app.get('/test/%s' % formdata.id) |
|
190 |
resp.status_int = 200 |
|
191 |
resp = app.get('/test/%s' % draft.id, status=302) |
|
189 |
resp = app.get('/test/%s/' % formdata.id) |
|
190 |
resp = app.get('/test/%s/' % draft.id, status=302) |
|
192 | 191 |
resp = resp.follow(status=403) |
193 | 192 | |
194 | 193 | |
... | ... | |
1478 | 1477 |
resp = resp.forms[0].submit() |
1479 | 1478 |
assert resp.location == 'http://example.net/code/%s/load' % tracking_code |
1480 | 1479 |
resp = resp.follow() |
1481 |
assert resp.location == 'http://example.net/test/%s' % formdata_id |
|
1480 |
assert resp.location == 'http://example.net/test/%s/' % formdata_id
|
|
1482 | 1481 |
resp = resp.follow() |
1483 | 1482 |
assert resp.location.startswith('http://example.net/test/?mt=') |
1484 | 1483 |
resp = resp.follow() |
1485 | 1484 | |
1486 | 1485 |
# check anonymous user can't get to it from the URL |
1487 | 1486 |
pub.session_manager.session_class.wipe() |
1488 |
resp = get_app(pub).get('http://example.net/test/%s' % formdata_id) |
|
1487 |
resp = get_app(pub).get('http://example.net/test/%s/' % formdata_id)
|
|
1489 | 1488 |
assert resp.location.startswith('http://example.net/login') |
1490 | 1489 | |
1491 | 1490 |
# or logged users that didn't enter the code: |
1492 | 1491 |
user = create_user(pub) |
1493 | 1492 |
login(get_app(pub), username='foo', password='foo').get( |
1494 |
'http://example.net/test/%s' % formdata_id, status=403) |
|
1493 |
'http://example.net/test/%s/' % formdata_id, status=403)
|
|
1495 | 1494 | |
1496 | 1495 |
# check we can also get to it as a logged user |
1497 | 1496 |
pub.session_manager.session_class.wipe() |
... | ... | |
1500 | 1499 |
resp = resp.forms[0].submit() |
1501 | 1500 |
assert resp.location == 'http://example.net/code/%s/load' % tracking_code.lower() |
1502 | 1501 |
resp = resp.follow() |
1503 |
assert resp.location == 'http://example.net/test/%s' % formdata_id |
|
1502 |
assert resp.location == 'http://example.net/test/%s/' % formdata_id
|
|
1504 | 1503 |
resp = resp.follow() |
1505 | 1504 | |
1506 | 1505 |
# go back as anonymous |
... | ... | |
1510 | 1509 |
resp = resp.forms[0].submit() |
1511 | 1510 |
assert resp.location == 'http://example.net/code/%s/load' % tracking_code |
1512 | 1511 |
resp = resp.follow() |
1513 |
assert resp.location == 'http://example.net/test/%s' % formdata_id |
|
1512 |
assert resp.location == 'http://example.net/test/%s/' % formdata_id
|
|
1514 | 1513 |
resp = resp.follow() |
1515 | 1514 |
assert resp.location.startswith('http://example.net/test/?mt=') |
1516 | 1515 |
resp = resp.follow() |
... | ... | |
1536 | 1535 |
resp = resp.forms[0].submit() |
1537 | 1536 |
assert resp.location == 'http://example.net/code/%s/load' % tracking_code |
1538 | 1537 |
resp = resp.follow() |
1539 |
assert resp.location == 'http://example.net/test/%s' % formdata_id |
|
1540 |
resp = resp.follow() |
|
1538 |
assert resp.location == 'http://example.net/test/%s/' % formdata_id |
|
1541 | 1539 |
resp = resp.follow() |
1542 | 1540 |
assert 'form_comment' in resp.text # makes sure user is treated as submitter |
1543 | 1541 |
resp.forms[0]['comment'] = 'hello world' |
... | ... | |
1551 | 1549 |
resp = resp.forms[0].submit() |
1552 | 1550 |
assert resp.location == 'http://example.net/code/%s/load' % tracking_code.lower() |
1553 | 1551 |
resp = resp.follow() |
1554 |
assert resp.location == 'http://example.net/test/%s' % formdata_id |
|
1552 |
assert resp.location == 'http://example.net/test/%s/' % formdata_id
|
|
1555 | 1553 |
resp = resp.follow() |
1556 | 1554 | |
1557 | 1555 | |
... | ... | |
1605 | 1603 |
resp = resp.forms[0].submit() |
1606 | 1604 |
assert resp.location == 'http://example.net/code/%s/load' % tracking_code |
1607 | 1605 |
resp = resp.follow() |
1608 |
assert resp.location == 'http://example.net/test/%s' % formdata_id |
|
1606 |
assert resp.location == 'http://example.net/test/%s/' % formdata_id
|
|
1609 | 1607 |
resp = resp.follow() |
1610 | 1608 |
assert resp.location.startswith('http://example.net/test/?mt=') |
1611 | 1609 |
resp = resp.follow() |
... | ... | |
1631 | 1629 |
resp = resp.forms[0].submit() |
1632 | 1630 |
assert resp.location == 'http://example.net/code/%s/load' % tracking_code |
1633 | 1631 |
resp = resp.follow() |
1634 |
assert resp.location == 'http://example.net/test/%s' % formdata_id |
|
1635 |
resp = resp.follow() |
|
1632 |
assert resp.location == 'http://example.net/test/%s/' % formdata_id |
|
1636 | 1633 |
resp = resp.follow() |
1637 | 1634 |
assert 'form_comment' in resp.text # makes sure user is treated as submitter |
1638 | 1635 |
resp.forms[0]['comment'] = 'hello world' |
... | ... | |
1646 | 1643 |
resp = resp.forms[0].submit() |
1647 | 1644 |
assert resp.location == 'http://example.net/code/%s/load' % tracking_code |
1648 | 1645 |
resp = resp.follow() |
1649 |
assert resp.location == 'http://example.net/test/%s' % formdata_id |
|
1650 |
resp = resp.follow() |
|
1646 |
assert resp.location == 'http://example.net/test/%s/' % formdata_id |
|
1651 | 1647 |
resp = resp.follow() |
1652 | 1648 |
assert 'form_comment' in resp.text # makes sure user is treated as submitter |
1653 | 1649 | |
... | ... | |
1740 | 1736 |
resp = resp.forms[0].submit() |
1741 | 1737 |
assert resp.location == 'http://example.net/code/%s/load' % tracking_code |
1742 | 1738 |
resp = resp.follow() |
1743 |
assert resp.location == 'http://example.net/test/%s' % formdata_id |
|
1739 |
assert resp.location == 'http://example.net/test/%s/' % formdata_id
|
|
1744 | 1740 |
resp = resp.follow() |
1745 | 1741 |
assert resp.location.startswith('http://example.net/test/?mt=') |
1746 | 1742 |
resp = resp.follow() |
... | ... | |
1790 | 1786 |
resp = resp.forms[0].submit() |
1791 | 1787 |
assert resp.location == 'http://example.net/code/%s/load' % tracking_code |
1792 | 1788 |
resp = resp.follow() |
1793 |
assert resp.location == 'http://example.net/test/%s' % formdata_id |
|
1789 |
assert resp.location == 'http://example.net/test/%s/' % formdata_id
|
|
1794 | 1790 |
resp = resp.follow() |
1795 | 1791 |
assert resp.location.startswith('http://example.net/test/?mt=') |
1796 | 1792 |
resp = resp.follow() |
... | ... | |
1933 | 1929 |
resp = resp.forms[0].submit() |
1934 | 1930 |
assert resp.location == 'http://example.net/code/%s/load' % code.id |
1935 | 1931 |
resp = resp.follow() |
1936 |
assert resp.location == 'http://example.net/test/%s' % formdata.id |
|
1932 |
assert resp.location == 'http://example.net/test/%s/' % formdata.id
|
|
1937 | 1933 |
resp = resp.follow() |
1938 | 1934 | |
1939 | 1935 |
# check we get a not found error message on non-existent code |
... | ... | |
2075 | 2071 |
formdata.status = 'draft' |
2076 | 2072 |
formdata.store() |
2077 | 2073 | |
2078 |
resp = get_app(pub).get('/test/%s' % formdata.id, status=302) |
|
2074 |
resp = get_app(pub).get('/test/%s/' % formdata.id, status=302)
|
|
2079 | 2075 |
assert resp.location.startswith('http://example.net/login') |
2080 | 2076 | |
2081 | 2077 |
formdata.user_id = user.id |
2082 | 2078 |
formdata.store() |
2083 |
resp = get_app(pub).get('/test/%s' % formdata.id, status=302) |
|
2079 |
resp = get_app(pub).get('/test/%s/' % formdata.id, status=302)
|
|
2084 | 2080 |
assert resp.location.startswith('http://example.net/login') |
2085 | 2081 | |
2086 |
resp = login(get_app(pub), 'foo', 'foo').get('/test/%s' % formdata.id, status=302) |
|
2082 |
resp = login(get_app(pub), 'foo', 'foo').get('/test/%s/' % formdata.id, status=302)
|
|
2087 | 2083 |
assert resp.location.startswith('http://example.net/test/?mt=') |
2088 | 2084 | |
2089 | 2085 |
formdata.user_id = 1000 |
2090 | 2086 |
formdata.store() |
2091 |
resp = login(get_app(pub), 'foo', 'foo').get('/test/%s' % formdata.id, status=403) |
|
2087 |
resp = login(get_app(pub), 'foo', 'foo').get('/test/%s/' % formdata.id, status=403)
|
|
2092 | 2088 | |
2093 | 2089 | |
2094 | 2090 |
def form_password_field_submit(app, password): |
... | ... | |
6338 | 6334 |
code.store() |
6339 | 6335 | |
6340 | 6336 |
resp = app.get('/code/%s/load' % code.id) |
6341 |
resp = resp.follow() # -> /test/1 |
|
6342 |
assert not 'backoffice' in resp.location |
|
6343 | 6337 |
resp = resp.follow() # -> /test/1/ |
6338 |
assert 'backoffice' not in resp.request.path |
|
6344 | 6339 |
assert 'The form has been recorded' in resp.text |
6345 | 6340 | |
6346 | 6341 |
# authorized access but not backoffice access |
... | ... | |
7171 | 7166 |
app = login(get_app(pub), username='foo', password='foo') |
7172 | 7167 |
resp = app.get('/test/') |
7173 | 7168 |
assert 'You already started to fill this form.' in resp.text |
7174 |
assert 'href="%s"' % draft.id in resp.text |
|
7169 |
assert 'href="%s/"' % draft.id in resp.text
|
|
7175 | 7170 | |
7176 | 7171 |
draft2 = formdef.data_class()() |
7177 | 7172 |
draft2.user_id = user.id |
wcs/api.py | ||
---|---|---|
105 | 105 |
d['last_update_time'] = misc.strftime('%Y-%m-%d %H:%M:%S', formdata.last_update_time) |
106 | 106 | |
107 | 107 |
if formdata.is_draft(): |
108 |
d['url'] = d['url'].rstrip('/') |
|
109 | 108 |
d['form_number_raw'] = d['form_number'] = None |
110 | 109 |
d['title'] = _('%(name)s (draft)') % {'name': formdata.formdef.name} |
111 | 110 |
else: |
... | ... | |
790 | 789 |
raise TraversalError() |
791 | 790 |
data = { |
792 | 791 |
'err': 0, |
793 |
'url': formdata.get_url().rstrip('/'),
|
|
792 |
'url': formdata.get_url(), |
|
794 | 793 |
'load_url': get_publisher().get_frontoffice_url() + '/code/%s/load' % component, |
795 | 794 |
} |
796 | 795 |
return json.dumps(data) |
wcs/backoffice/management.py | ||
---|---|---|
2221 | 2221 |
if self.filled.backoffice_submission: |
2222 | 2222 |
for role in get_request().user.get_roles(): |
2223 | 2223 |
if role in self.formdef.backoffice_submission_roles: |
2224 |
return redirect('../../../submission/%s/%s' % ( |
|
2224 |
return redirect('../../../submission/%s/%s/' % (
|
|
2225 | 2225 |
self.formdef.url_name, self.filled.id)) |
2226 | 2226 |
raise errors.AccessForbiddenError() |
2227 | 2227 |
wcs/backoffice/submission.py | ||
---|---|---|
30 | 30 |
from wcs.formdata import FormData |
31 | 31 |
from wcs.formdef import FormDef |
32 | 32 |
from wcs.categories import Category |
33 |
from wcs.forms.common import FormStatusPage |
|
33 | 34 |
from wcs.forms.root import FormPage as PublicFormFillPage |
34 | 35 | |
35 | 36 | |
... | ... | |
73 | 74 |
return redirect('../..') |
74 | 75 | |
75 | 76 | |
77 |
class SubmissionFormStatusPage(FormStatusPage): |
|
78 |
_q_exports_orig = ['', 'download', 'live'] |
|
79 | ||
80 |
def _q_index(self): |
|
81 |
if not self.filled.is_draft(): |
|
82 |
get_session().message = ('error', _('This form has already been submitted.')) |
|
83 |
return redirect(get_publisher().get_backoffice_url() + '/submission/') |
|
84 |
return super(SubmissionFormStatusPage, self)._q_index() |
|
85 | ||
86 | ||
76 | 87 |
class FormFillPage(PublicFormFillPage): |
77 | 88 |
_q_exports = ['', 'tempfile', 'autosave', 'code', |
78 | 89 |
('remove', 'remove_draft'), 'live'] |
... | ... | |
108 | 119 |
formdata.submission_context['return_url'] = return_url |
109 | 120 |
formdata.store() |
110 | 121 |
self.set_tracking_code(formdata) |
111 |
return redirect('%s' % formdata.id) |
|
122 |
return redirect('%s/' % formdata.id)
|
|
112 | 123 | |
113 | 124 |
self.selected_submission_channel = get_request().form.get('submission_channel') or '' |
114 | 125 |
return super(FormFillPage, self)._q_index(*args, **kwargs) |
... | ... | |
116 | 127 |
def html_top(self, *args, **kwargs): |
117 | 128 |
return html_top('submission', *args, **kwargs) |
118 | 129 | |
130 |
@classmethod |
|
131 |
def get_status_page_class(cls): |
|
132 |
return SubmissionFormStatusPage |
|
133 | ||
119 | 134 |
def check_authentication_context(self): |
120 | 135 |
pass |
121 | 136 | |
... | ... | |
380 | 395 |
formdata.submission_context['agent_id'], ignore_errors=True) |
381 | 396 |
if agent_user: |
382 | 397 |
label += ' (%s)' % agent_user.display_name |
383 |
r += htmltext('<a href="%s/%s">%s</a>') % ( |
|
398 |
r += htmltext('<a href="%s/%s/">%s</a>') % (
|
|
384 | 399 |
formdef.url_name, formdata.id, label) |
385 | 400 |
r += htmltext('</li>') |
386 | 401 |
wcs/forms/common.py | ||
---|---|---|
19 | 19 |
from quixote import get_publisher, get_request, get_response, get_session, redirect |
20 | 20 |
from quixote.directory import Directory |
21 | 21 |
from quixote.html import TemplateIO, htmltext |
22 |
from quixote.util import randbytes |
|
22 | 23 | |
23 | 24 |
from wcs import data_sources |
24 | 25 |
from wcs.api_utils import get_user_from_api_query_string, is_url_signed |
... | ... | |
226 | 227 |
return r.getvalue() |
227 | 228 | |
228 | 229 |
def _q_index(self): |
230 |
if self.filled.is_draft(): |
|
231 |
return self.restore_draft() |
|
232 | ||
229 | 233 |
mine = self.check_auth() |
230 | 234 |
if not mine and not get_request().is_in_backoffice(): |
231 | 235 |
# Access authorized but the form doesn't belong to the user; if the |
... | ... | |
259 | 263 |
templates=list(self.get_formdef_template_variants(self.status_templates)), |
260 | 264 |
context=context) |
261 | 265 | |
266 |
def restore_draft(self): |
|
267 |
# restore and redirect to draft |
|
268 |
session = get_session() |
|
269 |
filled = self.filled |
|
270 |
if not (get_request().is_in_backoffice() and filled.backoffice_submission): |
|
271 |
if session.is_anonymous_submitter(filled): |
|
272 |
pass |
|
273 |
elif session.user: |
|
274 |
if str(session.user) != str(filled.user_id): |
|
275 |
raise errors.AccessUnauthorizedError() |
|
276 |
else: |
|
277 |
raise errors.AccessUnauthorizedError() |
|
278 | ||
279 |
if get_request().get_query() == 'remove-draft': |
|
280 |
filled.remove_self() |
|
281 |
return redirect(get_publisher().get_root_url()) |
|
282 | ||
283 |
magictoken = randbytes(8) |
|
284 |
filled.feed_session() |
|
285 |
form_data = filled.data |
|
286 |
for field in filled.formdef.fields: |
|
287 |
if field.id not in form_data: |
|
288 |
continue |
|
289 |
if form_data[field.id] is None: |
|
290 |
# remove keys that were not set, this is required when we restore a |
|
291 |
# draft from SQL (where all columns are always defined). |
|
292 |
del form_data[field.id] |
|
293 |
continue |
|
294 |
if field.type == 'file': |
|
295 |
# add back file to session |
|
296 |
tempfile = session.add_tempfile(form_data[field.id]) |
|
297 |
form_data[field.id].token = tempfile['token'] |
|
298 |
form_data['is_recalled_draft'] = True |
|
299 |
form_data['draft_formdata_id'] = filled.id |
|
300 |
form_data['page_no'] = filled.page_no |
|
301 |
session.add_magictoken(magictoken, form_data) |
|
302 |
return redirect('../?mt=%s' % magictoken) |
|
303 | ||
262 | 304 |
def get_workflow_form(self, user): |
263 | 305 |
submitted_fields = [] |
264 | 306 |
form = self.filled.get_workflow_form(user, displayed_fields=submitted_fields) |
wcs/forms/root.py | ||
---|---|---|
175 | 175 |
if BotFilter.is_bot(): |
176 | 176 |
raise errors.AccessForbiddenError() |
177 | 177 |
get_session().mark_anonymous_formdata(formdata) |
178 |
return redirect(formdata.get_url().rstrip('/'))
|
|
178 |
return redirect(formdata.get_url()) |
|
179 | 179 | |
180 | 180 | |
181 | 181 |
class TrackingCodesDirectory(Directory): |
... | ... | |
794 | 794 | |
795 | 795 |
if self.has_draft_support() and form.get_submit() == 'savedraft': |
796 | 796 |
filled = self.save_draft(form_data, page_no) |
797 |
return redirect(filled.get_url().rstrip('/'))
|
|
797 |
return redirect(filled.get_url()) |
|
798 | 798 | |
799 | 799 |
for field in submitted_fields: |
800 | 800 |
if not field.is_visible(form_data, self.formdef) and 'f%s' % field.id in form._names: |
... | ... | |
925 | 925 | |
926 | 926 |
if self.has_draft_support() and form.get_submit() == 'savedraft': |
927 | 927 |
filled = self.save_draft(form_data, page_no = -1) |
928 |
return redirect(filled.get_url().rstrip('/'))
|
|
928 |
return redirect(filled.get_url()) |
|
929 | 929 | |
930 | 930 |
# so it gets FakeFileWidget in preview mode |
931 | 931 |
form = self.create_view_form(form_data, |
... | ... | |
1282 | 1282 |
get_response().set_content_type('image/png') |
1283 | 1283 |
return s.getvalue() |
1284 | 1284 | |
1285 |
@classmethod |
|
1286 |
def get_status_page_class(cls): |
|
1287 |
return PublicFormStatusPage |
|
1288 | ||
1285 | 1289 |
def _q_lookup(self, component): |
1286 | 1290 |
try: |
1287 | 1291 |
filled = self.formdef.data_class().get(component) |
1288 | 1292 |
except KeyError: |
1289 | 1293 |
raise errors.TraversalError() |
1290 | 1294 | |
1291 |
if not filled.is_draft(): |
|
1292 |
if get_request().is_in_backoffice(): |
|
1293 |
get_session().message = ('error', _('This form has already been submitted.')) |
|
1294 |
return redirect(get_publisher().get_backoffice_url() + '/submission/') |
|
1295 |
return PublicFormStatusPage(self.formdef, filled) |
|
1296 | ||
1297 |
# restore draft |
|
1298 |
session = get_session() |
|
1299 |
if not (get_request().is_in_backoffice() and filled.backoffice_submission): |
|
1300 |
if session.is_anonymous_submitter(filled): |
|
1301 |
pass |
|
1302 |
elif session.user: |
|
1303 |
if str(session.user) != str(filled.user_id): |
|
1304 |
raise errors.AccessUnauthorizedError() |
|
1305 |
else: |
|
1306 |
raise errors.AccessUnauthorizedError() |
|
1307 | ||
1308 |
if get_request().get_query() == 'remove-draft': |
|
1309 |
filled.remove_self() |
|
1310 |
return redirect(get_publisher().get_root_url()) |
|
1311 | ||
1312 |
magictoken = randbytes(8) |
|
1313 |
filled.feed_session() |
|
1314 |
form_data = filled.data |
|
1315 |
for field in filled.formdef.fields: |
|
1316 |
if not field.id in form_data: |
|
1317 |
continue |
|
1318 |
if form_data[field.id] is None: |
|
1319 |
# remove keys that were not set, this is required when we restore a |
|
1320 |
# draft from SQL (where all columns are always defined). |
|
1321 |
del form_data[field.id] |
|
1322 |
continue |
|
1323 |
if field.type == 'file': |
|
1324 |
# add back file to session |
|
1325 |
tempfile = session.add_tempfile(form_data[field.id]) |
|
1326 |
form_data[field.id].token = tempfile['token'] |
|
1327 |
form_data['is_recalled_draft'] = True |
|
1328 |
form_data['draft_formdata_id'] = filled.id |
|
1329 |
form_data['page_no'] = filled.page_no |
|
1330 |
session.add_magictoken(magictoken, form_data) |
|
1331 | ||
1332 |
if get_request().is_in_backoffice(): |
|
1333 |
return redirect('./?mt=%s' % magictoken) |
|
1334 |
else: |
|
1335 |
return redirect('%s?mt=%s' % (filled.formdef.get_url(), magictoken)) |
|
1295 |
return self.get_status_page_class()(self.formdef, filled) |
|
1336 | 1296 | |
1337 | 1297 | |
1338 | 1298 |
class RootDirectory(AccessControlled, Directory): |
wcs/templates/wcs/formdata_filling.html | ||
---|---|---|
22 | 22 |
{% endblocktrans %} |
23 | 23 |
</p> |
24 | 24 |
{% if drafts_length == 1 %} |
25 |
<p><a class="pk-button" href="{{drafts.0.internal_id}}">{% trans "Continue with draft" %}</a></p> |
|
25 |
<p><a class="pk-button" href="{{drafts.0.internal_id}}/">{% trans "Continue with draft" %}</a></p>
|
|
26 | 26 |
{% elif drafts_length > 1 %} |
27 | 27 |
<ul> |
28 | 28 |
{% for draft in drafts %} |
29 |
<li><a href="{{draft.internal_id}}">{% trans "continue with draft from " %} {{draft.receipt_date}} |
|
29 |
<li><a href="{{draft.internal_id}}/">{% trans "continue with draft from " %} {{draft.receipt_date}}
|
|
30 | 30 |
{{draft.receipt_time}}</a>, {% blocktrans with page_no=draft.page_no|add:1 %}on page {{page_no}}{% endblocktrans %}</li> |
31 | 31 |
{% endfor %} |
32 | 32 |
</ul> |
wcs/wf/resubmit.py | ||
---|---|---|
106 | 106 | |
107 | 107 |
workflow_data = { |
108 | 108 |
'resubmit_formdata_backoffice_url': new_formdata.get_url(backoffice=True), |
109 |
'resubmit_formdata_draft_url': new_formdata.get_url(backoffice=False).rstrip('/'),
|
|
109 |
'resubmit_formdata_draft_url': new_formdata.get_url(backoffice=False), |
|
110 | 110 |
} |
111 | 111 |
formdata.update_workflow_data(workflow_data) |
112 | 112 |
formdata.store() |
113 |
- |