Merge remote-tracking branch 'origin/dev' into masse_salariale_jp
authorJean-Philippe Caissy <jpcaissy@piji.ca>
Wed, 21 Mar 2012 14:22:10 +0000 (09:22 -0500)
committerJean-Philippe Caissy <jpcaissy@piji.ca>
Wed, 21 Mar 2012 14:22:10 +0000 (09:22 -0500)
project/rh/masse_salariale.py [new file with mode: 0644]
project/rh/static/admin/js/jquery-stickytableheaders.js [new file with mode: 0644]
project/rh/templates/rh/rapports/masse_salariale.html [new file with mode: 0644]
project/rh/templates/rh/rapports/remuneration.html [deleted file]
project/rh/templatetags/rapports.py
project/rh/urls.py
project/rh/views.py

diff --git a/project/rh/masse_salariale.py b/project/rh/masse_salariale.py
new file mode 100644 (file)
index 0000000..ea5039f
--- /dev/null
@@ -0,0 +1,454 @@
+# -*- encoding: utf-8 -*-
+import time
+import datetime
+import csv
+import StringIO
+
+from django.db.models import Q
+
+from datamaster_modeles import models as ref
+import rh.models as rh
+
+
+KEY_DATE_DEBUT = "debut"
+KEY_DATE_FIN = "fin"
+
+TYPE_REMUN_BSTG = (3,)
+TYPE_REMUN_MAD = (2,)
+TYPE_REMUN_BASE = (1,)
+TYPE_REMUN_FONC_RESP = (7, 8)
+TYPE_REMUN_EXPAT = (4,)
+TYPE_REMUN_LOGEMENT = (6,)
+TYPE_REMUN_TRANSP = (9,)
+TYPE_REMUN_13E = (18,)
+TYPE_REMUN_AUTRE_RECURR_NOT = (1, 2, 3, 4, 6, 7, 8, 9, 18, 13, 14, 15, 19)
+TYPE_PAIEMENT_PONCTUEL = u"Ponctuel"
+TYPE_PRIME_INTERIM = (19,)
+TYPE_PRIME_INSTALLATION = (13,)
+TYPE_PRIME_DEMENAG = (15,)
+TYPE_PRIME_AVION = (14,)
+TYPE_NATURE_PAIEMENT = u"Accessoire"
+TYPE_NATURE_CHARGES = u"Charges"
+
+
+class MasseSalariale():
+    """ Rapport de la masse salariale. """
+
+    def __init__(self, date_debut, date_fin, custom_filter=None):
+        """ date_debut: date de début pour les données temporelles
+        date_fin: idem
+        custom_filter: dictionnaire des paramètres à passer au queryset.
+        """
+        if not date_debut and not date_fin:
+            return
+
+        date_debut = datetime.date(
+                *time.strptime(date_debut, "%d-%m-%Y")[0:3]
+        )
+        date_fin = datetime.date(*time.strptime(date_fin, "%d-%m-%Y")[0:3])
+        rapport_date_delta = date_fin - date_debut
+
+        self.annee = date_fin.year
+
+        self.devise_base = rh.Devise.objects.filter(code='EUR')[0]
+        self.taux_change = {}
+
+        q_range = self.build_qs("date_", date_debut, date_fin)
+        q_range_d = self.build_qs("dossier__date_", date_debut, date_fin)
+        remunerations = rh.Remuneration.objects.filter(q_range) \
+                .filter(q_range_d) \
+
+        if custom_filter:
+            remunerations = remunerations.filter(**custom_filter)
+
+        remunerations = remunerations.exclude(supprime=True) \
+                .select_related(
+                        "dossier", "dossier_employe", "dossier_poste", "type"
+                        )
+
+        employes = {}
+        for r in remunerations:
+            if r.dossier.employe_id not in employes:
+                employes[r.dossier.employe_id] = {
+                    'dossiers': set(),
+                    'remunerations': []
+                }
+            employes[r.dossier.employe_id]['remunerations'].append(r)
+            employes[r.dossier.employe_id]['dossiers'].add(r.dossier)
+
+        self.employes = employes
+
+        self.rapport = []
+
+        pays_list = {}
+        for pays in ref.Pays.objects.all():
+            pays_list[pays.id] = pays
+
+        valeurs_point_par_imp = \
+                dict(
+                    (v.implantation.id, v) for v in \
+                    rh.ValeurPoint.objects.filter(annee=self.annee).all()
+                )
+
+        self.headers = (
+                ('bureau', u"Bureau"),
+                ('pays', u"Pays"),
+                ('implantation', u"Implantation"),
+                ('valeur_point', u"Valeur du point"),
+                ('numero_employe', u"Numéro d'employé"),
+                ('nom', u"Nom"),
+                ('prenom', u"Prénom"),
+                ('type_de_poste', u"Type de poste"),
+                ('intitule_de_poste', u"Intitulé du poste"),
+                ('niveau', u"Niveau"),
+                ('point', u"Point"),
+                ('regime_de_travail', u"Régime de travail"),
+                ('local_expatrie', u"Local / Expatrié"),
+                ('statut', u"Statut"),
+                ('date_fin_contrat', u"Date de fin de contrat"),
+                ('date_debut', u"Date de début"),
+                ('date_fin', u"Date de fin"),
+                ('nb_jours', u"Nombre de jours"),
+                ('devise', u"Devise"),
+                ('salaire_bstg_annuel', u"Salaire annuel BSTG"),
+                ('salaire_bstg_total', u"Salaire total BSTG"),
+                ('organisme_bstg', u"Organisme BSTG"),
+                ('salaire_theorique', u"Salaire théorique"),
+                ('salaire_base_brut', u"Salaire de base brut"),
+                ('salaire_complementaire', u"Salaire complémentaire"),
+                ('indemnite_fonctions', u"Indemnités de fonctions"),
+                ('indemnite_expat', u"Indemnités d'expatriation"),
+                ('indemnite_logement', u"Indemnités de logement"),
+                ('indemnite_transp', u"Indemnités de transport"),
+                ('indemnite_13e', u"Indemnités 13e mois"),
+                ('indemnite_autre', u"Autre indemnités"),
+                ('total_brut', u"Total brut"),
+                ('prime_interim', u"Prime d'intérim"),
+                ('prime_installation', u"Prime d'installation"),
+                ('prime_demenagement', u"Prime de déménagement"),
+                ('prime_avion', u"Prime d'avion"),
+                ('prime_autre', u"Autre prime"),
+                ('prime_total', u"Total des primes"),
+                ('charges_patronales', u"Charges patronales"),
+                ('charges_patronales_annee', u"Charge patronale %s" % \
+                        self.annee),
+                ('masse_salariale', u"Masse salariale"),
+                ('masse_salariale_annee', u"Masse salariale %s" % self.annee),
+                ('masse_salariale_annee_euro', u"Masse salariale euro %s" % \
+                        self.annee),
+        )
+
+        for item in self.employes.values():
+            dossiers = item['dossiers']
+            remuns = item['remunerations']
+            #TODO, choisir le dossier primaire
+            if len(dossiers) > 1:
+                #TODO
+                pass
+            dossier = list(dossiers)[0]
+            regime = float(dossier.poste.regime_travail) / 100
+
+            if dossier.poste.expatrie:
+                statut = "E"
+            else:
+                statut = "L"
+
+            #on détermine la date du début et fin du dossier si année en cours
+            try:
+                d_date_fin = dossier.date_fin \
+                        if dossier.date_fin.year == date_fin.year else None
+            except AttributeError:
+                d_date_fin = None
+            try:
+                d_date_debut = dossier.date_debut \
+                    if dossier.date_debut.year == date_fin.year else None
+            except AttributeError:
+                d_date_debut = None
+
+            pays = \
+                pays_list[dossier.poste.implantation.adresse_physique_pays.id]
+
+            #on détermine si les rémunérations sont tous dans la même devise
+            devise = remuns[0].devise
+            meme_devise = True
+            for r in remuns[1:]:
+                if devise != r.devise:
+                    meme_devise = False
+
+            if not meme_devise:
+                for r in remuns:
+                    self.convertir(r)
+
+            bstg_dossier = None
+            for d in dossiers:
+                if d.organisme_bstg:
+                    bstg_dossier = d
+
+            bstg_remun = None
+            if bstg_dossier:
+                for r in bstg_dossier.rh_remunerations.all():
+                    if r.type.id in TYPE_REMUN_BSTG:
+                        bstg_remun = r
+
+            if bstg_remun:
+                bstg_remun_euro = rh.Remuneration(
+                        montant=bstg_remun.montant, devise=bstg_remun.devise
+                )
+                self.convertir(bstg_remun_euro)
+
+            salaire_complement = 0.0
+            salaire_base = 0.0
+            indemnites = {
+                    'fonc_resp': 0.0,
+                    'expat': 0.0,
+                    'logement': 0.0,
+                    'transp': 0.0,
+                    '13e': 0.0,
+                    'autre_recurr': 0.0,
+            }
+
+            primes = {
+                    'interim': 0.0,
+                    'installation': 0.0,
+                    'demenagement': 0.0,
+                    'avion': 0.0,
+                    'autre': 0.0,
+                }
+            charges = 0.0
+            for r in remuns:
+                montant = float(r.montant)
+
+                if r.type_id in TYPE_REMUN_MAD:
+                    salaire_complement += montant
+
+                if r.type_id in TYPE_REMUN_BASE:
+                    salaire_base += montant
+
+                if r.type_id in TYPE_REMUN_FONC_RESP:
+                    indemnites['fonc_resp'] += montant
+
+                if r.type_id in TYPE_REMUN_EXPAT:
+                    indemnites['expat'] += montant
+
+                if r.type_id in TYPE_REMUN_LOGEMENT:
+                    indemnites['logement'] += montant
+
+                if r.type_id in TYPE_REMUN_TRANSP:
+                    indemnites['transp'] += montant
+
+                if r.type_id in TYPE_REMUN_13E:
+                    indemnites['13e'] += montant
+
+                if r.type_id not in TYPE_REMUN_AUTRE_RECURR_NOT \
+                        and r.type.type_paiement != TYPE_PAIEMENT_PONCTUEL:
+                    indemnites['autre_recurr'] += montant
+
+                if r.type_id in TYPE_PRIME_INTERIM:
+                    primes['interim'] += montant
+
+                if r.type_id in TYPE_PRIME_INSTALLATION:
+                    primes['installation'] += montant
+
+                if r.type_id in TYPE_PRIME_DEMENAG:
+                    primes['demenagement'] += montant
+
+                if r.type_id in TYPE_PRIME_AVION:
+                    primes['avion'] += montant
+
+                if r.type_id not in TYPE_REMUN_AUTRE_RECURR_NOT and \
+                        r.type.nature_remuneration == TYPE_NATURE_PAIEMENT:
+                    primes['autre'] += montant
+
+                if r.type.nature_remuneration == TYPE_NATURE_CHARGES:
+                    charges += montant
+
+            total_indemnites = sum(indemnites.values())
+
+            #Calcul du nombre de jours pour ce dossier.
+            if dossier.date_debut and dossier.date_debut > date_debut and \
+                    not dossier.date_fin:
+                date_delta = date_fin - dossier.date_fin
+            elif dossier.date_fin and dossier.date_fin < date_fin and \
+                    not dossier.date_debut:
+                date_delta = dossier.date_fin - date_debut
+            elif dossier.date_fin and dossier.date_debut:
+                date_delta = dossier.date_fin - date_debut
+            else:
+                date_delta = rapport_date_delta
+
+            masse_salariale = (salaire_base + total_indemnites + \
+                            sum(primes.values()) + charges)
+            masse_salariale_euro = rh.Remuneration(montant=masse_salariale,
+                        devise=remuns[0].devise)
+            self.convertir(masse_salariale_euro)
+
+            if dossier.classement and dossier.classement.coefficient:
+                coefficient = dossier.classement.coefficient
+            else:
+                coefficient = ""
+
+            #todo valeur du point si pas présent
+            valeur_point = valeurs_point_par_imp.get(
+                    dossier.poste.implantation_id
+                ) or ""
+
+            salaire_theorique = "%s" % (
+                    round(valeur_point.valeur * int(coefficient) * regime, 2) \
+                    if valeur_point and coefficient and regime else "")
+
+            item_rapport = {
+                    'bureau': dossier.poste.implantation.region.code,
+                    'pays': unicode(pays),
+                    'implantation': dossier.poste.implantation.nom_court,
+                    'type_implantation': dossier.poste.implantation.type,
+                    #'imputation': None,
+                    'valeur_point': valeur_point,
+                    'numero_employe': dossier.employe_id,
+                    'nom': dossier.employe.nom.upper(),
+                    'prenom': dossier.employe.prenom,
+                    'type_de_poste': dossier.poste.type_poste.nom,
+                    'intitule_de_poste': dossier.poste.nom,
+                    'niveau': unicode(dossier.classement),
+                    'point': coefficient,
+                    'regime_de_travail': "%s %%" % int(regime * 100),
+                    'local_expatrie': statut,
+                    'statut': dossier.statut.code,
+                    'date_fin_contrat': dossier.date_fin or "",
+                    'date_debut': d_date_debut or "",
+                    'date_fin': d_date_fin or "",
+                    'nb_jours': date_delta.days,
+                    'devise': remuns[0].devise,
+                    'salaire_bstg_annuel': bstg_remun.montant \
+                            if bstg_remun else "",
+                    'salaire_bstg_total': bstg_remun_euro.montant \
+                            if bstg_remun else "",
+                    'organisme_bstg': dossier.organisme_bstg or "",
+                    'salaire_theorique': salaire_theorique,
+                    'salaire_base_brut': \
+                            salaire_base * regime * (
+                                date_delta.days / rapport_date_delta.days
+                            ),
+                    'salaire_complementaire': \
+                            salaire_complement * regime * (
+                                date_delta.days / rapport_date_delta.days
+                            ),
+                    #'salaire_total': None
+                    'indemnite_fonctions': indemnites['fonc_resp'] * \
+                            regime * \
+                            (date_delta.days / rapport_date_delta.days),
+                    'indemnite_expat': indemnites['expat'] * regime * \
+                            (date_delta.days / rapport_date_delta.days),
+                    'indemnite_logement': indemnites['logement'] * \
+                            regime * \
+                            (date_delta.days / rapport_date_delta.days),
+                    'indemnite_transp': indemnites['transp'] * regime * \
+                            (date_delta.days / rapport_date_delta.days),
+                    'indemnite_13e': indemnites['13e'] * regime * \
+                            (date_delta.days / rapport_date_delta.days),
+                    'indemnite_autre': indemnites['autre_recurr'] * \
+                            regime * \
+                            (date_delta.days / rapport_date_delta.days),
+                    'indemnite_total': total_indemnites * regime * \
+                            (date_delta.days / rapport_date_delta.days),
+                    'total_brut': (
+                                total_indemnites + salaire_base +
+                                salaire_complement
+                            ) * regime * (
+                                date_delta.days / rapport_date_delta.days
+                            ),
+                    'prime_interim': primes['interim'] * regime * \
+                            (date_delta.days / rapport_date_delta.days),
+                    'prime_installation': primes['installation'] * regime * \
+                            (date_delta.days / rapport_date_delta.days),
+                    'prime_demenagement': primes['demenagement'] * regime * \
+                            (date_delta.days / rapport_date_delta.days),
+                    'prime_avion': primes['avion'] * regime * \
+                            (date_delta.days / rapport_date_delta.days),
+                    'prime_autre': primes['autre'] * regime * \
+                            (date_delta.days / rapport_date_delta.days),
+                    'prime_total': sum(primes.values()) * regime * \
+                            (date_delta.days / rapport_date_delta.days),
+                    'charges_patronales': charges,
+                    'charges_patronales_annee': charges * regime * \
+                            (date_delta.days / rapport_date_delta.days),
+                    'masse_salariale': masse_salariale,
+                    'masse_salariale_annee': masse_salariale * \
+                            regime * (
+                                    date_delta.days / rapport_date_delta.days
+                             ),
+                     'masse_salariale_annee_euro': \
+                            masse_salariale_euro.montant * regime * (
+                                    date_delta.days / rapport_date_delta.days
+                            ),
+            }
+
+            self.rapport.append(item_rapport)
+
+    def build_qs(self, prefix, date_debut, date_fin):
+        date_debut_null = \
+                Q(**{"%s%s__isnull" % (prefix, KEY_DATE_DEBUT): True})
+        date_fin_null = \
+                Q(**{"%s%s__isnull" % (prefix, KEY_DATE_FIN): True})
+        date_debut_superieure_ou_egale_a_borne_gauche = \
+                Q(**{"%s%s__gte" % (prefix, KEY_DATE_DEBUT): date_debut})
+        date_debut_inferieure_ou_egale_a_borne_gauche = \
+                Q(**{"%s%s__lte" % (prefix, KEY_DATE_DEBUT): date_debut})
+        date_fin_superieure_ou_egale_a_borne_gauche = \
+                Q(**{"%s%s__gte" % (prefix, KEY_DATE_FIN): date_debut})
+        date_fin_inferieure_ou_egale_a_borne_droite = \
+                Q(**{"%s%s__lte" % (prefix, KEY_DATE_FIN): date_fin})
+        date_debut_inferieure_ou_egale_a_borne_droite = \
+                Q(**{"%s%s__lte" % (prefix, KEY_DATE_DEBUT): date_fin})
+        date_fin_superieure_ou_egale_a_borne_droite = \
+                Q(**{"%s%s__gte" % (prefix, KEY_DATE_FIN): date_fin})
+
+        q_range = \
+            (
+                date_debut_null & date_fin_null
+            ) | (
+                date_debut_inferieure_ou_egale_a_borne_gauche &
+                date_fin_superieure_ou_egale_a_borne_gauche &
+                date_fin_inferieure_ou_egale_a_borne_droite
+            ) | (
+                date_debut_superieure_ou_egale_a_borne_gauche &
+                date_debut_inferieure_ou_egale_a_borne_droite &
+                date_fin_superieure_ou_egale_a_borne_droite
+            ) | (
+                date_debut_inferieure_ou_egale_a_borne_gauche &
+                date_fin_superieure_ou_egale_a_borne_droite
+            ) | (
+                date_debut_null &
+                date_fin_superieure_ou_egale_a_borne_droite
+            ) | (
+                date_debut_inferieure_ou_egale_a_borne_gauche &
+                date_fin_null
+            )
+
+        return q_range
+
+    def convertir(self, remuneration):
+        if remuneration.devise != self.devise_base:
+            remuneration.montant = float(remuneration.montant) * \
+                self.trouver_taux(remuneration.devise).taux
+            remuneration.devise = self.devise_base
+
+    def trouver_taux(self, devise):
+        if devise.code not in self.taux_change:
+            t = rh.TauxChange.objects.filter(
+                    devise=devise, annee=self.annee
+            )[0]
+            self.taux_change[devise.code] = t
+        return self.taux_change[devise.code]
+
+    def csv(self):
+        self.csv_handle = StringIO.StringIO()
+        csv_writer = csv.writer(self.csv_handle, delimiter=",",
+                doublequote=False, escapechar="\\", quoting=csv.QUOTE_ALL,
+        )
+        header = [v[0] for v in self.rapport[0]]
+        csv_writer.writerow(header)
+        for row in self.rapport:
+            values = [v[1] for v in row]
+            csv_writer.writerow(
+                    [unicode(r).encode('utf-8') for r in values]
+            )
diff --git a/project/rh/static/admin/js/jquery-stickytableheaders.js b/project/rh/static/admin/js/jquery-stickytableheaders.js
new file mode 100644 (file)
index 0000000..9f55aa7
--- /dev/null
@@ -0,0 +1,116 @@
+
+/*! Copyright (c) 2011 by Jonas Mosbech - https://github.com/jmosbech/StickyTableHeaders 
+    MIT license info: https://github.com/jmosbech/StickyTableHeaders/blob/master/license.txt */
+
+(function ($) {
+    $.StickyTableHeaders = function (el, options) {
+        // To avoid scope issues, use 'base' instead of 'this'
+        // to reference this class from internal events and functions.
+        var base = this;
+
+        // Access to jQuery and DOM versions of element
+        base.$el = $(el);
+        base.el = el;
+
+        // Cache DOM refs for performance reasons
+        base.$window = $(window);
+        base.$clonedHeader = null;
+        base.$originalHeader = null;
+
+        // Add a reverse reference to the DOM object
+        base.$el.data('StickyTableHeaders', base);
+
+        base.init = function () {
+            base.options = $.extend({}, $.StickyTableHeaders.defaultOptions, options);
+
+            base.$el.each(function () {
+                var $this = $(this);
+
+                // remove padding on <table> to fix issue #7
+                $this.css('padding', 0);
+
+                $this.wrap('<div class="divTableWithFloatingHeader"></div>');
+
+                base.$originalHeader = $('thead:first', this);
+                base.$clonedHeader = base.$originalHeader.clone();
+
+                base.$clonedHeader.addClass('tableFloatingHeader');
+                base.$clonedHeader.css({
+                    'position': 'fixed',
+                    'top': 0,
+                    'left': $this.css('margin-left'),
+                    'display': 'none'
+                });
+
+                base.$originalHeader.addClass('tableFloatingHeaderOriginal');
+                
+                base.$originalHeader.before(base.$clonedHeader);
+
+                // enabling support for jquery.tablesorter plugin
+                // forward clicks on clone to original
+                $('th', base.$clonedHeader).click(function(e){
+                    var index = $('th', base.$clonedHeader).index(this);
+                    $('th', base.$originalHeader).eq(index).click();
+                });
+                $this.bind('sortEnd', base.updateCloneFromOriginal );
+            });
+
+            base.updateTableHeaders();
+            base.$window.scroll(base.updateTableHeaders);
+            base.$window.resize(base.updateTableHeaders);
+        };
+
+        base.updateTableHeaders = function () {
+            base.$el.each(function () {
+                var $this = $(this);
+
+                var fixedHeaderHeight = isNaN(base.options.fixedOffset) ? base.options.fixedOffset.height() : base.options.fixedOffset;
+
+                var offset = $this.offset();
+                var scrollTop = base.$window.scrollTop() + fixedHeaderHeight;
+                var scrollLeft = base.$window.scrollLeft();
+
+                if ((scrollTop > offset.top) && (scrollTop < offset.top + $this.height())) {
+                    base.$clonedHeader.css({
+                        'top': fixedHeaderHeight,
+                        'margin-top': 0,
+                        'left': offset.left - scrollLeft,
+                        'display': 'block'
+                    });
+
+                    base.updateCloneFromOriginal();
+                }
+                else {
+                    base.$clonedHeader.css('display', 'none');
+                }
+            });
+        };
+
+        base.updateCloneFromOriginal = function () {
+            // Copy cell widths and classes from original header
+            $('th', base.$clonedHeader).each(function (index) {
+                var $this = $(this);
+                var origCell = $('th', base.$originalHeader).eq(index);
+                $this.removeClass().addClass(origCell.attr('class'));
+                $this.css('width', origCell.width());
+            });
+
+            // Copy row width from whole table
+            base.$clonedHeader.css('width', base.$originalHeader.width());
+        };
+
+        // Run initializer
+        base.init();
+    };
+
+    $.StickyTableHeaders.defaultOptions = {
+        fixedOffset: 0
+    };
+
+    $.fn.stickyTableHeaders = function (options) {
+        return this.each(function () {
+            (new $.StickyTableHeaders(this, options));
+        });
+    };
+
+})(jQuery);
diff --git a/project/rh/templates/rh/rapports/masse_salariale.html b/project/rh/templates/rh/rapports/masse_salariale.html
new file mode 100644 (file)
index 0000000..c4515ca
--- /dev/null
@@ -0,0 +1,42 @@
+{% extends 'rh/rapports/base.html' %}
+{% load adminmedia rapports i18n %}
+
+{% block nomrapport %}Rapport Postes{% endblock %}
+{% block count_elements %}<h2>{{ count }} postes</h2>{% endblock %}
+
+{% block extrastyle %}
+{{ block.super }}
+<script type="text/javascript" src="{{ STATIC_URL }}js/jquery-1.5.1.min.js"></script>
+<script type="text/javascript" src="{% admin_media_prefix %}js/jquery-stickytableheaders.js"></script>
+{% endblock %}
+
+{% block contentrapport %}
+{% comment %}
+<div id="changelist-filter">
+<h2>{% trans 'Filter' %}</h2>
+{% filter_region "dossier__poste__" %}
+{% filter_implantation "dossier__poste__" %}
+</div>
+{% endcomment %}
+<script type="text/javascript">
+    jQuery(document).ready(function(){
+        $("#result_list").stickyTableHeaders();
+    });
+</script>
+<table id="result_list" class="results">
+<thead>
+<tr>
+    {% table_header headers %}
+</tr>
+</thead>
+{% spaceless %}
+{% for row in rapport %}
+    <tr class="{% cycle 'row1' 'row2' %}">
+        {% for column in header_keys %}
+            <td>{{ row|hash:column }}</td>
+        {% endfor %}
+    </tr>
+{% endfor %}{% endspaceless %}
+</table>
+
+{% endblock %}
diff --git a/project/rh/templates/rh/rapports/remuneration.html b/project/rh/templates/rh/rapports/remuneration.html
deleted file mode 100644 (file)
index 3ad5e08..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-{% extends 'rh/rapports/base.html' %}
-{% load adminmedia rapports i18n %}
-
-{% block nomrapport %}Rapport de rémunération{% endblock %}
-
-{% block contentrapport %}
-
-<div id="changelist-filter">
-<h2>{% trans 'Filter' %}</h2>
-{% filter_region_remun %}
-{% filter_implantation_remun %}
-</div>
-
-<table id="result_list">
-<thead>
-<tr>
-    {% table_header headers %}
-</tr>
-</thead>
-{% spaceless %}{% for employe in employes %}
-<tr class="{% cycle 'row1' 'row2' %}">
-    <td style="text-align:right"><a href="{% url admin:rh_employe_change employe.id %}">{{ employe.id }}</a></td>
-    <td><a href="{% url admin:rh_employe_change employe.id %}">{{ employe.nom|upper }}</td></a>
-    <td><a href="{% url admin:rh_employe_change employe.id %}">{{ employe.prenom }}</a></td>
-       <td align="right">{{ employe.Traitement|default:0|floatformat:2 }} &euro;</td>
-       <td align="right">{{ employe.RAS|default:0|floatformat:2 }} &euro;</td>
-       <td align="right">{{ employe.Indemnite|default:0|floatformat:2 }} &euro;</td>
-       <td align="right">{{ employe.Accessoire|default:0|floatformat:2 }} &euro;</td>
-       <td align="right">{{ employe.Charges|default:0|floatformat:2 }} &euro;</td>
-       <td align="right">{{ employe.remun_sum_euro|default:0|floatformat:2 }} &euro;</td>
-</tr>
-{% endfor %}{% endspaceless %}
-</table>
-
-{% endblock %}
index cc7f828..218a8b0 100644 (file)
@@ -23,15 +23,19 @@ def filter_comble(context):
 
 
 @register.inclusion_tag('admin/filter.html', takes_context=True)
