You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

330 lines
14 KiB

from datetime import datetime, timedelta, timezone
from decimal import Decimal
from django.contrib.auth.models import User, Group
from django.shortcuts import get_object_or_404
from rest_framework import serializers
from caremyway.api.models import UserInfo, Client, Provider, WorkType, Manage, Price, Shift
class UserInfoSerializer(serializers.ModelSerializer):
class Meta:
model = UserInfo
fields = ('phone_number',)
def create(self, validated_data):
validated_data['user'] = self.context['request'].user
return serializers.ModelSerializer.create(self, validated_data)
class WorkTypeSerializer(serializers.ModelSerializer):
class Meta:
model = WorkType
fields = ('uuid', 'color', 'label', 'deleted')
read_only_fields = ('deleted',)
def create(self, validated_data):
validated_data['client'] = self.context['request'].user.client
return serializers.ModelSerializer.create(self, validated_data)
def update(self, instance, validated_data):
if 'label' in validated_data:
raise serializers.ValidationError("Cannot update field.")
return super().update(instance, validated_data)
class PriceSerializer(serializers.ModelSerializer):
get_employee_uuid = serializers.UUIDField(write_only=True)
get_work_type_uuid = serializers.UUIDField(write_only=True)
work_type = WorkTypeSerializer(read_only=True)
class Meta:
model = Price
fields = ('uuid', 'get_employee_uuid', 'get_work_type_uuid', 'work_type', 'amount', 'deleted')
read_only_fields = ('deleted',)
depth = 1
def create(self, validated_data):
user = self.context['request'].user
if not Client.objects.filter(user=user).exists():
raise serializers.ValidationError("User is not a client.")
client = user.client
manage_objs = Manage.objects.filter(deleted=False).filter(client=client)
employee_uuid = validated_data.pop('get_employee_uuid')
employee = get_object_or_404(manage_objs, uuid=employee_uuid)
worktype_objs = WorkType.objects.filter(deleted=False).filter(client=client)
work_type_uuid = validated_data.pop('get_work_type_uuid')
work_type = get_object_or_404(worktype_objs, uuid=work_type_uuid)
if not employee.approved:
raise serializers.ValidationError("Employee hasn't approved employment yet.")
if Price.objects.filter(deleted=False) \
.filter(work_type=work_type) \
.filter(management=employee).exists():
raise serializers.ValidationError("Price for this work already defined.")
validated_data['management'] = employee
validated_data['work_type'] = work_type
return serializers.ModelSerializer.create(self, validated_data)
class EmployeeUserSerializer(serializers.ModelSerializer):
userinfo = UserInfoSerializer(read_only=True)
class Meta:
model = User
fields = ('is_active', 'first_name', 'last_name', 'email', 'userinfo')
depth = 1
class EmployeeSerializer(serializers.ModelSerializer):
provider_email = serializers.EmailField(write_only=True)
provider = serializers.SerializerMethodField()
prices = PriceSerializer(many=True, read_only=True)
class Meta:
model = Manage
fields = ('uuid', 'provider', 'provider_email', 'note', 'approved', 'prices', 'deleted')
read_only_fields = ('approved', 'deleted')
def get_provider(self, obj):
if obj.approved == True:
user = User.objects.get(provider=obj.provider)
return EmployeeUserSerializer(user).data
else:
return obj.provider.user.email
def create(self, validated_data):
user = self.context['request'].user
if not Client.objects.filter(user=user).exists():
raise serializers.ValidationError("User is not a client.")
client = user.client
provider_email = validated_data.pop('provider_email')
provider = get_object_or_404(Provider, user__email=provider_email)
if Manage.objects.filter(deleted=False) \
.filter(provider=provider) \
.filter(client=client).exists():
raise serializers.ValidationError("Employee already added.")
validated_data['client'] = client
validated_data['provider'] = provider
return serializers.ModelSerializer.create(self, validated_data)
class ClientSerializer(serializers.ModelSerializer):
work_types = WorkTypeSerializer(many=True, read_only=True)
employees = EmployeeSerializer(many=True, read_only=True)
class Meta:
model = Client
fields = ('business_number', 'work_types', 'employees')
def create(self, validated_data):
user = self.context['request'].user
if Provider.objects.filter(user=user).exists():
raise serializers.ValidationError("User is already a Provider.")
validated_data['user'] = user
return serializers.ModelSerializer.create(self, validated_data)
class EmployerUserSerializer(serializers.ModelSerializer):
userinfo = UserInfoSerializer(read_only=True)
class Meta:
model = User
fields = ('is_active', 'first_name', 'last_name', 'email', 'userinfo')
depth = 1
class EmployerSerializer(serializers.ModelSerializer):
client = serializers.SerializerMethodField()
prices = PriceSerializer(many=True, read_only=True)
class Meta:
model = Manage
fields = ('uuid', 'client', 'note', 'approved', 'prices')
read_only_fields = ('note',)
def get_client(self, obj):
if obj.approved == True:
user = User.objects.get(client=obj.client)
return EmployerUserSerializer(user).data
else:
return obj.client.user.first_name + ' ' + obj.client.user.last_name
class ProviderSerializer(serializers.ModelSerializer):
employers = EmployerSerializer(many=True, read_only=True)
class Meta:
model = Provider
fields = ('sin', 'employers')
def create(self, validated_data):
user = self.context['request'].user
if Client.objects.filter(user=user).exists():
raise serializers.ValidationError("User is already a Client.")
validated_data['user'] = user
return serializers.ModelSerializer.create(self, validated_data)
class UserSerializer(serializers.ModelSerializer):
userinfo = UserInfoSerializer(read_only=True)
client = ClientSerializer(read_only=True)
provider = ProviderSerializer(read_only=True)
class Meta:
model = User
fields = ('username', 'is_active', 'first_name', 'last_name', 'email', 'userinfo', 'client', 'provider')
depth = 1
class ShiftSerializer(serializers.ModelSerializer):
price = serializers.SerializerMethodField()
amount = serializers.SerializerMethodField()
def get_price(self, obj):
return obj.price.uuid
def get_amount(self, obj):
if obj.actual_end:
shift_length = obj.actual_end - obj.actual_start
return Decimal(shift_length.total_seconds()) / 3600 * obj.set_price
else:
return None
class CShiftSerializer(ShiftSerializer):
get_price_uuid = serializers.UUIDField(write_only=True)
class Meta:
model = Shift
fields = ('uuid', 'chart', 'get_price_uuid', 'price', 'set_price', 'set_date', 'set_start', 'set_end', 'actual_start', 'actual_end', 'amount', 'description', 'deleted')
read_only_fields = ('chart', 'price', 'set_price', 'set_date', 'actual_start', 'actual_end', 'deleted')
def create(self, validated_data):
user = self.context['request'].user
if not Client.objects.filter(user=user).exists():
raise serializers.ValidationError("User is not a client.")
client = user.client
price_objs = Price.objects.filter(deleted=False).filter(management__client=client)
price_uuid = validated_data.pop('get_price_uuid')
price = get_object_or_404(price_objs, uuid=price_uuid)
if price.management.deleted:
raise serializers.ValidationError("Employment relationship was deleted.")
if price.work_type.deleted:
raise serializers.ValidationError("Type of work was deleted.")
if not price.management.approved:
raise serializers.ValidationError("Employee hasn't approved employment yet.")
now = datetime.now(timezone.utc)
set_start = validated_data['set_start']
set_end = validated_data['set_end']
if set_start > set_end:
raise serializers.ValidationError("Shift ends before it starts.")
if set_start > set_end - timedelta(hours=1):
raise serializers.ValidationError("Shift is less than one hour long.")
if set_start < now or set_end < now:
raise serializers.ValidationError("Shift is in the past.")
# TODO: Make sure provider isn't double-booked?????
validated_data['set_date'] = set_start.date()
validated_data['price'] = price
return serializers.ModelSerializer.create(self, validated_data)
class PShiftSerializer(ShiftSerializer):
action = serializers.ChoiceField(write_only=True, choices=['checkin', 'checkout'])
class Meta:
model = Shift
fields = ('uuid', 'action', 'chart', 'price', 'set_price', 'set_date', 'set_start', 'set_end', 'actual_start', 'actual_end', 'amount', 'description', 'deleted')
read_only_fields = ('uuid', 'price', 'set_price', 'set_date', 'set_start', 'set_end', 'actual_start', 'actual_end', 'description', 'deleted')
def update(self, instance, validated_data):
action = validated_data['action']
chart = validated_data['chart']
if action == 'checkin':
if instance.deleted:
raise serializers.ValidationError("Shift was deleted.")
if instance.actual_start:
raise serializers.ValidationError("Already checked in.")
if chart:
raise serializers.ValidationError("Can only provide chart on checkout.")
instance.actual_start = datetime.now(timezone.utc)
instance.set_price = instance.price.amount
elif action == 'checkout':
if not instance.actual_start:
raise serializers.ValidationError("Need to check in first.")
if instance.actual_end:
raise serializers.ValidationError("Already checked out.")
if not chart:
raise serializers.ValidationError("No chart info provided.")
instance.actual_end = datetime.now(timezone.utc)
instance.chart = chart
instance.save()
return instance
class TimeSheetSerializer(serializers.Serializer):
class ShiftSerializer(serializers.Serializer):
date = serializers.DateField()
start = serializers.DateTimeField()
end = serializers.DateTimeField()
hours = serializers.DecimalField(max_digits=8, decimal_places=2)
rate = serializers.DecimalField(max_digits=8, decimal_places=2)
amount = serializers.DecimalField(max_digits=8, decimal_places=2)
work = serializers.CharField()
management = serializers.CharField()
client = serializers.CharField()
provider = serializers.CharField()
payday = serializers.DateField()
paystart = serializers.DateField()
payend = serializers.DateField()
shifts = ShiftSerializer(many=True)
class RecordSheetSerializer(serializers.Serializer):
class RecordSerializer(serializers.Serializer):
payday = serializers.DateField()
reg_pay = serializers.DecimalField(max_digits=10, decimal_places=2)
vac_pay = serializers.DecimalField(max_digits=10, decimal_places=2)
earnings = serializers.DecimalField(max_digits=10, decimal_places=2)
cpp_ytd = serializers.DecimalField(max_digits=10, decimal_places=2)
cpp = serializers.DecimalField(max_digits=10, decimal_places=2)
ei_ytd = serializers.DecimalField(max_digits=10, decimal_places=2)
ei = serializers.DecimalField(max_digits=10, decimal_places=2)
taxable_income = serializers.DecimalField(max_digits=10, decimal_places=2)
fed_tax = serializers.DecimalField(max_digits=10, decimal_places=2)
fed_tax_payable = serializers.DecimalField(max_digits=10, decimal_places=2)
prov_tax = serializers.DecimalField(max_digits=10, decimal_places=2)
prov_tax_deduction = serializers.DecimalField(max_digits=10, decimal_places=2)
income_tax = serializers.DecimalField(max_digits=10, decimal_places=2)
total_deductions = serializers.DecimalField(max_digits=10, decimal_places=2)
net_pay = serializers.DecimalField(max_digits=10, decimal_places=2)
management = serializers.CharField()
client = serializers.CharField()
provider = serializers.CharField()
phone_number = serializers.CharField()
sin = serializers.CharField()
record = RecordSerializer(many=True)
class PayStubSerializer(serializers.Serializer):
management = serializers.CharField()
client = serializers.CharField()
provider = serializers.CharField()
payday = serializers.DateField()
reg_pay = serializers.DecimalField(max_digits=10, decimal_places=2)
vac_pay = serializers.DecimalField(max_digits=10, decimal_places=2)
earnings = serializers.DecimalField(max_digits=10, decimal_places=2)
cpp = serializers.DecimalField(max_digits=10, decimal_places=2)
ei = serializers.DecimalField(max_digits=10, decimal_places=2)
income_tax = serializers.DecimalField(max_digits=10, decimal_places=2)
total_deductions = serializers.DecimalField(max_digits=10, decimal_places=2)
net_pay = serializers.DecimalField(max_digits=10, decimal_places=2)