Debut de refactoring
authorBenoit C. Sirois <benoit.clennett-sirois@auf.org>
Wed, 13 Feb 2013 22:55:40 +0000 (17:55 -0500)
committerBenoit C. Sirois <benoit.clennett-sirois@auf.org>
Wed, 13 Feb 2013 22:55:40 +0000 (17:55 -0500)
project/assets/js/dae-embauche.js
project/dae/forms.py
project/dae/templates/dae/embauche-remun.html
project/dae/templates/dae/embauche.html
project/dae/views.py
project/dae/widgets.py [new file with mode: 0644]

index 557488a..28b1b5b 100644 (file)
@@ -41,59 +41,57 @@ function remun_line(input) {
   var prefix = idParts[0] + "-" + idParts[1];
   var field = idParts[2];
 
-  var montant_mensuel = $('#' + prefix + '-montant_mensuel');
   var montant_annuel = $('#' + prefix + '-montant');
-  var montant_mensuel_euros = $('#' + prefix + '-montant_mensuel_euros');
   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_mensuel.val(''); 
     montant_annuel.val(''); 
-    montant_mensuel_euros.val(''); 
     montant_annuel_euros.val(''); 
     return;
   }
 
-  if (input.attr('id') == montant_mensuel.attr('id') && montant_mensuel.val() != 0) {
-    value = (montant_mensuel.val() * 12);
-  }
-  else {
-    value = (montant_annuel.val());
-  }
+  value = (montant_annuel.val());
   value = roundNumber(value, 2)
 
-  montant_mensuel.val(roundNumber((value / 12), 2));
   montant_annuel.val(roundNumber(value, 0));
 
   var devise = $('#' + prefix + '-devise').val();
   var taux = parseFloat(DEVISES[devise]);
   if (isNaN(taux)) taux = 0;
-  montant_mensuel_euros.text(roundNumber((value / 12 * taux), 2))
   montant_annuel_euros.text(roundNumber((value * taux), 0))
   
 }
 
