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.

392 lines
17 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 = ('dob', 'address1', 'address2', 'city', 'province', 'postal_code', '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', 'alt_name', 'alt_address1', 'alt_address2', 'alt_city', 'alt_province', 'alt_phone_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', 'deleted')
read_only_fields = ('note', 'deleted')
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', 'cert_title1', 'cert_date1', 'cert_institution1', 'cert_title2', 'cert_date2', 'cert_institution2', 'cert_title3', 'cert_date3', 'cert_institution3', 'emerg_contact_name', 'emerg_contact_number', 'crim_record_check_date', '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.approved_end:
shift_length = obj.approved_end - obj.approved_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_start', 'set_end', 'actual_start', 'actual_end', 'approved_start', 'approved_end', 'approved_date', 'amount', 'description', 'provider_approved', 'deleted')
read_only_fields = ('chart', 'price', 'set_price', 'actual_start', 'actual_end', 'approved_date', 'provider_approved', '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']
approved_start = validated_data['approved_start']
approved_end = validated_data['approved_end']
if approved_start or approved_end:
raise serializers.ValidationError("Can't set approved time on creation.")
if not set_start or not set_end:
raise serializers.ValidationError("Must include shift start and end times.")
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['price'] = price
return serializers.ModelSerializer.create(self, validated_data)
def update(self, instance, validated_data):
set_start = validated_data['set_start']
set_end = validated_data['set_end']
approved_start = validated_data['approved_start']
approved_end = validated_data['approved_end']
if set_start and set_end:
if instance.actual_start:
raise serializers.ValidationError("Can't update after checkin.")
now = datetime.now(timezone.utc)
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.")
# Reset provider approval on update
instance.provider_approved = None
instance.set_start = set_start
instance.set_end = set_end
elif approved_start and approved_end:
if not instance.actual_start:
raise serializers.ValidationError("Can't approve / edit time until after checkin.")
if approved_start > approved_end:
raise serializers.ValidationError("Shift ends before it starts.")
if approved_start > approved_end - timedelta(hours=1):
raise serializers.ValidationError("Shift is less than one hour long.")
instance.approved_start = approved_start
instance.approved_end = approved_end
instance.approved_date = approved_start.date()
else:
raise serializers.ValidationError("Missing field.")
instance.save()
return instance
class PShiftSerializer(ShiftSerializer):
action = serializers.ChoiceField(write_only=True, allow_blank=True, choices=['checkin', 'checkout'])
class Meta:
model = Shift
fields = ('uuid', 'action', 'chart', 'price', 'set_price', 'set_start', 'set_end', 'actual_start', 'actual_end', 'approved_start', 'approved_end', 'approved_date', 'amount', 'description', 'provider_approved', 'deleted')
read_only_fields = ('uuid', 'price', 'set_price', 'set_start', 'set_end', 'actual_start', 'actual_end', 'approved_start', 'approved_end', 'approved_date', 'description', 'deleted')
def update(self, instance, validated_data):
provider_approved = validated_data['provider_approved']
action = validated_data['action']
chart = validated_data['chart']
if provider_approved == True:
if instance.deleted:
raise serializers.ValidationError("Shift was deleted.")
instance.provider_approved = True
elif provider_approved == False:
if instance.actual_start:
raise serializers.ValidationError("Can't disapprove after check in.")
instance.provider_approved = False
if action == 'checkin':
if instance.deleted:
raise serializers.ValidationError("Shift was deleted.")
if not instance.provider_approved:
raise serializers.ValidationError("Shift hasn't been approved by the provider..")
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)