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.
255 lines
10 KiB
255 lines
10 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) |
|
|
|
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(client=client).filter(deleted=False) |
|
employee_uuid = validated_data.pop('get_employee_uuid') |
|
employee = get_object_or_404(manage_objs, uuid=employee_uuid) |
|
worktype_objs = WorkType.objects.filter(client=client).filter(deleted=False) |
|
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(management=employee) \ |
|
.filter(work_type=work_type) \ |
|
.filter(deleted=False).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(client=client) \ |
|
.filter(provider=provider) \ |
|
.filter(deleted=False).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 CShiftSerializer(serializers.ModelSerializer): |
|
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', 'amount', '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(management__client=client).filter(deleted=False) |
|
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(serializers.ModelSerializer): |
|
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', 'amount', '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) |
|
shift_length = instance.actual_end - instance.actual_start |
|
instance.amount = Decimal(shift_length.total_seconds()) / 3600 * instance.set_price |
|
instance.chart = chart |
|
|
|
instance.save() |
|
return instance
|
|
|