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