48 |
48 |
from wcs.formdef import FormDef
|
49 |
49 |
from wcs.formdata import FormData
|
50 |
50 |
from wcs.roles import logged_users_role
|
51 |
|
from wcs.workflows import Workflow, EditableWorkflowStatusItem
|
|
51 |
from wcs.workflows import Workflow
|
52 |
52 |
|
53 |
53 |
from qommon.admin.texts import TextsDirectory
|
54 |
54 |
|
... | ... | |
221 |
221 |
|
222 |
222 |
self.tokens = TokensDirectory(self.formdef)
|
223 |
223 |
self.code = TrackingCodesDirectory(self.formdef)
|
|
224 |
self.action_url = '.'
|
|
225 |
self.edit_mode = False
|
224 |
226 |
|
225 |
227 |
self.page_number = len([
|
226 |
228 |
x for x in self.formdef.fields[1:] if x.type == 'page']) + 1
|
... | ... | |
255 |
257 |
if not user_roles.intersection(other_roles):
|
256 |
258 |
raise errors.AccessForbiddenError()
|
257 |
259 |
|
258 |
|
def step(self, step_no, page_no = 0, log_detail = None, data = None, editing = None):
|
|
260 |
def step(self, step_no, page_no=0, log_detail=None, data=None):
|
259 |
261 |
if step_no == 0:
|
260 |
262 |
self.substvars['current_page_no'] = str(page_no + 1)
|
261 |
263 |
if log_detail:
|
... | ... | |
282 |
284 |
if step_no > 0:
|
283 |
285 |
current_position = len(page_labels) + step_no
|
284 |
286 |
|
285 |
|
if self.formdef.confirmation and not editing:
|
|
287 |
if self.formdef.confirmation and not self.edit_mode:
|
286 |
288 |
page_labels.append(_('Validating'))
|
287 |
289 |
|
288 |
290 |
r = TemplateIO(html=True)
|
... | ... | |
327 |
329 |
|
328 |
330 |
return self.page(0)
|
329 |
331 |
|
330 |
|
def page(self, page_no, page_change = True, log_detail = None, editing = None):
|
|
332 |
def page(self, page_no, page_change=True, log_detail=None):
|
331 |
333 |
r = TemplateIO(html=True)
|
332 |
334 |
displayed_fields = []
|
333 |
335 |
|
... | ... | |
344 |
346 |
form = self.formdef.create_form(page_no, displayed_fields)
|
345 |
347 |
if get_request().is_in_backoffice():
|
346 |
348 |
form.attrs['data-is-backoffice'] = 'true'
|
347 |
|
if editing:
|
348 |
|
form.action = 'wfedit'
|
349 |
|
else:
|
350 |
|
form.action = '.'
|
|
349 |
form.action = self.action_url
|
351 |
350 |
# include a data-has-draft attribute on the <form> element when a draft
|
352 |
351 |
# already exists for the form; this will activate the autosave.
|
353 |
352 |
magictoken = get_request().form.get('magictoken')
|
354 |
353 |
if magictoken:
|
355 |
354 |
form_data = session.get_by_magictoken(magictoken, {})
|
356 |
|
if self.formdef.enable_tracking_codes and not editing:
|
|
355 |
if self.formdef.enable_tracking_codes and not self.edit_mode:
|
357 |
356 |
form.attrs['data-has-draft'] = 'yes'
|
358 |
357 |
else:
|
359 |
358 |
form_data = {}
|
... | ... | |
369 |
368 |
cancelurl = get_request().form['cancelurl']
|
370 |
369 |
session.add_magictoken(magictoken, {'__cancelurl': cancelurl})
|
371 |
370 |
|
372 |
|
if editing and page_no == self.page_number - 1:
|
|
371 |
if self.edit_mode and page_no == self.page_number - 1:
|
373 |
372 |
form.add_submit('submit', _('Save Changes'))
|
374 |
373 |
elif not self.formdef.confirmation and page_no == self.page_number - 1:
|
375 |
374 |
form.add_submit('submit', _('Submit'))
|
... | ... | |
432 |
431 |
req.form = {}
|
433 |
432 |
|
434 |
433 |
self.html_top(self.formdef.name)
|
435 |
|
r += self.form_side(0, page_no, log_detail=log_detail, data=data, editing=editing)
|
|
434 |
r += self.form_side(0, page_no, log_detail=log_detail, data=data)
|
436 |
435 |
r += get_session().display_message()
|
437 |
436 |
|
438 |
437 |
form.add_hidden('step', '0')
|
439 |
438 |
form.add_hidden('page', page_no)
|
440 |
439 |
|
441 |
440 |
form.add_submit('cancel', _('Cancel'), css_class = 'cancel')
|
442 |
|
if self.formdef.enable_tracking_codes and not editing:
|
|
441 |
if self.formdef.enable_tracking_codes and not self.edit_mode:
|
443 |
442 |
form.add_submit('savedraft', _('Save Draft'), css_class = 'save-draft',
|
444 |
443 |
attrs={'style': 'display: none'})
|
445 |
444 |
|
446 |
445 |
r += form.render()
|
447 |
446 |
return r.getvalue()
|
448 |
447 |
|
449 |
|
def form_side(self, step_no, page_no=0, log_detail=None, data=None, editing=None):
|
|
448 |
def form_side(self, step_no, page_no=0, log_detail=None, data=None):
|
450 |
449 |
'''Create the elements that typically appear aside the main form
|
451 |
450 |
(tracking code and steps).'''
|
452 |
451 |
r = TemplateIO(html=True)
|
453 |
452 |
r += htmltext('<div id="side">')
|
454 |
453 |
if self.formdef.enable_tracking_codes:
|
455 |
|
r += self.tracking_code_box(data, editing=editing)
|
456 |
|
r += self.step(step_no, page_no, log_detail, data=data, editing=editing)
|
|
454 |
r += self.tracking_code_box(data)
|
|
455 |
r += self.step(step_no, page_no, log_detail, data=data)
|
457 |
456 |
r += htmltext('</div> <!-- #side -->')
|
458 |
457 |
return r.getvalue()
|
459 |
458 |
|
460 |
|
def tracking_code_box(self, data, editing=False):
|
|
459 |
def tracking_code_box(self, data):
|
461 |
460 |
'''Create the tracking code box, it displays the current tracking code
|
462 |
461 |
or a 'save' button if it has not yet been created.'''
|
463 |
462 |
r = TemplateIO(html=True)
|
... | ... | |
477 |
476 |
r += htmltext('<a rel="popup" href="%s">%s</a>') % (
|
478 |
477 |
'code/%s/' % tracking_code, tracking_code)
|
479 |
478 |
else:
|
480 |
|
if editing:
|
|
479 |
if self.edit_mode:
|
481 |
480 |
return ''
|
482 |
481 |
r += htmltext('<button>%s</button>') % _('Save')
|
483 |
482 |
r += TextsDirectory.get_html_text('tracking-code-short-text')
|
... | ... | |
507 |
506 |
raise errors.AccessForbiddenError()
|
508 |
507 |
return False
|
509 |
508 |
|
510 |
|
def _q_index(self, log_detail = None, editing = None):
|
|
509 |
def _q_index(self, log_detail=None):
|
511 |
510 |
self.check_role()
|
512 |
511 |
if self.check_disabled():
|
513 |
512 |
return redirect(self.check_disabled())
|
... | ... | |
533 |
532 |
# first hit on first page, if tracking code are enabled and we
|
534 |
533 |
# are not editing an existing formdata, generate a new tracking
|
535 |
534 |
# code.
|
536 |
|
if not editing and self.formdef.enable_tracking_codes and not get_request().form.has_key('mt'):
|
|
535 |
if not self.edit_mode and self.formdef.enable_tracking_codes and not get_request().form.has_key('mt'):
|
537 |
536 |
tracking_code = get_publisher().tracking_code_class()
|
538 |
537 |
tracking_code.store()
|
539 |
538 |
token = randbytes(8)
|
... | ... | |
541 |
540 |
session.add_magictoken(token, {'future_tracking_code': tracking_code.id})
|
542 |
541 |
|
543 |
542 |
existing_formdata = None
|
544 |
|
if editing:
|
545 |
|
existing_formdata = editing.data
|
|
543 |
if self.edit_mode:
|
|
544 |
existing_formdata = self.edited_data.data
|
546 |
545 |
if not get_request().form:
|
547 |
546 |
# on the initial visit editing the form (i.e. not after
|
548 |
547 |
# clicking for previous or next page), we need to load the
|
549 |
548 |
# existing data into the session
|
550 |
|
editing.feed_session()
|
|
549 |
self.edited_data.feed_session()
|
551 |
550 |
token = randbytes(8)
|
552 |
551 |
get_request().form['magictoken'] = token
|
553 |
|
session.add_magictoken(token, editing.data)
|
|
552 |
session.add_magictoken(token, self.edited_data.data)
|
554 |
553 |
elif self.formdef.only_allow_one:
|
555 |
554 |
user_forms = get_user_forms(self.formdef)
|
556 |
555 |
if [x for x in user_forms if not x.is_draft()]:
|
... | ... | |
593 |
592 |
self.feed_current_data(magictoken)
|
594 |
593 |
return self.page(page_no, True)
|
595 |
594 |
self.feed_current_data(None)
|
596 |
|
return self.page(0, editing = editing)
|
|
595 |
return self.page(0)
|
597 |
596 |
|
598 |
597 |
if form.get_submit() == 'cancel':
|
599 |
598 |
get_logger().info('form %s - cancel' % (self.formdef.name))
|
600 |
|
if editing:
|
|
599 |
if self.edit_mode:
|
601 |
600 |
return redirect('.')
|
602 |
601 |
try:
|
603 |
602 |
magictoken = form.get_widget('magictoken').parse()
|
... | ... | |
634 |
633 |
form.add_submit('savedraft')
|
635 |
634 |
form.add_submit('submit')
|
636 |
635 |
if page_no > 0 and form.get_submit() == 'previous':
|
637 |
|
return self.previous_page(page_no, magictoken, editing = editing)
|
|
636 |
return self.previous_page(page_no, magictoken)
|
638 |
637 |
|
639 |
638 |
if self.formdef.enable_tracking_codes and form.get_submit() == 'removedraft':
|
640 |
639 |
self.remove_draft()
|
... | ... | |
657 |
656 |
# page hidden field had an error in its submission), in
|
658 |
657 |
# that case we just fall back to the first page.
|
659 |
658 |
page_no = 0
|
660 |
|
return self.page(page_no, page_change = False, editing = editing)
|
|
659 |
return self.page(page_no, page_change=False)
|
661 |
660 |
|
662 |
661 |
form_data = session.get_by_magictoken(magictoken, {})
|
663 |
662 |
data = self.formdef.get_data(form)
|
... | ... | |
693 |
692 |
if field.convert_value_to_str:
|
694 |
693 |
v = field.convert_value_to_str(v)
|
695 |
694 |
req.form['f%s' % k] = v
|
696 |
|
if editing:
|
697 |
|
form = self.formdef.create_view_form(form_data, use_tokens = False)
|
698 |
|
return self.submitted_existing(form, editing)
|
|
695 |
if self.edit_mode:
|
|
696 |
form = self.formdef.create_view_form(form_data, use_tokens=False)
|
|
697 |
return self.submitted_existing(form)
|
699 |
698 |
if self.formdef.confirmation:
|
700 |
699 |
return self.validating(form_data)
|
701 |
700 |
else:
|
... | ... | |
711 |
710 |
form.add_submit('savedraft')
|
712 |
711 |
|
713 |
712 |
else:
|
714 |
|
return self.page(page_no, editing = editing)
|
|
713 |
return self.page(page_no)
|
715 |
714 |
|
716 |
715 |
if step == 1:
|
717 |
716 |
form.add_submit('previous')
|
718 |
717 |
magictoken = form.get_widget('magictoken').parse()
|
719 |
718 |
|
720 |
719 |
if form.get_submit() == 'previous':
|
721 |
|
return self.previous_page(self.page_number, magictoken, editing = editing)
|
|
720 |
return self.previous_page(self.page_number, magictoken)
|
722 |
721 |
magictoken = form.get_widget('magictoken').parse()
|
723 |
722 |
form_data = session.get_by_magictoken(magictoken, {})
|
724 |
723 |
data = self.formdef.get_data(form)
|
... | ... | |
739 |
738 |
form_data = session.get_by_magictoken(magictoken, {})
|
740 |
739 |
|
741 |
740 |
if form.get_submit() == 'previous':
|
742 |
|
return self.previous_page(self.page_number, magictoken, editing = editing)
|
|
741 |
return self.previous_page(self.page_number, magictoken)
|
743 |
742 |
|
744 |
743 |
if self.formdef.enable_tracking_codes and form.get_submit() == 'removedraft':
|
745 |
744 |
self.remove_draft()
|
... | ... | |
761 |
760 |
return self.submitted(form, existing_formdata)
|
762 |
761 |
|
763 |
762 |
|
764 |
|
def previous_page(self, page_no, magictoken, editing = None):
|
|
763 |
def previous_page(self, page_no, magictoken):
|
765 |
764 |
session = get_session()
|
766 |
765 |
form_data = session.get_by_magictoken(magictoken, {})
|
767 |
766 |
|
... | ... | |
777 |
776 |
if previous_page.is_visible(form_data, self.formdef):
|
778 |
777 |
break
|
779 |
778 |
|
780 |
|
return self.page(page_no, page_change = True, editing = editing)
|
|
779 |
return self.page(page_no, page_change=True)
|
781 |
780 |
|
782 |
781 |
def remove_draft(self):
|
783 |
782 |
magictoken = get_request().form.get('magictoken')
|
... | ... | |
930 |
929 |
code.id = magictoken_data['future_tracking_code']
|
931 |
930 |
code.formdata = formdata # this will .store() the code
|
932 |
931 |
|
933 |
|
def submitted_existing(self, form, editing):
|
934 |
|
old_data = editing.data
|
935 |
|
editing.data = self.formdef.get_data(form)
|
936 |
|
editing.store()
|
937 |
|
return redirect('.')
|
|
932 |
def submitted_existing(self, form):
|
|
933 |
self.edited_data.data = self.formdef.get_data(form)
|
|
934 |
self.edited_data.store()
|
|
935 |
wf_status = self.edited_data.get_status()
|
|
936 |
url = None
|
|
937 |
for item in wf_status.items:
|
|
938 |
if item.id == self.edit_action_id and item.status:
|
|
939 |
self.edited_data.jump_status(item.status)
|
|
940 |
url = self.edited_data.perform_workflow()
|
|
941 |
break
|
|
942 |
return redirect(url or '.')
|
938 |
943 |
|
939 |
944 |
def tempfile(self):
|
940 |
945 |
self.check_role()
|
... | ... | |
1386 |
1391 |
|
1387 |
1392 |
|
1388 |
1393 |
class PublicFormStatusPage(FormStatusPage):
|
1389 |
|
_q_exports = ['', 'download', 'status', 'wfedit']
|
|
1394 |
_q_exports = ['', 'download', 'status']
|
|
1395 |
form_page_class = FormPage
|
1390 |
1396 |
|
1391 |
1397 |
def __init__(self, *args, **kwargs):
|
1392 |
1398 |
FormStatusPage.__init__(self, *args, **kwargs)
|
... | ... | |
1409 |
1415 |
r += htmltext('</div>')
|
1410 |
1416 |
return r.getvalue()
|
1411 |
1417 |
|
1412 |
|
def wfedit(self):
|
1413 |
|
wf_status = self.filled.get_status()
|
1414 |
|
for item in wf_status.items:
|
1415 |
|
if not isinstance(item, EditableWorkflowStatusItem):
|
1416 |
|
continue
|
1417 |
|
if item.check_auth(self.filled, get_request().user):
|
1418 |
|
f = FormPage(self.formdef.url_name)
|
1419 |
|
get_response().breadcrumb = get_response().breadcrumb[:-1]
|
1420 |
|
get_response().breadcrumb.append( ('wfedit', _('Edit')) )
|
1421 |
|
return f._q_index(editing = self.filled)
|
1422 |
|
|
1423 |
|
raise errors.AccessForbiddenError()
|
1424 |
|
|
1425 |
1418 |
|
1426 |
1419 |
TextsDirectory.register('welcome-logged',
|
1427 |
1420 |
N_('Welcome text on home page for logged users'))
|