3 from datetime
import datetime
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 project
.legacy
import models
as legacy
12 from project
.rh
import models
as rh
15 class Command(BaseCommand
):
16 help = 'Importe les données du système RH legacy'
18 def handle(self
, *args
, **options
):
19 self
.stdout
.write("Import de rh_classement...\n")
21 self
.stdout
.write("Import de rh_employe...\n")
23 self
.stdout
.write("Import de rh_familleemploi...\n")
25 self
.stdout
.write("Import de rh_typeposte...\n")
27 self
.stdout
.write("Import de rh_service...\n")
29 self
.stdout
.write("Import de rh_poste...\n")
31 self
.stdout
.write("Import de rh_organismebstg...\n")
33 self
.stdout
.write("Import de rh_statut...\n")
35 self
.stdout
.write("Import de rh_tauxchange...\n")
37 self
.stdout
.write("Import de rh_valeurpoint...\n")
39 self
.stdout
.write("Import de rh_typecontrat...\n")
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")
47 self
.stdout
.write("Import de rh_ayantdroit...\n")
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
66 cursor
= connection
.cursor()
67 cursor
.execute('TRUNCATE rh_employe')
68 cursor
.execute('TRUNCATE rh_employecommentaire')
69 odette
= User
.objects
.get(username
='odette.tremblay')
70 for fiche
in legacy
.Fiches
.objects
.extra():
71 employe
= rh
.Employe
.objects
.create(
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
,
84 province
=fiche
.etat_province
,
85 code_postal
=fiche
.code_postal_cedex
,
86 pays_id
=fiche
.pays_iso2
if fiche
.pays_iso2
!= '-1' else None,
87 date_creation
=fiche
.date_ouverture
,
88 date_modification
=fiche
.date_maj
,
90 nb_postes
=None, # meta
93 rh
.EmployeCommentaire
.objects
.create(
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
,
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(
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))
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)
134 cursor
= connection
.cursor()
135 cursor
.execute('TRUNCATE rh_poste')
136 for poste
in legacy
.ImplantationPostes
.objects
.select_related('type_poste'):
138 #legacy.Fiches.objects.filter(prenom='Odette')[0].dossiers.all()[0].ids_direction_service
140 # Aller chercher certaines informations dans le dernier dossier
142 dossiers
= legacy
.Dossiers
.objects
.filter(
143 Q(poste_1
=poste
.id_implantation_postes
) |
Q(poste_2
=poste
.id_implantation_postes
)
144 ).order_by('-id_dossier')
147 if dossiers
.count() == 0:
149 poste_du_responsable
= None
151 if dossiers
.count() > 0:
154 if d
.ids_direction_service
not in (None, ''):
158 # Déterminer le service
159 services
= dossier
.ids_direction_service
160 service
= int(services
.split('|')[0]) if services
else 1
161 if poste
.id_implantation_postes
== dossier
.poste_1
:
162 complement
= dossier
.complement_1
164 complement
= dossier
.complement_2
165 complement
= ' ' + complement
if complement
else ''
167 # Déterminer le poste du responsable
169 responsable
= dossier
.responsable
170 dossiers_du_responsable
= responsable
.dossiers
.order_by('-id_dossier')
171 if dossiers_du_responsable
.count() > 0:
172 poste_du_responsable
= dossiers_du_responsable
[0].poste_1
174 poste_du_responsable
= None
177 rh_poste
= rh
.Poste
.objects
.create(
178 id=poste
.id_implantation_postes
,
179 nom
=poste
.type_poste
.titre_poste_m
+ complement
,
180 nom_feminin
=poste
.type_poste
.titre_poste_f
+ complement
,
181 implantation_id
=poste
.id_implantation
,
182 type_poste_id
=poste
.type_poste_id
,
183 date_modification
=poste
.date_maj
,
186 responsable_id
=poste_du_responsable
,
189 if service
is None and poste
.actif
in ('0', 0, False):
190 rh_poste
.date_fin
= rh_poste
.date_modification
194 def sync_organismebstg():
195 connection
.cursor().execute('TRUNCATE rh_organismebstg')
196 for organisme
in legacy
.OrganismesBstg
.objects
.all():
197 rh
.OrganismeBstg
.objects
.create(
198 id=organisme
.id_bstg
,
199 nom
=organisme
.organisme_nom
,
200 type=organisme
.bstg_type
,
201 #actif=bool(organisme.actif)
205 connection
.cursor().execute('TRUNCATE rh_statut')
206 for statut
in legacy
.Statut
.objects
.all():
207 rh
.Statut
.objects
.create(
209 code
=statut
.statut_contractuel
,
210 nom
=statut
.description_statut_contractuel
,
211 #actif=bool(statut.actif)
214 def sync_tauxchange():
215 connection
.cursor().execute('TRUNCATE rh_tauxchange')
216 connection
.cursor().execute('TRUNCATE rh_devise')
218 # Certaines devises ont besoin d'un id spécifique (#2581)
219 rh
.Devise
.objects
.create(id=1, code
='AMD', nom
='Dram arménien')
220 rh
.Devise
.objects
.create(id=2, code
='CAD', nom
='Dollar canadien')
221 rh
.Devise
.objects
.create(id=3, code
='CAN', nom
='Dollar canadien')
222 rh
.Devise
.objects
.create(id=4, code
='DZD', nom
='Dinar algérien')
223 rh
.Devise
.objects
.create(id=5, code
='EUR', nom
='Euro')
224 rh
.Devise
.objects
.create(id=6, code
='GNF', nom
='Franc Guinéen')
225 rh
.Devise
.objects
.create(id=7, code
='KMF', nom
='Franc comorien')
226 rh
.Devise
.objects
.create(id=8, code
='LBP', nom
='Livre libanaise')
227 rh
.Devise
.objects
.create(id=9, code
='MAD', nom
='Dirham marocain')
228 rh
.Devise
.objects
.create(id=10, code
='MGF', nom
='Franc Malgache')
229 rh
.Devise
.objects
.create(id=11, code
='MRO', nom
='Ouguiya')
230 rh
.Devise
.objects
.create(id=12, code
='MUR', nom
='Roupie mauricienne')
231 rh
.Devise
.objects
.create(id=13, code
='SYP', nom
='Livre syrienne')
232 rh
.Devise
.objects
.create(id=14, code
='TND', nom
='Dinar tunisien')
233 rh
.Devise
.objects
.create(id=15, code
='US ', nom
='Dollar américain')
234 rh
.Devise
.objects
.create(id=16, code
='USD', nom
='Dollar américain')
235 rh
.Devise
.objects
.create(id=17, code
='VUV', nom
='Vatu')
236 rh
.Devise
.objects
.create(id=18, code
='XAF', nom
='Franc CFA')
237 rh
.Devise
.objects
.create(id=19, code
='XOF', nom
='Franc CFA')
239 for taux
in legacy
.TauxChangeAnnuel
.objects
.exclude(taux_annuel
=None):
242 devise
, created
= rh
.Devise
.objects
.get_or_create(code
=taux
.code_devise
)
244 devise
.nom
=taux
.nom_devise
247 # Créer le taux de change
248 rh
.TauxChange
.objects
.get_or_create(
251 taux
=taux
.taux_annuel
,
254 def sync_valeurpoint():
255 connection
.cursor().execute('TRUNCATE rh_valeurpoint')
256 for vp
in legacy
.ValeurPoint
.objects
.all():
258 # Trouver la devise associée à cette implantation
259 annee
= vp
.date_actif
[:4]
261 taux
= legacy
.TauxChangeAnnuel
.objects
.get(annee
=annee
, id_implantation
=vp
.id_implantation
)
264 devise
= rh
.Devise
.objects
.get(code
=taux
.code_devise
)
266 rh
.ValeurPoint
.objects
.create(
267 id=vp
.id_valeur_point
,
268 valeur
=vp
.valeur_point
,
269 implantation_id
=vp
.id_implantation
,
270 annee
=vp
.date_actif
[:4],
274 def sync_typecontrat():
275 connection
.cursor().execute('TRUNCATE rh_typecontrat')
276 for type in legacy
.TypeContrat
.objects
.all():
277 rh
.TypeContrat
.objects
.create(
278 id=type.id_type_contrat
,
279 nom
=type.nom_contrat
,
280 nom_long
=type.description_contrat
,
281 #actif=bool(type.actif_contrat)
284 def sync_typerevalorisation():
285 connection
.cursor().execute('TRUNCATE rh_typerevalorisation')
286 for type in legacy
.TypeRevalorisation
.objects
.all():
287 rh
.TypeRevalorisation
.objects
.create(
288 id=type.id_type_revalorisation
,
289 nom
=type.type_revalorisation
,
290 #actif=bool(type.actif)
293 def sync_typeremuneration():
294 connection
.cursor().execute('TRUNCATE rh_typeremuneration')
295 for type in legacy
.TypeRemuneration
.objects
.all():
296 rh
.TypeRemuneration
.objects
.create(
297 id=type.id_type_remuneration
,
298 nom
=type.type_remuneration
,
299 type_paiement
=type.type_paiement
,
300 nature_remuneration
=type.nature_remuneration
,
301 #actif=bool(type.actif)
306 def clean_date(date
):
307 if date
== '2003-06-31': # date inexistante (dossier 791-1)
315 def get_taux(annee
, devise
):
316 taux
= taux_cache
.get((annee
, devise
))
319 taux
= rh
.TauxChange
.objects
.filter(annee__gte
=annee
).order_by('annee')[0].taux
320 taux_cache
[(annee
, devise
)] = taux
323 cursor
= connection
.cursor()
324 cursor
.execute('TRUNCATE rh_contrat')
325 cursor
.execute('TRUNCATE rh_dossier')
326 cursor
.execute('TRUNCATE rh_remuneration')
327 cursor
.execute('TRUNCATE rh_dossiercommentaire')
328 odette
= User
.objects
.get(username
='odette.tremblay')
329 type_contrat_inconnu
= rh
.TypeContrat
.objects
.create(
333 dossiers
= legacy
.Dossiers
.objects
.annotate(timestamp_modif
=Max('historique__stamp'))
334 for dossier
in dossiers
:
335 date_modification
= datetime
.fromtimestamp(dossier
.timestamp_modif
) \
336 if dossier
.timestamp_modif
else None
337 dossier1
= rh
.Dossier
.objects
.create(
338 employe_id
=dossier
.employe_id
,
339 poste_id
=dossier
.poste_1
,
340 statut_id
=dossier
.id_statut
,
341 organisme_bstg_id
=dossier
.id_bstg
,
342 statut_residence
='expat' if dossier
.id_local_expatrie
== 1 else 'local',
343 classement_id
=dossier
.id_classement
,
344 regime_travail
=dossier
.regime_travail
,
345 date_debut
=clean_date(dossier
.date_debut_mandat
),
346 date_fin
=clean_date(dossier
.date_fin_mandat
),
347 date_modification
=date_modification
,
352 rh
.DossierCommentaire
.objects
.create(
354 texte
=dossier
.remarque
,
357 rh
.Contrat
.objects
.create(
359 type_contrat_id
=dossier
.id_type_contrat
or type_contrat_inconnu
.id,
360 date_debut
=clean_date(dossier
.date_debut_contrat
),
361 date_fin
=clean_date(dossier
.date_fin_contrat
),
366 remuns_precedentes
= {}
367 charges_precedentes
= None
368 pourcentage_charges
= 0
369 devise_charges
= rh
.Devise
.objects
.get(code
='EUR')
370 for remun
in legacy
.HistoRemuneration
.objects
.filter(no_dossier
=dossier
.no_dossier
) \
371 .order_by('id_histo_remuneration'):
373 # Calcul de la période
374 date_debut
= remun
.date_effective
375 if date_debut
== '200-08-09':
376 date_debut
= '2000-08-09'
377 elif date_debut
== '2003-06-31':
378 date_debut
= '2003-06-30'
379 if remun
.type_remuneration
.type_paiement
== 'Ponctuel':
380 date_fin
= date_debut
383 remun_precedente
= remuns_precedentes
.get(remun
.type_remuneration_id
)
385 if str(remun_precedente
.date_debut
) == str(date_debut
):
386 remun_precedente
.delete()
388 remun_precedente
.date_fin
= date_debut
389 remun_precedente
.save()
391 # Création de la ligne de rémunération
392 if remun
.type_remuneration
.nature_remuneration
!= 'Charges' and remun
.montant
!= 0:
393 devise
, created
= rh
.Devise
.objects
.get_or_create(code
=remun
.code_devise
)
395 rh_remun
= rh
.Remuneration
.objects
.create(
397 type_id
=remun
.type_remuneration_id
,
398 type_revalorisation_id
=remun
.id_type_revalorisation
,
399 montant
=Decimal(str(remun
.montant
)),
402 date_debut
=date_debut
,
406 # Se souvenir de ce type de rémunération
407 if remun
.type_remuneration
.type_paiement
== u
'Régulier':
408 remuns_precedentes
[remun
.type_remuneration_id
] = rh_remun
411 if remun
.type_remuneration
.nature_remuneration
== 'Charges':
412 pourcentage_charges
= remun
.pourcentage
414 if remun
.type_remuneration
.nature_remuneration
== 'Traitement':
415 devise_charges
= rh
.Devise
.objects
.get(code
=remun
.code_devise
)
417 if remun
.type_remuneration
.type_paiement
== u
'Régulier':
419 annee_charges
= int(date_debut
[:4])
420 taux2
= get_taux(annee_charges
, devise_charges
)
421 if pourcentage_charges
:
422 for remun_precedente
in remuns_precedentes
.values():
423 montant
= remun_precedente
.montant
424 devise
= remun_precedente
.devise
425 if devise
!= devise_charges
:
426 taux1
= get_taux(annee_charges
, devise
)
427 montant
= montant
* Decimal(str(taux1
)) / Decimal(str(taux2
))
428 if remun_precedente
.type.nature_remuneration
== 'Traitement':
429 montant
= montant
* remun_precedente
.dossier
.regime_travail
/ 100
430 montant
= montant
* pourcentage_charges
/ 100
431 montant
.quantize(remun_precedente
.montant
)
433 charges
= charges
* pourcentage_charges
/ 100
434 if charges_precedentes
:
435 if str(charges_precedentes
.date_debut
) == str(date_debut
):
436 charges_precedentes
.delete()
438 charges_precedentes
.date_fin
= date_debut
439 charges_precedentes
.save()
441 (not charges_precedentes
or charges_precedentes
.montant
!= charges
or
442 str(charges_precedentes
.date_debut
) == str(date_debut
)):
443 charges_precedentes
= rh
.Remuneration
.objects
.create(
446 type_revalorisation_id
=None,
447 montant
=Decimal(str(charges
)),
448 devise
=devise_charges
,
450 date_debut
=date_debut
,
451 commentaire
=u
'Charges patronales: %s%%' % pourcentage_charges
454 # Dossier différent pour le deuxième poste
456 dossier2
= rh
.Dossier
.objects
.create(
457 employe_id
=dossier
.employe_id
,
458 poste_id
=dossier
.poste_2
,
459 statut_id
=dossier
.id_statut
,
460 organisme_bstg_id
=dossier
.id_bstg
,
461 statut_residence
='expat' if dossier
.id_local_expatrie
== 1 else 'local',
462 classement_id
=dossier
.id_classement
,
463 regime_travail
=dossier
.regime_travail
,
464 date_debut
=clean_date(dossier
.date_debut_mandat
),
465 date_fin
=clean_date(dossier
.date_fin_mandat
),
470 rh
.DossierCommentaire
.objects
.create(
472 texte
=dossier
.remarque
,
475 rh
.Contrat
.objects
.create(
477 type_contrat_id
=dossier
.id_type_contrat
or type_contrat_inconnu
.id,
478 date_debut
=clean_date(dossier
.date_debut_contrat
),
479 date_fin
=clean_date(dossier
.date_fin_contrat
),
483 def sync_ayantdroit():
484 connection
.cursor().execute('TRUNCATE rh_ayantdroit')
485 odette
= User
.objects
.get(username
='odette.tremblay')
486 for ad
in legacy
.AyantDroit
.objects
.all():
487 rh_ad
= rh
.AyantDroit
.objects
.create(
488 id=ad
.id_ayant_droit
,
489 nom
=ad
.nom_ayant_droit
,
490 prenom
=ad
.prenom_ayant_droit
,
491 employe_id
=ad
.no_employe
,
492 lien_parente
=None if ad
.lien_parente
== 'Autre' else ad
.lien_parente
,
493 #actif=bool(ad.actif)
495 if ad
.commentaire_ayant_droit
:
496 rh
.AyantDroitCommentaire
.objects
.create(
498 texte
=ad
.commentaire_ayant_droit
,