From: Guillaume Pellerin Date: Fri, 16 Sep 2016 12:46:54 +0000 (+0200) Subject: First complete person data import (beta version) X-Git-Url: https://git.parisson.com/?a=commitdiff_plain;h=5e50337509452138c35015a1f5afa21560e228f7;p=mezzo.git First complete person data import (beta version) --- diff --git a/app/organization/network/admin.py b/app/organization/network/admin.py index 582aeeb7..ea481d52 100644 --- a/app/organization/network/admin.py +++ b/app/organization/network/admin.py @@ -105,6 +105,7 @@ class PersonAdmin(BaseTranslationModelAdmin): model = Person inlines = [PersonActivityInline, PersonAudioInline, PersonImageInline, PersonVideoInline, PersonBlockInline, PersonLinkInline ] first_fields = ['last_name', 'first_name', 'title', 'gender', 'user'] + search_fields = ['last_name', 'first_name'] def get_fieldsets(self, request, obj = None): res = super(PersonAdmin, self).get_fieldsets(request, obj) @@ -121,3 +122,4 @@ admin.site.register(DepartmentPage, DepartmentPageAdmin) admin.site.register(Team, TeamAdmin) admin.site.register(TeamPage, TeamPageAdmin) admin.site.register(Person, PersonAdmin) +admin.site.register(ActivityStatus) diff --git a/app/organization/network/management/commands/import-ircam-person-xls.py b/app/organization/network/management/commands/import-ircam-person-xls.py index 86c9606b..ea0bddea 100644 --- a/app/organization/network/management/commands/import-ircam-person-xls.py +++ b/app/organization/network/management/commands/import-ircam-person-xls.py @@ -46,7 +46,7 @@ def get_instance(model, field, value): class IrcamXLS: sheet_id = 2 - first_row = 21 + first_row = 20 def __init__(self, file): self.book = xlrd.open_workbook(file) @@ -69,6 +69,7 @@ class IrcamPerson(object): self.datemode = datemode last_name = self.row[0].value first_name = self.row[1].value + print(last_name) title = ' '.join((first_name, last_name)) self.person, c = Person.objects.get_or_create(title=title, first_name=first_name, last_name=last_name) @@ -85,12 +86,50 @@ class IrcamPerson(object): if birthday: self.person.birthday = datetime.datetime(*xlrd.xldate_as_tuple(birthday, self.datemode)) + # self.person.nationality = self.get_or_create_name(Nationality, self.row[33].value) + self.person.save() def get_or_create_name(self, model, column_id): return model.objects.get_or_create(name=self.row[column_id].value)[0] if self.row[column_id].value else None + def get_person(self, value): + if value: + name_exceptions = ['de', 'von'] + + names = value.split(' / ')[0] + names = names.split(' ') + + if names[0] == 'M.': + names.remove('M.') + + if names[0] == 'Mm.': + names.remove('Mm.') + + first_name = names[0].capitalize() + + last_name = [] + for name in names[1:]: + if name: + if name[0] != '(' and not name in name_exceptions: + last_name.append(name.capitalize()) + last_name = ' '.join(last_name) + + title = ' '.join((first_name, last_name)) + person, c = Person.objects.get_or_create(title=title) + + return person + + return None + def get_activity(self): + self.activity.date_begin = datetime.datetime(*xlrd.xldate_as_tuple(self.row[4].value, self.datemode)) if self.row[4].value else None + self.activity.date_end = datetime.datetime(*xlrd.xldate_as_tuple(self.row[5].value, self.datemode)) if self.row[5].value else None + try: + self.activity.weeks = int(self.row[6].value) if self.row[6].value else None + except: + pass + self.activity.status = self.get_or_create_name(ActivityStatus, 10) self.activity.is_permanent = True if self.row[11].value else False self.activity.framework = self.get_or_create_name(ActivityFramework, 12) @@ -101,22 +140,43 @@ class IrcamPerson(object): self.activity.second_employer = self.get_or_create_name(Organization, 16) self.activity.umr = self.get_or_create_name(UMR, 17) - self.activity.team, c = Team.objects.get_or_create(name=self.row[18].value, organization=self.organization) if self.row[18].value else (None, False) - self.activity.second_team, c = Team.objects.get_or_create(name=self.row[19].value, organization=self.organization) if self.row[19].value else (None, False) - self.activity.project, c = Project.objects.get_or_create(title=self.row[19].value) if self.row[19].value else (None, False) + self.activity.team, c = Team.objects.get_or_create(code=self.row[19].value, organization=self.organization) if self.row[19].value else (None, False) + self.activity.second_team, c = Team.objects.get_or_create(code=self.row[21].value, organization=self.organization) if self.row[21].value else (None, False) + self.activity.project, c = Project.objects.get_or_create(title=self.row[22].value) if self.row[22].value else (None, False) - quota = self.row[21].value + quota = self.row[23].value try: self.activity.rd_quota_float = float(quota) except: self.activity.rd_quota_text = str(quota) - self.activity.phd_doctoral_school = self.get_or_create_name(Organization, 23) - self.activity.phd_director, c = Person.objects.get_or_create(title=self.row[24].value.capitalize()) if self.row[24].value else (None, False) - self.activity.phd_officer_1, c = Person.objects.get_or_create(title=self.row[25].value.capitalize()) if self.row[25].value else (None, False) - self.activity.phd_officer_2, c = Person.objects.get_or_create(title=self.row[26].value.capitalize()) if self.row[26].value else (None, False) - # self.activity.phd_defense_date = datetime.datetime(*xlrd.xldate_as_tuple(self.row[27].value, self.datemode)) if self.row[27].value else None - # self.activity.phd_title = self.row[28].value + self.activity.phd_doctoral_school = self.get_or_create_name(Organization, 25) + self.activity.phd_director = self.get_person(self.row[26].value) + self.activity.phd_officer_1 = self.get_person(self.row[27].value) + self.activity.phd_officer_2 = self.get_person(self.row[28].value) + + self.activity.training_type = self.get_or_create_name(TrainingType, 29) + self.activity.training_level = self.get_or_create_name(TrainingLevel, 30) + self.activity.training_topic = self.get_or_create_name(TrainingTopic, 31) + self.activity.training_speciality = self.get_or_create_name(TrainingSpectiality, 32) + self.activity.function = self.get_or_create_name(ActivityFunction, 34) + + if self.activity.phd_director: + self.activity.phd_title = self.row[35].value + try: + self.activity.phd_defense_date = datetime.datetime(*xlrd.xldate_as_tuple(self.row[38].value, self.datemode)) if self.row[38].value else None + except: + pass + self.activity.phd_postdoctoralsituation = self.row[39].value + elif self.activity.training_type: + self.activity.training_title = self.row[35].value + + self.activity.rd_program = self.row[36].value + self.activity.comments = self.row[37].value + self.activity.hdr = self.row[40].value + self.activity.budget_code = self.get_or_create_name(BudgetCode, 41) + self.activity.date_modified_manual = datetime.datetime(*xlrd.xldate_as_tuple(self.row[42].value, self.datemode)) if self.row[42].value else None + self.activity.record_piece = self.get_or_create_name(RecordPiece, 43) if self.row[43].value else None self.activity.save() diff --git a/app/organization/network/migrations/0008_person_email.py b/app/organization/network/migrations/0008_person_email.py new file mode 100644 index 00000000..5c177cbd --- /dev/null +++ b/app/organization/network/migrations/0008_person_email.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.7 on 2016-09-16 09:35 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('organization-network', '0007_auto_20160914_1818'), + ] + + operations = [ + migrations.AddField( + model_name='person', + name='email', + field=models.EmailField(blank=True, max_length=254, null=True, verbose_name='email'), + ), + ] diff --git a/app/organization/network/migrations/0009_auto_20160916_1229.py b/app/organization/network/migrations/0009_auto_20160916_1229.py new file mode 100644 index 00000000..a102b764 --- /dev/null +++ b/app/organization/network/migrations/0009_auto_20160916_1229.py @@ -0,0 +1,49 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.7 on 2016-09-16 10:29 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('organization-network', '0008_person_email'), + ] + + operations = [ + migrations.RemoveField( + model_name='personactivity', + name='content', + ), + migrations.RemoveField( + model_name='personactivity', + name='content_en', + ), + migrations.RemoveField( + model_name='personactivity', + name='content_fr', + ), + migrations.RemoveField( + model_name='personactivity', + name='description', + ), + migrations.RemoveField( + model_name='personactivity', + name='description_en', + ), + migrations.RemoveField( + model_name='personactivity', + name='description_fr', + ), + migrations.AddField( + model_name='personactivity', + name='comments_en', + field=models.TextField(blank=True, null=True, verbose_name='comments'), + ), + migrations.AddField( + model_name='personactivity', + name='comments_fr', + field=models.TextField(blank=True, null=True, verbose_name='comments'), + ), + ] diff --git a/app/organization/network/migrations/0010_personactivity_weeks.py b/app/organization/network/migrations/0010_personactivity_weeks.py new file mode 100644 index 00000000..3c7aa03d --- /dev/null +++ b/app/organization/network/migrations/0010_personactivity_weeks.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.7 on 2016-09-16 10:38 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('organization-network', '0009_auto_20160916_1229'), + ] + + operations = [ + migrations.AddField( + model_name='personactivity', + name='weeks', + field=models.IntegerField(blank=True, null=True, verbose_name='number of weeks'), + ), + ] diff --git a/app/organization/network/migrations/0011_auto_20160916_1246.py b/app/organization/network/migrations/0011_auto_20160916_1246.py new file mode 100644 index 00000000..9fdfd026 --- /dev/null +++ b/app/organization/network/migrations/0011_auto_20160916_1246.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.7 on 2016-09-16 10:46 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('organization-network', '0010_personactivity_weeks'), + ] + + operations = [ + migrations.AddField( + model_name='team', + name='code', + field=models.CharField(blank=True, max_length=64, null=True, verbose_name='code'), + ), + migrations.AlterField( + model_name='personactivity', + name='umr', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='organization-network.UMR', verbose_name='UMR'), + ), + ] diff --git a/app/organization/network/migrations/0012_auto_20160916_1423.py b/app/organization/network/migrations/0012_auto_20160916_1423.py new file mode 100644 index 00000000..2327b7a9 --- /dev/null +++ b/app/organization/network/migrations/0012_auto_20160916_1423.py @@ -0,0 +1,32 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.7 on 2016-09-16 12:23 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('organization-network', '0011_auto_20160916_1246'), + ] + + operations = [ + migrations.CreateModel( + name='ActivityFunction', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=512, verbose_name='name')), + ('description', models.TextField(blank=True, verbose_name='description')), + ], + options={ + 'verbose_name': 'activity function', + }, + ), + migrations.AddField( + model_name='personactivity', + name='function', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='organization-network.ActivityFunction', verbose_name='function'), + ), + ] diff --git a/app/organization/network/models.py b/app/organization/network/models.py index 26b7fd3a..4bcf5b09 100644 --- a/app/organization/network/models.py +++ b/app/organization/network/models.py @@ -136,6 +136,7 @@ class Team(Named, URL): organization = models.ForeignKey('Organization', verbose_name=_('organization'), related_name="teams", blank=True, null=True, on_delete=models.SET_NULL) department = models.ForeignKey('Department', verbose_name=_('department'), related_name="teams", blank=True, null=True, on_delete=models.SET_NULL) + code = models.CharField(_('code'), max_length=64, blank=True, null=True) class Meta: verbose_name = _('team') @@ -168,6 +169,7 @@ class Person(Displayable, AdminThumbMixin): gender = models.CharField(_('gender'), max_length=16, choices=GENDER_CHOICES, blank=True) first_name = models.CharField(_('first name'), max_length=255, blank=True, null=True) last_name = models.CharField(_('last name'), max_length=255, blank=True, null=True) + email = models.EmailField(_('email'), blank=True, null=True) birthday = models.DateField(_('birthday'), blank=True, null=True) bio = RichTextField(_('biography'), blank=True) @@ -251,6 +253,12 @@ class ActivityFramework(Named): verbose_name = _('activity framework') +class ActivityFunction(Named): + + class Meta: + verbose_name = _('activity function') + + class BudgetCode(Named): class Meta: @@ -293,20 +301,22 @@ class UMR(Named): verbose_name = _('UMR') -class PersonActivity(Description, Period, RichText): +class PersonActivity(Period): """(Activity description)""" person = models.ForeignKey('Person', verbose_name=_('person')) + weeks = models.IntegerField(_('number of weeks'), blank=True, null=True) status = models.ForeignKey(ActivityStatus, verbose_name=_('status'), blank=True, null=True, on_delete=models.SET_NULL) is_permanent = models.BooleanField(_('permanent'), default=False) framework = models.ForeignKey(ActivityFramework, verbose_name=_('framework'), blank=True, null=True, on_delete=models.SET_NULL) grade = models.ForeignKey(ActivityGrade, verbose_name=_('grade'), blank=True, null=True, on_delete=models.SET_NULL) + function = models.ForeignKey(ActivityFunction, verbose_name=_('function'), blank=True, null=True, on_delete=models.SET_NULL) employer = models.ForeignKey(Organization, verbose_name=_('employer'), related_name='employer_activity', blank=True, null=True, on_delete=models.SET_NULL) attachment_organization = models.ForeignKey(Organization, verbose_name=_('attachment organization'), related_name='attachment_activity', blank=True, null=True, on_delete=models.SET_NULL) second_employer = models.ForeignKey(Organization, verbose_name=_('second employer'), related_name='second_employer_activity', blank=True, null=True, on_delete=models.SET_NULL) - umr = models.ForeignKey(UMR, verbose_name=_('training type'), blank=True, null=True, on_delete=models.SET_NULL) + umr = models.ForeignKey(UMR, verbose_name=_('UMR'), blank=True, null=True, on_delete=models.SET_NULL) team = models.ForeignKey('Team', verbose_name=_('team'), related_name='team_activity', blank=True, null=True, on_delete=models.SET_NULL) second_team = models.ForeignKey('Team', verbose_name=_('second team'), related_name='second_team_activity', blank=True, null=True, on_delete=models.SET_NULL) @@ -332,6 +342,7 @@ class PersonActivity(Description, Period, RichText): training_title = models.TextField(_('Training title'), blank=True) record_piece = models.ForeignKey(RecordPiece, blank=True, null=True, on_delete=models.SET_NULL) + date_added = models.DateTimeField(_('add date'), auto_now_add=True) date_modified = models.DateTimeField(_('modification date'), auto_now=True) date_modified_manual = models.DateTimeField(_('manual modification date'), blank=True, null=True) @@ -342,5 +353,8 @@ class PersonActivity(Description, Period, RichText): verbose_name = _('activity') verbose_name_plural = _('activities') - def __unicode__(self): - return ' - '.join((self.person, self.role, self.date_begin, self.date_end)) + def __str__(self): + if self.status: + return ' - '.join((self.status.name, str(self.date_begin), str(self.date_end))) + else: + return ' - '.join((str(self.date_begin), str(self.date_end))) diff --git a/app/organization/network/translation.py b/app/organization/network/translation.py index 8f330ee0..b9f06353 100644 --- a/app/organization/network/translation.py +++ b/app/organization/network/translation.py @@ -42,7 +42,7 @@ class PersonTranslationOptions(TranslationOptions): @register(PersonActivity) class PersonActivityTranslationOptions(TranslationOptions): - fields = ('description', 'content') + fields = ('comments',) @register(PersonAudio) diff --git a/app/scripts/app.sh b/app/scripts/app.sh index 6faf3f03..00c0cabf 100644 --- a/app/scripts/app.sh +++ b/app/scripts/app.sh @@ -18,7 +18,7 @@ gid='www-data' patterns='*.js;*.css;*.jpg;*.jpeg;*.gif;*.png;*.svg;*.ttf;*.eot;*.woff;*.woff2' # Staging -# pip install cartridge +pip install xlrd # pip install -U https://forge.ircam.fr/p/django-eve/source/download/dev/ # pip install -U https://github.com/stephenmcd/grappelli-safe/archive/dynamic_stacked.zip # pip install django-querysetsequence diff --git a/requirements.txt b/requirements.txt index 30aafe41..6618a48b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -16,3 +16,4 @@ django-querysetsequence django-autocomplete-light ipython cartridge +xlrd