Migration remuneration from float to decimal and data migrate
[auf_rh_dae.git] / project / legacy / management / commands / rh_import_legacy.py
CommitLineData
ca1a7b76
EMS
1# coding: utf-8
2
68f6108d 3from datetime import datetime
ca1a7b76
EMS
4from decimal import Decimal
5
6from django.contrib.auth.models import User
7from django.core.management.base import BaseCommand
8from django.db import connection
68f6108d 9from django.db.models import Q, Max
ca1a7b76
EMS
10
11from project.legacy import models as legacy
12from project.rh import models as rh
13
14
15class 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
51def 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,
e4cec79e 62 #actif=classement.actif
ca1a7b76
EMS
63 )
64
65def 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,
e4cec79e
OL
89 supprime=False,
90 nb_postes=None, # meta
ca1a7b76
EMS
91 )
92 if fiche.remarque:
93 rh.EmployeCommentaire.objects.create(
94 employe=employe,
95 texte=fiche.remarque,
96 owner=odette
97 )
98
99def 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,
e4cec79e 106 #actif=famille.actif
ca1a7b76
EMS
107 )
108
109def 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,
e4cec79e 120 #actif=bool(int(type.actif))
ca1a7b76
EMS
121 )
122
123def 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,
e4cec79e 130 #actif=bool(service.actif)
ca1a7b76
EMS
131 )
132
133def 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,
ca1a7b76
EMS
176 service_id=service,
177 supprime=False,
e4cec79e 178 responsable_id=poste_du_responsable,
ca1a7b76
EMS
179 )
180
181def sync_organismebstg():
182 connection.cursor().execute('TRUNCATE rh_organismebstg')
183 for organisme in legacy.OrganismesBstg.objects.all():
184 rh.OrganismeBstg.objects.create(
185 id=organisme.id_bstg,
186 nom=organisme.organisme_nom,
187 type=organisme.bstg_type,
e4cec79e 188 #actif=bool(organisme.actif)
ca1a7b76
EMS
189 )
190
191def sync_statut():
192 connection.cursor().execute('TRUNCATE rh_statut')
193 for statut in legacy.Statut.objects.all():
194 rh.Statut.objects.create(
195 id=statut.id_statut,
196 code=statut.statut_contractuel,
197 nom=statut.description_statut_contractuel,
e4cec79e 198 #actif=bool(statut.actif)
ca1a7b76
EMS
199 )
200
201def sync_tauxchange():
202 connection.cursor().execute('TRUNCATE rh_tauxchange')
203 connection.cursor().execute('TRUNCATE rh_devise')
6c1ea828
EMS
204
205 # Certaines devises ont besoin d'un id spécifique (#2581)
206 rh.Devise.objects.create(id=1, code='AMD', nom='Dram arménien')
207 rh.Devise.objects.create(id=2, code='CAD', nom='Dollar canadien')
208 rh.Devise.objects.create(id=3, code='CAN', nom='Dollar canadien')
209 rh.Devise.objects.create(id=4, code='DZD', nom='Dinar algérien')
210 rh.Devise.objects.create(id=5, code='EUR', nom='Euro')
211 rh.Devise.objects.create(id=6, code='GNF', nom='Franc Guinéen')
212 rh.Devise.objects.create(id=7, code='KMF', nom='Franc comorien')
213 rh.Devise.objects.create(id=8, code='LBP', nom='Livre libanaise')
214 rh.Devise.objects.create(id=9, code='MAD', nom='Dirham marocain')
215 rh.Devise.objects.create(id=10, code='MGF', nom='Franc Malgache')
216 rh.Devise.objects.create(id=11, code='MRO', nom='Ouguiya')
217 rh.Devise.objects.create(id=12, code='MUR', nom='Roupie mauricienne')
218 rh.Devise.objects.create(id=13, code='SYP', nom='Livre syrienne')
219 rh.Devise.objects.create(id=14, code='TND', nom='Dinar tunisien')
220 rh.Devise.objects.create(id=15, code='US ', nom='Dollar américain')
221 rh.Devise.objects.create(id=16, code='USD', nom='Dollar américain')
222 rh.Devise.objects.create(id=17, code='VUV', nom='Vatu')
223 rh.Devise.objects.create(id=18, code='XAF', nom='Franc CFA')
224 rh.Devise.objects.create(id=19, code='XOF', nom='Franc CFA')
225
ca1a7b76
EMS
226 for taux in legacy.TauxChangeAnnuel.objects.exclude(taux_annuel=None):
227
228 # Créer la devise
68f6108d 229 devise, created = rh.Devise.objects.get_or_create(code=taux.code_devise)
ca1a7b76
EMS
230 if created:
231 devise.nom=taux.nom_devise
232 devise.save()
233
234 # Créer le taux de change
235 rh.TauxChange.objects.get_or_create(
236 devise=devise,
237 annee=taux.annee,
238 taux=taux.taux_annuel,
ca1a7b76
EMS
239 )
240
241def sync_valeurpoint():
242 connection.cursor().execute('TRUNCATE rh_valeurpoint')
243 for vp in legacy.ValeurPoint.objects.all():
244
245 # Trouver la devise associée à cette implantation
77ad307b 246 annee = vp.date_actif[:4]
ca1a7b76 247 try:
77ad307b
EMS
248 taux = legacy.TauxChangeAnnuel.objects.get(annee=annee, id_implantation=vp.id_implantation)
249 except:
2e31de9f
EMS
250 continue
251 devise = rh.Devise.objects.get(code=taux.code_devise)
ca1a7b76
EMS
252
253 rh.ValeurPoint.objects.create(
254 id=vp.id_valeur_point,
255 valeur=vp.valeur_point,
256 implantation_id=vp.id_implantation,
257 annee=vp.date_actif[:4],
ca1a7b76
EMS
258 devise=devise
259 )
260
261def sync_typecontrat():
262 connection.cursor().execute('TRUNCATE rh_typecontrat')
263 for type in legacy.TypeContrat.objects.all():
264 rh.TypeContrat.objects.create(
265 id=type.id_type_contrat,
266 nom=type.nom_contrat,
267 nom_long=type.description_contrat,
e4cec79e 268 #actif=bool(type.actif_contrat)
ca1a7b76
EMS
269 )
270
271def sync_typerevalorisation():
272 connection.cursor().execute('TRUNCATE rh_typerevalorisation')
273 for type in legacy.TypeRevalorisation.objects.all():
274 rh.TypeRevalorisation.objects.create(
275 id=type.id_type_revalorisation,
276 nom=type.type_revalorisation,
e4cec79e 277 #actif=bool(type.actif)
ca1a7b76
EMS
278 )
279
280def sync_typeremuneration():
281 connection.cursor().execute('TRUNCATE rh_typeremuneration')
282 for type in legacy.TypeRemuneration.objects.all():
283 rh.TypeRemuneration.objects.create(
284 id=type.id_type_remuneration,
285 nom=type.type_remuneration,
286 type_paiement=type.type_paiement,
287 nature_remuneration=type.nature_remuneration,
e4cec79e 288 #actif=bool(type.actif)
ca1a7b76
EMS
289 )
290
291def sync_dossier():
292
293 def clean_date(date):
294 if date == '2003-06-31': # date inexistante (dossier 791-1)
295 return '2003-06-30'
296 elif date:
297 return date
298 else:
299 return None
300
301 taux_cache = {}
302 def get_taux(annee, devise):
303 taux = taux_cache.get((annee, devise))
304 if taux is not None:
305 return taux
306 taux = rh.TauxChange.objects.filter(annee__gte=annee).order_by('annee')[0].taux
307 taux_cache[(annee, devise)] = taux
308 return taux
309
310 cursor = connection.cursor()
311 cursor.execute('TRUNCATE rh_contrat')
312 cursor.execute('TRUNCATE rh_dossier')
313 cursor.execute('TRUNCATE rh_remuneration')
314 cursor.execute('TRUNCATE rh_dossiercommentaire')
315 odette = User.objects.get(username='odette.tremblay')
316 type_contrat_inconnu = rh.TypeContrat.objects.create(
317 nom='Inconnu',
318 nom_long='Inconnu',
ca1a7b76 319 )
68f6108d
EMS
320 dossiers = legacy.Dossiers.objects.annotate(timestamp_modif=Max('historique__stamp'))
321 for dossier in dossiers:
322 date_modification = datetime.fromtimestamp(dossier.timestamp_modif) \
323 if dossier.timestamp_modif else None
ca1a7b76
EMS
324 dossier1 = rh.Dossier.objects.create(
325 employe_id=dossier.employe_id,
326 poste_id=dossier.poste_1,
327 statut_id=dossier.id_statut,
328 organisme_bstg_id=dossier.id_bstg,
329 statut_residence='expat' if dossier.id_local_expatrie == 1 else 'local',
330 classement_id=dossier.id_classement,
331 regime_travail=dossier.regime_travail,
332 date_debut=clean_date(dossier.date_debut_mandat),
333 date_fin=clean_date(dossier.date_fin_mandat),
68f6108d 334 date_modification=date_modification,
ca1a7b76 335 remplacement=False,
ca1a7b76
EMS
336 supprime=False
337 )
338 if dossier.remarque:
339 rh.DossierCommentaire.objects.create(
340 dossier=dossier1,
341 texte=dossier.remarque,
342 owner=odette
343 )
344 rh.Contrat.objects.create(
345 dossier=dossier1,
346 type_contrat_id=dossier.id_type_contrat or type_contrat_inconnu.id,
347 date_debut=clean_date(dossier.date_debut_contrat),
348 date_fin=clean_date(dossier.date_fin_contrat),
ca1a7b76
EMS
349 supprime=False
350 )
351
352
353 remuns_precedentes = {}
354 charges_precedentes = None
355 pourcentage_charges = 0
356 devise_charges = rh.Devise.objects.get(code='EUR')
357 for remun in legacy.HistoRemuneration.objects.filter(no_dossier=dossier.no_dossier) \
358 .order_by('id_histo_remuneration'):
359
360 # Calcul de la période
361 date_debut = remun.date_effective
362 if date_debut == '200-08-09':
363 date_debut = '2000-08-09'
364 elif date_debut == '2003-06-31':
365 date_debut = '2003-06-30'
366 if remun.type_remuneration.type_paiement == 'Ponctuel':
367 date_fin = date_debut
368 else:
369 date_fin = None
370 remun_precedente = remuns_precedentes.get(remun.type_remuneration_id)
371 if remun_precedente:
372 if str(remun_precedente.date_debut) == str(date_debut):
373 remun_precedente.delete()
374 else:
375 remun_precedente.date_fin = date_debut
376 remun_precedente.save()
377
378 # Création de la ligne de rémunération
379 if remun.type_remuneration.nature_remuneration != 'Charges' and remun.montant != 0:
380 devise, created = rh.Devise.objects.get_or_create(code=remun.code_devise)
381
382 rh_remun = rh.Remuneration.objects.create(
ca1a7b76
EMS
383 dossier=dossier1,
384 type_id=remun.type_remuneration_id,
385 type_revalorisation_id=remun.id_type_revalorisation,
386 montant=remun.montant,
387 devise=devise,
388 supprime=False,
389 date_debut=date_debut,
390 date_fin=date_fin
391 )
392
393 # Se souvenir de ce type de rémunération
394 if remun.type_remuneration.type_paiement == u'Régulier':
395 remuns_precedentes[remun.type_remuneration_id] = rh_remun
396
397 # Charges patronales
398 if remun.type_remuneration.nature_remuneration == 'Charges':
399 pourcentage_charges = remun.pourcentage
400
401 if remun.type_remuneration.nature_remuneration == 'Traitement':
402 devise_charges = rh.Devise.objects.get(code=remun.code_devise)
403
404 if remun.type_remuneration.type_paiement == u'Régulier':
405 charges = 0
406 annee_charges = int(date_debut[:4])
407 taux2 = get_taux(annee_charges, devise_charges)
408 if pourcentage_charges:
409 for remun_precedente in remuns_precedentes.values():
410 montant = remun_precedente.montant
411 devise = remun_precedente.devise
412 if devise != devise_charges:
413 taux1 = get_taux(annee_charges, devise)
414 montant = montant * Decimal(str(taux1)) / Decimal(str(taux2))
415 if remun_precedente.type.nature_remuneration == 'Traitement':
416 montant = montant * remun_precedente.dossier.regime_travail / 100
417 montant = montant * pourcentage_charges / 100
418 montant.quantize(remun_precedente.montant)
419 charges += montant
420 charges = charges * pourcentage_charges / 100
421 if charges_precedentes:
422 if str(charges_precedentes.date_debut) == str(date_debut):
423 charges_precedentes.delete()
424 else:
425 charges_precedentes.date_fin = date_debut
426 charges_precedentes.save()
427 if charges > 0 and \
428 (not charges_precedentes or charges_precedentes.montant != charges or
429 str(charges_precedentes.date_debut) == str(date_debut)):
430 charges_precedentes = rh.Remuneration.objects.create(
ca1a7b76
EMS
431 dossier=dossier1,
432 type_id=17,
433 type_revalorisation_id=None,
434 montant=charges,
435 devise=devise_charges,
436 supprime=False,
437 date_debut=date_debut,
438 commentaire=u'Charges patronales: %s%%' % pourcentage_charges
439 )
440
441 # Dossier différent pour le deuxième poste
442 if dossier.poste_2:
443 dossier2 = rh.Dossier.objects.create(
444 employe_id=dossier.employe_id,
445 poste_id=dossier.poste_2,
446 statut_id=dossier.id_statut,
447 organisme_bstg_id=dossier.id_bstg,
448 statut_residence='expat' if dossier.id_local_expatrie == 1 else 'local',
449 classement_id=dossier.id_classement,
450 regime_travail=dossier.regime_travail,
451 date_debut=clean_date(dossier.date_debut_mandat),
452 date_fin=clean_date(dossier.date_fin_mandat),
453 remplacement=False,
ca1a7b76
EMS
454 supprime=False
455 )
68f6108d
EMS
456 if dossier.remarque:
457 rh.DossierCommentaire.objects.create(
458 dossier=dossier2,
459 texte=dossier.remarque,
460 owner=odette
461 )
462 rh.Contrat.objects.create(
ca1a7b76 463 dossier=dossier2,
68f6108d
EMS
464 type_contrat_id=dossier.id_type_contrat or type_contrat_inconnu.id,
465 date_debut=clean_date(dossier.date_debut_contrat),
466 date_fin=clean_date(dossier.date_fin_contrat),
68f6108d 467 supprime=False
ca1a7b76 468 )
ca1a7b76
EMS
469
470def sync_ayantdroit():
471 connection.cursor().execute('TRUNCATE rh_ayantdroit')
472 odette = User.objects.get(username='odette.tremblay')
473 for ad in legacy.AyantDroit.objects.all():
474 rh_ad = rh.AyantDroit.objects.create(
475 id=ad.id_ayant_droit,
476 nom=ad.nom_ayant_droit,
477 prenom=ad.prenom_ayant_droit,
478 employe_id=ad.no_employe,
479 lien_parente=None if ad.lien_parente == 'Autre' else ad.lien_parente,
e4cec79e 480 #actif=bool(ad.actif)
ca1a7b76
EMS
481 )
482 if ad.commentaire_ayant_droit:
483 rh.AyantDroitCommentaire.objects.create(
484 ayant_droit=rh_ad,
485 texte=ad.commentaire_ayant_droit,
486 owner=odette
487 )