3 from datetime
import datetime
, date
4 from decimal
import Decimal
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
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
16 if date
== '2003-06-31': # date inexistante (dossier 791-1)
24 class Command(BaseCommand
):
25 help = 'Importe les données du système RH legacy'
27 def handle(self
, *args
, **options
):
28 self
.stdout
.write("Import de rh_classement...\n")
30 self
.stdout
.write("Import de rh_employe...\n")
32 self
.stdout
.write("Import de rh_familleemploi...\n")
34 self
.stdout
.write("Import de rh_typeposte...\n")
36 self
.stdout
.write("Import de rh_service...\n")
38 self
.stdout
.write("Import de rh_poste...\n")
40 self
.stdout
.write("Import de rh_organismebstg...\n")
42 self
.stdout
.write("Import de rh_statut...\n")
44 self
.stdout
.write("Import de rh_tauxchange...\n")
46 self
.stdout
.write("Import de rh_valeurpoint...\n")
48 self
.stdout
.write("Import de rh_typecontrat...\n")
50 self
.stdout
.write("Import de rh_typerevalorisation...\n")
51 sync_typerevalorisation()
52 self
.stdout
.write("Import de rh_typeremuneration...\n")
53 sync_typeremuneration()
54 self
.stdout
.write("Import de rh_dossier...\n")
56 self
.stdout
.write("Import de rh_ayantdroit...\n")
58 self
.stdout
.write("Setup des devises dans rh.Poste...\n")
62 def sync_classement():
63 connection
.cursor().execute('TRUNCATE rh_classement')
64 for classement
in legacy
.Classement
.objects
.all():
65 rh
.Classement
.objects
.create(
66 id=classement
.id_classement
,
67 type=classement
.type_classement
,
68 echelon
=classement
.echelon
or 0,
69 degre
=classement
.degre
or 0,
70 coefficient
=classement
.coefficient
,
71 commentaire
=classement
.commentaire
,
72 date_modification
=classement
.date_modif
,
73 #actif=classement.actif
77 cursor
= connection
.cursor()
78 cursor
.execute('TRUNCATE rh_employe')
79 cursor
.execute('TRUNCATE rh_employecommentaire')
80 odette
= User
.objects
.get(username
='odette.tremblay')
81 for fiche
in legacy
.Fiches
.objects
.extra():
82 employe
= rh
.Employe
.objects
.create(
86 nationalite_id
=fiche
.nationalite
,
87 date_naissance
=fiche
.date_naissance
if fiche
.date_naissance
else None,
88 genre
=fiche
.sexe
.upper(),
89 situation_famille
=None if fiche
.situation_famille
== '-1' else fiche
.situation_famille
,
90 date_entree
=fiche
.date_entree
,
91 tel_domicile
=fiche
.tel_domicile
,
92 tel_cellulaire
=fiche
.tel_cellulaire
,
95 province
=fiche
.etat_province
,
96 code_postal
=fiche
.code_postal_cedex
,
97 pays_id
=fiche
.pays_iso2
if fiche
.pays_iso2
!= '-1' else None,
98 date_creation
=fiche
.date_ouverture
,
99 date_modification
=fiche
.date_maj
,
101 nb_postes
=None, # meta
104 rh
.EmployeCommentaire
.objects
.create(
106 texte
=fiche
.remarque
,
110 def sync_familleemploi():
111 cursor
= connection
.cursor()
112 cursor
.execute('TRUNCATE rh_familleemploi')
113 for famille
in legacy
.FamilleEmploi
.objects
.all():
114 rh
.FamilleEmploi
.objects
.create(
115 id=famille
.id_famille_emploi
,
116 nom
=famille
.famille_emploi
,
120 def sync_typeposte():
121 cursor
= connection
.cursor()
122 cursor
.execute('TRUNCATE rh_typeposte')
123 for type in legacy
.Postes
.objects
.all():
124 rh
.TypePoste
.objects
.create(
126 nom
=type.titre_poste_m
,
127 nom_feminin
=type.titre_poste_f
,
128 is_responsable
=bool(int(type.poste_responsable
)),
129 famille_emploi_id
=type.id_famille_emploi
,
130 date_modification
= type.datemaj
,
131 #actif=bool(int(type.actif))
135 cursor
= connection
.cursor()
136 cursor
.execute('TRUNCATE rh_service')
137 #for service in legacy.DirectionService.objects.all():
138 # rh.Service.objects.create(
139 # id=service.id_direction_service,
140 # nom=service.direction_service,
141 # archive=not bool(service.actif),
144 # Création des services à partir de la table de références
145 for s
in ref
.Service
.objects
.all():
146 rh
.Service
.objects
.create(
154 cursor
= connection
.cursor()
155 cursor
.execute('TRUNCATE rh_poste')
156 for poste
in legacy
.ImplantationPostes
.objects
.select_related('type_poste'):
158 #legacy.Fiches.objects.filter(prenom='Odette')[0].dossiers.all()[0].ids_direction_service
160 # Aller chercher certaines informations dans le dernier dossier
162 dossiers
= legacy
.Dossiers
.objects
.filter(
163 Q(poste_1
=poste
.id_implantation_postes
) |
Q(poste_2
=poste
.id_implantation_postes
)
164 ).order_by('-id_dossier')
167 if dossiers
.count() == 0:
169 poste_du_responsable
= None
173 if dossiers
.count() > 0:
176 if d
.ids_direction_service
not in (None, ''):
180 # Déterminer le service
181 services
= dossier
.ids_direction_service
182 service
= int(services
.split('|')[0]) if services
else 1
183 if poste
.id_implantation_postes
== dossier
.poste_1
:
184 complement
= dossier
.complement_1
186 complement
= dossier
.complement_2
187 complement
= ' ' + complement
if complement
else ''
189 # Déterminer le poste du responsable
191 responsable
= dossier
.responsable
192 dossiers_du_responsable
= responsable
.dossiers
.order_by('-id_dossier')
193 if dossiers_du_responsable
.count() > 0:
194 poste_du_responsable
= dossiers_du_responsable
[0].poste_1
196 poste_du_responsable
= None
198 date_debut
= clean_date(min(d
.date_debut_mandat
for d
in dossiers
))
199 if '' in (d
.date_fin_mandat
for d
in dossiers
):
202 date_fin
= clean_date(max(d
.date_fin_mandat
for d
in dossiers
))
205 rh_poste
= rh
.Poste
.objects
.create(
206 id=poste
.id_implantation_postes
,
207 nom
=poste
.type_poste
.titre_poste_m
+ complement
,
208 nom_feminin
=poste
.type_poste
.titre_poste_f
+ complement
,
209 implantation_id
=poste
.id_implantation
,
210 type_poste_id
=poste
.type_poste_id
,
211 date_modification
=poste
.date_maj
,
214 responsable_id
=poste_du_responsable
,
215 date_debut
=date_debut
,
219 if service
is None and poste
.actif
in ('0', 0, False):
220 rh_poste
.date_fin
= rh_poste
.date_modification
224 def sync_organismebstg():
225 connection
.cursor().execute('TRUNCATE rh_organismebstg')
226 for organisme
in legacy
.OrganismesBstg
.objects
.all():
227 rh
.OrganismeBstg
.objects
.create(
228 id=organisme
.id_bstg
,
229 nom
=organisme
.organisme_nom
,
230 type=organisme
.bstg_type
,
231 #actif=bool(organisme.actif)
235 connection
.cursor().execute('TRUNCATE rh_statut')
236 for statut
in legacy
.Statut
.objects
.all():
237 rh
.Statut
.objects
.create(
239 code
=statut
.statut_contractuel
,
240 nom
=statut
.description_statut_contractuel
,
241 #actif=bool(statut.actif)
244 def sync_tauxchange():
245 connection
.cursor().execute('TRUNCATE rh_tauxchange')
246 connection
.cursor().execute('TRUNCATE rh_devise')
248 # Certaines devises ont besoin d'un id spécifique (#2581)
249 rh
.Devise
.objects
.create(id=1, code
='AMD', nom
='Dram arménien')
250 rh
.Devise
.objects
.create(id=2, code
='CAD', nom
='Dollar canadien')
251 rh
.Devise
.objects
.create(id=3, code
='CAN', nom
='Dollar canadien')
252 rh
.Devise
.objects
.create(id=4, code
='DZD', nom
='Dinar algérien')
253 rh
.Devise
.objects
.create(id=5, code
='EUR', nom
='Euro')
254 rh
.Devise
.objects
.create(id=6, code
='GNF', nom
='Franc Guinéen')
255 rh
.Devise
.objects
.create(id=7, code
='KMF', nom
='Franc comorien')
256 rh
.Devise
.objects
.create(id=8, code
='LBP', nom
='Livre libanaise')
257 rh
.Devise
.objects
.create(id=9, code
='MAD', nom
='Dirham marocain')
258 rh
.Devise
.objects
.create(id=10, code
='MGF', nom
='Franc Malgache')
259 rh
.Devise
.objects
.create(id=11, code
='MRO', nom
='Ouguiya')
260 rh
.Devise
.objects
.create(id=12, code
='MUR', nom
='Roupie mauricienne')
261 rh
.Devise
.objects
.create(id=13, code
='SYP', nom
='Livre syrienne')
262 rh
.Devise
.objects
.create(id=14, code
='TND', nom
='Dinar tunisien')
263 rh
.Devise
.objects
.create(id=15, code
='US ', nom
='Dollar américain')
264 rh
.Devise
.objects
.create(id=16, code
='USD', nom
='Dollar américain')
265 rh
.Devise
.objects
.create(id=17, code
='VUV', nom
='Vatu')
266 rh
.Devise
.objects
.create(id=18, code
='XAF', nom
='Franc CFA')
267 rh
.Devise
.objects
.create(id=19, code
='XOF', nom
='Franc CFA')
269 for taux
in legacy
.TauxChangeAnnuel
.objects
.exclude(taux_annuel
=None):
272 devise
, created
= rh
.Devise
.objects
.get_or_create(code
=taux
.code_devise
)
274 devise
.nom
=taux
.nom_devise
277 # Créer le taux de change
278 rh
.TauxChange
.objects
.get_or_create(
281 taux
=taux
.taux_annuel
,
284 def sync_valeurpoint():
285 connection
.cursor().execute('TRUNCATE rh_valeurpoint')
286 for vp
in legacy
.ValeurPoint
.objects
.all():
288 # Trouver la devise associée à cette implantation
289 annee
= vp
.date_actif
[:4]
291 taux
= legacy
.TauxChangeAnnuel
.objects
.get(annee
=annee
, id_implantation
=vp
.id_implantation
)
294 devise
= rh
.Devise
.objects
.get(code
=taux
.code_devise
)
296 rh
.ValeurPoint
.objects
.create(
297 id=vp
.id_valeur_point
,
298 valeur
=vp
.valeur_point
,
299 implantation_id
=vp
.id_implantation
,
300 annee
=vp
.date_actif
[:4],
304 def sync_typecontrat():
305 connection
.cursor().execute('TRUNCATE rh_typecontrat')
306 for type in legacy
.TypeContrat
.objects
.all():
307 rh
.TypeContrat
.objects
.create(
308 id=type.id_type_contrat
,
309 nom
=type.nom_contrat
,
310 nom_long
=type.description_contrat
,
311 #actif=bool(type.actif_contrat)
314 def sync_typerevalorisation():
315 connection
.cursor().execute('TRUNCATE rh_typerevalorisation')
316 for type in legacy
.TypeRevalorisation
.objects
.all():
317 rh
.TypeRevalorisation
.objects
.create(
318 id=type.id_type_revalorisation
,
319 nom
=type.type_revalorisation
,
320 #actif=bool(type.actif)
323 def sync_typeremuneration():
324 connection
.cursor().execute('TRUNCATE rh_typeremuneration')
325 for type in legacy
.TypeRemuneration
.objects
.all():
326 rh
.TypeRemuneration
.objects
.create(
327 id=type.id_type_remuneration
,
328 nom
=type.type_remuneration
,
329 type_paiement
=type.type_paiement
,
330 nature_remuneration
=type.nature_remuneration
,
331 #actif=bool(type.actif)
337 def get_taux(annee
, devise
):
338 taux
= taux_cache
.get((annee
, devise
))
341 taux
= rh
.TauxChange
.objects
.filter(annee__gte
=annee
).order_by('annee')[0].taux
342 taux_cache
[(annee
, devise
)] = taux
345 cursor
= connection
.cursor()
346 cursor
.execute('TRUNCATE rh_contrat')
347 cursor
.execute('TRUNCATE rh_dossier')
348 cursor
.execute('TRUNCATE rh_remuneration')
349 cursor
.execute('TRUNCATE rh_dossiercommentaire')
350 cursor
.execute('TRUNCATE rh_responsableimplantation')
351 odette
= User
.objects
.get(username
='odette.tremblay')
352 type_contrat_inconnu
= rh
.TypeContrat
.objects
.create(
356 dossiers
= legacy
.Dossiers
.objects
.annotate(timestamp_modif
=Max('historique__stamp')) \
357 .order_by('no_dossier')
358 for dossier
in dossiers
:
359 date_modification
= datetime
.fromtimestamp(dossier
.timestamp_modif
) \
360 if dossier
.timestamp_modif
else None
361 dossier1
= rh
.Dossier
.objects
.create(
362 employe_id
=dossier
.employe_id
,
363 poste_id
=dossier
.poste_1
,
364 statut_id
=dossier
.id_statut
,
365 organisme_bstg_id
=dossier
.id_bstg
,
366 statut_residence
='expat' if dossier
.id_local_expatrie
== 1 else 'local',
367 classement_id
=dossier
.id_classement
,
368 regime_travail
=dossier
.regime_travail
,
369 date_debut
=clean_date(dossier
.date_debut_mandat
),
370 date_fin
=clean_date(dossier
.date_fin_mandat
),
371 date_modification
=date_modification
,
378 rh
.DossierCommentaire
.objects
.create(
380 texte
=dossier
.remarque
,
384 # Responsables d'implantation
385 today
= date
.today().isoformat()
386 if not dossier
.date_fin_mandat
or dossier
.date_fin_mandat
>= today
:
387 if dossier
.responsable_implantation_1
:
388 responsable
, created
= rh
.ResponsableImplantation
.objects
.get_or_create(
389 implantation_id
=dossier
.id_implantation_1
391 responsable
.employe_id
= dossier
.employe_id
393 if dossier
.responsable_implantation_2
:
394 responsable
, created
= rh
.ResponsableImplantation
.objects
.get_or_create(
395 implantation_id
=dossier
.id_implantation_2
397 responsable
.employe_id
= dossier
.employe_id
401 rh
.Contrat
.objects
.create(
403 type_contrat_id
=dossier
.id_type_contrat
or type_contrat_inconnu
.id,
404 date_debut
=clean_date(dossier
.date_debut_contrat
),
405 date_fin
=clean_date(dossier
.date_fin_contrat
),
410 remuns_precedentes
= {}
411 charges_precedentes
= None
412 pourcentage_charges
= 0
413 devise_charges
= rh
.Devise
.objects
.get(code
='EUR')
414 for remun
in legacy
.HistoRemuneration
.objects
.filter(no_dossier
=dossier
.no_dossier
) \
415 .order_by('id_histo_remuneration'):
417 # Calcul de la période
418 date_debut
= remun
.date_effective
419 if date_debut
== '200-08-09':
420 date_debut
= '2000-08-09'
421 elif date_debut
== '2003-06-31':
422 date_debut
= '2003-06-30'
423 if remun
.type_remuneration
.type_paiement
== 'Ponctuel':
424 date_fin
= date_debut
427 remun_precedente
= remuns_precedentes
.get(remun
.type_remuneration_id
)
429 if str(remun_precedente
.date_debut
) == str(date_debut
):
430 remun_precedente
.delete()
432 remun_precedente
.date_fin
= date_debut
433 remun_precedente
.save()
435 # Création de la ligne de rémunération
436 if remun
.type_remuneration
.nature_remuneration
!= 'Charges' and remun
.montant
!= 0:
437 devise
, created
= rh
.Devise
.objects
.get_or_create(code
=remun
.code_devise
)
439 rh_remun
= rh
.Remuneration
.objects
.create(
441 type_id
=remun
.type_remuneration_id
,
442 type_revalorisation_id
=remun
.id_type_revalorisation
,
443 montant
=remun
.montant
,
446 date_debut
=date_debut
,
450 # Se souvenir de ce type de rémunération
451 if remun
.type_remuneration
.type_paiement
== u
'Régulier':
452 remuns_precedentes
[remun
.type_remuneration_id
] = rh_remun
455 if remun
.type_remuneration
.nature_remuneration
== 'Charges':
456 pourcentage_charges
= remun
.pourcentage
458 if remun
.type_remuneration
.nature_remuneration
== 'Traitement':
459 devise_charges
= rh
.Devise
.objects
.get(code
=remun
.code_devise
)
461 if remun
.type_remuneration
.type_paiement
== u
'Régulier':
463 annee_charges
= int(date_debut
[:4])
464 taux2
= get_taux(annee_charges
, devise_charges
)
465 if pourcentage_charges
:
466 for remun_precedente
in remuns_precedentes
.values():
467 montant
= remun_precedente
.montant
468 devise
= remun_precedente
.devise
469 if devise
!= devise_charges
:
470 taux1
= get_taux(annee_charges
, devise
)
471 montant
= montant
* Decimal(str(taux1
)) / Decimal(str(taux2
))
472 if remun_precedente
.type.nature_remuneration
== 'Traitement':
473 montant
= montant
* remun_precedente
.dossier
.regime_travail
/ 100
474 montant
= montant
* pourcentage_charges
/ 100
475 montant
.quantize(remun_precedente
.montant
)
477 charges
= charges
* pourcentage_charges
/ 100
478 if charges_precedentes
:
479 if str(charges_precedentes
.date_debut
) == str(date_debut
):
480 charges_precedentes
.delete()
482 charges_precedentes
.date_fin
= date_debut
483 charges_precedentes
.save()
485 (not charges_precedentes
or charges_precedentes
.montant
!= charges
or
486 str(charges_precedentes
.date_debut
) == str(date_debut
)):
487 charges_precedentes
= rh
.Remuneration
.objects
.create(
490 type_revalorisation_id
=None,
491 montant
=Decimal(str(charges
)),
492 devise
=devise_charges
,
494 date_debut
=date_debut
,
495 commentaire
=u
'Charges patronales: %s%%' % pourcentage_charges
498 # Dossier différent pour le deuxième poste
500 dossier2
= rh
.Dossier
.objects
.create(
501 employe_id
=dossier
.employe_id
,
502 poste_id
=dossier
.poste_2
,
503 statut_id
=dossier
.id_statut
,
504 organisme_bstg_id
=dossier
.id_bstg
,
505 statut_residence
='expat' if dossier
.id_local_expatrie
== 1 else 'local',
506 classement_id
=dossier
.id_classement
,
507 regime_travail
=dossier
.regime_travail
,
508 date_debut
=clean_date(dossier
.date_debut_mandat
),
509 date_fin
=clean_date(dossier
.date_fin_mandat
),
514 rh
.DossierCommentaire
.objects
.create(
516 texte
=dossier
.remarque
,
519 rh
.Contrat
.objects
.create(
521 type_contrat_id
=dossier
.id_type_contrat
or type_contrat_inconnu
.id,
522 date_debut
=clean_date(dossier
.date_debut_contrat
),
523 date_fin
=clean_date(dossier
.date_fin_contrat
),
527 def sync_ayantdroit():
528 connection
.cursor().execute('TRUNCATE rh_ayantdroit')
529 odette
= User
.objects
.get(username
='odette.tremblay')
530 for ad
in legacy
.AyantDroit
.objects
.all():
531 rh_ad
= rh
.AyantDroit
.objects
.create(
532 id=ad
.id_ayant_droit
,
533 nom
=ad
.nom_ayant_droit
,
534 prenom
=ad
.prenom_ayant_droit
,
535 employe_id
=ad
.no_employe
,
536 lien_parente
=None if ad
.lien_parente
== 'Autre' else ad
.lien_parente
,
537 #actif=bool(ad.actif)
539 if ad
.commentaire_ayant_droit
:
540 rh
.AyantDroitCommentaire
.objects
.create(
542 texte
=ad
.commentaire_ayant_droit
,
547 for p
in rh
.Poste
.objects
.all():
548 if p
.implantation
is not None:
549 qs
= rh
.ValeurPoint
.objects
.filter(implantation
=p
.implantation
).order_by('-id')
552 p
.devise_min
= point
.devise
553 p
.devise_max
= point
.devise
554 p
.devise_comparaison
= point
.devise