This repository has been archived on 2023-02-21. You can view files and clone it, but cannot push or open issues or pull requests.
synchro-orleans/synchro_orleans/data/models.py

359 lines
14 KiB
Python

from csv import reader
import shutil
from os import path
from datetime import datetime
from django.db import models, transaction
from django.conf import settings
SEXES = (
('G', 'Homme'),
('F', 'Femme'),
)
BOOLEANS = {'O': True,
'N': False
}
INVOICES_DIR = 'factures'
INPUT_DATE_FORMAT = '%Y-%m-%d'
class PersonneManager(models.Manager):
attribute_mappings = {
'ID_PER': 'id',
'LIB_NOM_PERSONNE': 'nom',
'LIB_PRENOM_PERSONNE': 'prenom',
'TYP_SEXE': 'sexe',
'NUM_TELDOM_PER': 'telephone_domicile',
'NUM_TELPORT_PER': 'telephone_portable',
'NUM_TELPROF_PER': 'telephone_portable_professionnel',
'NUM_ALLOC_PER': 'numero_allocation',
'LIB_NOM_ALL': 'regime',
'LIB_NOM_CAI': 'cai',
'LIB_PAYS': 'pays',
'COD_POSTAL': 'code_postal',
'LIB_COMMUNE': 'commune',
'NUM_VOIE_ADR': 'voie',
'NUM_BAT_ADR': 'batiment',
'LIB_NOM_BTQ': 'btq',
'NUM_APPT_ADR': 'appartement',
'LIB_NOM_RUE': 'rue',
'LIB_COMP_ADR': 'complement_adresse',
}
def synchronize(self, source_file):
with open(source_file) as source:
csv_reader = reader(source, delimiter = ';')
caption = csv_reader.next()
attrs = map(lambda e: self.attribute_mappings[e], caption)
objs = ()
for row in csv_reader:
params = dict(zip(attrs, row))
# transform all inputs to unicode
for key, value in params.iteritems():
params[key] = value.decode('utf-8')
objs += (Personne(**params), )
self.all().delete()
self.bulk_create(objs)
class FamilleManager(models.Manager):
attribute_mappings = {
'ID_FAM': 'id',
'LOGIN': 'login',
'PASSWORD': 'password',
'COD_SECRET_FAM': 'code_secret',
'QF_CCAS': 'qf_ccas',
'QF_VO': 'qf_vo',
'LIB_PAYS_ADR': 'pays',
'COD_POSTAL_ADR': 'code_postal',
'LIB_COMMUNE_ADR': 'commune',
'NUM_VOIE_ADR': 'voie',
'NUM_BAT_ADR': 'batiment',
'LIB_NOM_BTQ': 'btq',
'NUM_APPT_ADR': 'appartement',
'LIB_NOM_RUE': 'rue',
'LIB_COMP_ADR': 'complement_adresse',
'NB_ENFANTS_CHARGE': 'nombre_enfants',
'ID_PER1': 'pers1',
'ID_PER2': 'pers2'
}
def synchronize(self, source_file):
with open(source_file) as source:
csv_reader = reader(source, delimiter = ';')
caption = csv_reader.next()
attrs = map(lambda e: self.attribute_mappings[e], caption)
fields = [field.name for field in self.model._meta.fields]
families = ()
families_links = ()
existing_families = dict((fam.id, fam) for fam in self.all())
links = ()
for row in csv_reader:
params = dict(zip(attrs, row))
obj_id = int(params['id'])
pers1 = params.pop('pers1')
pers2 = params.pop('pers2')
families_links += ((obj_id, pers1, pers2),)
changed = False
# transform all inputs to unicode
for key, value in params.iteritems():
params[key] = unicode(value, 'utf-8')
if obj_id not in existing_families:
families += (Famille(**params),)
else:
obj = existing_families.pop(obj_id)
for field in fields:
if getattr(obj, field) != params[field]:
changed = True
setattr(obj, field, params[field])
if changed:
obj.save()
if existing_families:
self.filter(id__in=existing_families).delete()
if families:
self.bulk_create(families)
for link in families_links:
family, pers1, pers2 = link
for person in (pers1, pers2):
try:
member = Personne.objects.get(pk=person)
famille = self.get(pk=family)
links += (LiaisonParentFamille(famille = famille,
personne = member),)
except ValueError:
pass
LiaisonParentFamille.objects.all().delete()
LiaisonParentFamille.objects.bulk_create(links)
class FactureManager(models.Manager):
attribute_mappings = {
'ID_FAC': 'id',
'ID_FAM': 'famille',
'MNT_FACTURE_FAC': 'montant',
'TYP_MONNAIE_FAC': 'devise',
'MNT_REGLE_FAC': 'montant_regle',
'MNT_SOLDE_FAC': 'solde',
'DAT_GENERATION_FAC': 'date_generation',
'DAT_LIMITEPAIE_FAC': 'date_limite_paie',
'LIB_PRENOM_PER_PAYEUR': 'prenom_payeur',
'LIB_NOM_PER_PAYEUR': 'nom_payeur',
'ON_PRELEVAUTO_INS': 'prelevement_automatique',
'DAT_DEBUT_PGE': 'debut_pge',
'DAT_FIN_PGE': 'fin_pge',
'ID_PYR': 'id_payeur_par_defaut'
}
def synchronize(self, source_file):
with open(source_file) as source:
source_pdf_directory = path.join(path.dirname(source_file), INVOICES_DIR)
csv_reader = reader(source, delimiter = ';')
caption = csv_reader.next()
attrs = map(lambda e: self.attribute_mappings[e], caption)
objs = ()
for row in csv_reader:
params = dict(zip(attrs, row))
# transform all inputs to unicode
for key, value in params.iteritems():
params[key] = unicode(value, 'utf-8')
params['prelevement_automatique'] = params['prelevement_automatique'] == 'O' or False
params['date_generation'] = datetime.strptime(params['date_generation'],
INPUT_DATE_FORMAT)
params['date_limite_paie'] = datetime.strptime(params['date_limite_paie'],
INPUT_DATE_FORMAT)
params['debut_pge'] = datetime.strptime(params['debut_pge'],
INPUT_DATE_FORMAT)
params['fin_pge'] = datetime.strptime(params['fin_pge'],
INPUT_DATE_FORMAT)
params['active'] = path.exists(settings.INVOICES_LOCATION_PATTERN.format(invoice_id = params['id']))
family = Famille.objects.get(pk = params.pop('famille'))
params['famille'] = family
objs += (Facture(**params), )
self.all().delete()
self.bulk_create(objs)
class KidManager(models.Manager):
attribute_mappings = {
'ID_FAM': 'famille',
'ID_PER': 'id_enfant',
'LIB_NOM_PER': 'nom',
'LIB_PRENOM_PER': 'prenom',
'TYP_SEXE_PER': 'sexe',
'DAT_NAISSANCE': 'date_naissance'
}
def synchronize(self, source_file):
with open(source_file) as source:
csv_reader = reader(source, delimiter = ';')
caption = csv_reader.next()
attrs = map(lambda e: self.attribute_mappings[e], caption)
objs = ()
for row in csv_reader:
params = dict(zip(attrs, row))
# transform all inputs to unicode
for key, value in params.iteritems():
params[key] = value.decode('utf-8')
family_id = params.pop('famille')
try:
params['date_naissance'] = datetime.strptime(params['date_naissance'],
INPUT_DATE_FORMAT)
except ValueError:
params.pop('date_naissance')
try:
family = Famille.objects.get(pk = family_id)
except Famille.DoesNotExist:
print "La famille %s de l'enfant kid %s n'existe pas(%s)" % (family_id, params['id_enfant'], row)
continue
params['famille'] = family
objs += (Enfant(**params), )
self.all().delete()
self.bulk_create(objs)
class Personne(models.Model):
id = models.AutoField(primary_key = True)
nom = models.CharField(max_length = 256, null = True, blank = True)
prenom = models.CharField(max_length = 256, null = True, blank = True)
sexe = models.CharField(choices = SEXES, max_length = 1, null = True)
telephone_domicile = models.CharField(max_length = 32, null = True, blank = True)
telephone_portable = models.CharField(max_length = 32, null = True, blank = True)
telephone_portable_professionnel = models.CharField(max_length = 32, null = True, blank = True)
numero_allocation = models.CharField(max_length = 32, null = True, blank = True)
regime = models.CharField(max_length = 32, null = True, blank = True)
cai = models.CharField(max_length = 32, null = True, blank = True)
pays = models.CharField(max_length = 32, null = True, blank = True)
code_postal = models.CharField(max_length = 16, null = True, blank = True)
commune = models.CharField(max_length = 32, null = True, blank = True)
voie = models.CharField(max_length = 32, null = True, blank = True)
batiment = models.CharField(max_length = 32, null = True, blank = True)
btq = models.CharField(max_length = 32, null = True, blank = True)
appartement = models.CharField(max_length = 32, null = True, blank = True)
rue = models.CharField(max_length = 64, null = True, blank = True)
complement_adresse = models.CharField(max_length = 64, null = True, blank = True)
email = models.EmailField(null = True, blank = True)
name_id = models.CharField(max_length = 256, null = True, blank = True, db_index = True)
objects = PersonneManager()
def __unicode__(self):
return u'%s %s' % (self.prenom, self.nom)
def is_federated(self):
return self.name_id is not None and len(self.name_id) > 0
is_federated.boolean = True
class LiaisonParentFamille(models.Model):
famille = models.ForeignKey('Famille')
personne = models.ForeignKey(Personne)
class LiaisonNameidFamille(models.Model):
"""
model used to grant permissions to a nameid to see all informations about
the family(children, invoices, etc)
"""
name_id = models.CharField(max_length = 256, db_index = True)
famille = models.ForeignKey('Famille', null=True)
link_date = models.DateTimeField(auto_now_add = True)
class Meta:
unique_together = ('name_id', 'famille')
class Famille(models.Model):
id = models.AutoField(primary_key = True)
login = models.CharField(max_length = 32, null = True, blank = True)
password = models.CharField(max_length = 128, null = True, blank = True)
code_secret = models.CharField(max_length = 128, null = True, blank = True)
qf_ccas = models.CharField(max_length = 128, null = True, blank = True)
qf_vo = models.CharField(max_length = 128, null = True, blank = True)
pays = models.CharField(max_length = 128, null = True, blank = True)
code_postal = models.CharField(max_length = 16, null = True, blank = True)
commune = models.CharField(max_length = 32, null = True, blank = True)
voie = models.CharField(max_length = 32, null = True, blank = True)
batiment = models.CharField(max_length = 32, null = True, blank = True)
btq = models.CharField(max_length = 32, null = True, blank = True)
appartement = models.CharField(max_length = 32, null = True, blank = True)
rue = models.CharField(max_length = 64, null = True, blank = True)
complement_adresse = models.CharField(max_length = 64, null = True, blank = True)
nombre_enfants = models.IntegerField(default = 0)
personnes = models.ManyToManyField(Personne, through = LiaisonParentFamille)
objects = FamilleManager()
def __unicode__(self):
personnes = u' et '.join([u'%s (%s)' % (p, p.id) for p in self.personnes.all()])
return u'Famille %s de %s' % (self.id, personnes)
class Facture(models.Model):
id = models.AutoField(primary_key = True)
famille = models.ForeignKey(Famille)
montant = models.DecimalField(max_digits = 6, decimal_places = 2)
devise = models.CharField(max_length = 3)
montant_regle = models.DecimalField(max_digits = 6, decimal_places = 2)
solde = models.DecimalField(max_digits = 6, decimal_places = 2)
date_generation = models.DateField()
date_limite_paie = models.DateField()
prenom_payeur = models.CharField(max_length = 128)
nom_payeur = models.CharField(max_length = 128)
prelevement_automatique = models.BooleanField()
debut_pge = models.DateField()
fin_pge = models.DateField()
paye = models.BooleanField(default = False)
objects = FactureManager()
active = models.BooleanField(default = False)
statut_tipi = models.CharField(max_length=16, blank=True, null=True)
date_reponse_tipi = models.DateTimeField(null=True, blank=True)
id_payeur_par_defaut = models.CharField(max_length=128, null=True, blank=True)
date_envoi_dernier_mail = models.DateTimeField(null=True, blank=True)
def __unicode__(self):
return 'Facture %s (Famille %s)' % (self.id, self.famille.id)
class Enfant(models.Model):
id_enfant = models.CharField(max_length=64)
famille = models.ForeignKey(Famille)
prenom = models.CharField(max_length = 128, null = True, blank = True)
nom = models.CharField(max_length = 128, null = True, blank = True)
sexe = models.CharField(choices = SEXES, max_length = 1, null = True)
date_naissance = models.DateField(null = True, blank = True)
objects = KidManager()
def __unicode__(self):
return u'%s %s' % (self.prenom, self.nom)
class InvoiceNotificationEmail(models.Model):
invoice_number = models.CharField(max_length=64)
date_sent = models.DateTimeField(auto_now_add=True)
class Meta:
get_latest_by = 'date_sent'