From 5633bf21a35eec22465505de89e715c5a9e0b312 Mon Sep 17 00:00:00 2001 From: Guillaume Pellerin Date: Tue, 4 Oct 2016 18:00:23 +0200 Subject: [PATCH] Add is_legacy and parent fields to Team, add second_team_text to Activity, fix various import methods --- app/organization/network/admin.py | 9 ++++++ .../commands/import-ircam-person-xls.py | 28 ++++++++++++++++--- .../0027_personactivity_second_team_text.py | 20 +++++++++++++ .../network/migrations/0028_team_is_legacy.py | 20 +++++++++++++ .../migrations/0029_auto_20161004_1556.py | 25 +++++++++++++++++ .../network/migrations/0030_team_parent.py | 21 ++++++++++++++ app/organization/network/models.py | 12 ++++++-- 7 files changed, 128 insertions(+), 7 deletions(-) create mode 100644 app/organization/network/migrations/0027_personactivity_second_team_text.py create mode 100644 app/organization/network/migrations/0028_team_is_legacy.py create mode 100644 app/organization/network/migrations/0029_auto_20161004_1556.py create mode 100644 app/organization/network/migrations/0030_team_parent.py diff --git a/app/organization/network/admin.py b/app/organization/network/admin.py index 939481b3..cbcd1bfa 100644 --- a/app/organization/network/admin.py +++ b/app/organization/network/admin.py @@ -60,6 +60,7 @@ class DepartmentAdmin(BaseTranslationModelAdmin): class TeamAdmin(BaseTranslationModelAdmin): model = Team + list_filter = ['department',] class TeamPageAdmin(PageAdmin): @@ -123,6 +124,13 @@ class PersonAdmin(BaseTranslationOrderedModelAdmin): list_display = ['last_name', 'first_name', 'email', 'gender'] list_filter = ['person_title', 'activities__date_from', 'activities__date_to', 'activities__is_permanent', 'activities__framework', 'activities__grade', 'activities__function', 'activities__team', 'activities__project',] + +class PersonActivityAdmin(admin.ModelAdmin): + + model = PersonActivity + list_display = ['person', 'team', 'status', 'date_from', 'date_to'] + + class PersonListBlockInlineAdmin(TabularDynamicInlineAdmin): model = PersonListBlockInline @@ -182,6 +190,7 @@ admin.site.register(Team, TeamAdmin) admin.site.register(TeamPage, TeamPageAdmin) admin.site.register(Person, PersonAdmin) admin.site.register(PersonListBlock, PersonListBlockAdmin) +admin.site.register(PersonActivity, PersonActivityAdmin) admin.site.register(ActivityStatus, ActivityStatusAdmin) admin.site.register(ActivityGrade, ActivityGradeAdmin) admin.site.register(ActivityFramework, ActivityFrameworkAdmin) 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 ca0abdc9..c1a9c2e3 100644 --- a/app/organization/network/management/commands/import-ircam-person-xls.py +++ b/app/organization/network/management/commands/import-ircam-person-xls.py @@ -10,6 +10,7 @@ from itertools import takewhile from django.conf import settings from django.core.management.base import BaseCommand, CommandError from django.contrib.auth.models import User +from django.db.models import Q from organization.core.models import * from organization.network.models import * @@ -119,7 +120,20 @@ class IrcamPerson(object): person, c = Person.objects.get_or_create(title=title) return person + return None + def get_team(self, code): + code = str(code) + qs = Q(code=code) | Q(code=code.lower()) | Q(code=code.upper()) | Q(code=code.capitalize()) + teams = Team.objects.filter(qs) + if teams: + return teams[0] + + qs = Q(title=code) | Q(title=code.lower()) | Q(title=code.upper()) | Q(title=code.capitalize()) + projects = Project.objects.filter(qs) + if projects: + self.activity.project = projects[0] + return None return None def get_activity(self): @@ -140,8 +154,11 @@ 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(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.team = self.get_team(self.row[19].value) + try: + self.activity.second_team = self.get_team(self.row[21].value) + except: + self.activity.second_team_text = self.row[21].value 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[23].value @@ -158,7 +175,7 @@ class IrcamPerson(object): 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.training_speciality = self.get_or_create_name(TrainingSpeciality, 32) self.activity.function = self.get_or_create_name(ActivityFunction, 34) if self.activity.phd_director: @@ -175,7 +192,10 @@ class IrcamPerson(object): 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 + try: + self.activity.date_modified_manual = datetime.datetime(*xlrd.xldate_as_tuple(self.row[42].value, self.datemode)) if self.row[42].value else None + except: + pass 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/0027_personactivity_second_team_text.py b/app/organization/network/migrations/0027_personactivity_second_team_text.py new file mode 100644 index 00000000..26b12ad0 --- /dev/null +++ b/app/organization/network/migrations/0027_personactivity_second_team_text.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.10 on 2016-10-03 23:01 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('organization-network', '0026_auto_20160929_1810'), + ] + + operations = [ + migrations.AddField( + model_name='personactivity', + name='second_team_text', + field=models.CharField(blank=True, max_length=256, null=True, verbose_name='second team text'), + ), + ] diff --git a/app/organization/network/migrations/0028_team_is_legacy.py b/app/organization/network/migrations/0028_team_is_legacy.py new file mode 100644 index 00000000..bd997c59 --- /dev/null +++ b/app/organization/network/migrations/0028_team_is_legacy.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.10 on 2016-10-04 07:23 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('organization-network', '0027_personactivity_second_team_text'), + ] + + operations = [ + migrations.AddField( + model_name='team', + name='is_legacy', + field=models.BooleanField(default=False, verbose_name='is legacy'), + ), + ] diff --git a/app/organization/network/migrations/0029_auto_20161004_1556.py b/app/organization/network/migrations/0029_auto_20161004_1556.py new file mode 100644 index 00000000..58efd4a3 --- /dev/null +++ b/app/organization/network/migrations/0029_auto_20161004_1556.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.10 on 2016-10-04 13:56 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('organization-network', '0028_team_is_legacy'), + ] + + operations = [ + migrations.AddField( + model_name='person', + name='external_id', + field=models.CharField(blank=True, max_length=128, null=True, verbose_name='external ID'), + ), + migrations.AddField( + model_name='personactivity', + name='external_id', + field=models.CharField(blank=True, max_length=128, null=True, verbose_name='external ID'), + ), + ] diff --git a/app/organization/network/migrations/0030_team_parent.py b/app/organization/network/migrations/0030_team_parent.py new file mode 100644 index 00000000..381cdfff --- /dev/null +++ b/app/organization/network/migrations/0030_team_parent.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.10 on 2016-10-04 15:55 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('organization-network', '0029_auto_20161004_1556'), + ] + + operations = [ + migrations.AddField( + model_name='team', + name='parent', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='children', to='organization-network.Team', verbose_name='parent team'), + ), + ] diff --git a/app/organization/network/models.py b/app/organization/network/models.py index 8423618a..30d83432 100644 --- a/app/organization/network/models.py +++ b/app/organization/network/models.py @@ -78,7 +78,7 @@ class Organization(Named, Address, URL, AdminThumbRelatedMixin): is_on_map = models.BooleanField(_('is on map'), default=True) admin_thumb_type = 'logo' - + class Meta: verbose_name = _('organization') ordering = ['name',] @@ -148,6 +148,8 @@ 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) + is_legacy = models.BooleanField(_('is legacy'), default=False) + parent = models.ForeignKey('Team', verbose_name=_('parent team'), related_name="children", blank=True, null=True, on_delete=models.SET_NULL) class Meta: verbose_name = _('team') @@ -194,6 +196,7 @@ class Person(Displayable, AdminThumbMixin): email = models.EmailField(_('email'), blank=True, null=True) birthday = models.DateField(_('birthday'), blank=True, null=True) bio = RichTextField(_('biography'), blank=True) + external_id = models.CharField(_('external ID'), blank=True, null=True, max_length=128) class Meta: verbose_name = _('person') @@ -372,6 +375,7 @@ class PersonActivity(Period): 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) + second_team_text = models.CharField(_('second team text'), blank=True, null=True, max_length=256) project = models.ForeignKey('organization-projects.Project', verbose_name=_('project'), blank=True, null=True, on_delete=models.SET_NULL) rd_quota_float = models.IntegerField(_('R&D quota (float)'), blank=True, null=True) @@ -402,12 +406,14 @@ class PersonActivity(Period): comments = models.TextField(_('comments'), blank=True) + external_id = models.CharField(_('external ID'), blank=True, null=True, max_length=128) + class Meta: verbose_name = _('activity') verbose_name_plural = _('activities') def __str__(self): if self.status: - return ' - '.join((self.status.name, str(self.date_begin), str(self.date_end))) + return ' - '.join((self.status.name, str(self.date_from), str(self.date_to))) else: - return ' - '.join((str(self.date_begin), str(self.date_end))) + return ' - '.join((str(self.date_from), str(self.date_to))) -- 2.39.5