from ordereddict import OrderedDict
from django import forms
from django.core.urlresolvers import reverse
+from django.core.exceptions import MultipleObjectsReturned
from django.forms.models import BaseInlineFormSet
from django.forms.models import (
inlineformset_factory,
from project import groups
from project.rh import models as rh
from project.dae import models as dae
-from .widgets import ReadOnlyChoiceWidget
+from .widgets import ReadOnlyChoiceWidget, ReadOnlyWidget
from project.dae.workflow import POSTE_ETATS_BOUTONS, POSTE_ETAT_FINALISE
def __init__(self, *a, **kw):
super(FlexibleRemunForm, self).__init__(*a, **kw)
- self.fields['type'].widget = ReadOnlyChoiceWidget(choices=self.fields['type'].choices)
+ # self.fields['type'].widget = ReadOnlyChoiceWidget(choices=self.fields['type'].choices)
def clean_devise(self):
devise = self.cleaned_data['devise']
return bool(changed_data)
+class ReadOnlyRemunForm(FlexibleRemunForm):
+ def __init__(self, *a, **kw):
+ super(FlexibleRemunForm, self).__init__(*a, **kw)
+ for field in self.fields:
+ field = self.fields[field]
+ if not isinstance(field.widget, (
+ forms.widgets.HiddenInput,
+ forms.widgets.Select)):
+ field.widget = ReadOnlyWidget()
+ elif isinstance(field.widget, forms.widgets.Select):
+ field.widget = ReadOnlyChoiceWidget(choices=field.choices)
+
+
class GroupedInlineFormset(BaseInlineFormSet):
- def set_groups(self, group_accessor, group_order=[]):
- """
- group_accessor: A function that will get the key and name from
- each form.
- group_order: list the group keys here in a list and
- GroupedInlineFormset.groups will be ordered (ordereddict) by
- the key sequence provided here. Any missing key from the
- sequence will
- """
+ def set_groups(self,
+ groups,
+ group_accessor,
+ choice_overrides=[]):
+
- # Build group list.
+ # Create pre-defined groups.
self.groups = OrderedDict()
- temp_groups = {}
- # self.groups_and_forms = []
+ for group in groups:
+ self.groups[group[0]] = {
+ 'name': group[1],
+ 'key': group[0],
+ 'forms': [],
+ }
+
+ # Assign each form to a group.
for form in self.forms:
- group_key, group_name = group_accessor(form)
- if not temp_groups.has_key(group_key):
- temp_groups[group_key] = {
- 'name': group_name,
- 'key': group_key,
- 'forms': [],
- }
- temp_groups[group_key]['forms'].append(form)
-
- for order_key in group_order:
- if temp_groups.has_key(order_key):
- self.groups[order_key] = temp_groups.pop(order_key)
-
- for key in temp_groups:
- self.groups[key] = temp_groups[key]
-
- del temp_groups
+ if bool(form.initial):
+ grp = group_accessor(form)
+ if grp[0] not in self.groups:
+ self.groups[grp[0]] = {
+ 'name': grp[1],
+ 'key': grp[0],
+ 'forms': [],
+ }
+ self.groups[grp[0]]['forms'].append(form)
+
+ # Add extra forms (n extra for each grop).
+ tmp_extras = []
+ for i in xrange(len(self.groups) * self.extra):
+ tmp_extras.insert(0, self._construct_form(i))
+
+ for g in self.groups:
+ for i in xrange(self.extra):
+ self.groups[g]['forms'].append(tmp_extras.pop())
+
+ # Override form choices with the data provided in
+ # choice_overrides
+ for key in choice_overrides:
+ for form in self.groups.get(key, {'forms': []})['forms']:
+ for field_key in choice_overrides[key]:
+ form.fields[field_key].choices = choice_overrides[
+ key][field_key]
+
+
+ # Create an iterable for easier access in template.
self.group_list = self.groups.values()
+ # def set_groups(self, group_accessor, groups, group_order=[]):
+ # """
+ # group_accessor: A function that will get the key and name from
+ # each form.
+ # group_order: list the group keys here in a list and
+ # GroupedInlineFormset.groups will be ordered (ordereddict) by
+ # the key sequence provided here. Any missing key from the
+ # sequence will
+ # """
+
+ # # Build group list.
+ # self.groups = OrderedDict()
+ # temp_groups = {}
+ # # self.groups_and_forms = []
+ # for form in self.forms:
+ # group_key, group_name = group_accessor(form)
+ # if not temp_groups.has_key(group_key):
+ # temp_groups[group_key] = {
+ # 'name': group_name,
+ # 'key': group_key,
+ # 'forms': [],
+ # }
+ # temp_groups[group_key]['forms'].append(form)
+
+ # for order_key in group_order:
+ # if temp_groups.has_key(order_key):
+ # self.groups[order_key] = temp_groups.pop(order_key)
+
+ # for key in temp_groups:
+ # self.groups[key] = temp_groups[key]
+
+ # del temp_groups
+
+ # self.group_list = self.groups.values()
+
def remun_formset_factory(parent_model,
model,
exclude=None,
can_order=False,
can_delete=True,
+ extra=2,
max_num=None,
formfield_callback=None,
- group_order=None):
+ groups=None,
+ choice_overrides=[]):
trs = rh.TypeRemuneration.objects.all()
- extra = max_num = trs.count()
+ # extra = max_num = trs.count()
fk = _get_foreign_key(parent_model, model, fk_name=fk_name)
# enforce a max_num=1 when the foreign key to the parent model is unique.
if fk.unique:
FormSet.fk = fk
def grouper(form):
- if 'type' in form.initial and form.initial['type']:
- return (form.initial['type'].nature_remuneration,
- form.initial['type'].nature_remuneration,
- )
+ rtype = form.initial['type']
+ if not isinstance(rtype, rh.TypeRemuneration):
+ rtype = rh.TypeRemuneration.objects.get(id=rtype)
+ return (rtype.nature_remuneration,
+ rtype.nature_remuneration
+ )
def __init__(inst, *a, **kw):
super(FormSet, inst).__init__(*a, **kw)
- # Set initial data.
- for form, tr in zip(inst.forms, trs):
- form.initial = {
- 'type': tr,
- }
+ # Warning, this constructor can be improved and made more
+ # efficient.. it's a bit of a hack that will help creating a
+ # "grouped" formset that works inside Django. Although the
+ # code makes several iterations, I've timed it at 1ms to
+ # for it's execution.
+
+ # # Set initial data.
+ # d_inst = kw.get('instance', None)
- # Set form grouping.
- inst.set_groups(grouper, group_order)
+ # Set initial for all form type.
+ # for form, tr in zip(inst.forms, trs):
+ # form.initial['type'] = tr
+ # # Set form grouping.
+ inst.set_groups(groups, grouper, choice_overrides)
+
+ # # Create groups list of choices for type field.
+ # inst.group_type_choices = {}
+ # for group_key in inst.groups:
+ # inst.group_type_choices[group_key] = []
+
+ # # Add choices based on form.initial which have been set above.
+ # for form in inst.forms:
+ # inst.group_type_choices[
+ # form.initial['type'].nature_remuneration].append(
+ # (form.initial['type'].id, form.initial['type'].nom)
+ # )
+
+ # # Finally... change the choices of each form in the formset:
+ # for form in inst.forms:
+ # form.fields['type'].choices = inst.group_type_choices[
+ # form.initial['type'].nature_remuneration]
+
+
FormSet.__init__ = __init__
return FormSet
+ReadOnlyRemunForm = remun_formset_factory(
+ dae.Dossier,
+ dae.Remuneration,
+ form=ReadOnlyRemunForm,
+ groups = [
+ (u'Traitement', u'Traitement',),
+ (u'Indemnité', u'Indemnité',),
+ (u'Charges', u'Charges',),
+ (u'Accessoire', u'Accessoire',),
+ ]
+ )
+
+null_choice = ('', '-' * 10)
RemunForm = remun_formset_factory(
dae.Dossier,
dae.Remuneration,
form=FlexibleRemunForm,
- group_order = [
- u'Traitement',
- u'Indemnité',
- u'Charges',
- u'Accessoire',
- ]
+ groups = [
+ (u'Traitement', u'Traitement',),
+ (u'Indemnité', u'Indemnité',),
+ (u'Charges', u'Charges',),
+ (u'Accessoire', u'Accessoire',),
+ ],
+ choice_overrides = {
+ u'Traitement': {
+ 'type': [null_choice] + list(
+ rh.TypeRemuneration.objects.filter(
+ nature_remuneration=u'Traitement').values_list(
+ 'id', 'nom')
+ )
+ },
+ u'Indemnité': {
+ 'type': [null_choice] + list(
+ rh.TypeRemuneration.objects.filter(
+ nature_remuneration=u'Indemnité').values_list(
+ 'id', 'nom')
+ )
+ },
+ u'Charges': {
+ 'type': [null_choice] + list(
+ rh.TypeRemuneration.objects.filter(
+ nature_remuneration=u'Charges').values_list(
+ 'id', 'nom')
+ )
+ },
+ u'Accessoire': {
+ 'type': [null_choice] + list(
+ rh.TypeRemuneration.objects.filter(
+ nature_remuneration=u'Accessoire').values_list(
+ 'id', 'nom')
+ )
+ },
+ }
)
+RemunForm = ReadOnlyRemunForm
+
class PosteForm(forms.ModelForm):
""" Formulaire des postes. """