summaryrefslogtreecommitdiff
path: root/ishtar_common/forms.py
diff options
context:
space:
mode:
Diffstat (limited to 'ishtar_common/forms.py')
-rw-r--r--ishtar_common/forms.py126
1 files changed, 117 insertions, 9 deletions
diff --git a/ishtar_common/forms.py b/ishtar_common/forms.py
index 985d2c3cf..36b0ef413 100644
--- a/ishtar_common/forms.py
+++ b/ishtar_common/forms.py
@@ -34,7 +34,7 @@ from django.utils.translation import ugettext_lazy as _
import models
import widgets
-from wizards import MultiValueDict
+from ishtar_common.utils import MultiValueDict
# from formwizard.forms import NamedUrlSessionFormWizard
@@ -105,7 +105,92 @@ def get_readonly_clean(key):
return func
-class FormSet(BaseFormSet):
+class CustomForm(object):
+ form_admin_name = ""
+ form_slug = ""
+ need_user_for_initialization = True
+
+ def __init__(self, *args, **kwargs):
+ current_user = None
+ if 'user' in kwargs:
+ try:
+ current_user = kwargs.pop('user').ishtaruser
+ except AttributeError:
+ pass
+ super(CustomForm, self).__init__(*args, **kwargs)
+ available, excluded = self.check_availability_and_excluded_fields(
+ current_user)
+ for exc in excluded:
+ if hasattr(self, 'fields'):
+ self.remove_field(exc)
+ else:
+ # formset
+ for form in self.forms:
+ if exc in form.fields:
+ form.fields.pop(exc)
+
+ def are_available(self, keys):
+ for k in keys:
+ if k not in self.fields:
+ return False
+ return True
+
+ def remove_field(self, key):
+ if key in self.fields:
+ self.fields.pop(key)
+
+ @classmethod
+ def check_availability_and_excluded_fields(cls, current_user):
+ if not current_user:
+ return True, []
+ base_q = {"form": cls.form_slug, 'available': True}
+ # order is important : try for user, user type then all
+ query_dicts = []
+ if current_user:
+ dct = base_q.copy()
+ dct.update({'users__pk': current_user.pk})
+ query_dicts = [dct]
+ for user_type in current_user.person.person_types.all():
+ dct = base_q.copy()
+ dct.update({'user_types__pk': user_type.pk}),
+ query_dicts.append(dct)
+ dct = base_q.copy()
+ dct.update({'apply_to_all': True})
+ query_dicts.append(dct)
+ excluded_lst = []
+ for query_dict in query_dicts:
+ q = models.CustomForm.objects.filter(**query_dict)
+ if not q.count():
+ continue
+ # todo: prevent multiple result in database
+ form = q.all()[0]
+ if not form.enabled:
+ return False, []
+ for excluded in form.excluded_fields.all():
+ # could have be filtered previously
+ excluded_lst.append(excluded.field)
+ break
+ return True, excluded_lst
+
+ @classmethod
+ def get_custom_fields(cls):
+ if hasattr(cls, 'base_fields'):
+ fields = cls.base_fields
+ else:
+ # formset
+ fields = cls.form.base_fields
+ customs = []
+ for key in fields:
+ field = fields[key]
+ # cannot customize display of required and hidden field
+ # field with no label are also rejected
+ if field.required or field.widget.is_hidden or not field.label:
+ continue
+ customs.append((key, field.label))
+ return sorted(customs, key=lambda x: x[1])
+
+
+class FormSet(CustomForm, BaseFormSet):
def __init__(self, *args, **kwargs):
self.readonly = False
if 'readonly' in kwargs:
@@ -261,8 +346,31 @@ class IshtarForm(forms.Form):
self.fields[k].widget.attrs['class'] = 'form-control'
+class FieldType(object):
+ def __init__(self, key, model, is_multiple=False, extra_args=None):
+ self.key = key
+ self.model = model
+ self.is_multiple = is_multiple
+ self.extra_args = extra_args
+
+ def get_choices(self, initial=None):
+ args = {
+ 'empty_first': not self.is_multiple,
+ 'initial': initial
+ }
+ if self.extra_args:
+ args.update(self.extra_args)
+ return self.model.get_types(**args)
+
+ def get_help(self):
+ args = {}
+ if self.extra_args:
+ args.update(self.extra_args)
+ return self.model.get_help(**args)
+
+
class ManageOldType(IshtarForm):
- TYPES = [] # (field_name, model, is_multiple) list
+ TYPES = [] # FieldType list
def __init__(self, *args, **kwargs):
"""
@@ -301,12 +409,12 @@ class ManageOldType(IshtarForm):
self.init_data[k].append(val)
self.init_data = MultiValueDict(self.init_data)
super(ManageOldType, self).__init__(*args, **kwargs)
- for field_name, model, is_multiple in self.TYPES:
- self.fields[field_name].choices = \
- model.get_types(
- empty_first=not is_multiple,
- initial=self.init_data.get(field_name))
- self.fields[field_name].help_text = model.get_help()
+ for field in self.TYPES:
+ if field.key not in self.fields:
+ continue
+ self.fields[field.key].choices = field.get_choices(
+ initial=self.init_data.get(field.key))
+ self.fields[field.key].help_text = field.get_help()
class DocumentGenerationForm(forms.Form):