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