Done forms
authorBenoit C. Sirois <benoit.clennett-sirois@auf.org>
Tue, 19 Feb 2013 19:49:55 +0000 (14:49 -0500)
committerBenoit C. Sirois <benoit.clennett-sirois@auf.org>
Tue, 19 Feb 2013 19:49:55 +0000 (14:49 -0500)
project/assets/js/dae-embauche.js
project/dae/forms.py
project/dae/templates/dae/embauche-remun.html
project/dae/templates/dae/table_remuneration.html
project/dae/views.py
project/dae/widgets.py
project/settings.py

index 18b46a6..f370d00 100644 (file)
@@ -63,29 +63,29 @@ function round2(n) {
 }
 
 function remun_line(input) {
-  var idParts = input.attr('id').split('-');
-  var prefix = idParts[0] + "-" + idParts[1];
-  var field = idParts[2];
+    var idParts = input.attr('id').split('-');
+    var prefix = idParts[0] + "-" + idParts[1];
+    var field = idParts[2];
 
-  var montant_annuel = $('#' + prefix + '-montant');
-  var montant_annuel_euros = $('#' + prefix + '-montant_annuel_euros');
+    var montant_annuel = $('#' + prefix + '-montant');
+    var montant_annuel_euros = $('#' + prefix + '-montant_annuel_euros');
 
-  /* auto calcul a besoin d'un type (autrement ca devient un champs requis)*/
-  if ($('#' + prefix + '-type').val() == '') {
-    montant_annuel.val(''); 
-    montant_annuel_euros.val(''); 
-    return;
-  }
+    /* auto calcul a besoin d'un type (autrement ca devient un champs requis)*/
+    // if ($('#' + prefix + '-type').val() == '') {
+    //         montant_annuel.val(''); 
+    //         montant_annuel_euros.val(''); 
+    //         return;
+    // }
 
-  value = (montant_annuel.val());
-  value = roundNumber(value, 2)
+    value = (montant_annuel.val());
+    value = roundNumber(value, 2)
 
-  montant_annuel.val(roundNumber(value, 0));
+    montant_annuel.val(roundNumber(value, 2));
 
-  var devise = $('#' + prefix + '-devise').val();
-  var taux = parseFloat(DEVISES[devise]);
-  if (isNaN(taux)) taux = 0;
-  montant_annuel_euros.text(roundNumber((value * taux), 0))
+    var devise = $('#' + prefix + '-devise').val();
+    var taux = parseFloat(DEVISES[devise]);
+    if (isNaN(taux)) taux = 0;
+    montant_annuel_euros.text(roundNumber((value * taux), 2));
 }
 
 function totalByIndex(selector, accessor) {
@@ -107,7 +107,7 @@ function totalByIndex(selector, accessor) {
            }
            subtot += clean_float(val);
        });
-       $(this).html(subtot);
+       $(this).html(roundNumber(subtot, 2));
     });
 }
 