-function remun_totaux() {
-    $('#global-cost input[type="text"]').each(function() {
-        remun_line($(this));
+function totalByIndex(selector, prevUntil, prevAll) {
+    $(selector).each(function(){
+    var subtot = 0;
+    var i = $(this).index();
+    if (prevUntil !== undefined && prevUntil !== null && prevUntil !== false) {
+       var prevs = $(this).parent('tr').prevUntil(prevUntil);
+    } else if (prevAll !== undefined && prevAll !== null && prevAll !== false) {
+       var prevs = $(this).parent('tr').prevAll(prevAll);
+    }
+    prevs.each(function(){
+       var cell = $($(this).children('td')[i]);
+       var val;
+       if (cell.children('input').length == 1) {
+           val = cell.children('input').val();
+       } else {
+           val = cell.html();
+       }
+       subtot += clean_float(val);
     });
-
-    var total_cout = 0;
-    $("tr.cout td.cumulable").each(function() {
-        total_cout += clean_float($(this).html());
+    $(this).html(subtot);
     });
-    $("#sous-total-cout").html(total_cout);
+}
 
-    var total_aide = 0;
-    $("tr.aide td.cumulable").each(function() {
-        total_aide += clean_float($(this).html());
+function remun_totaux() {
+    $('#global-cost input[type="text"]').each(function() {
+        remun_line($(this));
     });
-    $("#sous-total-aide").html(total_aide);
-
-    var total = total_cout + total_aide;
-    $("#remun-total").html(total);
-
+    totalByIndex('#global-cost td.sous-total', ':not(.calculable)', null)
+    totalByIndex('#global-cost th.total', null, '.sous-totaux')
 }
 
 
@@ -147,7 +145,7 @@ $(document).ready(function() {
 
     /* totaux remu */
     $('#global-cost input, #global-cost select').change(function() {
-        remun_line($(this));
+        // remun_line($(this));
         remun_totaux();
     });
 
index c409c9b..5d31886 100644 (file)
@@ -4,7 +4,11 @@ import datetime
 from django import forms
 from django.core.urlresolvers import reverse
 from django.forms.models import BaseInlineFormSet
-from django.forms.models import inlineformset_factory, modelformset_factory
+from django.forms.models import (
+    inlineformset_factory,
+    modelformset_factory,
+    _get_foreign_key,
+    )
 from django.db.models import Q, Max, Count
 from django.shortcuts import redirect
 from django.contrib.admin import widgets as admin_widgets
@@ -18,6 +22,7 @@ from auf.django.workflow.models import WorkflowCommentaire
 from project import groups
 from project.rh import models as rh
 from project.dae import models as dae
+from .widgets import ReadOnlyChoiceWidget
 from project.dae.workflow import POSTE_ETATS_BOUTONS, POSTE_ETAT_FINALISE
 
 
@@ -255,6 +260,10 @@ class FlexibleRemunForm(forms.ModelForm):
     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':
@@ -271,9 +280,92 @@ class FlexibleRemunForm(forms.ModelForm):
         else:
             return devise
 
-RemunForm = inlineformset_factory(
-    dae.Dossier, dae.Remuneration, extra=5, form=FlexibleRemunForm
-)
+
+class GroupedInlineFormset(BaseInlineFormSet):
+
+    def set_groups(self, group_accessor):
+        """
+        group_accessor: A function that will get the key and name from
+        each form.
+        """
+
+        # Build group list.
+        self.groups = {}
+        # self.groups_and_forms = []
+        for form in self.forms:
+            group_key, group_name = group_accessor(form)
+            if not self.groups.has_key(group_key):
+                self.groups[group_key] = {
+                    'name': group_name,
+                    'forms': [],
+                    }
+            self.groups[group_key]['forms'].append(form)
+        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,
+                          max_num=None,
+                          formfield_callback=None):
+    """
+    Returns an ``InlineFormSet`` for the given kwargs.
+
+    You must provide ``fk_name`` if ``model`` has more than one ``ForeignKey``
+    to ``parent_model``.
+    """
+    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
+
+    def grouper(form):
+        if 'type' in form.initial and form.initial['type']:
+            return (form.initial['type'].nature_remuneration,
+                    form.initial['type'].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,
+                }
+
+        # Set form grouping.
+        inst.set_groups(grouper)
+
+    FormSet.__init__ = __init__
+
+    return FormSet
+
+
+RemunForm = remun_formset_factory(
+    dae.Dossier, dae.Remuneration, form=FlexibleRemunForm
+    )
 
 
 class PosteForm(forms.ModelForm):
index c509243..74df855 100644 (file)
@@ -6,26 +6,41 @@
 <tr>
   <th>Type</th>
   <th>Devise locale</th>
-  <th>Mensuel</th>
   <th>Annuel</th>
-  <th>Mensuel Euros</th>
   <th>Annuel Euros</th>
   <th>Précision</th>
   <th>Supprimer</th>
 </tr>
-{% for f in remunForm.forms %}
+{% for group in remunForm.group_list %}
 <tr>
+  <th colspan="6">{{ group.name }}</th>
+</tr>
+{% for f in group.forms %}
+<tr class="calculable">
     {{ f.id }}
     <td>{{ f.type.errors }} {{ f.type }}</td>
     <td>{{ f.devise.errors }} {{ f.devise }}</td>
-    <td>{{ f.montant_mensuel.errors }} {{ f.montant_mensuel }}</td>
-    <td>{{ f.montant.errors }} {{ f.montant }}</td>
-    <td id="id_{{ f.prefix }}-montant_mensuel_euros"></td>
-    <td id="id_{{ f.prefix }}-montant_annuel_euros"></td>
+    <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>
     <td>{{ f.DELETE }}</td>
 </tr>
 {% endfor %}
+<tr class="sous-totaux">
+    <td>Sous-total</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>
+</tr>
+{% endfor %}
+<tr>
+    <th><strong>Total</strong></th>
+    <th><!-- Laisser ce td pour que le javascript fonctionne bien. --></th>
+    <th class="total"></th>
+    <th class="total"></th>
+    <th colspan="2"></th>
+</tr>
 </table>
 
 {% comment %}
index ab36845..43aed1c 100644 (file)
@@ -12,7 +12,7 @@
   <script type="text/javascript">
     var DEVISES = {};
     {% for d in devises %}
-    DEVISES['{{d.devise_code}}'] = {{d.taux_euro}};
+    DEVISES['{{d.devise_code}}'] = {{d.taux_euro|stringformat:"f"}};
     {% endfor %}
   </script>
 
index 642baf9..53faea2 100644 (file)
@@ -439,6 +439,7 @@ def embauche(request, key=None, dossier_id=None):
                 request.user
             )
         )
+        
         remunForm = RemunForm(request.POST, instance=dossier)
 
         if employe_form.is_valid() and \
diff --git a/project/dae/widgets.py b/project/dae/widgets.py
new file mode 100644 (file)
index 0000000..076123c
--- /dev/null
@@ -0,0 +1,13 @@
+from django.utils.safestring import mark_safe
+from django.forms.widgets import Select
+
+
+class ReadOnlyChoiceWidget(Select):
+    def render(self, name, value, attrs=None, choices=()):
+        return mark_safe(
+            '<span>%(display)s</span><input type="hidden" '
+            'name="%(name)s" value="%(value)s" />' % {
+                'display': dict(self.choices)[value],
+                'name': name,
+                'value': value,
+            })