Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convert business units to DB table #992

Merged
merged 6 commits into from
Mar 11, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 11 additions & 30 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion tock/api/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class UserDataSerializer(serializers.Serializer):
organization = serializers.StringRelatedField()

def get_unit(self,obj):
return obj.get_unit_display()
return obj.unit

class ReportingPeriodSerializer(serializers.ModelSerializer):
class Meta:
Expand Down
7 changes: 6 additions & 1 deletion tock/employees/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,12 @@ class UserDataAdmin(admin.ModelAdmin):
search_fields = ('user__username',)

def unit_info(self, obj):
return obj.get_unit_display()
"""
Because historically unit was not a required field,
don't follow the relationship to `unit.name` or we'll break the admin.
Instead, let Django resolve the object `str` if it doesn't exist.
"""
return obj.unit
unit_info.short_description = 'Unit'

def get_organization_name(self, obj):
Expand Down
21 changes: 21 additions & 0 deletions tock/employees/migrations/0027_auto_20200310_0914.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Generated by Django 2.2.10 on 2020-03-10 13:14

from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

dependencies = [
('employees', '0026_auto_20200303_1821'),
('organizations', '0004_unit_org'),

]

operations = [
migrations.AlterField(
model_name='userdata',
name='unit',
field=models.ForeignKey(blank=True, help_text='The business unit within the organization in which this person sits.', null=True, on_delete=django.db.models.deletion.CASCADE, to='organizations.Unit', verbose_name='Business Unit'),
),
]
31 changes: 5 additions & 26 deletions tock/employees/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from django.core.validators import MaxValueValidator
from django.db import IntegrityError, models
from django.db.models import Q
from organizations.models import Organization
from organizations.models import Organization, Unit
from projects.models import ProfitLossAccount
from rest_framework.authtoken.models import Token

Expand Down Expand Up @@ -75,37 +75,12 @@ def save(self, *args, **kwargs):


class UserData(models.Model):

UNIT_CHOICES = (
(0, 'Operations-Team Operations'),
(1, 'Operations-Talent'),
(2, 'Operations-Infrastructure'),
(3, 'Operations-Front Office'),
(4, 'Chapters-Acquisition'),
(5, 'Chapters-Engineering'),
(6, 'Chapters-Design'),
(7, 'Chapters-Product'),
#(8, 'Chapters-Strategists'), Deprecated. Should not be used.
(9, 'Business-Acquisition Services'),
(10, 'Business-Custom Partner Solutions'),
(11, 'Business-Learn'),
(12, 'Business-Products & Platforms'),
(13, 'Business-Transformation Services'),
(14, 'PIF-Fellows'),
(15, 'PIF-Operations'),
(16, 'Unknown / N/A'),
(17, 'Chapters-Account Management'),
(18, 'Portfolio-Human Services'),
(19, 'Portfolio-National Security & Intelligence')
)

user = models.OneToOneField(User, related_name='user_data', verbose_name='Tock username', on_delete=models.CASCADE)
start_date = models.DateField(blank=True, null=True, verbose_name='Employee start date')
end_date = models.DateField(blank=True, null=True, verbose_name='Employee end date')
current_employee = models.BooleanField(default=True, verbose_name='Is Current Employee')
is_18f_employee = models.BooleanField(default=True, verbose_name='Is 18F Employee')
is_billable = models.BooleanField(default=True, verbose_name="Is 18F Billable Employee")
unit = models.IntegerField(null=True, choices=UNIT_CHOICES, verbose_name="Select 18F unit", blank=True)
billable_expectation = models.DecimalField(validators=[MaxValueValidator(limit_value=1)],
default=0.80, decimal_places=2, max_digits=3,
verbose_name="Percentage of hours (expressed as a decimal) expected to be billable each week")
Expand All @@ -122,6 +97,10 @@ class UserData(models.Model):
verbose_name='Is alternative work schedule eligible'
)
organization = models.ForeignKey(Organization, blank=True, null=True, on_delete=models.CASCADE)
unit = models.ForeignKey(Unit, blank=True, null=True, on_delete=models.CASCADE,
verbose_name="Business Unit",
help_text="The business unit within the organization in which this person sits."
)

class Meta:
verbose_name='Employee'
Expand Down
27 changes: 20 additions & 7 deletions tock/employees/tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from django.contrib.auth.models import User

from rest_framework.authtoken.models import Token
from organizations.models import Organization
from organizations.models import Organization, Unit
from employees.models import EmployeeGrade, UserData

