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>
200 lines
5.9 KiB
Python
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)
|