index 01aee78..d7d043a 100644 (file)
@@ -255,7 +255,7 @@ PosteComparaisonFormSet = inlineformset_factory(
 
 
 class FlexibleRemunForm(forms.ModelForm):
-
+    # Utilisé dans templats.
     montant_mensuel = forms.DecimalField(required=False)
     montant = forms.DecimalField(required=True, label='Montant annuel')
 
@@ -309,8 +309,10 @@ class FlexibleRemunForm(forms.ModelForm):
 
 
 class ReadOnlyRemunForm(FlexibleRemunForm):
+    # Utilisé dans templats.
+
     def __init__(self, *a, **kw):
-        super(FlexibleRemunForm, self).__init__(*a, **kw)
+        super (ReadOnlyRemunForm, self).__init__(*a, **kw)
         for field in self.fields:
             field = self.fields[field]
             if not isinstance(field.widget, (
@@ -353,7 +355,8 @@ class GroupedInlineFormset(BaseInlineFormSet):
         # 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))
+            tmp_extras.insert(0,
+        self._construct_form(self.initial_form_count() + i))
 
         for g in self.groups:
             for i in xrange(self.extra):
@@ -417,6 +420,7 @@ def remun_formset_factory(parent_model,
                           exclude=None,
                           can_order=False,
                           can_delete=True,
+                          read_only=False,
                           extra=2,
                           max_num=None,
                           formfield_callback=None,
@@ -441,6 +445,7 @@ def remun_formset_factory(parent_model,
     }
     FormSet = modelformset_factory(model, **kwargs)
     FormSet.fk = fk
+    FormSet.read_only = read_only
 
     def grouper(form):
         rtype = form.initial['type']
@@ -450,104 +455,83 @@ def remun_formset_factory(parent_model,
                 rtype.nature_remuneration
                 )
 
-    def __init__(inst, *a, **kw):
-        super(FormSet, inst).__init__(*a, **kw)
 
-        # 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 initial for all form type.
-        # for form, tr in zip(inst.forms, trs):
-        #     form.initial['type'] = tr
-
-        # # Set form grouping.
+    # Monkey patch FormSet.
+    def __init__(inst, *a, **kw):
+        super(inst.__class__, inst).__init__(*a, **kw)
         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,
-    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')
-                )
-            },
-        }
-    )
+def remun_formset_factory_factory(read_only=False):
+    """
+    Don't we love factory factories?
+    """
+    
+    null_choice = ('', '-' * 10)
+    extras = 2 if not read_only else 0
+    can_delete = False if read_only else True
+    form_class = ReadOnlyRemunForm if read_only else FlexibleRemunForm
+
+    return remun_formset_factory(
+        dae.Dossier,
+        dae.Remuneration,
+        form=form_class,
+        extra=extras,
+        can_delete=can_delete,
+        read_only=read_only,
+        groups = [
+            (u'Traitement', u'Traitement',),
+            (u'Indemnité', u'Indemnité',),
+            (u'Charges', u'Charges',),
+            (u'Accessoire', u'Accessoire',),
+            (u'RAS', u'Rémunération autre source',),
+            ],
+        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')
+                    )
+                },
+            u'RAS': {
+                'type': [null_choice] + list(
+                    rh.TypeRemuneration.objects.filter(
+                        nature_remuneration=u'RAS').values_list(
+                        'id', 'nom')
+                    )
+                },
+            }
+        )
 
-RemunForm = ReadOnlyRemunForm
+RemunForm = remun_formset_factory_factory(read_only=False)
+ReadOnlyRemunForm = remun_formset_factory_factory(read_only=True)
 
 
 class PosteForm(forms.ModelForm):
index 73ae79d..52b7ee8 100644 (file)
@@ -9,7 +9,9 @@
   <th>Annuel</th>
   <th>Annuel Euros</th>
   <th>Précision</th>
+  {% if not remunForm.read_only %}
   <th>Supprimer</th>
+  {% endif %}
 </tr>
 {% for group in remunForm.group_list %}
 {% if group.key != 'RAS' %}
     <td>{{ f.type.errors }} {{ f.type }}</td>
     <td>{{ f.devise.errors }} {{ f.devise }}</td>
     <td class="monnaie cumulable">{{ f.montant.errors }} {{ f.montant }}</td>
-    <td class="euro cumulable" id="{{ f.prefix }}-montant_annuel_euros"></td>
+    <td class="euro cumulable" id="id_{{ f.prefix }}-montant_annuel_euros"></td>
     <td>{{ f.commentaire.errors }} {{ f.commentaire }}</td>
+    {% if not remunForm.read_only %}
     <td>{{ f.DELETE }}</td>
+    {% endif %}
 </tr>
 {% endfor %}
 <tr class="sous-totaux">
-    <td>Sous-total -
-      <a class="addlink" href="/admin/dae/poste/add/">
+    <td>Sous-total{% if not remunForm.read_only %} - 
+      <a class="addlink" href="#">
        [<span class="icon">Ajouter une ligne</span>]
       </a>
+      {% endif %}
     </td>
     <td><!-- Laisser ce td pour que le javascript fonctionne bien. --></td>
     <td class="sous-total"></td>
     <td class="sous-total"></td>
-    <td colspan="2"></td>
+    <td>&nbsp;</td>
+    {% if not remunForm.read_only %}
+    <td>&nbsp;</td>
+    {% endif %}
 </tr>
 {% endif %}
 {% endfor %}
     <th><!-- Laisser ce td pour que le javascript fonctionne bien. --></th>
     <th class="total"></th>
     <th class="total"></th>
