Files
mayan-edms/mayan/apps/sources/wizards.py
Roberto Rosario 4d46ca3343 Unify document type selection forms
Merge all document type selection forms into a single smarter form
that can perform permission filtering and allow single or multiple
selections.

This commit also add the document type selection for submit
view to the file metadata app.

This commit also updates the document type selection views
for the OCR, document parsing, and upload wizard to use
the new document type selection form and removes their
respective document type selection forms.

Signed-off-by: Roberto Rosario <Roberto.Rosario@mayan-edms.com>
2018-12-14 18:06:23 -04:00

200 lines
5.9 KiB
Python

from __future__ import unicode_literals
from furl import furl
from django.apps import apps
from django.contrib import messages
from django.http import HttpResponseRedirect
from django.urls import reverse
from django.utils.decorators import classonlymethod
from django.utils.translation import ugettext_lazy as _
from formtools.wizard.views import SessionWizardView
from mayan.apps.documents.forms import DocumentTypeFilteredSelectForm
from mayan.apps.documents.permissions import permission_document_create
from .icons import icon_wizard_submit
class WizardStep(object):
_registry = {}
_deregistry = {}
@classmethod
def deregister(cls, step):
cls._deregistry[step.name] = step
@classmethod
def deregister_all(cls):
for step in cls.get_all():
cls.deregister(step=step)
@classmethod
def done(cls, wizard):
return {}
@classmethod
def get(cls, name):
for step in cls.get_all():
if name == step.name:
return step
@classmethod
def get_all(cls):
return sorted(
[
step for step in cls._registry.values() if step.name not in cls._deregistry
], key=lambda x: x.number
)
@classmethod
def get_choices(cls, attribute_name):
return [
(step.name, getattr(step, attribute_name)) for step in cls.get_all()
]
@classmethod
def get_form_initial(cls, wizard):
return {}
@classmethod
def get_form_kwargs(cls, wizard):
return {}
@classmethod
def post_upload_process(cls, document, querystring=None):
for step in cls.get_all():
step.step_post_upload_process(
document=document, querystring=querystring
)
@classmethod
def register(cls, step):
if step.name in cls._registry:
raise Exception('A step with this name already exists: %s' % step.name)
if step.number in [reigstered_step.number for reigstered_step in cls.get_all()]:
raise Exception('A step with this number already exists: %s' % step.name)
cls._registry[step.name] = step
@classmethod
def reregister(cls, name):
cls._deregistry.pop(name)
@classmethod
def reregister_all(cls):
cls._deregistry = {}
@classmethod
def step_post_upload_process(cls, document, querystring=None):
pass
class WizardStepDocumentType(WizardStep):
form_class = DocumentTypeFilteredSelectForm
label = _('Select document type')
name = 'document_type_selection'
number = 0
@classmethod
def condition(cls, wizard):
return True
@classmethod
def done(cls, wizard):
cleaned_data = wizard.get_cleaned_data_for_step(cls.name)
if cleaned_data:
return {
'document_type_id': cleaned_data['document_type'].pk
}
@classmethod
def get_form_kwargs(cls, wizard):
return {
'permission': permission_document_create,
'user': wizard.request.user
}
WizardStep.register(WizardStepDocumentType)
class DocumentCreateWizard(SessionWizardView):
template_name = 'appearance/generic_wizard.html'
@classonlymethod
def as_view(cls, *args, **kwargs):
cls.form_list = WizardStep.get_choices(attribute_name='form_class')
cls.condition_dict = dict(WizardStep.get_choices(attribute_name='condition'))
return super(DocumentCreateWizard, cls).as_view(*args, **kwargs)
def dispatch(self, request, *args, **kwargs):
InteractiveSource = apps.get_model(
app_label='sources', model_name='InteractiveSource'
)
form_list = WizardStep.get_choices(attribute_name='form_class')
condition_dict = dict(WizardStep.get_choices(attribute_name='condition'))
result = self.__class__.get_initkwargs(form_list=form_list, condition_dict=condition_dict)
self.form_list = result['form_list']
self.condition_dict = result['condition_dict']
if not InteractiveSource.objects.filter(enabled=True).exists():
messages.error(
request,
_(
'No interactive document sources have been defined or '
'none have been enabled, create one before proceeding.'
)
)
return HttpResponseRedirect(reverse('sources:setup_source_list'))
return super(
DocumentCreateWizard, self
).dispatch(request, *args, **kwargs)
def get_context_data(self, form, **kwargs):
context = super(
DocumentCreateWizard, self
).get_context_data(form=form, **kwargs)
wizard_step = WizardStep.get(name=self.steps.current)
context.update({
'form_css_classes': 'form-hotkey-double-click',
'step_title': _(
'Step %(step)d of %(total_steps)d: %(step_label)s'
) % {
'step': self.steps.step1, 'total_steps': len(self.form_list),
'step_label': wizard_step.label,
},
'submit_label': _('Next step'),
'submit_icon_class': icon_wizard_submit,
'title': _('Document upload wizard'),
'wizard_step': wizard_step,
'wizard_steps': WizardStep.get_all(),
})
return context
def get_form_initial(self, step):
return WizardStep.get(name=step).get_form_initial(wizard=self) or {}
def get_form_kwargs(self, step):
return WizardStep.get(name=step).get_form_kwargs(wizard=self) or {}
def done(self, form_list, **kwargs):
query_dict = {}
for step in WizardStep.get_all():
query_dict.update(step.done(wizard=self) or {})
url = furl(reverse('sources:upload_interactive'))
# Use equal and not .update() to get the same result as using
# urlencode(doseq=True)
url.args = query_dict
return HttpResponseRedirect(url)