diff options
Diffstat (limited to 'ishtar_common/forms.py')
| -rw-r--r-- | ishtar_common/forms.py | 126 | 
1 files changed, 117 insertions, 9 deletions
| diff --git a/ishtar_common/forms.py b/ishtar_common/forms.py index 5c3de7b77..eebd912ea 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: @@ -250,8 +335,31 @@ def get_data_from_formset(data):      return values +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(object): -    TYPES = []  # (field_name, model, is_multiple) list +    TYPES = []  # FieldType list      def __init__(self, *args, **kwargs):          """ @@ -290,12 +398,12 @@ class ManageOldType(object):                          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): | 