from hours.models import (
Expand Down Expand Up @@ -57,19 +57,26 @@ def setUp(self):
)
# Create Organization.
self.regular_user_org = Organization.objects.create(
name='18F',
description='18F',
active=True
)
# Create Unit.
self.regular_user_unit = Unit.objects.create(
name='Engineering',
description='18F Engineering Chapter',
org=self.regular_user_org,
active=True
)
# Create UserData object related to regular_user.
self.regular_user_userdata = UserData.objects.create(
user=self.regular_user,
start_date= datetime.date(2014, 1, 1),
end_date=datetime.date(2100, 1, 1),
unit=1,
is_18f_employee=True,
current_employee=True,
organization=self.regular_user_org
organization=self.regular_user_org,
unit=self.regular_user_unit
)
# Create a sample reporting period
self.reporting_period = ReportingPeriod.objects.create(
Expand Down Expand Up @@ -100,7 +107,7 @@ def test_user_data_is_stored(self):
userdata.end_date,
datetime.date(2100, 1, 1)
)
self.assertEqual(userdata.unit, 1)
self.assertEqual(userdata.unit, self.regular_user_unit)

def test_is_late(self):
""" Check if the user is late when no Timecard is present """
Expand All @@ -112,9 +119,15 @@ def test_is_late(self):
self.assertEqual(userdata.is_late, False)

def test_organization_name(self):
""" Check to see if we can get organization name correctly"""
"""
Check to see if we can get organization name and unit correctly.
And that the organization_name shortcut matches
the name from the relationship.
"""
userdata = self.regular_user_userdata
self.assertEqual(userdata.organization_name, 'Engineering')
self.assertEqual(userdata.organization.name, '18F')
self.assertEqual(userdata.organization_name, '18F')
self.assertEqual(userdata.unit.name, 'Engineering')

def test_organization_name_empty(self):
""" Check to see if we can get empty organization name"""
Expand All @@ -130,7 +143,7 @@ def test_organization_name_empty(self):
user=user1,
start_date= datetime.date(2014, 1, 1),
end_date=datetime.date(2100, 1, 1),
unit=1,
unit=self.regular_user_unit,
is_18f_employee=True,
current_employee=True
)
Expand Down
6 changes: 4 additions & 2 deletions tock/hours/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@

from api.tests import client
from api.views import UserDataSerializer, ProjectSerializer
from employees.models import UserData, Organization
from employees.models import UserData
from organizations.models import Organization, Unit
from hours.utils import number_of_hours
from hours.forms import choice_label_for_project
from hours.views import GeneralSnippetsTimecardSerializer, ReportsList
Expand Down Expand Up @@ -923,7 +924,8 @@ def setUp(self):
self.user = User.objects.first()
self.ud = UserData.objects.first()
self.ud.user = self.user
self.ud.unit = 0
self.ud.organization = Organization.objects.first()
self.ud.unit = Unit.objects.first()
self.ud.save()
self.rp_1 = hours.models.ReportingPeriod.objects.create(
start_date=datetime.date(2016, 10, 1),
Expand Down
8 changes: 0 additions & 8 deletions tock/hours/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,21 +94,13 @@ class GeneralSnippetsTimecardSerializer(serializers.Serializer):
)
hours_spent = serializers.DecimalField(max_digits=5, decimal_places=2)
notes = serializers.CharField()
unit = serializers.SerializerMethodField()
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We had already defined unit on L88

employee_organization = serializers.CharField(
source='timecard.user.user_data.organization_name'
)
project_organization = serializers.CharField(
source='project.organization_name'
)

def get_unit(self, obj):
try:
unit = obj.timecard.user.user_data.get_unit_display()
except ObjectDoesNotExist:
unit = ''
return unit


class SlimBulkTimecardSerializer(serializers.Serializer):
project_name = serializers.CharField(source='project.name')
Expand Down
8 changes: 7 additions & 1 deletion tock/organizations/admin.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
from django.contrib import admin

from .models import Organization
from .models import Organization, Unit


class OrganizationAdmin(admin.ModelAdmin):
list_display = ('name', 'description', 'active',)
list_filter = ('active',)
search_fields = ('name',)


class UnitAdmin(admin.ModelAdmin):
list_display = ('name', 'description')
search_fields = ('name',)

admin.site.register(Organization, OrganizationAdmin)
admin.site.register(Unit, UnitAdmin)
Loading