Commit | Line | Data |
---|---|---|
ca1a7b76 EMS |
1 | # coding: utf-8 |
2 | ||
68f6108d | 3 | from datetime import datetime |
ca1a7b76 EMS |
4 | from decimal import Decimal |
5 | ||
6 | from django.contrib.auth.models import User | |
7 | from django.core.management.base import BaseCommand | |
8 | from django.db import connection | |
68f6108d | 9 | from django.db.models import Q, Max |
ca1a7b76 EMS |
10 | |
11 | from project.legacy import models as legacy | |
12 | from project.rh import models as rh | |
13 | ||
14 | ||
15 | class Command(BaseCommand): | |
16 | help = 'Importe les données du système RH legacy' | |
17 | ||
18 | def handle(self, *args, **options): | |
19 | self.stdout.write("Import de rh_classement...\n") | |
20 | sync_classement() | |
21 | self.stdout.write("Import de rh_employe...\n") | |
22 | sync_employe() | |
23 | self.stdout.write("Import de rh_familleemploi...\n") | |
24 | sync_familleemploi() | |
25 | self.stdout.write("Import de rh_typeposte...\n") | |
26 | sync_typeposte() | |
27 | self.stdout.write("Import de rh_service...\n") | |
28 | sync_service() | |
29 | self.stdout.write("Import de rh_poste...\n") | |
30 | sync_poste() | |
31 | self.stdout.write("Import de rh_organismebstg...\n") | |
32 | sync_organismebstg() | |
33 | self.stdout.write("Import de rh_statut...\n") | |
34 | sync_statut() | |
35 | self.stdout.write("Import de rh_tauxchange...\n") | |
36 | sync_tauxchange() | |
37 | self.stdout.write("Import de rh_valeurpoint...\n") | |
38 | sync_valeurpoint() | |
39 | self.stdout.write("Import de rh_typecontrat...\n") | |
40 | sync_typecontrat() | |
41 | self.stdout.write("Import de rh_typerevalorisation...\n") | |
42 | sync_typerevalorisation() | |
43 | self.stdout.write("Import de rh_typeremuneration...\n") | |
44 | sync_typeremuneration() | |
45 | self.stdout.write("Import de rh_dossier...\n") | |
46 | sync_dossier() | |
47 | self.stdout.write("Import de rh_ayantdroit...\n") | |
48 | sync_ayantdroit() | |
49 | ||
50 | ||
51 | def sync_classement(): | |
52 | connection.cursor().execute('TRUNCATE rh_classement') | |
53 | for classement in legacy.Classement.objects.all(): | |
54 | rh.Classement.objects.create( | |
55 | id=classement.id_classement, | |
56 | type=classement.type_classement, | |
57 | echelon=classement.echelon or 0, | |
58 | degre=classement.degre or 0, | |
59 | coefficient=classement.coefficient, | |
60 | commentaire=classement.commentaire, | |
61 | date_modification=classement.date_modif, | |
62 | actif=classement.actif | |
63 | ) | |
64 | ||
65 | def sync_employe(): | |
66 | cursor = connection.cursor() | |
67 | cursor.execute('TRUNCATE rh_employe') | |
68 | cursor.execute('TRUNCATE rh_employecommentaire') | |
69 | odette = User.objects.get(username='odette.tremblay') | |
68f6108d | 70 | for fiche in legacy.Fiches.objects.extra(): |
ca1a7b76 EMS |
71 | employe = rh.Employe.objects.create( |
72 | id=fiche.no_employe, | |
73 | nom=fiche.nom, | |
74 | prenom=fiche.prenom, | |
75 | nationalite_id=fiche.nationalite, | |
76 | date_naissance=fiche.date_naissance if fiche.date_naissance else None, | |
77 | genre=fiche.sexe.upper(), | |
78 | situation_famille=None if fiche.situation_famille == '-1' else fiche.situation_famille, | |
79 | date_entree=fiche.date_entree, | |
80 | tel_domicile=fiche.tel_domicile, | |
81 | tel_cellulaire=fiche.tel_cellulaire, | |
82 | adresse=fiche.no_rue, | |
83 | ville=fiche.ville, | |
84 | province=fiche.etat_province, | |
85 | code_postal=fiche.code_postal_cedex, | |
b15a6add | 86 | pays_id=fiche.pays_iso2 if fiche.pays_iso2 != '-1' else None, |
ca1a7b76 EMS |
87 | date_creation=fiche.date_ouverture, |
88 | date_modification=fiche.date_maj, | |
89 | actif=True, | |
90 | supprime=False | |
91 | ) | |
92 | if fiche.remarque: | |
93 | rh.EmployeCommentaire.objects.create( | |
94 | employe=employe, | |
95 | texte=fiche.remarque, | |
96 | owner=odette | |
97 | ) | |
98 | ||
99 | def sync_familleemploi(): | |
100 | cursor = connection.cursor() | |
101 | cursor.execute('TRUNCATE rh_familleemploi') | |
102 | for famille in legacy.FamilleEmploi.objects.all(): | |
103 | rh.FamilleEmploi.objects.create( | |
104 | id=famille.id_famille_emploi, | |
105 | nom=famille.famille_emploi, | |
106 | actif=famille.actif | |
107 | ) | |
108 | ||
109 | def sync_typeposte(): | |
110 | cursor = connection.cursor() | |
111 | cursor.execute('TRUNCATE rh_typeposte') | |
112 | for type in legacy.Postes.objects.all(): | |
113 | rh.TypePoste.objects.create( | |
114 | id=type.id_poste, | |
115 | nom=type.titre_poste_m, | |
116 | nom_feminin=type.titre_poste_f, | |
117 | is_responsable=bool(int(type.poste_responsable)), | |
118 | famille_emploi_id=type.id_famille_emploi, | |
119 | date_modification = type.datemaj, | |
120 | actif=bool(int(type.actif)) | |
121 | ) | |
122 | ||
123 | def sync_service(): | |
124 | cursor = connection.cursor() | |
125 | cursor.execute('TRUNCATE rh_service') | |
126 | for service in legacy.DirectionService.objects.all(): | |
127 | rh.Service.objects.create( | |
128 | id=service.id_direction_service, | |
129 | nom=service.direction_service, | |
130 | actif=bool(service.actif) | |
131 | ) | |
132 | ||
133 | def sync_poste(): | |
134 | cursor = connection.cursor() | |
135 | cursor.execute('TRUNCATE rh_poste') | |
136 | for poste in legacy.ImplantationPostes.objects.select_related('type_poste'): | |
137 | ||
138 | # Aller chercher certaines informations dans le dernier dossier | |
139 | # associé à ce poste | |
140 | dossiers = legacy.Dossiers.objects.filter( | |
141 | Q(poste_1=poste.id_implantation_postes) | Q(poste_2=poste.id_implantation_postes) | |
142 | ).order_by('-id_dossier') | |
143 | poste_du_responsable = 149 | |
144 | service = 1 | |
145 | complement = '' | |
146 | if dossiers.count() > 0: | |
147 | dossier = dossiers[0] | |
148 | ||
149 | # Déterminer le service | |
150 | services = dossier.ids_direction_service | |
151 | service = int(services.split('|')[0]) if services else 1 | |
152 | if poste.id_implantation_postes == dossier.poste_1: | |
153 | complement = dossier.complement_1 | |
154 | else: | |
155 | complement = dossier.complement_2 | |
156 | complement = ' ' + complement if complement else '' | |
157 | ||
158 | # Déterminer le poste du responsable | |
159 | try: | |
160 | responsable = dossier.responsable | |
161 | except legacy.Fiches.DoesNotExist: | |
162 | pass | |
163 | else: | |
164 | dossiers_du_responsable = responsable.dossiers.order_by('-id_dossier') | |
165 | if dossiers_du_responsable.count() > 0: | |
166 | poste_du_responsable = dossiers_du_responsable[0].poste_1 | |
167 | ||
168 | # Créer le poste | |
169 | rh.Poste.objects.create( | |
170 | id=poste.id_implantation_postes, | |
171 | nom=poste.type_poste.titre_poste_m + complement, | |
172 | nom_feminin=poste.type_poste.titre_poste_f + complement, | |
173 | implantation_id=poste.id_implantation, | |
174 | type_poste_id=poste.type_poste_id, | |
175 | date_modification=poste.date_maj, | |
176 | actif=poste.actif, | |
177 | service_id=service, | |
178 | supprime=False, | |
179 | responsable_id=poste_du_responsable | |
180 | ) | |
181 | ||
182 | def sync_organismebstg(): | |
183 | connection.cursor().execute('TRUNCATE rh_organismebstg') | |
184 | for organisme in legacy.OrganismesBstg.objects.all(): | |
185 | rh.OrganismeBstg.objects.create( | |
186 | id=organisme.id_bstg, | |
187 | nom=organisme.organisme_nom, | |
188 | type=organisme.bstg_type, | |
189 | actif=bool(organisme.actif) | |
190 | ) | |
191 | ||
192 | def sync_statut(): | |
193 | connection.cursor().execute('TRUNCATE rh_statut') | |
194 | for statut in legacy.Statut.objects.all(): | |
195 | rh.Statut.objects.create( | |
196 | id=statut.id_statut, | |
197 | code=statut.statut_contractuel, | |
198 | nom=statut.description_statut_contractuel, | |
199 | actif=bool(statut.actif) | |
200 | ) | |
201 | ||
202 | def sync_tauxchange(): | |
203 | connection.cursor().execute('TRUNCATE rh_tauxchange') | |
204 | connection.cursor().execute('TRUNCATE rh_devise') | |
6c1ea828 EMS |
205 | |
206 | # Certaines devises ont besoin d'un id spécifique (#2581) | |
207 | rh.Devise.objects.create(id=1, code='AMD', nom='Dram arménien') | |
208 | rh.Devise.objects.create(id=2, code='CAD', nom='Dollar canadien') | |
209 | rh.Devise.objects.create(id=3, code='CAN', nom='Dollar canadien') | |
210 | rh.Devise.objects.create(id=4, code='DZD', nom='Dinar algérien') | |
211 | rh.Devise.objects.create(id=5, code='EUR', nom='Euro') | |
212 | rh.Devise.objects.create(id=6, code='GNF', nom='Franc Guinéen') | |
213 | rh.Devise.objects.create(id=7, code='KMF', nom='Franc comorien') | |
214 | rh.Devise.objects.create(id=8, code='LBP', nom='Livre libanaise') | |
215 | rh.Devise.objects.create(id=9, code='MAD', nom='Dirham marocain') | |
216 | rh.Devise.objects.create(id=10, code='MGF', nom='Franc Malgache') | |
217 | rh.Devise.objects.create(id=11, code='MRO', nom='Ouguiya') | |
218 | rh.Devise.objects.create(id=12, code='MUR', nom='Roupie mauricienne') | |
219 | rh.Devise.objects.create(id=13, code='SYP', nom='Livre syrienne') | |
220 | rh.Devise.objects.create(id=14, code='TND', nom='Dinar tunisien') | |
221 | rh.Devise.objects.create(id=15, code='US ', nom='Dollar américain') | |
222 | rh.Devise.objects.create(id=16, code='USD', nom='Dollar américain') | |
223 | rh.Devise.objects.create(id=17, code='VUV', nom='Vatu') | |
224 | rh.Devise.objects.create(id=18, code='XAF', nom='Franc CFA') | |
225 | rh.Devise.objects.create(id=19, code='XOF', nom='Franc CFA') | |
226 | ||
ca1a7b76 EMS |
227 | for taux in legacy.TauxChangeAnnuel.objects.exclude(taux_annuel=None): |
228 | ||
229 | # Créer la devise | |
68f6108d | 230 | devise, created = rh.Devise.objects.get_or_create(code=taux.code_devise) |
ca1a7b76 EMS |
231 | if created: |
232 | devise.nom=taux.nom_devise | |
233 | devise.save() | |
234 | ||
235 | # Créer le taux de change | |
236 | rh.TauxChange.objects.get_or_create( | |
237 | devise=devise, | |
238 | annee=taux.annee, | |
239 | taux=taux.taux_annuel, | |
240 | actif=True | |
241 | ) | |
242 | ||
243 | def sync_valeurpoint(): | |
244 | connection.cursor().execute('TRUNCATE rh_valeurpoint') | |
245 | for vp in legacy.ValeurPoint.objects.all(): | |
246 | ||
247 | # Trouver la devise associée à cette implantation | |
77ad307b | 248 | annee = vp.date_actif[:4] |
ca1a7b76 | 249 | try: |
77ad307b EMS |
250 | taux = legacy.TauxChangeAnnuel.objects.get(annee=annee, id_implantation=vp.id_implantation) |
251 | except: | |
2e31de9f EMS |
252 | continue |
253 | devise = rh.Devise.objects.get(code=taux.code_devise) | |
ca1a7b76 EMS |
254 | |
255 | rh.ValeurPoint.objects.create( | |
256 | id=vp.id_valeur_point, | |
257 | valeur=vp.valeur_point, | |
258 | implantation_id=vp.id_implantation, | |
259 | annee=vp.date_actif[:4], | |
260 | actif=True, | |
261 | devise=devise | |
262 | ) | |
263 | ||
264 | def sync_typecontrat(): | |
265 | connection.cursor().execute('TRUNCATE rh_typecontrat') | |
266 | for type in legacy.TypeContrat.objects.all(): | |
267 | rh.TypeContrat.objects.create( | |
268 | id=type.id_type_contrat, | |
269 | nom=type.nom_contrat, | |
270 | nom_long=type.description_contrat, | |
271 | actif=bool(type.actif_contrat) | |
272 | ) | |
273 | ||
274 | def sync_typerevalorisation(): | |
275 | connection.cursor().execute('TRUNCATE rh_typerevalorisation') | |
276 | for type in legacy.TypeRevalorisation.objects.all(): | |
277 | rh.TypeRevalorisation.objects.create( | |
278 | id=type.id_type_revalorisation, | |
279 | nom=type.type_revalorisation, | |
280 | actif=bool(type.actif) | |
281 | ) | |
282 | ||
283 | def sync_typeremuneration(): | |
284 | connection.cursor().execute('TRUNCATE rh_typeremuneration') | |
285 | for type in legacy.TypeRemuneration.objects.all(): | |
286 | rh.TypeRemuneration.objects.create( | |
287 | id=type.id_type_remuneration, | |
288 | nom=type.type_remuneration, | |
289 | type_paiement=type.type_paiement, | |
290 | nature_remuneration=type.nature_remuneration, | |
291 | actif=bool(type.actif) | |
292 | ) | |
293 | ||
294 | def sync_dossier(): | |
295 | ||
296 | def clean_date(date): | |
297 | if date == '2003-06-31': # date inexistante (dossier 791-1) | |
298 | return '2003-06-30' | |
299 | elif date: | |
300 | return date | |
301 | else: | |
302 | return None | |
303 | ||
304 | taux_cache = {} | |
305 | def get_taux(annee, devise): | |
306 | taux = taux_cache.get((annee, devise)) | |
307 | if taux is not None: | |
308 | return taux | |
309 | taux = rh.TauxChange.objects.filter(annee__gte=annee).order_by('annee')[0].taux | |
310 | taux_cache[(annee, devise)] = taux | |
311 | return taux | |
312 | ||
313 | cursor = connection.cursor() | |
314 | cursor.execute('TRUNCATE rh_contrat') | |
315 | cursor.execute('TRUNCATE rh_dossier') | |
316 | cursor.execute('TRUNCATE rh_remuneration') | |
317 | cursor.execute('TRUNCATE rh_dossiercommentaire') | |
318 | odette = User.objects.get(username='odette.tremblay') | |
319 | type_contrat_inconnu = rh.TypeContrat.objects.create( | |
320 | nom='Inconnu', | |
321 | nom_long='Inconnu', | |
322 | actif=False | |
323 | ) | |
68f6108d EMS |
324 | dossiers = legacy.Dossiers.objects.annotate(timestamp_modif=Max('historique__stamp')) |
325 | for dossier in dossiers: | |
326 | date_modification = datetime.fromtimestamp(dossier.timestamp_modif) \ | |
327 | if dossier.timestamp_modif else None | |
ca1a7b76 EMS |
328 | dossier1 = rh.Dossier.objects.create( |
329 | employe_id=dossier.employe_id, | |
330 | poste_id=dossier.poste_1, | |
331 | statut_id=dossier.id_statut, | |
332 | organisme_bstg_id=dossier.id_bstg, | |
333 | statut_residence='expat' if dossier.id_local_expatrie == 1 else 'local', | |
334 | classement_id=dossier.id_classement, | |
335 | regime_travail=dossier.regime_travail, | |
336 | date_debut=clean_date(dossier.date_debut_mandat), | |
337 | date_fin=clean_date(dossier.date_fin_mandat), | |
68f6108d | 338 | date_modification=date_modification, |
ca1a7b76 EMS |
339 | remplacement=False, |
340 | actif=True, | |
341 | supprime=False | |
342 | ) | |
343 | if dossier.remarque: | |
344 | rh.DossierCommentaire.objects.create( | |
345 | dossier=dossier1, | |
346 | texte=dossier.remarque, | |
347 | owner=odette | |
348 | ) | |
349 | rh.Contrat.objects.create( | |
350 | dossier=dossier1, | |
351 | type_contrat_id=dossier.id_type_contrat or type_contrat_inconnu.id, | |
352 | date_debut=clean_date(dossier.date_debut_contrat), | |
353 | date_fin=clean_date(dossier.date_fin_contrat), | |
354 | actif=True, | |
355 | supprime=False | |
356 | ) | |
357 | ||
358 | ||
359 | remuns_precedentes = {} | |
360 | charges_precedentes = None | |
361 | pourcentage_charges = 0 | |
362 | devise_charges = rh.Devise.objects.get(code='EUR') | |
363 | for remun in legacy.HistoRemuneration.objects.filter(no_dossier=dossier.no_dossier) \ | |
364 | .order_by('id_histo_remuneration'): | |
365 | ||
366 | # Calcul de la période | |
367 | date_debut = remun.date_effective | |
368 | if date_debut == '200-08-09': | |
369 | date_debut = '2000-08-09' | |
370 | elif date_debut == '2003-06-31': | |
371 | date_debut = '2003-06-30' | |
372 | if remun.type_remuneration.type_paiement == 'Ponctuel': | |
373 | date_fin = date_debut | |
374 | else: | |
375 | date_fin = None | |
376 | remun_precedente = remuns_precedentes.get(remun.type_remuneration_id) | |
377 | if remun_precedente: | |
378 | if str(remun_precedente.date_debut) == str(date_debut): | |
379 | remun_precedente.delete() | |
380 | else: | |
381 | remun_precedente.date_fin = date_debut | |
382 | remun_precedente.save() | |
383 | ||
384 | # Création de la ligne de rémunération | |
385 | if remun.type_remuneration.nature_remuneration != 'Charges' and remun.montant != 0: | |
386 | devise, created = rh.Devise.objects.get_or_create(code=remun.code_devise) | |
387 | ||
388 | rh_remun = rh.Remuneration.objects.create( | |
389 | actif=True, | |
390 | dossier=dossier1, | |
391 | type_id=remun.type_remuneration_id, | |
392 | type_revalorisation_id=remun.id_type_revalorisation, | |
393 | montant=remun.montant, | |
394 | devise=devise, | |
395 | supprime=False, | |
396 | date_debut=date_debut, | |
397 | date_fin=date_fin | |
398 | ) | |
399 | ||
400 | # Se souvenir de ce type de rémunération | |
401 | if remun.type_remuneration.type_paiement == u'Régulier': | |
402 | remuns_precedentes[remun.type_remuneration_id] = rh_remun | |
403 | ||
404 | # Charges patronales | |
405 | if remun.type_remuneration.nature_remuneration == 'Charges': | |
406 | pourcentage_charges = remun.pourcentage | |
407 | ||
408 | if remun.type_remuneration.nature_remuneration == 'Traitement': | |
409 | devise_charges = rh.Devise.objects.get(code=remun.code_devise) | |
410 | ||
411 | if remun.type_remuneration.type_paiement == u'Régulier': | |
412 | charges = 0 | |
413 | annee_charges = int(date_debut[:4]) | |
414 | taux2 = get_taux(annee_charges, devise_charges) | |
415 | if pourcentage_charges: | |
416 | for remun_precedente in remuns_precedentes.values(): | |
417 | montant = remun_precedente.montant | |
418 | devise = remun_precedente.devise | |
419 | if devise != devise_charges: | |
420 | taux1 = get_taux(annee_charges, devise) | |
421 | montant = montant * Decimal(str(taux1)) / Decimal(str(taux2)) | |
422 | if remun_precedente.type.nature_remuneration == 'Traitement': | |
423 | montant = montant * remun_precedente.dossier.regime_travail / 100 | |
424 | montant = montant * pourcentage_charges / 100 | |
425 | montant.quantize(remun_precedente.montant) | |
426 | charges += montant | |
427 | charges = charges * pourcentage_charges / 100 | |
428 | if charges_precedentes: | |
429 | if str(charges_precedentes.date_debut) == str(date_debut): | |
430 | charges_precedentes.delete() | |
431 | else: | |
432 | charges_precedentes.date_fin = date_debut | |
433 | charges_precedentes.save() | |
434 | if charges > 0 and \ | |
435 | (not charges_precedentes or charges_precedentes.montant != charges or | |
436 | str(charges_precedentes.date_debut) == str(date_debut)): | |
437 | charges_precedentes = rh.Remuneration.objects.create( | |
438 | actif=True, | |
439 | dossier=dossier1, | |
440 | type_id=17, | |
441 | type_revalorisation_id=None, | |
442 | montant=charges, | |
443 | devise=devise_charges, | |
444 | supprime=False, | |
445 | date_debut=date_debut, | |
446 | commentaire=u'Charges patronales: %s%%' % pourcentage_charges | |
447 | ) | |
448 | ||
449 | # Dossier différent pour le deuxième poste | |
450 | if dossier.poste_2: | |
451 | dossier2 = rh.Dossier.objects.create( | |
452 | employe_id=dossier.employe_id, | |
453 | poste_id=dossier.poste_2, | |
454 | statut_id=dossier.id_statut, | |
455 | organisme_bstg_id=dossier.id_bstg, | |
456 | statut_residence='expat' if dossier.id_local_expatrie == 1 else 'local', | |
457 | classement_id=dossier.id_classement, | |
458 | regime_travail=dossier.regime_travail, | |
459 | date_debut=clean_date(dossier.date_debut_mandat), | |
460 | date_fin=clean_date(dossier.date_fin_mandat), | |
461 | remplacement=False, | |
462 | actif=True, | |
463 | supprime=False | |
464 | ) | |
68f6108d EMS |
465 | if dossier.remarque: |
466 | rh.DossierCommentaire.objects.create( | |
467 | dossier=dossier2, | |
468 | texte=dossier.remarque, | |
469 | owner=odette | |
470 | ) | |
471 | rh.Contrat.objects.create( | |
ca1a7b76 | 472 | dossier=dossier2, |
68f6108d EMS |
473 | type_contrat_id=dossier.id_type_contrat or type_contrat_inconnu.id, |
474 | date_debut=clean_date(dossier.date_debut_contrat), | |
475 | date_fin=clean_date(dossier.date_fin_contrat), | |
476 | actif=True, | |
477 | supprime=False | |
ca1a7b76 | 478 | ) |
ca1a7b76 EMS |
479 | |
480 | def sync_ayantdroit(): | |
481 | connection.cursor().execute('TRUNCATE rh_ayantdroit') | |
482 | odette = User.objects.get(username='odette.tremblay') | |
483 | for ad in legacy.AyantDroit.objects.all(): | |
484 | rh_ad = rh.AyantDroit.objects.create( | |
485 | id=ad.id_ayant_droit, | |
486 | nom=ad.nom_ayant_droit, | |
487 | prenom=ad.prenom_ayant_droit, | |
488 | employe_id=ad.no_employe, | |
489 | lien_parente=None if ad.lien_parente == 'Autre' else ad.lien_parente, | |
490 | actif=bool(ad.actif) | |
491 | ) | |
492 | if ad.commentaire_ayant_droit: | |
493 | rh.AyantDroitCommentaire.objects.create( | |
494 | ayant_droit=rh_ad, | |
495 | texte=ad.commentaire_ayant_droit, | |
496 | owner=odette | |
497 | ) |