1 # -*- encoding: utf-8 -*-
8 from auf
.django
.references
import models
as ref
9 from django
.db
.models
import Q
, Count
11 from project
.rh
import ods
12 from project
.rh
import models
as rh
15 KEY_DATE_DEBUT
= "debut"
18 TYPE_REMUN_BSTG
= (3,)
20 TYPE_REMUN_BASE
= (1,)
21 TYPE_REMUN_FONC_RESP
= (7, 8)
22 TYPE_REMUN_EXPAT
= (4,)
23 TYPE_REMUN_LOGEMENT
= (6,)
24 TYPE_REMUN_SCOLARITE
= (5,)
25 TYPE_REMUN_TRANSP
= (9,)
26 TYPE_REMUN_13E
= (18,)
27 TYPE_PRIME_INTERIM
= (19,)
28 TYPE_REMUN_ALL_INDEMNITES
= list(itertools
.chain(*(
29 TYPE_REMUN_BSTG
, TYPE_REMUN_BASE
, TYPE_REMUN_FONC_RESP
,
30 TYPE_REMUN_EXPAT
, TYPE_REMUN_LOGEMENT
, TYPE_REMUN_TRANSP
,
31 TYPE_REMUN_13E
, TYPE_PRIME_INTERIM
, TYPE_REMUN_SCOLARITE
)))
32 TYPE_PRIME_INSTALLATION
= (13,)
33 TYPE_PRIME_DEMENAG
= (15,)
34 TYPE_PRIME_AVION
= (14,)
35 TYPE_PRIME_ALL
= list(itertools
.chain(
36 *(TYPE_PRIME_INSTALLATION
, TYPE_PRIME_DEMENAG
, TYPE_PRIME_AVION
)
38 TYPE_CHARGE_PATRONALE
= (17,)
39 TYPE_CHARGE_ALL
= list(itertools
.chain(*(TYPE_CHARGE_PATRONALE
,)))
40 TYPE_NATURE_INDEMN
= u
"Indemnité"
41 TYPE_NATURE_PAIEMENT
= u
"Accessoire"
42 TYPE_NATURE_CHARGES
= u
"Charges"
43 TYPE_NATURE_TRAITEMENT
= u
"Traitement"
44 HEADER_SEPARATOR
= ('sep', ods
.Separator(), {'columnwidth': '0.4cm'})
47 class MasseSalariale():
48 """ Rapport de la masse salariale. """
50 def __init__(self
, date_debut
, date_fin
, custom_filter
=None,
51 ne_pas_grouper
=False):
52 """ date_debut: date de début pour les données temporelles
54 custom_filter: dictionnaire des paramètres à passer au queryset.
56 if not date_debut
and not date_fin
:
59 date_debut
= datetime
.date(
60 *time
.strptime(date_debut
, "%d-%m-%Y")[0:3]
62 date_fin
= datetime
.date(*time
.strptime(date_fin
, "%d-%m-%Y")[0:3])
64 rapport_date_delta
= date_fin
- date_debut
65 rapport_date_delta
+= datetime
.timedelta(days
=1)
67 self
.annee
= date_fin
.year
69 self
.devise_base
= rh
.Devise
.objects
.filter(code
='EUR')[0]
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
) \
78 remunerations
= remunerations
.filter(**custom_filter
)
79 self
.custom_filter
= custom_filter
82 self
.implantation
= None
83 if 'dossier__poste__implantation__region' in custom_filter
:
84 self
.region
= ref
.Region
.objects
.get(
85 id=custom_filter
['dossier__poste__implantation__region']
87 if 'dossier__poste__implantation' in custom_filter
:
88 self
.implantation
= ref
.Implantation
.objects
.get(
89 id=custom_filter
['dossier__poste__implantation']
92 remunerations
= remunerations
.exclude(supprime
=True) \
94 "dossier", "dossier_employe", "dossier_poste", "type"
98 for k
, v
in self
.custom_filter
.items():
99 custom_filter
[k
.replace('dossier__', '')] = v
100 count_dossiers_by_employe
= dict((d
['id'], d
['count']) for d
in
101 rh
.Dossier
.objects
.filter(q_range
).values('id') \
102 .filter(**custom_filter
) \
103 .annotate(count
=Count('employe')))
107 lineariser_dossiers
= not ne_pas_grouper
109 for r
in remunerations
:
110 if lineariser_dossiers
:
111 key
= r
.dossier
.employe_id
115 if key
not in contenu
:
120 if lineariser_dossiers
:
121 contenu
[key
]['remunerations'].append(r
)
123 if r
.dossier_id
== key
:
124 contenu
[key
]['remunerations'].append(r
)
125 contenu
[key
]['dossiers'].add(r
.dossier
)
130 for pays
in ref
.Pays
.objects
.all():
131 pays_list
[pays
.id] = pays
133 valeurs_point_par_imp
= \
135 (v
.implantation
.id, v
) for v
in \
136 rh
.ValeurPoint
.objects
.filter(annee
=self
.annee
).all()
140 ('bureau', u
"Bureau", {'columnwidth': '2cm'}),
141 ('pays', u
"Pays", {'columnwidth': '3.5cm'}),
142 ('implantation', u
"Implantation", {'columnwidth': '3cm'}),
143 ('valeur_point', u
"Valeur du point",
144 {'columnwidth': '2.3cm'}),
145 ('numero_employe', u
"Numéro d'employé",
146 {'columnwidth': '2.4cm'}),
147 ('nom', u
"Nom", {'columnwidth': '5.4cm'}),
148 ('prenom', u
"Prénom", {'columnwidth': '4.8cm'}),
149 ('type_de_poste', u
"Type de poste", {'columnwidth': '2.7cm'}),
150 ('intitule_de_poste', u
"Intitulé du poste",
151 {'columnwidth': '7.25cm'}),
152 ('niveau', u
"Niveau actel", {'columnwidth': '1.75cm'}),
153 ('point', u
"Point", {'columnwidth': '1.75cm'}),
154 ('regime_de_travail', u
"Régime de travail annuel",
155 {'columnwidth': '2cm'}),
156 ('local_expatrie', u
"Local / Expatrié",
157 {'columnwidth': '2.25cm'}),
158 ('statut', u
"Statut", {'columnwidth': '1.25cm'}),
159 ('date_fin_contrat', u
"Date de fin de contrat",
160 {'columnwidth': '2cm'}),
162 ('date_debut', u
"Date de début", {'columnwidth': '1.92cm'}),
163 ('date_fin', u
"Date de fin", {'columnwidth': '1.92cm'}),
164 ('nb_jours', u
"Nombre de jours", {'columnwidth': '2.82cm'}),
166 ('devise', u
"Devise", {'columnwidth': '1.46cm'}),
167 ('salaire_bstg_annuel', u
"Salaire BSTG ANNUEL",
168 {'columnwidth': '2.5cm'}),
169 ('salaire_bstg_euro', u
"Salaire BSTG EUR",
170 {'columnwidth': '2.5cm'}),
171 ('organisme_bstg', u
"Organisme BSTG",
172 {'columnwidth': '2.9cm'}),
174 ('salaire_theorique', u
"Salaire théorique ANNUEL",
175 {'columnwidth': '2.5cm', 'background-color': '#ecab44'}),
176 ('salaire_base_brut', u
"Salaire de base brut",
177 {'columnwidth': '2.5cm', 'background-color': '#ecab44'}),
178 ('salaire_complementaire', u
"Salaire complémentaire",
179 {'columnwidth': '2.5cm', 'background-color': '#ecab44'}),
181 ('indemnite_fonctions', u
"Indemnités de fonctions",
182 {'columnwidth': '2.5cm', 'background-color': '#fff840'}),
183 ('indemnite_expat', u
"Indemnités d'expatriation",
184 {'columnwidth': '2.5cm', 'background-color': '#fff840'}),
185 ('indemnite_scolarite', u
"Indemnités de frais de scolarité",
186 {'columnwidth': '2.5cm', 'background-color': '#fff840'}),
187 ('indemnite_logement', u
"Indemnités de logement",
188 {'columnwidth': '2.5cm', 'background-color': '#fff840'}),
189 ('indemnite_transp', u
"Indemnités de transport",
190 {'columnwidth': '2.5cm', 'background-color': '#fff840'}),
191 ('indemnite_13e', u
"Indemnités 13e mois",
192 {'columnwidth': '2.5cm', 'background-color': '#fff840'}),
193 ('prime_interim', u
"Prime d'intérim",
194 {'columnwidth': '2.5cm', 'background-color': '#fff840'}),
195 ('indemnite_autre', u
"Autre indemnités",
196 {'columnwidth': '2.5cm', 'background-color': '#fff840'}),
197 ('indemnite_sous_total', u
"Sous-total d'indemnités",
198 {'columnwidth': '2.5cm', 'background-color': '#fff840'}),
200 ('prime_installation', u
"Prime d'installation",
201 {'columnwidth': '2.5cm', 'background-color': '#d7fb0f'}),
202 ('prime_demenagement', u
"Prime de déménagement",
203 {'columnwidth': '2.5cm', 'background-color': '#d7fb0f'}),
204 ('prime_avion', u
"Prime d'avion",
205 {'columnwidth': '2.5cm', 'background-color': '#d7fb0f'}),
206 ('prime_autre', u
"Autre prime",
207 {'columnwidth': '2.5cm', 'background-color': '#d7fb0f'}),
208 ('prime_sous_total', u
"Total des primes",
209 {'columnwidth': '2.5cm', 'background-color': '#d7fb0f'}),
211 ('charges_patronales', u
"Charges patronales",
212 {'columnwidth': '2.5cm', 'background-color': '#fb680f'}),
213 ('charges_autre', u
"Autres charges patronales",
214 {'columnwidth': '2.5cm', 'background-color': '#fb680f'}),
215 ('charges_sous_total', u
"Sous-total des charges patronales",
216 {'columnwidth': '2.5cm', 'background-color': '#fb680f'}),
218 ('sous_total_traitement_annee', u
"Total traitements",
219 {'background-color': '#ecab44'}),
220 ('sous_total_indemnite_annee', u
"Total indemnités",
221 {'background-color': '#fff840'}),
222 ('sous_total_accessoire_annee', u
"Total accessoires",
223 {'background-color': '#d7fb0f'}),
224 ('sous_total_charges_annee', u
"Total charges",
225 {'background-color': '#fb680f'}),
227 ('masse_salariale', u
"Masse salariale ANNUELLE",
228 {'columnwidth': '2.5cm', 'background-color': '#e6c6ed'}),
229 ('masse_salariale_annee', u
"Masse salariale",
230 {'columnwidth': '2.5cm', 'background-color': '#e6c6ed'}),
231 ('masse_salariale_annee_euro', u
"Masse salariale %s EUR" % \
233 'columnwidth': '2.5cm',
234 'background-color': '#e6c6ed'
240 grand_total_euro
= 0.0
242 if not lineariser_dossiers
:
243 for dossier_id
, count
in count_dossiers_by_employe
.items():
244 if dossier_id
not in contenu
or \
245 len(contenu
[dossier_id
]['dossiers']) != count
:
247 if dossier_id
in contenu
:
248 for d
in contenu
[dossier_id
]['dossiers']:
251 for k
, v
in self
.custom_filter
.items():
252 custom_filter
[k
.replace('dossier__', '')] = v
254 employe_id
= rh
.Dossier
.objects
.values('employe').filter(
255 id=dossier_id
).all()[0]['employe']
256 dossiers
= rh
.Dossier
.objects
.filter(q_range
) \
257 .filter(employe
=employe_id
) \
258 .filter(**custom_filter
) \
261 if d
.id not in contenu
:
263 'dossiers': set((d
,)),
267 contenu
[d
.id]['dossiers'].add(d
)
269 postes
= rh
.Poste
.objects
272 for k
, v
in self
.custom_filter
.items():
273 custom_filter
[k
.replace('dossier__poste__', '')] = v
276 postes
= postes
.filter(**custom_filter
)
278 postes_vacants
= [p
for p
in postes
.filter(q_range
).all()
280 remuneration_base
= rh
.TypeRemuneration
.objects
.get(
281 id=TYPE_REMUN_BASE
[0])
282 remuneration_indem
= rh
.TypeRemuneration(
283 nature_remuneration
=TYPE_NATURE_INDEMN
)
284 remuneration_charge
= rh
.TypeRemuneration(
285 nature_remuneration
=TYPE_NATURE_CHARGES
)
286 for p
in postes_vacants
:
288 d
.employe
= rh
.Employe()
289 d
.statut
= rh
.Statut()
291 d
.classement
= p
.classement_max
292 d
.point
= p
.valeur_point_max
296 montant
=p
.salaire_max
, devise
=p
.devise_max
,
297 type=remuneration_base
300 montant
=p
.indemn_max
, devise
=p
.devise_max
,
301 type=remuneration_indem
304 montant
=p
.autre_max
, devise
=p
.devise_max
,
305 type=remuneration_charge
311 montant
=0, devise
=self
.devise_base
, type=type
314 remuneration_base
, remuneration_indem
,
318 contenu
['p_%s' % p
.id] = {
319 'dossiers': set([d
]),
320 'remunerations': remunerations
323 for item
in contenu
.values():
324 dossiers
= item
['dossiers']
325 remuns
= item
['remunerations']
329 dossier
= list(dossiers
)[0]
334 regime
= (float(dossier
.regime_travail
) / 100)
336 if dossier
.statut_residence
== "expat":
341 #on détermine la date du début et fin du dossier si année en cours
343 d_date_fin
= dossier
.date_fin \
344 if dossier
.date_fin
.year
== date_fin
.year
else None
345 except AttributeError:
348 d_date_debut
= dossier
.date_debut \
349 if dossier
.date_debut
.year
== date_fin
.year
else None
350 except AttributeError:
354 pays_list
[dossier
.poste
.implantation
.adresse_physique_pays
.id]
356 #on détermine si les rémunérations sont tous dans la même devise
358 devise
= remuns
[0].devise
360 devise
= self
.devise_base
363 if devise
!= r
.devise
:
369 devise
= remuns
[0].devise
378 for r
in bstg_dossier
.rh_remunerations
.all():
379 if r
.type.id in TYPE_REMUN_MAD
:
380 bstg_remun
= rh
.Remuneration(
381 montant
=float(r
.montant
),
386 bstg_remun_euro
= rh
.Remuneration(
387 montant
=float(bstg_remun
.montant
),
388 devise
=bstg_remun
.devise
390 self
.convertir(bstg_remun_euro
)
392 salaire_complement
= 0.0
416 total_remun_annee
= {
423 #Calcul du nombre de jours pour ce dossier.
424 dossier_date_delta
= self
.calculer_nombre_jours(
425 dossier
.date_debut
, dossier
.date_fin
,
426 date_debut
, date_fin
)
428 masse_salariale
= 0.0
429 masse_salariale_annee
= 0.0
431 montant
= float(r
.montant
)
432 if r
.date_fin
is None and dossier
.date_fin
is not None:
433 r
.date_fin
= min(date_fin
, dossier
.date_fin
)
434 facteur
= self
.calculer_nombre_jours(
435 r
.date_debut
, r
.date_fin
,
436 date_debut
, date_fin
).days \
437 / float(rapport_date_delta
.days
)
439 if r
.type_id
in TYPE_REMUN_BSTG
:
440 salaire_complement
+= montant
* facteur
442 if r
.type_id
not in TYPE_REMUN_MAD
:
443 masse_salariale
+= montant
444 masse_salariale_annee
+= montant
* regime
446 if r
.type_id
in TYPE_REMUN_BASE
:
447 salaire_base
+= montant
* facteur
449 if r
.type_id
in TYPE_REMUN_FONC_RESP
:
450 indemnites
['fonc_resp'] += montant
* facteur
452 if r
.type_id
in TYPE_REMUN_EXPAT
:
453 indemnites
['expat'] += montant
* facteur
455 if r
.type_id
in TYPE_REMUN_SCOLARITE
:
456 indemnites
['scolarite'] += montant
* facteur
458 if r
.type_id
in TYPE_REMUN_LOGEMENT
:
459 indemnites
['logement'] += montant
* facteur
461 if r
.type_id
in TYPE_REMUN_TRANSP
:
462 indemnites
['transp'] += montant
* facteur
464 if r
.type_id
in TYPE_REMUN_13E
:
465 indemnites
['13e'] += montant
* facteur
467 if r
.type_id
in TYPE_PRIME_INTERIM
:
468 indemnites
['interim'] += montant
* facteur
470 if r
.type_id
not in TYPE_REMUN_ALL_INDEMNITES \
471 and r
.type.nature_remuneration
== TYPE_NATURE_INDEMN \
472 and r
.type_id
!= TYPE_REMUN_MAD
:
473 indemnites
['autre_recurr'] += montant
* facteur
475 if r
.type_id
in TYPE_PRIME_INSTALLATION
:
476 primes
['installation'] += montant
* facteur
478 if r
.type_id
in TYPE_PRIME_DEMENAG
:
479 primes
['demenagement'] += montant
* facteur
481 if r
.type_id
in TYPE_PRIME_AVION
:
482 primes
['avion'] += montant
* facteur
484 if r
.type_id
not in TYPE_PRIME_ALL
and \
485 r
.type.nature_remuneration
== TYPE_NATURE_PAIEMENT
:
486 primes
['autre'] += montant
* facteur
488 if r
.type_id
in TYPE_CHARGE_PATRONALE
:
489 charges
['patronale'] += montant
* facteur
491 if r
.type_id
not in TYPE_CHARGE_ALL
and \
492 r
.type.nature_remuneration
== TYPE_NATURE_CHARGES
:
493 charges
['autre'] += montant
* facteur
495 if r
.type.nature_remuneration
== TYPE_NATURE_INDEMN
or \
497 total_remun_annee
['indemnite'] += montant
* facteur
499 if r
.type.nature_remuneration
== TYPE_NATURE_PAIEMENT
:
500 total_remun_annee
['accessoire'] += montant
* facteur
502 if r
.type.nature_remuneration
== TYPE_NATURE_CHARGES
:
503 total_remun_annee
['charges'] += montant
* facteur
505 if (r
.type.nature_remuneration
== TYPE_NATURE_TRAITEMENT
and
506 r
.type.id not in (TYPE_REMUN_MAD
, 7)
507 ) or r
.type_id
== TYPE_REMUN_BSTG
:
508 total_remun_annee
['traitement'] += montant
* facteur
510 total_indemnites
= sum(indemnites
.values())
512 masse_salariale_euro
= rh
.Remuneration(
513 montant
=masse_salariale_annee
, devise
=devise
)
514 self
.convertir(masse_salariale_euro
)
516 if dossier
.classement
and dossier
.classement
.coefficient
:
517 coefficient
= dossier
.classement
.coefficient
521 #todo valeur du point si pas présent
522 valeur_point
= valeurs_point_par_imp
.get(
523 dossier
.poste
.implantation_id
526 valeur_point_label
= "%s %s" % (valeur_point
.valeur
,
527 valeur_point
.devise
.code
)
529 valeur_point_label
= ""
531 salaire_theorique
= (
532 round(valeur_point
.valeur
* int(coefficient
) * regime
, 2) \
533 if valeur_point
and coefficient
and regime
else None)
536 'bureau': dossier
.poste
.implantation
.region
.code
,
537 'pays': unicode(pays
),
538 'implantation': dossier
.poste
.implantation
.nom_court
,
539 'type_implantation': dossier
.poste
.implantation
.type,
541 'valeur_point': valeur_point_label
,
542 'numero_employe': dossier
.employe_id
,
543 'nom': dossier
.employe
.nom
.upper(),
544 'prenom': dossier
.employe
.prenom
,
545 'type_de_poste': dossier
.poste
.type_poste
.nom
,
546 'intitule_de_poste': dossier
.poste
.nom_feminin
547 if dossier
.employe
.genre
== "F" else
549 'niveau': dossier
.classement
,
550 'point': coefficient
,
551 'regime_de_travail': "%s %%" % int(regime
* 100),
552 'local_expatrie': statut
,
553 'statut': dossier
.statut
.code
,
554 'date_fin_contrat': dossier
.date_fin
or "",
555 'date_debut': d_date_debut
or "",
556 'date_fin': d_date_fin
or "",
557 'nb_jours': dossier_date_delta
.days
,
558 'devise': devise
.code
,
559 'salaire_bstg_annuel': bstg_remun
.montant \
560 if bstg_remun
else "",
561 'salaire_bstg_euro': bstg_remun_euro
.montant \
562 if bstg_remun
else "",
563 'organisme_bstg': dossier
.organisme_bstg
or "",
564 'salaire_theorique': salaire_theorique
,
565 'salaire_base_brut': \
566 salaire_base
* regime
,
567 'salaire_complementaire': \
568 salaire_complement
* regime
,
569 #'salaire_total': None
570 'indemnite_fonctions': indemnites
['fonc_resp'] * \
572 'indemnite_expat': indemnites
['expat'] * regime
,
573 'indemnite_scolarite': indemnites
['scolarite'] * \
575 'indemnite_logement': indemnites
['logement'] * \
577 'indemnite_transp': indemnites
['transp'] * regime
,
578 'indemnite_13e': indemnites
['13e'] * regime
,
579 'prime_interim': indemnites
['interim'] * regime
,
580 'indemnite_autre': indemnites
['autre_recurr'] * \
582 'indemnite_sous_total': total_indemnites
* regime
,
584 total_indemnites
+ salaire_base
+
587 'prime_installation': primes
['installation'] * regime
,
588 'prime_demenagement': primes
['demenagement'] * regime
,
589 'prime_avion': primes
['avion'] * regime
,
590 'prime_autre': primes
['autre'] * regime
,
591 'prime_sous_total': sum(primes
.values()) * regime
,
592 'charges_patronales': charges
['patronale'] * regime
,
593 'charges_autre': charges
['autre'] * regime
,
594 'charges_sous_total': sum(charges
.values()) * regime
,
595 'sous_total_traitement_annee': \
596 total_remun_annee
['traitement'] * regime
,
597 'sous_total_indemnite_annee': \
598 total_remun_annee
['indemnite'] * regime
,
599 'sous_total_accessoire_annee': \
600 total_remun_annee
['accessoire'] * regime
,
601 'sous_total_charges_annee': \
602 total_remun_annee
['charges'] * regime
,
603 'masse_salariale': masse_salariale
* regime
,
604 'masse_salariale_annee': masse_salariale_annee
* regime
,
605 'masse_salariale_annee_euro': \
606 masse_salariale_euro
.montant
* regime
,
607 'sep': ods
.Separator(),
610 grand_total_euro
+= round(masse_salariale_euro
.montant
* regime
612 dossier_date_delta
.days
/ rapport_date_delta
.days
615 self
.rapport
.append(item_rapport
)
617 self
.rapport
= sorted(self
.rapport
, key
=lambda r
: r
['nom'])
619 self
.grand_totaux
= (grand_total
, grand_total_euro
)
621 def calculer_nombre_jours(self
, debut
, fin
, debut_limite
, fin_limite
):
622 """Calcul le nombre de jours entre fin et debut, sans dépasser
623 les limites. Si debut ou fin set null, on prend debut_limite/fin_limi
631 if debut
< debut_limite
:
636 fin
+= datetime
.timedelta(days
=1)
639 def build_qs(self
, prefix
, date_debut
, date_fin
):
641 Q(**{"%s%s__isnull" % (prefix
, KEY_DATE_DEBUT
): True})
643 Q(**{"%s%s__isnull" % (prefix
, KEY_DATE_FIN
): True})
644 date_debut_superieure_ou_egale_a_borne_gauche
= \
645 Q(**{"%s%s__gte" % (prefix
, KEY_DATE_DEBUT
): date_debut
})
646 date_debut_inferieure_ou_egale_a_borne_gauche
= \
647 Q(**{"%s%s__lte" % (prefix
, KEY_DATE_DEBUT
): date_debut
})
648 date_fin_superieure_ou_egale_a_borne_gauche
= \
649 Q(**{"%s%s__gte" % (prefix
, KEY_DATE_FIN
): date_debut
})
650 date_fin_inferieure_ou_egale_a_borne_droite
= \
651 Q(**{"%s%s__lte" % (prefix
, KEY_DATE_FIN
): date_fin
})
652 date_debut_inferieure_ou_egale_a_borne_droite
= \
653 Q(**{"%s%s__lte" % (prefix
, KEY_DATE_DEBUT
): date_fin
})
654 date_fin_superieure_ou_egale_a_borne_droite
= \
655 Q(**{"%s%s__gte" % (prefix
, KEY_DATE_FIN
): date_fin
})
659 date_debut_null
& date_fin_null
661 date_fin_superieure_ou_egale_a_borne_gauche
&
662 date_fin_inferieure_ou_egale_a_borne_droite
&
664 date_debut_inferieure_ou_egale_a_borne_gauche |
668 date_debut_superieure_ou_egale_a_borne_gauche
&
669 date_debut_inferieure_ou_egale_a_borne_droite
&
671 date_fin_superieure_ou_egale_a_borne_droite |
675 date_debut_inferieure_ou_egale_a_borne_gauche
&
676 date_fin_superieure_ou_egale_a_borne_droite
679 date_fin_superieure_ou_egale_a_borne_droite
681 date_debut_inferieure_ou_egale_a_borne_gauche
&
686 def convertir(self
, remuneration
):
687 if remuneration
.devise
!= self
.devise_base
:
689 remuneration
.montant
= float(remuneration
.montant
) * \
690 self
.trouver_taux(remuneration
.devise
).taux
691 remuneration
.devise
= self
.devise_base
692 except AttributeError:
695 def trouver_taux(self
, devise
):
696 if devise
.code
not in self
.taux_change
:
698 t
= rh
.TauxChange
.objects
.filter(
699 devise
=devise
, annee
=self
.annee
703 self
.taux_change
[devise
.code
] = t
704 return self
.taux_change
[devise
.code
]
707 self
.csv_handle
= StringIO
.StringIO()
708 csv_writer
= csv
.writer(self
.csv_handle
, delimiter
=",",
709 doublequote
=False, escapechar
="\\", quoting
=csv
.QUOTE_ALL
,
711 header
= [v
[0] for v
in self
.rapport
[0]]
712 csv_writer
.writerow(header
)
713 for row
in self
.rapport
:
714 values
= [v
[1] for v
in row
]
716 [unicode(r
).encode('utf-8') for r
in values
]
720 self
.doc
= ods
.OpenDocumentSpreadsheet()
722 nom
= u
"Masse salariale %s" % self
.annee
724 nom
+= u
" %s" % self
.region
725 elif self
.implantation
:
726 nom
+= u
" %s" % self
.implantation
728 table
= self
.doc
.add_table(name
=nom
)
730 for h
in self
.headers
:
732 table
.add_column(**h
[2])
734 table
.add_row([h
[1] for h
in self
.headers
], rowheight
='2cm')
736 for r
in self
.rapport
:
737 table
.add_row([r
[h
[0]] for h
in self
.headers
])
739 #a.doc.write('hello_world.ods')