+DossierComparaisonFormSet = modelformset_factory(
+ dae.DossierComparaison, extra=3, max_num=3, form=DossierComparaisonForm
+)
+
+
+class PosteComparaisonForm(
+ filtered_archived_fields_form_factory('classement'),
+ forms.ModelForm):
+
+ recherche = AutoCompleteSelectField('dae_postes', required=False)
+
+ cmp_poste = forms.IntegerField(
+ widget=forms.widgets.HiddenInput,
+ required=False,
+ )
+
+ class Meta:
+ model = dae.PosteComparaison
+ exclude = ('poste',)
+
+# Ce formset est utilisé dans le cas de la création de poste prépopulé avec les
+# données de RH
+PosteComparaisonFormSetInitial = inlineformset_factory(
+ dae.Poste,
+ dae.PosteComparaison,
+ extra=3,
+ max_num=3,
+ form=PosteComparaisonForm,
+ formset=BaseInlineFormSetWithInitial,
+)
+PosteComparaisonFormSet = inlineformset_factory(
+ dae.Poste,
+ dae.PosteComparaison,
+ extra=3,
+ max_num=3,
+ form=PosteComparaisonForm,
+)
+
+
+class FlexibleRemunForm(
+ filtered_archived_fields_form_factory(
+ 'type',
+ ),
+ forms.ModelForm):
+ # Utilisé dans templats.
+ montant_mensuel = forms.DecimalField(required=False)
+ montant = forms.DecimalField(required=True, label='Montant annuel')
+
+ class Meta:
+ model = dae.Remuneration
+
+ def __init__(self, *a, **kw):
+ super(FlexibleRemunForm, self).__init__(*a, **kw)
+ # self.fields['type'].widget = ReadOnlyChoiceWidget(choices=self.fields['type'].choices)
+
+ def clean_devise(self):
+ devise = self.cleaned_data['devise']
+ if devise.code == 'EUR':
+ return devise
+ implantation = ref.Implantation.objects.get(
+ id=self.data['implantation']
+ )
+ liste_taux = devise.tauxchange_set.order_by('-annee')
+ if len(liste_taux) == 0:
+ raise forms.ValidationError(
+ u"La devise %s n'a pas de taux pour l'implantation %s" %
+ (devise, implantation)
+ )
+ else:
+ return devise
+
+ def has_changed(self):
+ """
+ Modification de has_changed pour qu'il ignore les montant a 0
+ et les 'types'.
+ """
+
+ changed_data = self.changed_data
+
+ # Type is set in hidden fields, it shouldn't be changed by the
+ # user; ignore when checking if data has changed.
+ if 'type' in changed_data:
+ changed_data.pop(changed_data.index('type'))
+
+ # Montant is set to 0 in javascript, ifnore 'montant' data if
+ # its value is 0.
+
+ # Generer le key tel qu'identifié dans self.data:
+ montant_key = '-'.join((self.prefix, 'montant'))
+
+ if ('montant' in changed_data and
+ self.data.get(montant_key, '0') == '0'):
+ changed_data.pop(changed_data.index('montant'))
+
+ return bool(changed_data)
+
+
+class ReadOnlyRemunForm(FlexibleRemunForm):
+ # Utilisé dans templats.
+
+ def __init__(self, *a, **kw):
+ super (ReadOnlyRemunForm, 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,
+ groups,
+ group_accessor,
+ choice_overrides=[]):
+
+
+ # Create pre-defined groups.
+ self.groups = OrderedDict()
+ for group in groups:
+ self.groups[group[0]] = {
+ 'name': group[1],
+ 'key': group[0],
+ 'forms': [],
+ }
+
+ # Assign each form to a group.
+ ungrouped_forms = []
+ for form in self.forms:
+ 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)
+ else:
+ ungrouped_forms.append(form)
+
+
+ # Distribuer les extras de django dans les groupes, et ajouter
+ # des extras pour les groupes en nécessitant.
+ f_count = len(self.forms)
+ for g in self.groups:
+ for i in xrange(f_count, f_count + self.extra):
+ if len(ungrouped_forms) == 0:
+ f_count += 1
+
+ if len(ungrouped_forms) > 0:
+ new_form = ungrouped_forms.pop()
+ else:
+ new_form = self._construct_form(i)
+ self.forms.append(new_form)
+
+ self.groups[g]['forms'].append(new_form)
+
+
+ # 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 remun_formset_factory(parent_model,
+ model,
+ form=forms.ModelForm,
+ formset=GroupedInlineFormset,
+ fk_name=None,
+ fields=None,
+ exclude=None,
+ can_order=False,
+ can_delete=True,
+ read_only=False,
+ extra=2,
+ max_num=None,
+ formfield_callback=None,
+ groups=None,
+ choice_overrides=[]):
+ trs = rh.TypeRemuneration.objects.all()
+ # 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:
+ max_num = 1
+ kwargs = {
+ 'form': form,
+ 'formfield_callback': formfield_callback,
+ 'formset': formset,
+ 'extra': extra,
+ 'can_delete': can_delete,
+ 'can_order': can_order,
+ 'fields': fields,
+ 'exclude': exclude,
+ 'max_num': max_num,
+ }
+ FormSet = modelformset_factory(model, **kwargs)
+ FormSet.fk = fk
+ FormSet.read_only = read_only
+
+ def grouper(form):
+ rtype = form.initial['type']
+ if not isinstance(rtype, rh.TypeRemuneration):
+ rtype = rh.TypeRemuneration.objects.get(id=rtype)
+ return (rtype.nature_remuneration,
+ rtype.nature_remuneration
+ )
+
+
+
+ # Monkey patch FormSet.
+ def __init__(inst, *a, **kw):
+ super(inst.__class__, inst).__init__(*a, **kw)
+ inst.set_groups(groups, grouper, choice_overrides)
+
+ FormSet.__init__ = __init__
+
+ return FormSet
+
+
+def remun_formset_factory_factory(
+ read_only=False,
+ parent_model=dae.Dossier,
+ model=dae.Remuneration,
+ exclude_archived=False):