diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..2664d1a --- /dev/null +++ b/.editorconfig @@ -0,0 +1,13 @@ +# EditorConfig is awesome: http://EditorConfig.org + +root = true + +[*] +end_of_line = lf +insert_final_newline = true +charset = utf-8 +indent_style = space +indent_size = 4 + +[*.{html,js,s{a,c}ss}] +indent_size = 2 diff --git a/jupiter/settings.py b/jupiter/settings.py index daefdd7..a630c0b 100644 --- a/jupiter/settings.py +++ b/jupiter/settings.py @@ -31,6 +31,9 @@ # Application definition INSTALLED_APPS = ( + 'jupiter.sked', + 'scheduler', + 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', @@ -40,7 +43,6 @@ 'rest_framework', 'rest_auth', 'rest_framework.authtoken', - 'scheduler', 'simple_history' ) @@ -123,9 +125,6 @@ ) } -if not os.environ.get('LOCAL'): - REST_FRAMEWORK['DEFAULT_RENDERER_CLASSES'] = ('rest_framework.renderers.JSONRenderer', ) - REST_AUTH_SERIALIZERS = { 'USER_DETAILS_SERIALIZER': 'scheduler.serializers.UserSerializer' } diff --git a/jupiter/sked/__init__.py b/jupiter/sked/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/jupiter/sked/admin.py b/jupiter/sked/admin.py new file mode 100644 index 0000000..35a7481 --- /dev/null +++ b/jupiter/sked/admin.py @@ -0,0 +1,7 @@ +from django.contrib import admin + +from . import models + +admin.site.register(models.Organization) +admin.site.register(models.OrgGroup) +admin.site.register(models.OrgUsers) diff --git a/jupiter/sked/apps.py b/jupiter/sked/apps.py new file mode 100644 index 0000000..5d9652f --- /dev/null +++ b/jupiter/sked/apps.py @@ -0,0 +1,7 @@ +from __future__ import unicode_literals + +from django.apps import AppConfig + + +class SkedConfig(AppConfig): + name = 'sked' diff --git a/jupiter/sked/migrations/0001_initial.py b/jupiter/sked/migrations/0001_initial.py new file mode 100644 index 0000000..0c16dd6 --- /dev/null +++ b/jupiter/sked/migrations/0001_initial.py @@ -0,0 +1,203 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.4 on 2016-10-27 03:52 +from __future__ import unicode_literals + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import uuid + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='Date', + fields=[ + ('id', models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False)), + ('description', models.CharField(max_length=100)), + ('deleted', models.DateTimeField(null=True)), + ('date', models.DateField(db_index=True)), + ], + options={ + 'abstract': False, + }, + ), + migrations.CreateModel( + name='Expertise', + fields=[ + ('id', models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False)), + ('description', models.CharField(max_length=100)), + ('deleted', models.DateTimeField(null=True)), + ], + options={ + 'abstract': False, + }, + ), + migrations.CreateModel( + name='Job', + fields=[ + ('id', models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False)), + ('description', models.CharField(max_length=100)), + ('deleted', models.DateTimeField(null=True)), + ], + options={ + 'abstract': False, + }, + ), + migrations.CreateModel( + name='JobTaskFact', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('backlog_minutes', models.IntegerField(default=0)), + ('complete_minutes', models.IntegerField(default=0)), + ('job_complete', models.BooleanField(default=False)), + ('date', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='sked.Date')), + ('expertise', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='sked.Expertise')), + ('job', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='sked.Job')), + ], + ), + migrations.CreateModel( + name='JobTasks', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('job', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='sked.Job')), + ], + ), + migrations.CreateModel( + name='JobType', + fields=[ + ('id', models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False)), + ('description', models.CharField(max_length=100)), + ('deleted', models.DateTimeField(null=True)), + ], + options={ + 'abstract': False, + }, + ), + migrations.CreateModel( + name='Organization', + fields=[ + ('id', models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False)), + ('description', models.CharField(max_length=100)), + ], + ), + migrations.CreateModel( + name='Product', + fields=[ + ('id', models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False)), + ('description', models.CharField(max_length=100)), + ('deleted', models.DateTimeField(null=True)), + ('organization', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='sked.Organization')), + ], + options={ + 'abstract': False, + }, + ), + migrations.CreateModel( + name='ProductTasks', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('product', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='sked.Product')), + ], + ), + migrations.CreateModel( + name='Task', + fields=[ + ('id', models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False)), + ('description', models.CharField(max_length=100)), + ('deleted', models.DateTimeField(null=True)), + ('organization', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='sked.Organization')), + ], + options={ + 'abstract': False, + }, + ), + migrations.CreateModel( + name='Technician', + fields=[ + ('id', models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False)), + ('description', models.CharField(max_length=100)), + ('deleted', models.DateTimeField(null=True)), + ('organization', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='sked.Organization')), + ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + options={ + 'abstract': False, + }, + ), + migrations.AddField( + model_name='producttasks', + name='task', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='sked.Task'), + ), + migrations.AddField( + model_name='jobtype', + name='organization', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='sked.Organization'), + ), + migrations.AddField( + model_name='jobtasks', + name='task', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='sked.Task'), + ), + migrations.AddField( + model_name='jobtaskfact', + name='organization', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='sked.Organization'), + ), + migrations.AddField( + model_name='jobtaskfact', + name='product', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='sked.Product'), + ), + migrations.AddField( + model_name='jobtaskfact', + name='task', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='sked.Task'), + ), + migrations.AddField( + model_name='jobtaskfact', + name='technician', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='sked.Technician'), + ), + migrations.AddField( + model_name='job', + name='organization', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='sked.Organization'), + ), + migrations.AddField( + model_name='job', + name='product', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='sked.Product'), + ), + migrations.AddField( + model_name='job', + name='type', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='sked.JobType'), + ), + migrations.AddField( + model_name='expertise', + name='organization', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='sked.Organization'), + ), + migrations.AddField( + model_name='date', + name='organization', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='sked.Organization'), + ), + migrations.AlterUniqueTogether( + name='producttasks', + unique_together=set([('product', 'task')]), + ), + migrations.AlterUniqueTogether( + name='jobtasks', + unique_together=set([('job', 'task')]), + ), + ] diff --git a/jupiter/sked/migrations/0002_auto_20161212_0027.py b/jupiter/sked/migrations/0002_auto_20161212_0027.py new file mode 100644 index 0000000..f4d4f4e --- /dev/null +++ b/jupiter/sked/migrations/0002_auto_20161212_0027.py @@ -0,0 +1,63 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.4 on 2016-12-12 00:27 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion +import uuid + + +class Migration(migrations.Migration): + + dependencies = [ + ('sked', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='jobtaskfact', + name='job_type', + field=models.ForeignKey(default=uuid.uuid4, on_delete=django.db.models.deletion.CASCADE, to='sked.JobType'), + preserve_default=False, + ), + migrations.AlterField( + model_name='date', + name='id', + field=models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='expertise', + name='id', + field=models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='job', + name='id', + field=models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='jobtype', + name='id', + field=models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='organization', + name='id', + field=models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='product', + name='id', + field=models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='task', + name='id', + field=models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='technician', + name='id', + field=models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False), + ), + ] diff --git a/jupiter/sked/migrations/0003_auto_20170122_1921.py b/jupiter/sked/migrations/0003_auto_20170122_1921.py new file mode 100644 index 0000000..fcdef1f --- /dev/null +++ b/jupiter/sked/migrations/0003_auto_20170122_1921.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.4 on 2017-01-22 19:21 +from __future__ import unicode_literals + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import uuid + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('sked', '0002_auto_20161212_0027'), + ] + + operations = [ + migrations.CreateModel( + name='OrgGroup', + fields=[ + ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), + ('organization', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='sked.Organization')), + ], + ), + migrations.CreateModel( + name='OrgUsers', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('org_group', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='sked.OrgGroup')), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + ), + migrations.AlterUniqueTogether( + name='orgusers', + unique_together=set([('org_group', 'user')]), + ), + ] diff --git a/jupiter/sked/migrations/__init__.py b/jupiter/sked/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/jupiter/sked/models.py b/jupiter/sked/models.py new file mode 100644 index 0000000..0942aac --- /dev/null +++ b/jupiter/sked/models.py @@ -0,0 +1,108 @@ +from __future__ import unicode_literals +import uuid + +from django.conf import settings +from django.db import models + + +class Organization(models.Model): + id = models.UUIDField(editable=False, default=uuid.uuid4, primary_key=True) + description = models.CharField(max_length=100) + + def __unicode__(self): + return self.description + + +class OrgGroup(models.Model): + id = models.UUIDField(editable=False, default=uuid.uuid4, primary_key=True) + organization = models.ForeignKey(Organization) + + +class OrgUsers(models.Model): + org_group = models.ForeignKey(OrgGroup) + user = models.ForeignKey(settings.AUTH_USER_MODEL) + + class Meta: + unique_together = ( + ('org_group', 'user'), + ) + + +class Dimension(models.Model): + id = models.UUIDField(editable=False, default=uuid.uuid4, primary_key=True) + description = models.CharField(max_length=100) + organization = models.ForeignKey(Organization) + deleted = models.DateTimeField(null=True) + + def __unicode__(self): + return self.description + + class Meta: + abstract = True + + +class Technician(Dimension): + user = models.OneToOneField('auth.User') + + +class Expertise(Dimension): + pass + + +class Product(Dimension): + pass + + +class Task(Dimension): + pass + + +class ProductTasks(models.Model): + product = models.ForeignKey(Product) + task = models.ForeignKey(Task) + + class Meta: + unique_together = [ + ('product', 'task'), + ] + + +class JobType(Dimension): + pass + + +class Job(Dimension): + product = models.ForeignKey(Product) + type = models.ForeignKey(JobType) + + +class JobTasks(models.Model): + job = models.ForeignKey(Job) + task = models.ForeignKey(Task) + + class Meta: + unique_together = [ + ('job', 'task'), + ] + + +class Date(Dimension): + date = models.DateField(db_index=True) + + +class JobTaskFact(models.Model): + organization = models.ForeignKey(Organization) + + # dimensions + technician = models.ForeignKey(Technician) + expertise = models.ForeignKey(Expertise) + job = models.ForeignKey(Job) + job_type = models.ForeignKey(JobType) + product = models.ForeignKey(Product) + task = models.ForeignKey(Task) + date = models.ForeignKey(Date) + + # metrics + backlog_minutes = models.IntegerField(default=0) + complete_minutes = models.IntegerField(default=0) + job_complete = models.BooleanField(default=False) diff --git a/jupiter/sked/serializers.py b/jupiter/sked/serializers.py new file mode 100644 index 0000000..afa7844 --- /dev/null +++ b/jupiter/sked/serializers.py @@ -0,0 +1,103 @@ +from rest_framework import serializers +from rest_framework.reverse import reverse + +from . import models + + +class OrganizationSerializer(serializers.ModelSerializer): + technicians = serializers.SerializerMethodField() + expertises = serializers.SerializerMethodField() + jobs = serializers.SerializerMethodField() + job_types = serializers.SerializerMethodField() + products = serializers.SerializerMethodField() + tasks = serializers.SerializerMethodField() + dates = serializers.SerializerMethodField() + + def get_technicians(self, obj): + return reverse('technician-list', kwargs={'organization_id': obj.pk}, request=self.context['request']) + + def get_expertises(self, obj): + return reverse('expertise-list', kwargs={'organization_id': obj.pk}, request=self.context['request']) + + def get_jobs(self, obj): + return reverse('job-list', kwargs={'organization_id': obj.pk}, request=self.context['request']) + + def get_job_types(self, obj): + return reverse('jobtype-list', kwargs={'organization_id': obj.pk}, request=self.context['request']) + + def get_products(self, obj): + return reverse('product-list', kwargs={'organization_id': obj.pk}, request=self.context['request']) + + def get_tasks(self, obj): + return reverse('task-list', kwargs={'organization_id': obj.pk}, request=self.context['request']) + + def get_dates(self, obj): + return reverse('date-list', kwargs={'organization_id': obj.pk}, request=self.context['request']) + + class Meta: + model = models.Organization + + +class DimensionSerializer(serializers.ModelSerializer): + + def get_default_field_names(self, *args, **kwargs): + field_names = super(DimensionSerializer, self).get_default_field_names(*args, **kwargs) + field_names.remove('deleted') + field_names.remove('organization') + return field_names + + +class TechnicianSerializer(DimensionSerializer): + + class Meta: + model = models.Technician + + +class ExpertiseSerializer(DimensionSerializer): + + class Meta: + model = models.Expertise + + +class JobSerializer(DimensionSerializer): + + class Meta: + model = models.Job + + +class JobTasksSerializer(serializers.ModelSerializer): + + class Meta: + model = models.JobTasks + exclude = ['id', 'job'] + + +class JobTypeSerializer(DimensionSerializer): + + class Meta: + model = models.JobType + + +class ProductSerializer(DimensionSerializer): + + class Meta: + model = models.Product + + +class ProductTasksSerializer(serializers.ModelSerializer): + + class Meta: + model = models.ProductTasks + exclude = ['id', 'product'] + + +class TaskSerializer(DimensionSerializer): + + class Meta: + model = models.Task + + +class DateSerializer(DimensionSerializer): + + class Meta: + model = models.Date diff --git a/jupiter/sked/tests/__init__.py b/jupiter/sked/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/jupiter/sked/tests/core/__init__.py b/jupiter/sked/tests/core/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/jupiter/sked/tests/core/test_serializers.py b/jupiter/sked/tests/core/test_serializers.py new file mode 100644 index 0000000..45243f0 --- /dev/null +++ b/jupiter/sked/tests/core/test_serializers.py @@ -0,0 +1,31 @@ +import unittest + +from django import http + +from ... import models, serializers + + +class OrganizationSerializerTestCase(unittest.TestCase): + + def setUp(self): + self.request = http.HttpRequest() + self.request.META['SERVER_NAME'] = 'testhost' + self.request.META['SERVER_PORT'] = 80 + self.organization = models.Organization() + self.serialized = serializers.OrganizationSerializer( + self.organization, + context={'request': self.request}, + ).data + + def test_serialized(self): + self.assertEquals(self.serialized, { + 'id': str(self.organization.pk), + 'description': '', + 'dates': 'http://testhost/api/v1/orgs/{}/dates/'.format(self.organization.pk), + 'expertises': 'http://testhost/api/v1/orgs/{}/expertises/'.format(self.organization.pk), + 'jobs': 'http://testhost/api/v1/orgs/{}/jobs/'.format(self.organization.pk), + 'job_types': 'http://testhost/api/v1/orgs/{}/job-types/'.format(self.organization.pk), + 'products': 'http://testhost/api/v1/orgs/{}/products/'.format(self.organization.pk), + 'tasks': 'http://testhost/api/v1/orgs/{}/tasks/'.format(self.organization.pk), + 'technicians': 'http://testhost/api/v1/orgs/{}/technicians/'.format(self.organization.pk), + }) diff --git a/jupiter/sked/tests/shell/__init__.py b/jupiter/sked/tests/shell/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/jupiter/sked/tests/shell/factories.py b/jupiter/sked/tests/shell/factories.py new file mode 100644 index 0000000..c83f614 --- /dev/null +++ b/jupiter/sked/tests/shell/factories.py @@ -0,0 +1,31 @@ +from django.contrib import auth +import factory + +from ... import models + + +class UserFactory(factory.DjangoModelFactory): + + class Meta: + model = auth.get_user_model() + + +class OrgFactory(factory.DjangoModelFactory): + + class Meta: + model = models.Organization + + +class OrgGroupFactory(factory.DjangoModelFactory): + organization = factory.SubFactory(OrgFactory) + + class Meta: + model = models.OrgGroup + + +class OrgUsersFactory(factory.DjangoModelFactory): + org_group = factory.SubFactory(OrgGroupFactory) + user = factory.SubFactory(UserFactory) + + class Meta: + model = models.OrgUsers diff --git a/jupiter/sked/tests/shell/test_views.py b/jupiter/sked/tests/shell/test_views.py new file mode 100644 index 0000000..90b48bd --- /dev/null +++ b/jupiter/sked/tests/shell/test_views.py @@ -0,0 +1,18 @@ +from django import http, test +from rest_framework import views as drf_views + +from . import factories +from ... import views + + +class PermissionTestCase(test.TestCase): + + def test_has_permission(self): + request = http.HttpRequest() + org_user = factories.OrgUsersFactory.create() + view = drf_views.APIView(kwargs={'organization_id': org_user.org_group.organization_id}) + request.user = org_user.user + + has_perm = views.OrgAccessPermission().has_permission(request, view) + + self.assertTrue(has_perm) diff --git a/jupiter/sked/urls.py b/jupiter/sked/urls.py new file mode 100644 index 0000000..dcbdb57 --- /dev/null +++ b/jupiter/sked/urls.py @@ -0,0 +1,17 @@ +from rest_framework import routers + +from . import views + +router = routers.DefaultRouter() +router.register('orgs', views.OrganizationViewset) +router.register('orgs/(?P[^/]+)/technicians', views.TechnicianViewset) +router.register('orgs/(?P[^/]+)/expertises', views.ExpertiseViewset) +router.register('orgs/(?P[^/]+)/jobs', views.JobViewset) +router.register('orgs/(?P[^/]+)/jobs/(?P[^/]+)/tasks', views.JobTasksViewset) +router.register('orgs/(?P[^/]+)/job-types', views.JobTypeViewset) +router.register('orgs/(?P[^/]+)/products', views.ProductViewset) +router.register('orgs/(?P[^/]+)/products/(?P[^/]+)/tasks', views.ProductTasksViewset) +router.register('orgs/(?P[^/]+)/tasks', views.TaskViewset) +router.register('orgs/(?P[^/]+)/dates', views.DateViewset) + +urlpatterns = router.urls diff --git a/jupiter/sked/views.py b/jupiter/sked/views.py new file mode 100644 index 0000000..c76c889 --- /dev/null +++ b/jupiter/sked/views.py @@ -0,0 +1,88 @@ +from django.utils import timezone +from rest_framework import permissions, viewsets +from django.contrib.auth import models + +from . import models, serializers + + +class OrgAccessPermission(permissions.BasePermission): + + def has_permission(self, request, view): + return request.user.is_active and models.OrgUsers.objects.filter( + user=request.user, + org_group__organization=view.kwargs['organization_id'], + ).exists() + + +class OrganizationViewset(viewsets.ReadOnlyModelViewSet): + queryset = models.Organization.objects.all() + serializer_class = serializers.OrganizationSerializer + + +class DimensionViewset(viewsets.ModelViewSet): + permission_classes = (OrgAccessPermission,) + + def perform_create(self, serializer): + serializer.save(organization_id=self.kwargs['organization_id']) + + def perform_destroy(self, instance): + instance.deleted = timezone.now() + instance.save(update_fields=['deleted']) + + def get_queryset(self): + queryset = super(DimensionViewset, self).get_queryset() + return queryset.filter( + deleted__isnull=True, + organization=self.kwargs['organization_id'], + ) + + +class TechnicianViewset(DimensionViewset): + queryset = models.Technician.objects.all() + serializer_class = serializers.TechnicianSerializer + + +class ExpertiseViewset(DimensionViewset): + queryset = models.Expertise.objects.all() + serializer_class = serializers.ExpertiseSerializer + + +class JobViewset(DimensionViewset): + queryset = models.Job.objects.all() + serializer_class = serializers.JobSerializer + + +class JobTasksViewset(viewsets.ModelViewSet): + queryset = models.JobTasks.objects.all() + serializer_class = serializers.JobTasksSerializer + + def perform_create(self, serializer): + serializer.save(job_id=self.kwargs['job_id']) + + +class JobTypeViewset(DimensionViewset): + queryset = models.JobType.objects.all() + serializer_class = serializers.JobTypeSerializer + + +class ProductViewset(DimensionViewset): + queryset = models.Product.objects.all() + serializer_class = serializers.ProductSerializer + + +class ProductTasksViewset(viewsets.ModelViewSet): + queryset = models.ProductTasks.objects.all() + serializer_class = serializers.ProductTasksSerializer + + def perform_create(self, serializer): + serializer.save(product_id=self.kwargs['product_id']) + + +class TaskViewset(DimensionViewset): + queryset = models.Task.objects.all() + serializer_class = serializers.TaskSerializer + + +class DateViewset(DimensionViewset): + queryset = models.Date.objects.all() + serializer_class = serializers.DateSerializer diff --git a/jupiter/urls.py b/jupiter/urls.py index 1b3aeb3..04fd623 100644 --- a/jupiter/urls.py +++ b/jupiter/urls.py @@ -4,6 +4,7 @@ from rest_framework import routers from scheduler import views +from sked import urls as sked_urls router = routers.DefaultRouter() router.register(r'users', views.UserViewSet) @@ -19,6 +20,7 @@ url(r'^$', views.index, name='index'), url(r'^admin/', include(admin.site.urls)), url(r'^api/', include(router.urls)), + url(r'^api/v1/', include(sked_urls)), url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')), url(r'^rest-auth/login/$', views.CustomLoginView.as_view()), url(r'^rest-auth/', include('rest_auth.urls')),