Merge branch 'dev', remote-tracking branch 'origin' into masse_salariale_jp
[auf_rh_dae.git] / project / rh / masse_salariale.py
CommitLineData
98d6eb6c
JPC
1# -*- encoding: utf-8 -*-
2import time
3import datetime
4
5from django.db.models import Q
6
7from datamaster_modeles import models as ref
8
9import rh.models as rh
10
11
12KEY_DATE_DEBUT = "debut"
13KEY_DATE_FIN = "fin"
4d17560e
JPC
14
15TYPE_REMUN_BSTG = (3,)
16TYPE_REMUN_MAD = (2,)
17TYPE_REMUN_BASE = (1,)
18TYPE_REMUN_FONC_RESP = (7,8)
19TYPE_REMUN_EXPAT = (4,)
20TYPE_REMUN_LOGEMENT = (6,)
21TYPE_REMUN_TRANSP = (9,)
22TYPE_REMUN_13E = (18,)
23TYPE_REMUN_AUTRE_RECURR_NOT = (1,2,3,4,6,7,8,9,18,13,14,15,19)
24TYPE_PAIEMENT_PONCTUEL = u"Ponctuel"
9163be6f
JPC
25
26
98d6eb6c
JPC
27class MasseSalariale():
28 """ Rapport de la masse salariale. """
29
30 def __init__(self, date_debut, date_fin):
31 """ date_debut: date de début pour les données temporelles
32 date_fin: idem
33 """
34 date_debut = datetime.date(
35 *time.strptime(date_debut, "%d-%m-%Y")[0:3]
36 )
37 date_fin = datetime.date(*time.strptime(date_fin, "%d-%m-%Y")[0:3])
9163be6f 38 rapport_date_delta = date_fin - date_debut
98d6eb6c
JPC
39
40 self.annee = date_fin.year
41
42 self.devise_base = rh.Devise.objects.filter(code='EUR')[0]
43 self.taux_change = {}
44
45 q_range = self.build_qs("date_", date_debut, date_fin)
46 q_range_d = self.build_qs("dossier__date_", date_debut, date_fin)
47 remunerations = rh.Remuneration.objects.filter(q_range) \
48 .filter(q_range_d) \
49 .exclude(supprime=True) \
50 .select_related("dossier", "dossier_employe", "dossier_poste")
51
52 employes = {}
53 for r in remunerations:
54 if r.dossier.employe_id not in employes:
9163be6f
JPC
55 employes[r.dossier.employe_id] = {
56 'dossiers': set(),
57 'remunerations': []
58 }
98d6eb6c
JPC
59 employes[r.dossier.employe_id]['remunerations'].append(r)
60 employes[r.dossier.employe_id]['dossiers'].add(r.dossier)
61
62 self.employes = employes
9163be6f 63
98d6eb6c
JPC
64 self.rapport = []
65
66 pays_list = ref.Pays.objects.all()
67 valeurs_point_par_imp = \
68 dict(
9163be6f
JPC
69 (v.implantation.id, v) for v in \
70 rh.ValeurPoint.objects.filter(annee=self.annee).all()
98d6eb6c
JPC
71 )
72 for item in self.employes.values():
73 dossiers = item['dossiers']
74 remuns = item['remunerations']
75 #TODO, choisir le dossier primaire
76 if len(dossiers) > 1:
77 #TODO
78 pass
79 dossier = list(dossiers)[0]
80 regime = dossier.poste.regime_travail
9163be6f 81
98d6eb6c
JPC
82 if dossier.poste.expatrie:
83 statut = "E"
84 else:
85 statut = "L"
86
9163be6f
JPC
87 #on détermine la date du début et fin du dossier si année en cours
88 try:
89 d_date_fin = dossier.date_fin \
90 if dossier.date_fin.year == date_fin.year else None
91 except AttributeError:
92 d_date_fin = None
93 try:
94 d_date_debut = dossier.date_debut \
95 if dossier.date_debut.year == date_fin.year else None
96 except AttributeError:
97 d_date_debut = None
98d6eb6c
JPC
98
99 pays = \
100 pays_list[dossier.poste.implantation.adresse_physique_pays.id]
101
102 #on détermine si les rémunérations sont tous dans la même devise
103 devise = remuns[0].devise
104 meme_devise = True
105 for r in remuns[1:]:
106 if devise != r.devise:
107 meme_devise = False
108
109 if not meme_devise:
110 for r in remuns:
111 self.convertir(r)
112
113 bstg_dossier = None
114 for d in dossiers:
115 if d.organisme_bstg:
116 bstg_dossier = d
117
9163be6f 118 bstg_remun = None
98d6eb6c 119 if bstg_dossier:
9163be6f 120 for r in bstg_dossier.rh_remunerations.all():
4d17560e 121 if r.type in TYPE_REMUN_BSTG:
9163be6f 122 bstg_remun = r
98d6eb6c 123
4d17560e
JPC
124 salaire_complement = 0.0
125 salaire_base = 0.0
126 indemnites = {
127 'fonc_resp': 0.0,
128 'expat': 0.0,
129 'logement': 0.0,
130 'transp': 0.0,
131 '13e': 0.0,
132 'autre_recurr': 0.0,
133 }
134 for r in remuns:
135 montant = float(r.montant)
136 if r.type in TYPE_REMUN_MAD:
137 salaire_complement += montant
138
139 if r.type in TYPE_REMUN_BASE:
140 salaire_base += montant
141
142 if r.type in TYPE_REMUN_FONC_RESP:
143 indemnites['fonc_resp'] += montant
144
145 if r.type in TYPE_REMUN_EXPAT:
146 indemnites['expat'] += montant
147
148 if r.type in TYPE_REMUN_LOGEMENT:
149 indemnites['logement'] += montant
150
151 if r.type in TYPE_REMUN_TRANSP:
152 indemnites['transp'] += montant
153
154 if r.type in TYPE_REMUN_13E:
155 indemnites['13e'] += montant
156
157 if r.type not in TYPE_REMUN_AUTRE_RECURR_NOT \
158 and r.type.type_paiement != TYPE_PAIEMENT_PONCTUEL:
159 indemnites['autre_recurr'] += montant
160
161 total_indemnites = sum(indemnites.values())
162
9163be6f 163 #Calcul du nombre de jours pour ce dossier.
4d17560e
JPC
164 if dossier.date_debut and dossier.date_debut > date_debut and \
165 not dossier.date_fin:
166 date_delta = date_fin - dossier.date_fin
167 elif dossier.date_fin and dossier.date_fin < date_fin and \
168 not dossier.date_debut:
169 date_delta = dossier.date_fin - date_debut
170 elif dossier.date_fin and dossier.date_debut:
171 date_delta = dossier.date_fin - date_debut
172 else:
9163be6f 173 date_delta = rapport_date_delta
98d6eb6c
JPC
174
175 item_rapport = {
176 'bureau': dossier.poste.implantation.region.code,
177 'pays': pays,
178 'implantation': dossier.poste.implantation.nom_court,
179 'type_implantation': dossier.poste.implantation.type,
180 #'imputation': None,
9163be6f
JPC
181 'valeur_point':
182 #todo valeur du point si pas présent
98d6eb6c
JPC
183 valeurs_point_par_imp.get(
184 dossier.poste.implantation_id
9163be6f 185 ),
98d6eb6c
JPC
186 'numero_employe': dossier.employe_id,
187 'nom': dossier.employe.nom.upper(),
188 'prenom': dossier.employe.prenom,
189 'type_de_poste': dossier.poste.type_poste.nom,
190 'intitule_de_poste': dossier.poste.nom,
191 'niveau': dossier.classement,
9163be6f 192 'point': "%s" %
98d6eb6c 193 dossier.classement.coefficient \
9163be6f
JPC
194 if dossier.classement and
195 dossier.classement.coefficient
98d6eb6c
JPC
196 else "",
197 'regime_de_travail': "%s %%" % regime,
198 'local_expatrie': statut,
199 'statut': dossier.statut.code,
200 'date_fin_contrat': dossier.date_fin,
9163be6f
JPC
201 'date_debut': d_date_debut,
202 'date_fin': d_date_fin,
98d6eb6c
JPC
203 'nb_jours': date_delta.days,
204 'devise': remuns[0].devise,
9163be6f
JPC
205 'salaire_bstg_annuel': bstg_remun.montant \
206 if bstg_remun else None,
207 'salaire_bstg_total':
208 self.convertir(bstg_remun) \
209 * regime * date_delta.days \
210 if bstg_remun else None,
4d17560e
JPC
211 'organisme_bstg': dossier.organisme_bstg,
212 'salaire_base_brut': \
213 salaire_base * regime * date_delta.days
214 'salaire_
98d6eb6c
JPC
215 }
216
217 self.rapport.append(item_rapport)
218
98d6eb6c
JPC
219 def build_qs(self, prefix, date_debut, date_fin):
220 date_debut_null = \
221 Q(**{"%s%s__isnull" % (prefix, KEY_DATE_DEBUT): True})
222 date_fin_null = \
223 Q(**{"%s%s__isnull" % (prefix, KEY_DATE_FIN): True})
224 date_debut_superieure_ou_egale_a_borne_gauche = \
225 Q(**{"%s%s__gte" % (prefix, KEY_DATE_DEBUT): date_debut})
226 date_debut_inferieure_ou_egale_a_borne_gauche = \
227 Q(**{"%s%s__lte" % (prefix, KEY_DATE_DEBUT): date_debut})
228 date_fin_superieure_ou_egale_a_borne_gauche = \
229 Q(**{"%s%s__gte" % (prefix, KEY_DATE_FIN): date_debut})
230 date_fin_inferieure_ou_egale_a_borne_droite = \
231 Q(**{"%s%s__lte" % (prefix, KEY_DATE_FIN): date_fin})
232 date_debut_inferieure_ou_egale_a_borne_droite = \
233 Q(**{"%s%s__lte" % (prefix, KEY_DATE_DEBUT): date_fin})
234 date_fin_superieure_ou_egale_a_borne_droite = \
235 Q(**{"%s%s__gte" % (prefix, KEY_DATE_FIN): date_fin})
236
237 q_range = \
238 (
239 date_debut_null & date_fin_null
240 ) | (
241 date_debut_inferieure_ou_egale_a_borne_gauche &
242 date_fin_superieure_ou_egale_a_borne_gauche &
243 date_fin_inferieure_ou_egale_a_borne_droite
244 ) | (
245 date_debut_superieure_ou_egale_a_borne_gauche &
246 date_debut_inferieure_ou_egale_a_borne_droite &
247 date_fin_superieure_ou_egale_a_borne_droite
248 ) | (
249 date_debut_inferieure_ou_egale_a_borne_gauche &
250 date_fin_superieure_ou_egale_a_borne_droite
251 ) | (
252 date_debut_null &
253 date_fin_superieure_ou_egale_a_borne_droite
254 ) | (
255 date_debut_inferieure_ou_egale_a_borne_gauche &
256 date_fin_null
257 )
258
259 return q_range
260
261 def convertir(self, remuneration):
9163be6f
JPC
262 if remuneration.devise != self.devise_base:
263 remuneration.montant = float(remuneration.montant) * \
264 self.trouver_taux(remuneration.devise).taux
265 remuneration.devise = self.devise_base
98d6eb6c
JPC
266
267 def trouver_taux(self, devise):
268 if devise.code not in self.taux_change:
269 t = rh.TauxChange.objects.filter(
270 devise=devise, annee=self.annee
271 )[0]
272 self.taux_change[devise.code] = t
273 return self.taux_change[devise.code]