Merge remote-tracking branch 'origin/dev' into masse_salariale_jp
[auf_rh_dae.git] / project / rh / masse_salariale.py
CommitLineData
98d6eb6c
JPC
1# -*- encoding: utf-8 -*-
2import time
3import datetime
899aea3b
JPC
4import csv
5import StringIO
07f120f3 6import itertools
98d6eb6c
JPC
7
8from django.db.models import Q
9
10from datamaster_modeles import models as ref
c99116c3 11import rh.ods as ods
98d6eb6c
JPC
12import rh.models as rh
13
14
15KEY_DATE_DEBUT = "debut"
16KEY_DATE_FIN = "fin"
4d17560e
JPC
17
18TYPE_REMUN_BSTG = (3,)
19TYPE_REMUN_MAD = (2,)
20TYPE_REMUN_BASE = (1,)
95ad7aab 21TYPE_REMUN_FONC_RESP = (7, 8)
4d17560e
JPC
22TYPE_REMUN_EXPAT = (4,)
23TYPE_REMUN_LOGEMENT = (6,)
9fd09bdc 24TYPE_REMUN_SCOLARITE = (5,)
4d17560e
JPC
25TYPE_REMUN_TRANSP = (9,)
26TYPE_REMUN_13E = (18,)
95ad7aab 27TYPE_PRIME_INTERIM = (19,)
07f120f3
JPC
28TYPE_REMUN_ALL_INDEMNITES = list(itertools.chain(*(TYPE_REMUN_BSTG,
29 TYPE_REMUN_MAD, TYPE_REMUN_BASE, TYPE_REMUN_FONC_RESP,
30 TYPE_REMUN_EXPAT, TYPE_REMUN_LOGEMENT, TYPE_REMUN_TRANSP,
9fd09bdc 31 TYPE_REMUN_13E, TYPE_PRIME_INTERIM, TYPE_REMUN_SCOLARITE)))
95ad7aab
JPC
32TYPE_PRIME_INSTALLATION = (13,)
33TYPE_PRIME_DEMENAG = (15,)
34TYPE_PRIME_AVION = (14,)
07f120f3
JPC
35TYPE_PRIME_ALL = list(itertools.chain(
36 *(TYPE_PRIME_INSTALLATION, TYPE_PRIME_DEMENAG, TYPE_PRIME_AVION)
37 ))
38TYPE_CHARGE_PATRONALE = (17,)
39TYPE_CHARGE_ALL = list(itertools.chain(*(TYPE_CHARGE_PATRONALE,)))
40TYPE_NATURE_INDEMN = u"Indemnité"
899aea3b
JPC
41TYPE_NATURE_PAIEMENT = u"Accessoire"
42TYPE_NATURE_CHARGES = u"Charges"
5c5de149 43TYPE_NATURE_TRAITEMENT = u"Traitement"
43b30700 44HEADER_SEPARATOR = ('sep', ods.Separator, {'columnwidth': '0.4cm'})
899aea3b 45
9163be6f 46
98d6eb6c
JPC
47class MasseSalariale():
48 """ Rapport de la masse salariale. """
49
c99116c3
JPC
50 def __init__(self, date_debut, date_fin, custom_filter=None,
51 ne_pas_grouper=False):
98d6eb6c
JPC
52 """ date_debut: date de début pour les données temporelles
53 date_fin: idem
df37184c 54 custom_filter: dictionnaire des paramètres à passer au queryset.
98d6eb6c 55 """
df37184c
JPC
56 if not date_debut and not date_fin:
57 return
58
98d6eb6c
JPC
59 date_debut = datetime.date(
60 *time.strptime(date_debut, "%d-%m-%Y")[0:3]
61 )
62 date_fin = datetime.date(*time.strptime(date_fin, "%d-%m-%Y")[0:3])
5c5de149 63
9163be6f 64 rapport_date_delta = date_fin - date_debut
e5a3a08e 65 rapport_date_delta += datetime.timedelta(days=1)
98d6eb6c
JPC
66
67 self.annee = date_fin.year
68
69 self.devise_base = rh.Devise.objects.filter(code='EUR')[0]
70 self.taux_change = {}
71
72 q_range = self.build_qs("date_", date_debut, date_fin)
73 q_range_d = self.build_qs("dossier__date_", date_debut, date_fin)
74 remunerations = rh.Remuneration.objects.filter(q_range) \
75 .filter(q_range_d) \
023bdc65
JPC
76
77 if custom_filter:
78 remunerations = remunerations.filter(**custom_filter)
79
80 remunerations = remunerations.exclude(supprime=True) \
899aea3b
JPC
81 .select_related(
82 "dossier", "dossier_employe", "dossier_poste", "type"
83 )
98d6eb6c 84
c99116c3
JPC
85 contenu = {}
86
87 lineariser_dossiers = not ne_pas_grouper
88
98d6eb6c 89 for r in remunerations:
c99116c3
JPC
90 if lineariser_dossiers:
91 key = r.dossier.employe_id
92 else:
93 key = r.dossier_id
94
95 if key not in contenu:
96 contenu[key] = {
9163be6f
JPC
97 'dossiers': set(),
98 'remunerations': []
99 }
c99116c3
JPC
100 if lineariser_dossiers:
101 contenu[key]['remunerations'].append(r)
102 else:
103 if r.dossier_id == key:
104 contenu[key]['remunerations'].append(r)
105 contenu[key]['dossiers'].add(r.dossier)
9163be6f 106
98d6eb6c
JPC
107 self.rapport = []
108
57e2b793
JPC
109 pays_list = {}
110 for pays in ref.Pays.objects.all():
111 pays_list[pays.id] = pays
112
98d6eb6c
JPC
113 valeurs_point_par_imp = \
114 dict(
9163be6f
JPC
115 (v.implantation.id, v) for v in \
116 rh.ValeurPoint.objects.filter(annee=self.annee).all()
98d6eb6c 117 )
57e2b793
JPC
118
119 self.headers = (
3c8ffdfb
JPC
120 ('bureau', u"Bureau", {'columnwidth': '2cm'}),
121 ('pays', u"Pays", {'columnwidth': '3.5cm'}),
122 ('implantation', u"Implantation", {'columnwidth': '3cm'}),
5c5de149 123 ('valeur_point', u"Valeur du point",
3c8ffdfb
JPC
124 {'columnwidth': '2.3cm'}),
125 ('numero_employe', u"Numéro d'employé",
126 {'columnwidth': '2.4cm'}),
127 ('nom', u"Nom", {'columnwidth': '5.4cm'}),
128 ('prenom', u"Prénom", {'columnwidth': '4.8cm'}),
129 ('type_de_poste', u"Type de poste", {'columnwidth': '2.7cm'}),
130 ('intitule_de_poste', u"Intitulé du poste",
131 {'columnwidth': '7.25cm'}),
132 ('niveau', u"Niveau", {'columnwidth': '1.75cm'}),
133 ('point', u"Point", {'columnwidth': '1.75cm'}),
134 ('regime_de_travail', u"Régime de travail",
135 {'columnwidth': '2cm'}),
136 ('local_expatrie', u"Local / Expatrié",
137 {'columnwidth': '2.25cm'}),
138 ('statut', u"Statut", {'columnwidth': '1.25cm'}),
139 ('date_fin_contrat', u"Date de fin de contrat",
140 {'columnwidth': '2cm'}),
e232bfe8 141 HEADER_SEPARATOR,
3c8ffdfb
JPC
142 ('date_debut', u"Date de début", {'columnwidth': '1.92cm'}),
143 ('date_fin', u"Date de fin", {'columnwidth': '1.92cm'}),
144 ('nb_jours', u"Nombre de jours", {'columnwidth': '2.82cm'}),
e232bfe8 145 HEADER_SEPARATOR,
3c8ffdfb 146 ('devise', u"Devise", {'columnwidth': '1.46cm'}),
cb9cce2b 147 ('salaire_bstg_annuel', u"Salaire BSTG ANNUEL",
3c8ffdfb 148 {'columnwidth': '2.5cm'}),
cb9cce2b 149 ('salaire_bstg_total', u"Salaire BSTG total ",
3c8ffdfb
JPC
150 {'columnwidth': '2.5cm'}),
151 ('organisme_bstg', u"Organisme BSTG",
152 {'columnwidth': '2.9cm'}),
e232bfe8 153 HEADER_SEPARATOR,
3c8ffdfb 154 ('salaire_theorique', u"Salaire théorique",
9fd09bdc 155 {'columnwidth': '2.5cm', 'background-color': '#ecab44'}),
3c8ffdfb 156 ('salaire_base_brut', u"Salaire de base brut",
9fd09bdc 157 {'columnwidth': '2.5cm', 'background-color': '#ecab44'}),
3c8ffdfb 158 ('salaire_complementaire', u"Salaire complémentaire",
9fd09bdc 159 {'columnwidth': '2.5cm', 'background-color': '#ecab44'}),
e232bfe8 160 HEADER_SEPARATOR,
3c8ffdfb 161 ('indemnite_fonctions', u"Indemnités de fonctions",
9fd09bdc 162 {'columnwidth': '2.5cm', 'background-color': '#fff840'}),
3c8ffdfb 163 ('indemnite_expat', u"Indemnités d'expatriation",
9fd09bdc
JPC
164 {'columnwidth': '2.5cm', 'background-color': '#fff840'}),
165 ('indemnite_scolarite', u"Indemnités de frais de scolarité",
166 {'columnwidth': '2.5cm', 'background-color': '#fff840'}),
3c8ffdfb 167 ('indemnite_logement', u"Indemnités de logement",
9fd09bdc 168 {'columnwidth': '2.5cm', 'background-color': '#fff840'}),
3c8ffdfb 169 ('indemnite_transp', u"Indemnités de transport",
9fd09bdc 170 {'columnwidth': '2.5cm', 'background-color': '#fff840'}),
3c8ffdfb 171 ('indemnite_13e', u"Indemnités 13e mois",
9fd09bdc 172 {'columnwidth': '2.5cm', 'background-color': '#fff840'}),
3c8ffdfb 173 ('prime_interim', u"Prime d'intérim",
9fd09bdc 174 {'columnwidth': '2.5cm', 'background-color': '#fff840'}),
3c8ffdfb 175 ('indemnite_autre', u"Autre indemnités",
9fd09bdc 176 {'columnwidth': '2.5cm', 'background-color': '#fff840'}),
3c8ffdfb 177 ('indemnite_sous_total', u"Sous-total d'indemnités",
9fd09bdc 178 {'columnwidth': '2.5cm', 'background-color': '#fff840'}),
e232bfe8 179 HEADER_SEPARATOR,
3c8ffdfb 180 ('prime_installation', u"Prime d'installation",
9fd09bdc 181 {'columnwidth': '2.5cm', 'background-color': '#d7fb0f'}),
3c8ffdfb 182 ('prime_demenagement', u"Prime de déménagement",
9fd09bdc 183 {'columnwidth': '2.5cm', 'background-color': '#d7fb0f'}),
3c8ffdfb 184 ('prime_avion', u"Prime d'avion",
9fd09bdc 185 {'columnwidth': '2.5cm', 'background-color': '#d7fb0f'}),
3c8ffdfb 186 ('prime_autre', u"Autre prime",
9fd09bdc 187 {'columnwidth': '2.5cm', 'background-color': '#d7fb0f'}),
3c8ffdfb 188 ('prime_sous_total', u"Total des primes",
9fd09bdc 189 {'columnwidth': '2.5cm', 'background-color': '#d7fb0f'}),
e232bfe8 190 HEADER_SEPARATOR,
3c8ffdfb 191 ('charges_patronales', u"Charges patronales",
9fd09bdc 192 {'columnwidth': '2.5cm', 'background-color': '#fb680f'}),
3c8ffdfb 193 ('charges_autre', u"Autres charges patronales",
9fd09bdc 194 {'columnwidth': '2.5cm', 'background-color': '#fb680f'}),
3c8ffdfb 195 ('charges_sous_total', u"Sous-total des charges patronales",
9fd09bdc 196 {'columnwidth': '2.5cm', 'background-color': '#fb680f'}),
e232bfe8 197 HEADER_SEPARATOR,
9fd09bdc
JPC
198 ('sous_total_traitement_annee', u"Total traitement annuel",
199 {'background-color': '#f88680'}),
200 ('sous_total_indemnite_annee', u"Total indemnités annuel",
201 {'background-color': '#f88680'}),
202 ('sous_total_accessoire_annee', u"Total accessoires annuel",
203 {'background-color': '#f88680'}),
204 ('sous_total_charges_annee', u"Total charges annuel",
205 {'background-color': '#f88680'}),
e232bfe8 206 HEADER_SEPARATOR,
cb9cce2b 207 ('masse_salariale', u"Masse salariale annuelle",
9fd09bdc 208 {'columnwidth': '2.5cm', 'background-color': '#e6c6ed'}),
3c8ffdfb 209 ('masse_salariale_annee', u"Masse salariale %s" % self.annee,
9fd09bdc 210 {'columnwidth': '2.5cm', 'background-color': '#e6c6ed'}),
cb9cce2b 211 ('masse_salariale_annee_euro', u"Masse salariale %s EUR" % \
9fd09bdc
JPC
212 self.annee, {
213 'columnwidth': '2.5cm',
214 'background-color': '#e6c6ed'
215 }
216 ),
57e2b793
JPC
217 )
218
778fb9d6
JPC
219 grand_total = 0.0
220 grand_total_euro = 0.0
221
c99116c3 222 for item in contenu.values():
98d6eb6c
JPC
223 dossiers = item['dossiers']
224 remuns = item['remunerations']
07f120f3 225
07f120f3
JPC
226 for d in dossiers:
227 if d.principal:
228 dossier = list(dossiers)[0]
229
95ad7aab 230 regime = float(dossier.poste.regime_travail) / 100
9163be6f 231
f7fc1166 232 if dossier.statut_residence == "expat":
98d6eb6c
JPC
233 statut = "E"
234 else:
235 statut = "L"
236
9163be6f
JPC
237 #on détermine la date du début et fin du dossier si année en cours
238 try:
239 d_date_fin = dossier.date_fin \
240 if dossier.date_fin.year == date_fin.year else None
241 except AttributeError:
242 d_date_fin = None
243 try:
244 d_date_debut = dossier.date_debut \
245 if dossier.date_debut.year == date_fin.year else None
246 except AttributeError:
247 d_date_debut = None
98d6eb6c
JPC
248
249 pays = \
250 pays_list[dossier.poste.implantation.adresse_physique_pays.id]
251
252 #on détermine si les rémunérations sont tous dans la même devise
253 devise = remuns[0].devise
254 meme_devise = True
255 for r in remuns[1:]:
256 if devise != r.devise:
257 meme_devise = False
258
259 if not meme_devise:
260 for r in remuns:
261 self.convertir(r)
262
263 bstg_dossier = None
264 for d in dossiers:
265 if d.organisme_bstg:
266 bstg_dossier = d
267
9163be6f 268 bstg_remun = None
98d6eb6c 269 if bstg_dossier:
9163be6f 270 for r in bstg_dossier.rh_remunerations.all():
958e67e8 271 if r.type.id in TYPE_REMUN_BSTG:
9163be6f 272 bstg_remun = r
98d6eb6c 273
958e67e8 274 if bstg_remun:
df37184c
JPC
275 bstg_remun_euro = rh.Remuneration(
276 montant=bstg_remun.montant, devise=bstg_remun.devise
277 )
958e67e8 278 self.convertir(bstg_remun_euro)
958e67e8 279
4d17560e
JPC
280 salaire_complement = 0.0
281 salaire_base = 0.0
282 indemnites = {
283 'fonc_resp': 0.0,
284 'expat': 0.0,
9fd09bdc 285 'scolarite': 0.0,
4d17560e
JPC
286 'logement': 0.0,
287 'transp': 0.0,
288 '13e': 0.0,
289 'autre_recurr': 0.0,
07f120f3 290 'interim': 0.0,
4d17560e 291 }
95ad7aab
JPC
292
293 primes = {
95ad7aab
JPC
294 'installation': 0.0,
295 'demenagement': 0.0,
296 'avion': 0.0,
297 'autre': 0.0,
298 }
07f120f3
JPC
299 charges = {
300 'patronale': 0.0,
301 'autre': 0.0,
302 }
5c5de149
JPC
303
304 total_remun_annee = {
305 'traitement': 0.0,
306 'indemnite': 0.0,
307 'accessoire': 0.0,
308 'charges': 0.0,
309 }
310
4d17560e
JPC
311 for r in remuns:
312 montant = float(r.montant)
95ad7aab
JPC
313
314 if r.type_id in TYPE_REMUN_MAD:
4d17560e
JPC
315 salaire_complement += montant
316
95ad7aab 317 if r.type_id in TYPE_REMUN_BASE:
4d17560e
JPC
318 salaire_base += montant
319
95ad7aab 320 if r.type_id in TYPE_REMUN_FONC_RESP:
4d17560e
JPC
321 indemnites['fonc_resp'] += montant
322
95ad7aab 323 if r.type_id in TYPE_REMUN_EXPAT:
4d17560e
JPC
324 indemnites['expat'] += montant
325
9fd09bdc
JPC
326 if r.type_id in TYPE_REMUN_SCOLARITE:
327 indemnites['scolarite'] += montant
328
95ad7aab 329 if r.type_id in TYPE_REMUN_LOGEMENT:
4d17560e
JPC
330 indemnites['logement'] += montant
331
95ad7aab 332 if r.type_id in TYPE_REMUN_TRANSP:
4d17560e
JPC
333 indemnites['transp'] += montant
334
95ad7aab 335 if r.type_id in TYPE_REMUN_13E:
4d17560e
JPC
336 indemnites['13e'] += montant
337
95ad7aab 338 if r.type_id in TYPE_PRIME_INTERIM:
07f120f3
JPC
339 indemnites['interim'] += montant
340
341 if r.type_id not in TYPE_REMUN_ALL_INDEMNITES \
342 and r.type.nature_remuneration == TYPE_NATURE_INDEMN:
343 indemnites['autre_recurr'] += montant
95ad7aab
JPC
344
345 if r.type_id in TYPE_PRIME_INSTALLATION:
346 primes['installation'] += montant
347
348 if r.type_id in TYPE_PRIME_DEMENAG:
349 primes['demenagement'] += montant
350
351 if r.type_id in TYPE_PRIME_AVION:
352 primes['avion'] += montant
353
07f120f3 354 if r.type_id not in TYPE_PRIME_ALL and \
95ad7aab
JPC
355 r.type.nature_remuneration == TYPE_NATURE_PAIEMENT:
356 primes['autre'] += montant
357
07f120f3
JPC
358 if r.type_id in TYPE_CHARGE_PATRONALE:
359 charges['patronale'] += montant
360
361 if r.type_id not in TYPE_CHARGE_ALL and \
362 r.type.nature_remuneration == TYPE_NATURE_CHARGES:
363 charges['autre'] += montant
899aea3b 364
5c5de149
JPC
365 if r.type.nature_remuneration == TYPE_NATURE_INDEMN:
366 total_remun_annee['indemnite'] += montant
367
368 if r.type.nature_remuneration == TYPE_NATURE_PAIEMENT:
369 total_remun_annee['accessoire'] += montant
370
371 if r.type.nature_remuneration == TYPE_NATURE_CHARGES:
372 total_remun_annee['charges'] += montant
373
374 if r.type.nature_remuneration == TYPE_NATURE_TRAITEMENT:
375 total_remun_annee['traitement'] += montant
376
4d17560e
JPC
377 total_indemnites = sum(indemnites.values())
378
9163be6f 379 #Calcul du nombre de jours pour ce dossier.
4d17560e
JPC
380 if dossier.date_debut and dossier.date_debut > date_debut and \
381 not dossier.date_fin:
382 date_delta = date_fin - dossier.date_fin
383 elif dossier.date_fin and dossier.date_fin < date_fin and \
384 not dossier.date_debut:
385 date_delta = dossier.date_fin - date_debut
386 elif dossier.date_fin and dossier.date_debut:
387 date_delta = dossier.date_fin - date_debut
388 else:
9163be6f 389 date_delta = rapport_date_delta
98d6eb6c 390
899aea3b 391 masse_salariale = (salaire_base + total_indemnites + \
07f120f3 392 sum(primes.values()) + sum(charges.values()))
df37184c 393 masse_salariale_euro = rh.Remuneration(montant=masse_salariale,
023bdc65
JPC
394 devise=remuns[0].devise)
395 self.convertir(masse_salariale_euro)
396
22b53270
JPC
397 if dossier.classement and dossier.classement.coefficient:
398 coefficient = dossier.classement.coefficient
399 else:
400 coefficient = ""
401
402 #todo valeur du point si pas présent
403 valeur_point = valeurs_point_par_imp.get(
404 dossier.poste.implantation_id
405 ) or ""
406
3244a3c2 407 salaire_theorique = (
22b53270 408 round(valeur_point.valeur * int(coefficient) * regime, 2) \
3244a3c2 409 if valeur_point and coefficient and regime else None)
22b53270 410
3d2b92bc
JPC
411 rapport_nombre_jours = (float(date_delta.days)
412 / rapport_date_delta.days)
57e2b793
JPC
413 item_rapport = {
414 'bureau': dossier.poste.implantation.region.code,
415 'pays': unicode(pays),
416 'implantation': dossier.poste.implantation.nom_court,
417 'type_implantation': dossier.poste.implantation.type,
418 #'imputation': None,
419 'valeur_point': valeur_point,
420 'numero_employe': dossier.employe_id,
421 'nom': dossier.employe.nom.upper(),
422 'prenom': dossier.employe.prenom,
423 'type_de_poste': dossier.poste.type_poste.nom,
f7fc1166
JPC
424 'intitule_de_poste': dossier.poste.nom_feminin
425 if dossier.employe.genre == "F" else
426 dossier.poste.nom,
57e2b793
JPC
427 'niveau': unicode(dossier.classement),
428 'point': coefficient,
429 'regime_de_travail': "%s %%" % int(regime * 100),
430 'local_expatrie': statut,
431 'statut': dossier.statut.code,
432 'date_fin_contrat': dossier.date_fin or "",
433 'date_debut': d_date_debut or "",
434 'date_fin': d_date_fin or "",
435 'nb_jours': date_delta.days,
cb9cce2b 436 'devise': remuns[0].devise.code,
57e2b793
JPC
437 'salaire_bstg_annuel': bstg_remun.montant \
438 if bstg_remun else "",
439 'salaire_bstg_total': bstg_remun_euro.montant \
440 if bstg_remun else "",
441 'organisme_bstg': dossier.organisme_bstg or "",
442 'salaire_theorique': salaire_theorique,
443 'salaire_base_brut': \
3d2b92bc 444 salaire_base * regime * rapport_nombre_jours,
57e2b793 445 'salaire_complementaire': \
3d2b92bc
JPC
446 salaire_complement * regime *
447 rapport_nombre_jours,
57e2b793
JPC
448 #'salaire_total': None
449 'indemnite_fonctions': indemnites['fonc_resp'] * \
3d2b92bc 450 regime * rapport_nombre_jours,
57e2b793 451 'indemnite_expat': indemnites['expat'] * regime * \
3d2b92bc 452 rapport_nombre_jours,
9fd09bdc
JPC
453 'indemnite_scolarite': indemnites['scolarite'] * \
454 regime * rapport_nombre_jours,
57e2b793 455 'indemnite_logement': indemnites['logement'] * \
3d2b92bc 456 regime * rapport_nombre_jours,
57e2b793 457 'indemnite_transp': indemnites['transp'] * regime * \
3d2b92bc 458 rapport_nombre_jours,
57e2b793 459 'indemnite_13e': indemnites['13e'] * regime * \
3d2b92bc 460 rapport_nombre_jours,
07f120f3 461 'prime_interim': indemnites['interim'] * regime * \
3d2b92bc 462 rapport_nombre_jours,
57e2b793 463 'indemnite_autre': indemnites['autre_recurr'] * \
3d2b92bc 464 regime * rapport_nombre_jours,
07f120f3 465 'indemnite_sous_total': total_indemnites * regime * \
3d2b92bc 466 rapport_nombre_jours,
57e2b793 467 'total_brut': (
95ad7aab
JPC
468 total_indemnites + salaire_base +
469 salaire_complement
3d2b92bc 470 ) * regime * rapport_nombre_jours,
57e2b793 471 'prime_installation': primes['installation'] * regime * \
3d2b92bc 472 rapport_nombre_jours,
57e2b793 473 'prime_demenagement': primes['demenagement'] * regime * \
3d2b92bc 474 rapport_nombre_jours,
57e2b793 475 'prime_avion': primes['avion'] * regime * \
3d2b92bc 476 rapport_nombre_jours,
57e2b793 477 'prime_autre': primes['autre'] * regime * \
3d2b92bc 478 rapport_nombre_jours,
07f120f3 479 'prime_sous_total': sum(primes.values()) * regime * \
3d2b92bc 480 rapport_nombre_jours,
07f120f3
JPC
481 'charges_patronales': charges['patronale'],
482 'charges_autre': charges['autre'],
483 'charges_sous_total': sum(charges.values()),
5c5de149
JPC
484 'sous_total_traitement_annee': \
485 total_remun_annee['traitement'],
486 'sous_total_indemnite_annee': \
487 total_remun_annee['indemnite'],
488 'sous_total_accessoire_annee': \
489 total_remun_annee['accessoire'],
490 'sous_total_charges_annee': \
491 total_remun_annee['charges'],
57e2b793
JPC
492 'masse_salariale': masse_salariale,
493 'masse_salariale_annee': masse_salariale * \
3d2b92bc 494 regime * rapport_nombre_jours,
5c5de149 495 'masse_salariale_annee_euro': \
3d2b92bc
JPC
496 masse_salariale_euro.montant * regime *
497 rapport_nombre_jours,
43b30700 498 'sep': ods.Separator(),
57e2b793 499 }
98d6eb6c 500
3d2b92bc 501 grand_total += round(masse_salariale, 2)
c99116c3 502 grand_total_euro += round(masse_salariale_euro.montant * regime
3d2b92bc 503 * (
778fb9d6 504 date_delta.days / rapport_date_delta.days
3d2b92bc 505 ), 2)
778fb9d6 506
98d6eb6c
JPC
507 self.rapport.append(item_rapport)
508
3b1a2937
JPC
509 self.rapport = sorted(self.rapport, key=lambda r: r['nom'])
510
778fb9d6
JPC
511 self.grand_totaux = (grand_total, grand_total_euro)
512
98d6eb6c
JPC
513 def build_qs(self, prefix, date_debut, date_fin):
514 date_debut_null = \
515 Q(**{"%s%s__isnull" % (prefix, KEY_DATE_DEBUT): True})
516 date_fin_null = \
517 Q(**{"%s%s__isnull" % (prefix, KEY_DATE_FIN): True})
518 date_debut_superieure_ou_egale_a_borne_gauche = \
519 Q(**{"%s%s__gte" % (prefix, KEY_DATE_DEBUT): date_debut})
520 date_debut_inferieure_ou_egale_a_borne_gauche = \
521 Q(**{"%s%s__lte" % (prefix, KEY_DATE_DEBUT): date_debut})
522 date_fin_superieure_ou_egale_a_borne_gauche = \
523 Q(**{"%s%s__gte" % (prefix, KEY_DATE_FIN): date_debut})
524 date_fin_inferieure_ou_egale_a_borne_droite = \
525 Q(**{"%s%s__lte" % (prefix, KEY_DATE_FIN): date_fin})
526 date_debut_inferieure_ou_egale_a_borne_droite = \
527 Q(**{"%s%s__lte" % (prefix, KEY_DATE_DEBUT): date_fin})
528 date_fin_superieure_ou_egale_a_borne_droite = \
529 Q(**{"%s%s__gte" % (prefix, KEY_DATE_FIN): date_fin})
530
531 q_range = \
532 (
533 date_debut_null & date_fin_null
534 ) | (
535 date_debut_inferieure_ou_egale_a_borne_gauche &
536 date_fin_superieure_ou_egale_a_borne_gauche &
537 date_fin_inferieure_ou_egale_a_borne_droite
538 ) | (
539 date_debut_superieure_ou_egale_a_borne_gauche &
540 date_debut_inferieure_ou_egale_a_borne_droite &
541 date_fin_superieure_ou_egale_a_borne_droite
542 ) | (
543 date_debut_inferieure_ou_egale_a_borne_gauche &
544 date_fin_superieure_ou_egale_a_borne_droite
545 ) | (
546 date_debut_null &
547 date_fin_superieure_ou_egale_a_borne_droite
548 ) | (
549 date_debut_inferieure_ou_egale_a_borne_gauche &
550 date_fin_null
551 )
552
553 return q_range
554
555 def convertir(self, remuneration):
9163be6f 556 if remuneration.devise != self.devise_base:
8b6e7b9a
JPC
557 try:
558 remuneration.montant = float(remuneration.montant) * \
559 self.trouver_taux(remuneration.devise).taux
560 remuneration.devise = self.devise_base
561 except AttributeError:
562 pass
98d6eb6c
JPC
563
564 def trouver_taux(self, devise):
565 if devise.code not in self.taux_change:
8b6e7b9a
JPC
566 try:
567 t = rh.TauxChange.objects.filter(
568 devise=devise, annee=self.annee
569 )[0]
570 except IndexError:
571 return None
98d6eb6c
JPC
572 self.taux_change[devise.code] = t
573 return self.taux_change[devise.code]
899aea3b
JPC
574
575 def csv(self):
576 self.csv_handle = StringIO.StringIO()
023bdc65
JPC
577 csv_writer = csv.writer(self.csv_handle, delimiter=",",
578 doublequote=False, escapechar="\\", quoting=csv.QUOTE_ALL,
579 )
580 header = [v[0] for v in self.rapport[0]]
581 csv_writer.writerow(header)
582 for row in self.rapport:
583 values = [v[1] for v in row]
584 csv_writer.writerow(
585 [unicode(r).encode('utf-8') for r in values]
586 )
c99116c3
JPC
587
588 def ods(self):
3c8ffdfb
JPC
589 self.doc = ods.OpenDocumentSpreadsheet()
590 table = self.doc.add_table(name=u'Masse salariale %s' % self.annee)
591
592 for h in self.headers:
593 if len(h) > 2:
594 table.add_column(**h[2])
595
6d7419c4
JPC
596 table.add_row([h[1] for h in self.headers], rowheight='2cm')
597
598 for r in self.rapport:
599 table.add_row([r[h[0]] for h in self.headers])
3c8ffdfb 600
028b8438 601 #a.doc.write('hello_world.ods')