|
|
|
@ -1,11 +1,18 @@ |
|
|
|
|
import calendar, datetime |
|
|
|
|
from datetime import timedelta |
|
|
|
|
from decimal import Decimal |
|
|
|
|
from itertools import groupby |
|
|
|
|
from django.shortcuts import render |
|
|
|
|
from django.contrib.auth.models import User, Group |
|
|
|
|
from django.core import exceptions |
|
|
|
|
from django.db.models import Q |
|
|
|
|
from caremyway.api.models import UserInfo, Client, Provider, WorkType, Manage, Price, Shift |
|
|
|
|
from rest_framework import viewsets, permissions, status |
|
|
|
|
from rest_framework import viewsets, permissions, status, serializers |
|
|
|
|
from rest_framework.decorators import api_view |
|
|
|
|
from rest_framework.response import Response |
|
|
|
|
from rest_framework.views import APIView |
|
|
|
|
from caremyway.api.serializers import UserSerializer, UserInfoSerializer, ClientSerializer, ProviderSerializer, WorkTypeSerializer, EmployeeSerializer, EmployerSerializer, PriceSerializer, CShiftSerializer, PShiftSerializer |
|
|
|
|
from rest_framework.renderers import StaticHTMLRenderer |
|
|
|
|
from caremyway.api.serializers import UserSerializer, UserInfoSerializer, ClientSerializer, ProviderSerializer, WorkTypeSerializer, EmployeeSerializer, EmployerSerializer, PriceSerializer, CShiftSerializer, PShiftSerializer, TimeSheetSerializer |
|
|
|
|
|
|
|
|
|
class UserViewSet(viewsets.ModelViewSet): |
|
|
|
|
lookup_field = 'username' |
|
|
|
@ -18,7 +25,7 @@ class UserViewSet(viewsets.ModelViewSet): |
|
|
|
|
return User.objects.filter(username=self.request.user) |
|
|
|
|
|
|
|
|
|
class UserInfoViewSet(viewsets.ModelViewSet): |
|
|
|
|
lookup_field = "user__username" |
|
|
|
|
lookup_field = 'user__username' |
|
|
|
|
serializer_class = UserInfoSerializer |
|
|
|
|
|
|
|
|
|
# Disallow DELETE |
|
|
|
@ -28,7 +35,7 @@ class UserInfoViewSet(viewsets.ModelViewSet): |
|
|
|
|
return UserInfo.objects.filter(user__username=self.request.user) |
|
|
|
|
|
|
|
|
|
class ClientViewSet(viewsets.ModelViewSet): |
|
|
|
|
lookup_field = "user__username" |
|
|
|
|
lookup_field = 'user__username' |
|
|
|
|
serializer_class = ClientSerializer |
|
|
|
|
|
|
|
|
|
# Disallow DELETE |
|
|
|
@ -38,7 +45,7 @@ class ClientViewSet(viewsets.ModelViewSet): |
|
|
|
|
return Client.objects.filter(user__username=self.request.user) |
|
|
|
|
|
|
|
|
|
class ProviderViewSet(viewsets.ModelViewSet): |
|
|
|
|
lookup_field = "user__username" |
|
|
|
|
lookup_field = 'user__username' |
|
|
|
|
serializer_class = ProviderSerializer |
|
|
|
|
|
|
|
|
|
# Disallow DELETE |
|
|
|
@ -48,7 +55,7 @@ class ProviderViewSet(viewsets.ModelViewSet): |
|
|
|
|
return Provider.objects.filter(user__username=self.request.user) |
|
|
|
|
|
|
|
|
|
class WorkTypeViewSet(viewsets.ModelViewSet): |
|
|
|
|
lookup_field = "uuid" |
|
|
|
|
lookup_field = 'uuid' |
|
|
|
|
serializer_class = WorkTypeSerializer |
|
|
|
|
|
|
|
|
|
def get_queryset(self): |
|
|
|
@ -61,7 +68,7 @@ class WorkTypeViewSet(viewsets.ModelViewSet): |
|
|
|
|
return Response(status=status.HTTP_204_NO_CONTENT) |
|
|
|
|
|
|
|
|
|
class EmployeeViewSet(viewsets.ModelViewSet): |
|
|
|
|
lookup_field = "uuid" |
|
|
|
|
lookup_field = 'uuid' |
|
|
|
|
serializer_class = EmployeeSerializer |
|
|
|
|
|
|
|
|
|
def get_queryset(self): |
|
|
|
@ -74,7 +81,7 @@ class EmployeeViewSet(viewsets.ModelViewSet): |
|
|
|
|
return Response(status=status.HTTP_204_NO_CONTENT) |
|
|
|
|
|
|
|
|
|
class EmployerViewSet(viewsets.ModelViewSet): |
|
|
|
|
lookup_field = "uuid" |
|
|
|
|
lookup_field = 'uuid' |
|
|
|
|
serializer_class = EmployerSerializer |
|
|
|
|
|
|
|
|
|
# Disallow creation and deletions of relationships |
|
|
|
@ -84,7 +91,7 @@ class EmployerViewSet(viewsets.ModelViewSet): |
|
|
|
|
return Manage.objects.filter(provider__user__username=self.request.user) |
|
|
|
|
|
|
|
|
|
class PriceViewSet(viewsets.ModelViewSet): |
|
|
|
|
lookup_field = "uuid" |
|
|
|
|
lookup_field = 'uuid' |
|
|
|
|
serializer_class = PriceSerializer |
|
|
|
|
|
|
|
|
|
def get_queryset(self): |
|
|
|
@ -97,12 +104,12 @@ class PriceViewSet(viewsets.ModelViewSet): |
|
|
|
|
return Response(status=status.HTTP_204_NO_CONTENT) |
|
|
|
|
|
|
|
|
|
class CShiftViewSet(viewsets.ModelViewSet): |
|
|
|
|
lookup_field = "uuid" |
|
|
|
|
lookup_field = 'uuid' |
|
|
|
|
serializer_class = CShiftSerializer |
|
|
|
|
|
|
|
|
|
def get_queryset(self): |
|
|
|
|
return Shift.objects.filter(price__management__client__user__username=self.request.user) \ |
|
|
|
|
.filter(deleted=False) \ |
|
|
|
|
return Shift.objects.filter(deleted=False) \ |
|
|
|
|
.filter(price__management__client__user__username=self.request.user) \ |
|
|
|
|
.order_by('-set_start') |
|
|
|
|
|
|
|
|
|
def destroy(self, request, *args, **kwargs): |
|
|
|
@ -116,17 +123,100 @@ class CShiftViewSet(viewsets.ModelViewSet): |
|
|
|
|
return Response(status=status.HTTP_204_NO_CONTENT) |
|
|
|
|
|
|
|
|
|
class PShiftViewSet(viewsets.ModelViewSet): |
|
|
|
|
lookup_field = "uuid" |
|
|
|
|
lookup_field = 'uuid' |
|
|
|
|
serializer_class = PShiftSerializer |
|
|
|
|
|
|
|
|
|
# Disallow creation and deletions of relationships |
|
|
|
|
http_method_names = ['get', 'head', 'put', 'options'] |
|
|
|
|
|
|
|
|
|
def get_queryset(self): |
|
|
|
|
return Shift.objects.filter(price__management__provider__user__username=self.request.user) \ |
|
|
|
|
.filter(deleted=False) \ |
|
|
|
|
return Shift.objects.filter(deleted=False) \ |
|
|
|
|
.filter(price__management__provider__user__username=self.request.user) \ |
|
|
|
|
.order_by('-set_start') |
|
|
|
|
|
|
|
|
|
def validate_param(value, field): |
|
|
|
|
class ValidateParam(serializers.Serializer): |
|
|
|
|
value = field |
|
|
|
|
|
|
|
|
|
obj = ValidateParam(data={'value': value}) |
|
|
|
|
if obj.is_valid(): |
|
|
|
|
return obj.validated_data.get('value'); |
|
|
|
|
else: |
|
|
|
|
raise serializers.ValidationError(obj.errors['value']) |
|
|
|
|
|
|
|
|
|
def get_paystart(payday): |
|
|
|
|
# Assumes payday is a valided date obj |
|
|
|
|
if payday.day == 15: |
|
|
|
|
paystart_day = 1 |
|
|
|
|
elif payday.day == calendar.monthrange(payday.year, payday.month)[1]: |
|
|
|
|
paystart_day = 16 |
|
|
|
|
else: |
|
|
|
|
raise serializers.ValidationError("Date is not a valid payday.") |
|
|
|
|
|
|
|
|
|
return datetime.date(payday.year, payday.month, paystart_day) - timedelta(days=4) |
|
|
|
|
|
|
|
|
|
def get_payend(payday): |
|
|
|
|
return payday - timedelta(days=4) |
|
|
|
|
|
|
|
|
|
def get_timesheet(user, payday, manage=None): |
|
|
|
|
paystart = get_paystart(payday) |
|
|
|
|
payend = get_payend(payday) |
|
|
|
|
|
|
|
|
|
shifts = Shift.objects.filter(deleted=False) \ |
|
|
|
|
.exclude(actual_end__isnull=True) \ |
|
|
|
|
.filter( |
|
|
|
|
Q(price__management__client__user__username=user) |
|
|
|
|
| Q(price__management__provider__user__username=user)) \ |
|
|
|
|
.filter(set_date__gte=paystart) \ |
|
|
|
|
.filter(set_date__lte=payend) \ |
|
|
|
|
.order_by('price__management', 'actual_start') |
|
|
|
|
if manage: |
|
|
|
|
shifts = shifts.filter(price__management__uuid=manage) |
|
|
|
|
|
|
|
|
|
manage_shifts = groupby(shifts, lambda x: x.price.management) |
|
|
|
|
|
|
|
|
|
timesheets = [] |
|
|
|
|
for management, shifts in manage_shifts: |
|
|
|
|
timesheet = {} |
|
|
|
|
timesheet['client'] = management.client |
|
|
|
|
timesheet['provider'] = management.provider |
|
|
|
|
timesheet['payday'] = payday |
|
|
|
|
timesheet['paystart'] = paystart |
|
|
|
|
timesheet['payend'] = payend |
|
|
|
|
timesheet['shifts'] = [] |
|
|
|
|
|
|
|
|
|
for s in shifts: |
|
|
|
|
shift = {} |
|
|
|
|
shift['date'] = s.set_date |
|
|
|
|
shift['start'] = s.actual_start |
|
|
|
|
shift['end'] = s.actual_end |
|
|
|
|
shift['hours'] = (shift['end'] - shift['start']).total_seconds() / 3600 |
|
|
|
|
shift['rate'] = s.set_price |
|
|
|
|
shift['amount'] = Decimal(shift['hours']) * shift['rate'] |
|
|
|
|
shift['work'] = s.price.work_type.label |
|
|
|
|
|
|
|
|
|
timesheet['shifts'].append(shift) |
|
|
|
|
timesheets.append(timesheet) |
|
|
|
|
|
|
|
|
|
return timesheets |
|
|
|
|
|
|
|
|
|
class ReportView(APIView): |
|
|
|
|
def get(self, request, *args, **kwargs): |
|
|
|
|
response = [] |
|
|
|
|
|
|
|
|
|
report_type = kwargs['type'] |
|
|
|
|
qp = request.query_params |
|
|
|
|
|
|
|
|
|
if report_type == 'timesheet': |
|
|
|
|
payday = validate_param(qp.get('payday'), serializers.DateField()) |
|
|
|
|
manage = validate_param(qp.get('manage'), serializers.UUIDField(allow_null=True)) |
|
|
|
|
|
|
|
|
|
timesheet = get_timesheet(request.user, payday, manage) |
|
|
|
|
|
|
|
|
|
response = TimeSheetSerializer(timesheet, many=True).data |
|
|
|
|
|
|
|
|
|
return Response(response, status=status.HTTP_200_OK) |
|
|
|
|
|
|
|
|
|
@api_view() |
|
|
|
|
def null_view(request): |
|
|
|
|
return Response(status=status.HTTP_400_BAD_REQUEST) |
|
|
|
|