-def filter_region(context):
+def filter_region(context, prefix=None):
+
+    label = "".join([prefix or "", "implantation__region"])
     return {'title': u"région",
-            'choices': prepare_choices(Region.objects.values_list('id', 'nom'), 'implantation__region', context, remove=['pays', 'nord_sud'])}
+            'choices': prepare_choices(Region.objects.values_list('id', 'nom'), label, context, remove=['pays', 'nord_sud'])}
 
 
 @register.inclusion_tag('admin/filter.html', takes_context=True)
-def filter_implantation(context):
+def filter_implantation(context, prefix=None):
+
+    label = "".join([prefix or "", "implantation"])
     return {'title': u"implantation",
-            'choices': prepare_choices(Implantation.objects.values_list('id', 'nom'), 'implantation', context)}
+            'choices': prepare_choices(Implantation.objects.values_list('id', 'nom'), label, context)}
 
 
 @register.inclusion_tag('admin/filter.html', takes_context=True)
@@ -220,3 +224,10 @@ class SortHeaders:
 @register.filter
 def split(str, splitter):
     return str.split(splitter)
+
+@register.filter
+def hash(h,key):
+    if key in h:
+        return h[key]
+    else:
+        raise Exception("%s does not exist" % key)
index cf676a7..65dc300 100644 (file)
@@ -8,6 +8,7 @@ urlpatterns = patterns(
     url(r'^admin/rh/rapports/employes_sans_contrats$', 'rapports_employe_sans_contrat', name='rhr_employe_sans_contrat'),
     url(r'^admin/rh/rapports/contrats$', 'rapports_contrat', name='rhr_contrats'),
     url(r'^admin/rh/rapports/remuneration$', 'rapports_remuneration', name='rhr_remuneration'),
+    url(r'^admin/rh/rapports/masse_salariale$', 'rapports_masse_salariale', name='rhr_masse_salariale'),
     url(r'^admin/rh/rapports/postes_par_service$', 'rapports_postes_service', name='rhr_postes_service'),
     url(r'^admin/rh/rapports/postes_par_implantation$', 'rapports_postes_implantation', name='rhr_postes_implantation'),
     url(r'^admin/rh/rapports/postes_modelisation$', 'rapports_postes_modelisation', name='rhr_postes_modelisation'),
index 914b269..8b2e155 100644 (file)
@@ -21,6 +21,7 @@ from rh.decorators import drh_or_admin_required
 from rh.templatetags.rapports import SortHeaders
 from rh.change_list import RechercheTemporelle
 from rh import graph as rh_graph
+from rh.masse_salariale import MasseSalariale
 
 # pas de reference a DAE devrait etre refactorisé
 from dae.utils import get_employe_from_user
@@ -195,6 +196,37 @@ def rapports_contrat(request):
 
 @login_required
 @drh_or_admin_required
+def rapports_masse_salariale(request):
+
+    date_debut = request.GET.get("date_debut", None)
+    date_fin = request.GET.get("date_fin", None)
+
+    implantation = request.GET.get('dossier__poste__implantation')
+    region = request.GET.get('dossier__poste__implantation__region')
+
+    custom_filter = {}
+    if implantation:
+        custom_filter['dossier__poste__implantation'] = implantation
+    if region:
+        custom_filter['dossier__poste__implantation__region'] = region
+
+    c = {
+            'headers': [],
+    }
+    if date_debut or date_fin:
+        masse = MasseSalariale(date_debut, date_fin, custom_filter)
+        if masse.rapport:
+            c['rapport'] = masse.rapport
+            headers = masse.headers
+            c['header_keys'] = [h[0] for h in masse.headers]
+            h = SortHeaders(request, headers, order_field_type="ot", order_field="o")
+            c['headers'] = list(h.headers())
+
+    return render_to_response('rh/rapports/masse_salariale.html', c, RequestContext(request))
+
+
+@login_required
+@drh_or_admin_required
 def rapports_remuneration(request):
 
     lookup_params = dict(request.GET.items())
@@ -567,4 +599,3 @@ def organigrammes_region(request, id):
     }
 
     return render_to_response('rh/organigrammes/vide.html', c, RequestContext(request), mimetype="image/svg+xml")
-