From aa1e35844314a49f1a470f28336edc8fc09f93c5 Mon Sep 17 00:00:00 2001 From: Emilie Date: Thu, 22 Dec 2016 17:34:52 +0100 Subject: [PATCH] [Timesheet] add weekly hour management --- app/local_settings.py | 1 + app/organization/network/admin.py | 12 ++++ .../migrations/0070_auto_20161222_1656.py | 58 +++++++++++++++++++ app/organization/network/models.py | 41 +++++++++++++ app/organization/network/translation.py | 12 ++++ .../migrations/0032_project_external_id.py | 20 +++++++ app/organization/projects/models.py | 1 + 7 files changed, 145 insertions(+) create mode 100644 app/organization/network/migrations/0070_auto_20161222_1656.py create mode 100644 app/organization/projects/migrations/0032_project_external_id.py diff --git a/app/local_settings.py b/app/local_settings.py index 47f22b9d..90be2cae 100644 --- a/app/local_settings.py +++ b/app/local_settings.py @@ -142,6 +142,7 @@ ADMIN_MENU_ORDER = ( 'organization-network.TrainingTopic', 'organization-network.TrainingLevel', 'organization-network.TrainingSpeciality', + 'organization-network.ActivityWeeklyHourVolume' )), (_('Projects'), ('organization-projects.Project', 'organization-projects.ProjectProgram', diff --git a/app/organization/network/admin.py b/app/organization/network/admin.py index fcbbb1d0..f2fc4c77 100644 --- a/app/organization/network/admin.py +++ b/app/organization/network/admin.py @@ -139,6 +139,16 @@ class PersonAdminBase(BaseTranslationModelAdmin): model = Person +class ActivityWeeklyHourVolumeAdmin(BaseTranslationModelAdmin): + + model = ActivityWeeklyHourVolume + + +class PersonActivityWeeklyHourVolumeAdminInline(TabularDynamicInlineAdmin): + + model = PersonActivityWeeklyHourVolume + + class PersonActivityInline(StackedDynamicInlineAdmin): model = PersonActivity @@ -199,6 +209,7 @@ class PersonActivityAdmin(BaseTranslationModelAdmin): list_filter = [ 'date_from', 'date_to', 'is_permanent', 'framework', 'grade', 'status', 'teams', 'projects',] + inlines = [PersonActivityWeeklyHourVolumeAdminInline,] def get_teams(self, instance): values = [] @@ -273,6 +284,7 @@ admin.site.register(ActivityStatus, ActivityStatusAdmin) admin.site.register(ActivityGrade, ActivityGradeAdmin) admin.site.register(ActivityFramework, ActivityFrameworkAdmin) admin.site.register(ActivityFunction, ActivityFunctionAdmin) +admin.site.register(ActivityWeeklyHourVolume, ActivityWeeklyHourVolumeAdmin) admin.site.register(TrainingType, TrainingTypeAdmin) admin.site.register(TrainingLevel, TrainingLevelAdmin) admin.site.register(TrainingTopic, TrainingTopicAdmin) diff --git a/app/organization/network/migrations/0070_auto_20161222_1656.py b/app/organization/network/migrations/0070_auto_20161222_1656.py new file mode 100644 index 00000000..f56bedd7 --- /dev/null +++ b/app/organization/network/migrations/0070_auto_20161222_1656.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.11 on 2016-12-22 15:56 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('organization-network', '0069_auto_20161216_1649'), + ] + + operations = [ + migrations.CreateModel( + name='ActivityWeeklyHourVolume', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('title', models.CharField(max_length=1024, verbose_name='title')), + ('description', models.TextField(blank=True, verbose_name='description')), + ('monday_hours', models.IntegerField(verbose_name='monday hours')), + ('tuesday_hours', models.IntegerField(verbose_name='tuesday hours')), + ('wednesday_hours', models.IntegerField(verbose_name='wednesday hours')), + ('thursday_hours', models.IntegerField(verbose_name='thursday hours')), + ('friday_hours', models.IntegerField(verbose_name='friday hours')), + ], + options={ + 'verbose_name_plural': 'Activity Weekly Hour Volumes', + 'verbose_name': 'Activity Weekly Hour Volume', + }, + ), + migrations.CreateModel( + name='PersonActivityWeeklyHourVolume', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('monday_hours', models.IntegerField(blank=True, null=True, verbose_name='monday hours')), + ('tuesday_hours', models.IntegerField(blank=True, null=True, verbose_name='tuesday hours')), + ('wednesday_hours', models.IntegerField(blank=True, null=True, verbose_name='wednesday hours')), + ('thursday_hours', models.IntegerField(blank=True, null=True, verbose_name='thursday hours')), + ('friday_hours', models.IntegerField(blank=True, null=True, verbose_name='friday hours')), + ('activity', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='person_activity_weekly_hour_volume', to='organization-network.PersonActivity', verbose_name='activity')), + ], + options={ + 'verbose_name': 'Person Activity Weekly Hour Volume', + }, + ), + migrations.AddField( + model_name='person', + name='register_id', + field=models.CharField(blank=True, max_length=128, null=True, verbose_name='register ID'), + ), + migrations.AddField( + model_name='personactivity', + name='weekly_hour_volume', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='organization-network.ActivityWeeklyHourVolume'), + ), + ] diff --git a/app/organization/network/models.py b/app/organization/network/models.py index 5e391257..6d2f2c2b 100644 --- a/app/organization/network/models.py +++ b/app/organization/network/models.py @@ -96,6 +96,7 @@ BOX_SIZE_CHOICES = [ (6, 6), ] + class Organization(Named, Address, URL, AdminThumbRelatedMixin, Orderable): """(Organization description)""" @@ -294,6 +295,7 @@ class Person(Displayable, AdminThumbMixin): last_name = models.CharField(_('last name'), max_length=255, blank=True, null=True) email = models.EmailField(_('email'), blank=True, null=True) telephone = models.CharField(_('telephone'), max_length=64, blank=True, null=True) + register_id = models.CharField(_('register ID'), blank=True, null=True, max_length=128) 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) @@ -458,6 +460,32 @@ class UMR(Named): verbose_name = _('UMR') +class ActivityWeeklyHourVolume(Titled): + + monday_hours = models.IntegerField(_('monday hours')) + tuesday_hours = models.IntegerField(_('tuesday hours')) + wednesday_hours = models.IntegerField(_('wednesday hours')) + thursday_hours = models.IntegerField(_('thursday hours')) + friday_hours = models.IntegerField(_('friday hours')) + + class Meta: + verbose_name = _('Activity Weekly Hour Volume') + verbose_name_plural = _('Activity Weekly Hour Volumes') + + +class PersonActivityWeeklyHourVolume(models.Model): + + activity = models.OneToOneField('PersonActivity', verbose_name=_('activity'), related_name="person_activity_weekly_hour_volume", blank=True, null=True, on_delete=models.CASCADE) + monday_hours = models.IntegerField(_('monday hours'), blank=True, null=True) + tuesday_hours = models.IntegerField(_('tuesday hours'), blank=True, null=True) + wednesday_hours = models.IntegerField(_('wednesday hours'), blank=True, null=True) + thursday_hours = models.IntegerField(_('thursday hours'), blank=True, null=True) + friday_hours = models.IntegerField(_('friday hours'), blank=True, null=True) + + class Meta: + verbose_name = _('Person Activity Weekly Hour Volume') + + class PersonActivity(Period): """(Activity description)""" @@ -507,6 +535,8 @@ class PersonActivity(Period): external_id = models.CharField(_('external ID'), blank=True, null=True, max_length=128) + weekly_hour_volume = models.ForeignKey('ActivityWeeklyHourVolume', blank=True, null=True, on_delete=models.SET_NULL) + class Meta: verbose_name = _('activity') verbose_name_plural = _('activities') @@ -517,3 +547,14 @@ class PersonActivity(Period): return ' - '.join((self.status.name, str(self.date_from), str(self.date_to))) else: return ' - '.join((str(self.date_from), str(self.date_to))) + + def save(self, *args, **kwargs): + super(PersonActivity, self).save(args, kwargs) + if self.weekly_hour_volume and not hasattr(self, 'person_activity_weekly_hour_volume'): + self.person_activity_weekly_hour_volume = PersonActivityWeeklyHourVolume(activity=self) + self.person_activity_weekly_hour_volume.monday_hours = self.weekly_hour_volume.monday_hours + self.person_activity_weekly_hour_volume.tuesday_hours = self.weekly_hour_volume.tuesday_hours + self.person_activity_weekly_hour_volume.wednesday_hours = self.weekly_hour_volume.wednesday_hours + self.person_activity_weekly_hour_volume.thursday_hours = self.weekly_hour_volume.thursday_hours + self.person_activity_weekly_hour_volume.friday_hours = self.weekly_hour_volume.friday_hours + self.person_activity_weekly_hour_volume.save() diff --git a/app/organization/network/translation.py b/app/organization/network/translation.py index d1bcb30c..1f722475 100644 --- a/app/organization/network/translation.py +++ b/app/organization/network/translation.py @@ -214,3 +214,15 @@ class OrganizationLinkedInlineTranslationOptions(TranslationOptions): class OrganizationLinkedBlockInlineTranslationOptions(TranslationOptions): fields = [] + + +@register(ActivityWeeklyHourVolume) +class ActivityWeeklyHourVolumeTranslationOptions(TranslationOptions): + + fields = [] + + +@register(PersonActivityWeeklyHourVolume) +class PersonActivityWeeklyHourVolumeTranslationOptions(TranslationOptions): + + fields = [] diff --git a/app/organization/projects/migrations/0032_project_external_id.py b/app/organization/projects/migrations/0032_project_external_id.py new file mode 100644 index 00000000..193342ff --- /dev/null +++ b/app/organization/projects/migrations/0032_project_external_id.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.11 on 2016-12-22 15:56 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('organization-projects', '0031_auto_20161205_1536'), + ] + + operations = [ + migrations.AddField( + model_name='project', + name='external_id', + field=models.CharField(blank=True, max_length=128, null=True, verbose_name='register ID'), + ), + ] diff --git a/app/organization/projects/models.py b/app/organization/projects/models.py index df69a4a3..8d0e5316 100644 --- a/app/organization/projects/models.py +++ b/app/organization/projects/models.py @@ -50,6 +50,7 @@ class Project(Displayable, Period, RichText): """(Project description)""" type = models.CharField(_('type'), max_length=128, choices=PROJECT_TYPE_CHOICES) + external_id = models.CharField(_('register ID'), blank=True, null=True, max_length=128) program = models.ForeignKey('ProjectProgram', verbose_name=_('project program'), related_name='projects', blank=True, null=True, on_delete=models.SET_NULL) program_type = models.ForeignKey('ProjectProgramType', verbose_name=_('project program type'), related_name='projects', blank=True, null=True, on_delete=models.SET_NULL) lead_team = models.ForeignKey('organization-network.Team', verbose_name=_('lead team'), related_name='leader_projects', blank=True, null=True) -- 2.39.5