-    <th colspan="2"></th>
+    <th>&nbsp;</th>
+    {% if not remunForm.read_only %}
+    <th>&nbsp;</th>
+    {% endif %}
 </tr>
 <tr>
     <th><strong>Rémunération autre source</strong></th>
     <th><!-- Laisser ce td pour que le javascript fonctionne bien. --></th>
     <th></th>
     <th></th>
-    <th colspan="2"></th>
+    <th>&nbsp;</th>
+    {% if not remunForm.read_only %}
+    <th>&nbsp;</th>
+    {% endif %}
 </tr>
 {% for f in remunForm.groups.RAS.forms %}
 <tr class="calculable remunform">
     <td class="monnaie cumulable">{{ f.montant.errors }} {{ f.montant }}</td>
     <td class="euro cumulable" id="id_{{ f.prefix }}-montant_annuel_euros"></td>
     <td>{{ f.commentaire.errors }} {{ f.commentaire }}</td>
+    {% if not remunForm.read_only %}
     <td>{{ f.DELETE }}</td>
+    {% endif %}
 </tr>
 {% endfor %}
 <tr class="sous-totaux">
-    <td>Sous-total - 
+    <td>Sous-total{% if not remunForm.read_only %} - 
       <a class="addlink" href="#">
        [<span class="icon">Ajouter une ligne</span>]
       </a>
+      {% endif %}
     </td>
     <td><!-- Laisser ce td pour que le javascript fonctionne bien. --></td>
     <td class="sous-total"></td>
     <td class="sous-total"></td>
-    <td colspan="2"></td>
+    <td>&nbsp;</td>
+    {% if not remunForm.read_only %}
+    <td>&nbsp;</td>
+    {% endif %}
 </tr>
 </table>
index 2de99af..39fb195 100644 (file)
@@ -1 +1,3 @@
-{{ form.as_p }}
+<table cellspacing="0" id="global-cost">
+  {% include 'dae/embauche-remun.html' %}
+</table>
index b924683..53eeb99 100644 (file)
@@ -52,7 +52,7 @@ def tableau_remuneration(request, dossier_id):
     return render(
         request,
         'dae/table_remuneration.html', {
-            'form': form,
+            'remunForm': form,
             })
 
 
index 1ceda29..a9ffd7a 100644 (file)
@@ -1,17 +1,25 @@
 from django.utils.safestring import mark_safe
 from django.forms.widgets import Select, TextInput
+from django.db.models.query import QuerySet
 
 
-class ReadOnlyChoiceWidget(Select):
-    def render(self, name, value, attrs=None, choices=()):
-        try:
-            key = long(value)
-        except ValueError:
-            key = ''
+class ReadOnlyChoiceWidget(TextInput):
+    def __init__(self, *a, **kw):
+        choices = kw.pop('choices', [])
+        super(ReadOnlyChoiceWidget, self).__init__(*a, **kw)
+        self.choices = choices
+    
+    def render(self, name, value, attrs=None):
+        if isinstance(self.choices, QuerySet) and value:
+            display = self.choices.get(id=value)
+        elif value:
+            display = dict(self.choices)[value]
+        else:
+            display = ''
         return mark_safe(
-            '%(display)s</span><input type="hidden" '
-            'name="%(name)s" id="%(name)s" value="%(value)s" />' % {
-                'display': dict(self.choices)[key],
+            '%(display)s<input id="id_%(name)s" type="hidden" '
+            'name="%(name)s" value="%(value)s" />' % {
+                'display': display,
                 'name': name,
                 'value': value,
             })
@@ -20,7 +28,7 @@ class ReadOnlyChoiceWidget(Select):
 class ReadOnlyWidget(TextInput):
     def render(self, name, value, attrs=None):
         return mark_safe(
-            '%(display)s<input id="%(name)s" type="hidden" '
+            '%(display)s<input id="id_%(name)s" type="hidden" '
             'name="%(name)s" value="%(value)s" />' % {
                 'display': value,
                 'name': name,
index 802ad13..bd4769b 100644 (file)
@@ -225,7 +225,7 @@ LOGGING = {
     },
     'loggers': {
         'django.db.backends': {
-            'level': 'DEBUG',
+            'level': 'ERROR',
             'handlers': ['console'],
             'propagate': False,
         },