505 lines
15 KiB
Python
505 lines
15 KiB
Python
from rest_framework import serializers
|
|
from leave.models import *
|
|
from leave.forms import calculate_requested_days, cal_effective_requested_days
|
|
from employee.models import Employee
|
|
|
|
|
|
def leave_Validations(self, data):
|
|
start_date = data.get("start_date")
|
|
end_date = data.get("end_date")
|
|
start_date_breakdown = (
|
|
data.get("start_date_breakdown")
|
|
if data.get("start_date_breakdown") is not None
|
|
else "full_day"
|
|
)
|
|
end_date_breakdown = (
|
|
data.get("end_date_breakdown")
|
|
if data.get("end_date_breakdown") is not None
|
|
else "full_day"
|
|
)
|
|
employee = data.get("employee_id")
|
|
leave_type_id = data.get("leave_type_id")
|
|
attachment = data.get("attachment")
|
|
available_leave = (
|
|
AvailableLeave.objects.filter(
|
|
leave_type_id=leave_type_id, employee_id=employee
|
|
)[0]
|
|
if AvailableLeave.objects.filter(
|
|
leave_type_id=leave_type_id, employee_id=employee
|
|
).exists()
|
|
else None
|
|
)
|
|
if not available_leave:
|
|
raise serializers.ValidationError(
|
|
f"Employee is not assigned with leave type {leave_type_id}."
|
|
)
|
|
|
|
requested_days = calculate_requested_days(
|
|
start_date, end_date, start_date_breakdown, end_date_breakdown
|
|
)
|
|
effective_requested_days = cal_effective_requested_days(
|
|
start_date=start_date,
|
|
end_date=end_date,
|
|
leave_type_id=leave_type_id,
|
|
requested_days=requested_days,
|
|
)
|
|
|
|
total_leave_days = (
|
|
available_leave.available_days + available_leave.carryforward_days
|
|
)
|
|
errors = {}
|
|
# checking if there is any requested days is overlapping with the existing leave request
|
|
leave_requests = employee.leaverequest_set.filter(
|
|
start_date__lte=end_date, end_date__gte=start_date
|
|
)
|
|
if self.instance:
|
|
leave_requests = leave_requests.exclude(id=self.instance.id)
|
|
if leave_requests:
|
|
raise serializers.ValidationError(
|
|
"There is already a leave request for this date range."
|
|
)
|
|
|
|
# checking if the end date is less than the start date
|
|
if not start_date <= end_date:
|
|
errors["end_date"] = ["End date should not be less than start date."]
|
|
|
|
if start_date == end_date and start_date_breakdown != end_date_breakdown:
|
|
raise serializers.ValidationError(
|
|
"There is a mismatch in the breakdown of the start date and end date."
|
|
)
|
|
|
|
if not effective_requested_days <= total_leave_days:
|
|
raise serializers.ValidationError("Employee doesn't have enough leave days..")
|
|
|
|
if leave_type_id.require_attachment == "yes" and attachment == None:
|
|
errors["attachment"] = ["This field is required."]
|
|
|
|
if errors:
|
|
raise serializers.ValidationError(errors)
|
|
|
|
|
|
class GetAvailableLeaveTypeSerializer(serializers.ModelSerializer):
|
|
leave_type_id = serializers.SerializerMethodField()
|
|
icon = serializers.SerializerMethodField()
|
|
|
|
class Meta:
|
|
model = AvailableLeave
|
|
fields = [
|
|
"id",
|
|
"leave_type_id",
|
|
"icon",
|
|
"available_days",
|
|
"carryforward_days",
|
|
"total_leave_days",
|
|
]
|
|
|
|
def get_leave_type_id(self, obj):
|
|
if obj.leave_type_id:
|
|
return LeaveTypeAllGetSerializer(obj.leave_type_id).data
|
|
return None
|
|
|
|
def get_icon(self, obj):
|
|
try:
|
|
return obj.leave_type_id.icon.url
|
|
except:
|
|
return None
|
|
|
|
|
|
class GetAvailableLeaveTypeSerializer(serializers.ModelSerializer):
|
|
leave_type_id = serializers.SerializerMethodField()
|
|
icon = serializers.SerializerMethodField()
|
|
total_leave_days = serializers.SerializerMethodField()
|
|
|
|
class Meta:
|
|
model = AvailableLeave
|
|
fields = [
|
|
"id",
|
|
"leave_type_id",
|
|
"icon",
|
|
"available_days",
|
|
"carryforward_days",
|
|
"total_leave_days",
|
|
]
|
|
|
|
def get_leave_type_id(self, obj):
|
|
if obj.leave_type_id:
|
|
return LeaveTypeAllGetSerializer(obj.leave_type_id).data
|
|
return None
|
|
|
|
def get_icon(self, obj):
|
|
try:
|
|
return obj.leave_type_id.icon.url
|
|
except:
|
|
return None
|
|
|
|
def get_total_leave_days(self, obj):
|
|
return obj.available_days + obj.carryforward_days
|
|
|
|
|
|
class userLeaveRequestGetAllSerilaizer(serializers.ModelSerializer):
|
|
leave_type_id = serializers.SerializerMethodField()
|
|
|
|
class Meta:
|
|
model = LeaveRequest
|
|
exclude = [
|
|
"requested_date",
|
|
"description",
|
|
"attachment",
|
|
"approved_available_days",
|
|
"approved_carryforward_days",
|
|
"created_at",
|
|
"reject_reason",
|
|
"employee_id",
|
|
"created_by",
|
|
]
|
|
|
|
def get_leave_type_id(self, obj):
|
|
if obj.leave_type_id:
|
|
return LeaveTypeAllGetSerializer(obj.leave_type_id).data
|
|
return None
|
|
|
|
|
|
class UserLeaveRequestGetSerilaizer(serializers.ModelSerializer):
|
|
leave_type_id = serializers.SerializerMethodField()
|
|
|
|
class Meta:
|
|
model = LeaveRequest
|
|
exclude = [
|
|
"requested_date",
|
|
"approved_available_days",
|
|
"approved_carryforward_days",
|
|
"created_at",
|
|
"reject_reason",
|
|
"employee_id",
|
|
"created_by",
|
|
]
|
|
|
|
def get_leave_type_id(self, obj):
|
|
if obj.leave_type_id:
|
|
return LeaveTypeAllGetSerializer(obj.leave_type_id).data
|
|
return None
|
|
|
|
|
|
class LeaveRequestCreateUpdateSerializer(serializers.ModelSerializer):
|
|
|
|
class Meta:
|
|
model = LeaveRequest
|
|
fields = [
|
|
"employee_id",
|
|
"leave_type_id",
|
|
"start_date",
|
|
"start_date_breakdown",
|
|
"end_date",
|
|
"end_date_breakdown",
|
|
"description",
|
|
"attachment",
|
|
]
|
|
|
|
def validate(self, data):
|
|
leave_Validations(self, data)
|
|
return data
|
|
|
|
|
|
class UpdateLeaveRequestSerializer(serializers.ModelSerializer):
|
|
|
|
class Meta:
|
|
model = LeaveRequest
|
|
fields = [
|
|
"start_date",
|
|
"start_date_breakdown",
|
|
"end_date",
|
|
"end_date_breakdown",
|
|
"description",
|
|
"attachment",
|
|
]
|
|
|
|
def validate(self, data):
|
|
leave_Validations(self, data)
|
|
return data
|
|
|
|
|
|
class LeaveTypeGetCreateSerilaizer(serializers.ModelSerializer):
|
|
class Meta:
|
|
model = LeaveType
|
|
fields = "__all__"
|
|
|
|
def validate(self, data):
|
|
reset = data.get("reset")
|
|
reset_based = data.get("reset_based")
|
|
reset_month = data.get("reset_month")
|
|
reset_day = data.get("reset_day")
|
|
reset_weekday = data.get("reset_weekday")
|
|
carryforward_type = data.get("carryforward_type")
|
|
carryforward_max = data.get("carryforward_max")
|
|
if reset == True:
|
|
if reset_based == None:
|
|
raise serializers.ValidationError(
|
|
{"reset_based": ["This field is required."]}
|
|
)
|
|
elif reset_based == "yearly" and reset_month == None:
|
|
raise serializers.ValidationError(
|
|
{"reset_month": ["This field is required."]}
|
|
)
|
|
elif reset_based in ["yearly", "monthly"] and reset_day == "":
|
|
raise serializers.ValidationError(
|
|
{"reset_day": ["This field is required."]}
|
|
)
|
|
elif reset_based == "weekly" and reset_weekday == None:
|
|
raise serializers.ValidationError(
|
|
{"reset_weekday": ["This field is required."]}
|
|
)
|
|
# elif carryforward_type in ['carryforward', 'carryforward expire'] and carryforward_max
|
|
return data
|
|
|
|
|
|
class LeaveTypeAllGetSerializer(serializers.ModelSerializer):
|
|
class Meta:
|
|
model = LeaveType
|
|
fields = ["id", "name", "icon"]
|
|
|
|
|
|
class LeaveAllocationRequestCreateSerializer(serializers.ModelSerializer):
|
|
requested_days = serializers.FloatField(required=True)
|
|
|
|
class Meta:
|
|
model = LeaveAllocationRequest
|
|
fields = [
|
|
"leave_type_id",
|
|
"employee_id",
|
|
"requested_days",
|
|
"created_by",
|
|
"description",
|
|
"attachment",
|
|
]
|
|
|
|
|
|
class AssignLeaveCreateSerializer(serializers.Serializer):
|
|
leave_type_ids = serializers.PrimaryKeyRelatedField(
|
|
many=True, queryset=LeaveType.objects.all()
|
|
)
|
|
employee_ids = serializers.PrimaryKeyRelatedField(
|
|
many=True, queryset=Employee.objects.all()
|
|
)
|
|
|
|
def validate_leave_type_ids(self, value):
|
|
if not value:
|
|
raise serializers.ValidationError(
|
|
{"leave_type_ids": ["This field is required."]}
|
|
)
|
|
return value
|
|
|
|
def validate_employee_ids(self, value):
|
|
if not value:
|
|
raise serializers.ValidationError(
|
|
{"employee_ids": ["This field is required."]}
|
|
)
|
|
return value
|
|
|
|
|
|
class AssignLeaveGetSerializer(serializers.ModelSerializer):
|
|
|
|
employee_id = serializers.SerializerMethodField()
|
|
leave_type_id = serializers.SerializerMethodField()
|
|
|
|
class Meta:
|
|
model = AvailableLeave
|
|
exclude = ["reset_date", "expired_date"]
|
|
|
|
def get_employee_id(self, obj):
|
|
employee = obj.employee_id
|
|
if employee:
|
|
return EmployeeGetSerializer(employee).data
|
|
return None
|
|
|
|
def get_leave_type_id(self, obj):
|
|
if obj.leave_type_id:
|
|
return LeaveTypeAllGetSerializer(obj.leave_type_id).data
|
|
return None
|
|
|
|
|
|
class EmployeeGetSerializer(serializers.ModelSerializer):
|
|
full_name = serializers.SerializerMethodField()
|
|
|
|
class Meta:
|
|
model = Employee
|
|
fields = ["id", "full_name", "employee_profile", "badge_id"]
|
|
|
|
def get_full_name(self, obj):
|
|
return obj.get_full_name()
|
|
|
|
|
|
class AvailableLeaveUpdateSerializer(serializers.ModelSerializer):
|
|
available_days = serializers.FloatField(required=True)
|
|
|
|
class Meta:
|
|
model = AvailableLeave
|
|
fields = ["available_days", "carryforward_days"]
|
|
|
|
|
|
class LeaveRequestGetAllSerilaizer(serializers.ModelSerializer):
|
|
employee_id = serializers.SerializerMethodField()
|
|
leave_type_id = serializers.SerializerMethodField()
|
|
multiple_approve = serializers.SerializerMethodField()
|
|
|
|
class Meta:
|
|
model = LeaveRequest
|
|
exclude = [
|
|
"requested_date",
|
|
"description",
|
|
"attachment",
|
|
"approved_available_days",
|
|
"approved_carryforward_days",
|
|
"created_at",
|
|
"reject_reason",
|
|
"created_by",
|
|
]
|
|
|
|
def get_employee_id(self, obj):
|
|
employee = obj.employee_id
|
|
if employee:
|
|
return EmployeeGetSerializer(employee).data
|
|
return None
|
|
|
|
def get_leave_type_id(self, obj):
|
|
if obj.leave_type_id:
|
|
return LeaveTypeAllGetSerializer(obj.leave_type_id).data
|
|
return None
|
|
|
|
def get_multiple_approve(self, obj):
|
|
approvals = LeaveRequestConditionApproval.objects.filter(leave_request_id=obj)
|
|
employee = self.context["request"].user.employee_get
|
|
if approvals and obj.status == "requested":
|
|
is_approved = approvals.filter(is_approved=True)
|
|
count = f"{is_approved.count()} / {approvals.count()}"
|
|
is_approved = (
|
|
True if is_approved.filter(manager_id=employee).exists() else False
|
|
)
|
|
return {"count": count, "is_approved": is_approved}
|
|
return None
|
|
|
|
|
|
class LeaveRequestGetSerilaizer(serializers.ModelSerializer):
|
|
employee_id = serializers.SerializerMethodField()
|
|
leave_type_id = serializers.SerializerMethodField()
|
|
multiple_approve = serializers.SerializerMethodField()
|
|
|
|
class Meta:
|
|
model = LeaveRequest
|
|
exclude = [
|
|
"requested_date",
|
|
"approved_available_days",
|
|
"approved_carryforward_days",
|
|
"created_at",
|
|
"reject_reason",
|
|
"created_by",
|
|
]
|
|
|
|
def get_employee_id(self, obj):
|
|
employee = obj.employee_id
|
|
if employee:
|
|
return EmployeeGetSerializer(employee).data
|
|
return None
|
|
|
|
def get_leave_type_id(self, obj):
|
|
if obj.leave_type_id:
|
|
return LeaveTypeAllGetSerializer(obj.leave_type_id).data
|
|
return None
|
|
|
|
def get_multiple_approve(self, obj):
|
|
approvals = LeaveRequestConditionApproval.objects.filter(leave_request_id=obj)
|
|
employee = self.context["request"].user.employee_get
|
|
if approvals and obj.status == "requested":
|
|
is_approved = approvals.filter(is_approved=True)
|
|
count = f"{is_approved.count()} / {approvals.count()}"
|
|
is_approved = (
|
|
True if is_approved.filter(manager_id=employee).exists() else False
|
|
)
|
|
return {"count": count, "is_approved": is_approved}
|
|
return None
|
|
|
|
|
|
class LeaveAllocationRequestSerilaizer(serializers.ModelSerializer):
|
|
class Meta:
|
|
model = LeaveAllocationRequest
|
|
exclude = [
|
|
"requested_date",
|
|
"status",
|
|
"created_by",
|
|
"created_at",
|
|
"reject_reason",
|
|
]
|
|
|
|
|
|
class LeaveAllocationRequestGetSerializer(serializers.ModelSerializer):
|
|
employee_id = serializers.SerializerMethodField()
|
|
leave_type_id = serializers.SerializerMethodField()
|
|
created_by = serializers.SerializerMethodField()
|
|
|
|
class Meta:
|
|
model = LeaveAllocationRequest
|
|
exclude = ["requested_date", "created_at", "reject_reason"]
|
|
|
|
def get_employee_id(self, obj):
|
|
employee = obj.employee_id
|
|
if employee:
|
|
return EmployeeGetSerializer(employee).data
|
|
return None
|
|
|
|
def get_leave_type_id(self, obj):
|
|
if obj.leave_type_id:
|
|
return LeaveTypeAllGetSerializer(obj.leave_type_id).data
|
|
return None
|
|
|
|
def get_created_by(self, obj):
|
|
created_by = obj.created_by
|
|
if created_by:
|
|
return EmployeeGetSerializer(created_by).data
|
|
return None
|
|
|
|
|
|
class CompanyLeaveSerializer(serializers.ModelSerializer):
|
|
class Meta:
|
|
model = CompanyLeave
|
|
exclude = ["company_id"]
|
|
|
|
|
|
class HoildaySerializer(serializers.ModelSerializer):
|
|
class Meta:
|
|
model = Holiday
|
|
exclude = ["company_id"]
|
|
|
|
def validate(self, data):
|
|
start_date = data.get("start_date")
|
|
end_date = data.get("end_date")
|
|
if end_date and not start_date <= end_date:
|
|
raise serializers.ValidationError(
|
|
{"end_date": ["End date should not be less than start date."]}
|
|
)
|
|
return data
|
|
|
|
|
|
class LeaveRequestApproveSerializer(serializers.ModelSerializer):
|
|
|
|
class Meta:
|
|
model = LeaveRequest
|
|
fields = []
|
|
|
|
def validate(self, data):
|
|
leave_request = self.instance
|
|
if leave_request.status != "requested":
|
|
raise serializers.ValidationError("Nothing to approve.")
|
|
employee_id = leave_request.employee_id
|
|
leave_type_id = leave_request.leave_type_id
|
|
available_leave = AvailableLeave.objects.get(
|
|
leave_type_id=leave_type_id, employee_id=employee_id
|
|
)
|
|
total_available_leave = (
|
|
available_leave.available_days + available_leave.carryforward_days
|
|
)
|
|
if not total_available_leave >= leave_request.requested_days:
|
|
raise serializers.ValidationError(
|
|
f"{employee_id} dont have enough leave days to approve the request.."
|
|
)
|
|
data["available_leave"] = available_leave
|
|
return data
|