[ADD] HORILLA API: Add Horilla API into master code base
This commit is contained in:
301
horilla_api/api_views/asset/views.py
Normal file
301
horilla_api/api_views/asset/views.py
Normal file
@@ -0,0 +1,301 @@
|
||||
from rest_framework.views import APIView
|
||||
from rest_framework.response import Response
|
||||
from rest_framework import status
|
||||
from asset.models import *
|
||||
from ...api_serializers.asset.serializers import *
|
||||
from rest_framework.pagination import PageNumberPagination
|
||||
from rest_framework.permissions import IsAuthenticated
|
||||
from django_filters.rest_framework import DjangoFilterBackend
|
||||
from ...api_filters.asset.filters import AssetCategoryFilter
|
||||
from asset.filters import AssetFilter
|
||||
from django.http import QueryDict
|
||||
from datetime import date
|
||||
|
||||
class AssetAPIView(APIView):
|
||||
permission_classes = [IsAuthenticated]
|
||||
filter_backends = [DjangoFilterBackend]
|
||||
filterset_class = AssetFilter
|
||||
|
||||
def get_asset(self, pk):
|
||||
try:
|
||||
return Asset.objects.get(pk=pk)
|
||||
except Asset.DoesNotExist as e:
|
||||
raise serializers.ValidationError(e)
|
||||
|
||||
def get(self, request, pk=None):
|
||||
if pk:
|
||||
asset = self.get_asset(pk)
|
||||
serializer = AssetSerializer(asset)
|
||||
return Response(serializer.data)
|
||||
paginator = PageNumberPagination()
|
||||
queryset = Asset.objects.all()
|
||||
filterset = self.filterset_class(request.GET, queryset=queryset)
|
||||
page = paginator.paginate_queryset(filterset.qs, request)
|
||||
serializer = AssetGetAllSerializer(page, many=True)
|
||||
return paginator.get_paginated_response(serializer.data)
|
||||
|
||||
def post(self, request):
|
||||
serializer = AssetSerializer(data=request.data)
|
||||
if serializer.is_valid():
|
||||
serializer.save()
|
||||
return Response(serializer.data, status=status.HTTP_201_CREATED)
|
||||
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
def put(self, request, pk):
|
||||
asset = self.get_asset(pk)
|
||||
serializer = AssetSerializer(asset, data=request.data)
|
||||
if serializer.is_valid():
|
||||
serializer.save()
|
||||
return Response(serializer.data)
|
||||
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
def delete(self, request, pk):
|
||||
asset = self.get_asset(pk)
|
||||
asset.delete()
|
||||
return Response(status=status.HTTP_204_NO_CONTENT)
|
||||
|
||||
class AssetCategoryAPIView(APIView):
|
||||
permission_classes = [IsAuthenticated]
|
||||
filter_backends = [DjangoFilterBackend]
|
||||
filterset_class = AssetCategoryFilter
|
||||
|
||||
def get_asset_category(self, pk):
|
||||
try:
|
||||
return AssetCategory.objects.get(pk=pk)
|
||||
except AssetCategory.DoesNotExist as e:
|
||||
raise serializers.ValidationError(e)
|
||||
|
||||
def get(self, request, pk=None):
|
||||
if pk:
|
||||
asset_category = self.get_asset_category(pk)
|
||||
serializer = AssetCategorySerializer(asset_category)
|
||||
return Response(serializer.data)
|
||||
paginator = PageNumberPagination()
|
||||
queryset = AssetCategory.objects.all()
|
||||
filterset = self.filterset_class(request.GET, queryset=queryset)
|
||||
page = paginator.paginate_queryset(filterset.qs, request)
|
||||
serializer = AssetCategorySerializer(page, many=True)
|
||||
return paginator.get_paginated_response(serializer.data)
|
||||
|
||||
def post(self, request):
|
||||
serializer = AssetCategorySerializer(data=request.data)
|
||||
if serializer.is_valid():
|
||||
serializer.save()
|
||||
return Response(serializer.data, status=status.HTTP_201_CREATED)
|
||||
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
def put(self, request, pk):
|
||||
asset_category = self.get_asset_category(pk)
|
||||
serializer = AssetCategorySerializer(asset_category, data=request.data)
|
||||
if serializer.is_valid():
|
||||
serializer.save()
|
||||
return Response(serializer.data)
|
||||
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
def delete(self, request, pk):
|
||||
asset_category = self.get_asset_category(pk)
|
||||
asset_category.delete()
|
||||
return Response(status=status.HTTP_204_NO_CONTENT)
|
||||
|
||||
|
||||
class AssetLotAPIView(APIView):
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
def get_asset_lot(self, pk):
|
||||
try:
|
||||
return AssetLot.objects.get(pk=pk)
|
||||
except AssetLot.DoesNotExist as e:
|
||||
raise serializers.ValidationError(e)
|
||||
|
||||
def get(self, request, pk=None):
|
||||
if pk:
|
||||
asset_lot = self.get_asset_lot(pk)
|
||||
serializer = AssetLotSerializer(asset_lot)
|
||||
return Response(serializer.data)
|
||||
paginator = PageNumberPagination()
|
||||
assets = AssetLot.objects.all()
|
||||
page = paginator.paginate_queryset(assets, request)
|
||||
serializer = AssetLotSerializer(page, many=True)
|
||||
return paginator.get_paginated_response(serializer.data)
|
||||
|
||||
def post(self, request):
|
||||
serializer = AssetLotSerializer(data=request.data)
|
||||
if serializer.is_valid():
|
||||
serializer.save()
|
||||
return Response(serializer.data, status=status.HTTP_201_CREATED)
|
||||
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
def put(self, request, pk):
|
||||
asset_lot = self.get_asset_lot(pk)
|
||||
serializer = AssetLotSerializer(asset_lot, data=request.data)
|
||||
if serializer.is_valid():
|
||||
serializer.save()
|
||||
return Response(serializer.data)
|
||||
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
def delete(self, request, pk):
|
||||
asset_lot = self.get_asset_lot(pk)
|
||||
asset_lot.delete()
|
||||
return Response(status=status.HTTP_204_NO_CONTENT)
|
||||
|
||||
|
||||
class AssetAllocationAPIView(APIView):
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
def get_asset_assignment(self, pk):
|
||||
try:
|
||||
return AssetAssignment.objects.get(pk=pk)
|
||||
except AssetAssignment.DoesNotExist as e:
|
||||
raise serializers.ValidationError(e)
|
||||
|
||||
def get(self, request, pk=None):
|
||||
if pk:
|
||||
asset_assignment = self.get_asset_assignment(pk)
|
||||
serializer = AssetAssignmentGetSerializer(asset_assignment)
|
||||
return Response(serializer.data)
|
||||
paginator = PageNumberPagination()
|
||||
assets = AssetAssignment.objects.all()
|
||||
page = paginator.paginate_queryset(assets, request)
|
||||
serializer = AssetAssignmentGetSerializer(page, many=True)
|
||||
return paginator.get_paginated_response(serializer.data)
|
||||
|
||||
def post(self, request):
|
||||
serializer = AssetAssignmentSerializer(data=request.data)
|
||||
if serializer.is_valid():
|
||||
serializer.save()
|
||||
return Response(serializer.data, status=status.HTTP_201_CREATED)
|
||||
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
def put(self, request, pk):
|
||||
asset_assignment = self.get_asset_assignment(pk)
|
||||
serializer = AssetAssignmentSerializer(
|
||||
asset_assignment, data=request.data)
|
||||
if serializer.is_valid():
|
||||
serializer.save()
|
||||
return Response(serializer.data)
|
||||
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
def delete(self, request, pk):
|
||||
asset_assignment = self.get_asset_assignment(pk)
|
||||
asset_assignment.delete()
|
||||
return Response(status=status.HTTP_204_NO_CONTENT)
|
||||
|
||||
|
||||
class AssetRequestAPIView(APIView):
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
def get_asset_request(self, pk):
|
||||
try:
|
||||
return AssetRequest.objects.get(pk=pk)
|
||||
except AssetRequest.DoesNotExist as e:
|
||||
raise serializers.ValidationError(e)
|
||||
|
||||
def get(self, request, pk=None):
|
||||
if pk:
|
||||
asset_request = self.get_asset_request(pk)
|
||||
serializer = AssetRequestGetSerializer(asset_request)
|
||||
return Response(serializer.data)
|
||||
paginator = PageNumberPagination()
|
||||
assets = AssetRequest.objects.all().order_by('-id')
|
||||
page = paginator.paginate_queryset(assets, request)
|
||||
serializer = AssetRequestGetSerializer(page, many=True)
|
||||
return paginator.get_paginated_response(serializer.data)
|
||||
|
||||
def post(self, request):
|
||||
serializer = AssetRequestSerializer(data=request.data)
|
||||
if serializer.is_valid():
|
||||
serializer.save()
|
||||
return Response(serializer.data, status=status.HTTP_201_CREATED)
|
||||
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
def put(self, request, pk):
|
||||
asset_request = self.get_asset_request(pk)
|
||||
serializer = AssetRequestSerializer(asset_request, data=request.data)
|
||||
if serializer.is_valid():
|
||||
serializer.save()
|
||||
return Response(serializer.data)
|
||||
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
def delete(self, request, pk):
|
||||
asset_request = self.get_asset_request(pk)
|
||||
asset_request.delete()
|
||||
return Response(status=status.HTTP_204_NO_CONTENT)
|
||||
|
||||
|
||||
class AssetRejectAPIView(APIView):
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
def get_asset_request(self, pk):
|
||||
try:
|
||||
return AssetRequest.objects.get(pk=pk)
|
||||
except AssetRequest.DoesNotExist as e:
|
||||
raise serializers.ValidationError(e)
|
||||
|
||||
def put(self, request, pk):
|
||||
asset_request = self.get_asset_request(pk)
|
||||
if asset_request.asset_request_status == "Requested":
|
||||
asset_request.asset_request_status = 'Rejected'
|
||||
asset_request.save()
|
||||
return Response(status=204)
|
||||
raise serializers.ValidationError({"error":"Access Denied.."})
|
||||
|
||||
|
||||
|
||||
class AssetApproveAPIView(APIView):
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
def get_asset_request(self, pk):
|
||||
try:
|
||||
return AssetRequest.objects.get(pk=pk)
|
||||
except AssetRequest.DoesNotExist as e:
|
||||
raise serializers.ValidationError(e)
|
||||
|
||||
def put(self, request, pk):
|
||||
asset_request = self.get_asset_request(pk)
|
||||
if asset_request.asset_request_status == "Requested":
|
||||
data = request.data
|
||||
if isinstance(data, QueryDict):
|
||||
data = data.dict()
|
||||
data['assigned_to_employee_id'] = asset_request.requested_employee_id.id
|
||||
data['assigned_by_employee_id'] = request.user.employee_get.id
|
||||
serializer = AssetApproveSerializer(data=data, context={'asset_request': asset_request})
|
||||
if serializer.is_valid():
|
||||
serializer.save()
|
||||
asset_id = Asset.objects.get(id=data['asset_id'])
|
||||
asset_id.asset_status = "In use"
|
||||
asset_id.save()
|
||||
asset_request.asset_request_status = 'Approved'
|
||||
asset_request.save()
|
||||
return Response(status=200)
|
||||
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||
raise serializers.ValidationError({"error":"Access Denied.."})
|
||||
|
||||
|
||||
class AssetReturnAPIView(APIView):
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
def get_asset_assignment(self, pk):
|
||||
try:
|
||||
return AssetAssignment.objects.get(pk=pk)
|
||||
except AssetAssignment.DoesNotExist as e:
|
||||
raise serializers.ValidationError(e)
|
||||
|
||||
def put(self, request, pk):
|
||||
asset_assignment = self.get_asset_assignment(pk)
|
||||
if request.user.has_perm('app_name.change_mymodel'):
|
||||
serializer = AssetReturnSerializer(instance=asset_assignment, data=request.data)
|
||||
if serializer.is_valid():
|
||||
images = [ReturnImages.objects.create(image=image) for image in request.data.getlist('image')]
|
||||
asset_return = serializer.save()
|
||||
asset_return.return_images.set(images)
|
||||
if asset_return.return_status == 'Healthy':
|
||||
Asset.objects.filter(id=pk).update(asset_status='Available')
|
||||
else:
|
||||
Asset.objects.filter(id=pk).update(asset_status='Not-Available')
|
||||
AssetAssignment.objects.filter(id=asset_return.id).update(return_date=date.today())
|
||||
return Response(status=200)
|
||||
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||
else:
|
||||
AssetAssignment.objects.filter(id=pk).update(return_request=True)
|
||||
return Response(status=200)
|
||||
|
||||
23
horilla_api/api_views/attendance/permission_views.py
Normal file
23
horilla_api/api_views/attendance/permission_views.py
Normal file
@@ -0,0 +1,23 @@
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.views import APIView
|
||||
from rest_framework.permissions import IsAuthenticated
|
||||
from ...api_decorators.base.decorators import manager_permission_required
|
||||
|
||||
|
||||
class AttendancePermissionCheck(APIView):
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
@manager_permission_required("attendance.view_attendance")
|
||||
def get(self,request):
|
||||
return Response(status=200)
|
||||
|
||||
|
||||
class AttendancePermissionCheck(APIView):
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
@manager_permission_required("attendance.view_attendance")
|
||||
def get(self,request):
|
||||
|
||||
return Response(status=200)
|
||||
|
||||
|
||||
917
horilla_api/api_views/attendance/views.py
Normal file
917
horilla_api/api_views/attendance/views.py
Normal file
@@ -0,0 +1,917 @@
|
||||
from django.db.models import Case, Value, When, F, CharField
|
||||
from django.http import QueryDict
|
||||
from attendance.models import AttendanceActivity
|
||||
from rest_framework.views import APIView
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.permissions import IsAuthenticated
|
||||
from datetime import date, datetime, timedelta, timezone
|
||||
from attendance.models import EmployeeShiftDay
|
||||
from attendance.views.dashboard import (
|
||||
find_expected_attendances,
|
||||
find_late_come,
|
||||
find_on_time,
|
||||
)
|
||||
from attendance.views.views import *
|
||||
from attendance.views.clock_in_out import *
|
||||
from django.shortcuts import get_object_or_404
|
||||
from rest_framework.response import Response
|
||||
from attendance.models import Attendance
|
||||
from base.methods import is_reportingmanager
|
||||
from ...api_decorators.base.decorators import manager_permission_required
|
||||
from ...api_methods.base.methods import groupby_queryset, permission_based_queryset
|
||||
from employee.filters import EmployeeFilter
|
||||
from horilla_api.api_serializers.attendance.serializers import (
|
||||
AttendanceActivitySerializer,
|
||||
AttendanceLateComeEarlyOutSerializer,
|
||||
AttendanceOverTimeSerializer,
|
||||
AttendanceRequestSerializer,
|
||||
AttendanceSerializer,
|
||||
MailTemplateSerializer,
|
||||
)
|
||||
from rest_framework.pagination import PageNumberPagination
|
||||
from django.utils.decorators import method_decorator
|
||||
from django.contrib.auth.decorators import permission_required
|
||||
from django.conf import settings
|
||||
from django.core.mail import EmailMessage
|
||||
from recruitment.models import RecruitmentMailTemplate
|
||||
from base.backends import ConfiguredEmailBackend
|
||||
from django import template
|
||||
from base.methods import generate_pdf
|
||||
|
||||
# Create your views here.
|
||||
|
||||
|
||||
def query_dict(data):
|
||||
query_dict = QueryDict("", mutable=True)
|
||||
for key, value in data.items():
|
||||
if isinstance(value, list):
|
||||
for item in value:
|
||||
query_dict.appendlist(key, item)
|
||||
else:
|
||||
query_dict.update({key: value})
|
||||
return query_dict
|
||||
|
||||
|
||||
class ClockInAPIView(APIView):
|
||||
"""
|
||||
Allows authenticated employees to clock in, determining the correct shift and attendance date, including handling night shifts.
|
||||
|
||||
Methods:
|
||||
post(request): Processes and records the clock-in time.
|
||||
"""
|
||||
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
def post(self, request):
|
||||
employee, work_info = employee_exists(request)
|
||||
datetime_now = datetime.now()
|
||||
if request.__dict__.get("datetime"):
|
||||
datetime_now = request.datetime
|
||||
if employee and work_info is not None:
|
||||
shift = work_info.shift_id
|
||||
date_today = date.today()
|
||||
if request.__dict__.get("date"):
|
||||
date_today = request.date
|
||||
attendance_date = date_today
|
||||
day = date_today.strftime("%A").lower()
|
||||
day = EmployeeShiftDay.objects.get(day=day)
|
||||
now = datetime.now().strftime("%H:%M")
|
||||
if request.__dict__.get("time"):
|
||||
now = request.time.strftime("%H:%M")
|
||||
now_sec = strtime_seconds(now)
|
||||
mid_day_sec = strtime_seconds("12:00")
|
||||
minimum_hour, start_time_sec, end_time_sec = shift_schedule_today(
|
||||
day=day, shift=shift
|
||||
)
|
||||
if start_time_sec > end_time_sec:
|
||||
# night shift
|
||||
# ------------------
|
||||
# Night shift in Horilla consider a 24 hours from noon to next day noon,
|
||||
# the shift day taken today if the attendance clocked in after 12 O clock.
|
||||
|
||||
if mid_day_sec > now_sec:
|
||||
# Here you need to create attendance for yesterday
|
||||
|
||||
date_yesterday = date_today - timedelta(days=1)
|
||||
day_yesterday = date_yesterday.strftime("%A").lower()
|
||||
day_yesterday = EmployeeShiftDay.objects.get(day=day_yesterday)
|
||||
minimum_hour, start_time_sec, end_time_sec = shift_schedule_today(
|
||||
day=day_yesterday, shift=shift
|
||||
)
|
||||
attendance_date = date_yesterday
|
||||
day = day_yesterday
|
||||
clock_in_attendance_and_activity(
|
||||
employee=employee,
|
||||
date_today=date_today,
|
||||
attendance_date=attendance_date,
|
||||
day=day,
|
||||
now=now,
|
||||
shift=shift,
|
||||
minimum_hour=minimum_hour,
|
||||
start_time=start_time_sec,
|
||||
end_time=end_time_sec,
|
||||
in_datetime=datetime_now,
|
||||
)
|
||||
return Response({"message": "Clocked-In"}, status=200)
|
||||
return Response(
|
||||
{
|
||||
"error": "You Don't have work information filled or your employee detail neither entered "
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
class ClockOutAPIView(APIView):
|
||||
"""
|
||||
Allows authenticated employees to clock out, updating the latest attendance record and handling early outs.
|
||||
|
||||
Methods:
|
||||
post(request): Records the clock-out time.
|
||||
"""
|
||||
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
def post(self, request):
|
||||
datetime_now = datetime.now()
|
||||
if request.__dict__.get("datetime"):
|
||||
datetime_now = request.datetime
|
||||
employee, work_info = employee_exists(request)
|
||||
shift = work_info.shift_id
|
||||
date_today = date.today()
|
||||
if request.__dict__.get("date"):
|
||||
date_today = request.date
|
||||
day = date_today.strftime("%A").lower()
|
||||
day = EmployeeShiftDay.objects.get(day=day)
|
||||
attendance = (
|
||||
Attendance.objects.filter(employee_id=employee)
|
||||
.order_by("id", "attendance_date")
|
||||
.last()
|
||||
)
|
||||
if attendance is not None:
|
||||
day = attendance.attendance_day
|
||||
now = datetime.now().strftime("%H:%M")
|
||||
if request.__dict__.get("time"):
|
||||
now = request.time.strftime("%H:%M")
|
||||
minimum_hour, start_time_sec, end_time_sec = shift_schedule_today(
|
||||
day=day, shift=shift
|
||||
)
|
||||
early_out_instance = attendance.late_come_early_out.filter(type="early_out")
|
||||
if not early_out_instance.exists():
|
||||
early_out(
|
||||
attendance=attendance, start_time=start_time_sec, end_time=end_time_sec
|
||||
)
|
||||
|
||||
clock_out_attendance_and_activity(
|
||||
employee=employee, date_today=date_today, now=now, out_datetime=datetime_now
|
||||
)
|
||||
return Response({"message": "Clocked-Out"}, status=200)
|
||||
|
||||
|
||||
class AttendanceView(APIView):
|
||||
"""
|
||||
Handles CRUD operations for attendance records.
|
||||
|
||||
Methods:
|
||||
get_queryset(request, type): Returns filtered attendance records.
|
||||
get(request, pk=None, type=None): Retrieves a specific record or a list of records.
|
||||
post(request): Creates a new attendance record.
|
||||
put(request, pk): Updates an existing attendance record.
|
||||
delete(request, pk): Deletes an attendance record and adjusts related overtime if needed.
|
||||
"""
|
||||
|
||||
permission_classes = [IsAuthenticated]
|
||||
filterset_class = AttendanceFilters
|
||||
|
||||
def get_queryset(self, request, type):
|
||||
if type == "ot":
|
||||
condition = AttendanceValidationCondition.objects.first()
|
||||
minot = strtime_seconds("00:30")
|
||||
if condition is not None:
|
||||
minot = strtime_seconds(condition.minimum_overtime_to_approve)
|
||||
queryset = Attendance.objects.filter(
|
||||
overtime_second__gte=minot,
|
||||
attendance_validated=True,
|
||||
)
|
||||
|
||||
elif type == "validated":
|
||||
queryset = Attendance.objects.filter(attendance_validated=True)
|
||||
elif type == "non-validated":
|
||||
queryset = Attendance.objects.filter(attendance_validated=False)
|
||||
else:
|
||||
queryset = Attendance.objects.all()
|
||||
user = request.user
|
||||
# checking user level permissions
|
||||
perm = "attendance.view_attendance"
|
||||
queryset = permission_based_queryset(user, perm, queryset, user_obj=True)
|
||||
return queryset
|
||||
|
||||
def get(self, request, pk=None, type=None):
|
||||
# individual object workflow
|
||||
if pk:
|
||||
attendance = get_object_or_404(Attendance, pk=pk)
|
||||
serializer = AttendanceSerializer(instance=attendance)
|
||||
return Response(serializer.data, status=200)
|
||||
# permission based querysete
|
||||
attendances = self.get_queryset(request, type)
|
||||
# filtering queryset
|
||||
attendances_filter_queryset = self.filterset_class(
|
||||
request.GET, queryset=attendances
|
||||
).qs
|
||||
field_name = request.GET.get("groupby_field", None)
|
||||
if field_name:
|
||||
url = request.build_absolute_uri()
|
||||
return groupby_queryset(
|
||||
request, url, field_name, attendances_filter_queryset
|
||||
)
|
||||
# pagination workflow
|
||||
paginater = PageNumberPagination()
|
||||
page = paginater.paginate_queryset(attendances_filter_queryset, request)
|
||||
serializer = AttendanceSerializer(page, many=True)
|
||||
return paginater.get_paginated_response(serializer.data)
|
||||
|
||||
@manager_permission_required("attendance.add_attendance")
|
||||
def post(self, request):
|
||||
serializer = AttendanceSerializer(data=request.data)
|
||||
if serializer.is_valid():
|
||||
validated_data = serializer.validated_data
|
||||
instance = Attendance(**validated_data)
|
||||
instance.save()
|
||||
return Response(serializer.data, status=200)
|
||||
return Response(serializer.errors, status=400)
|
||||
|
||||
@method_decorator(
|
||||
permission_required("attendance.change_attendance", raise_exception=True)
|
||||
)
|
||||
def put(self, request, pk):
|
||||
try:
|
||||
attendance = Attendance.objects.get(id=pk)
|
||||
except Attendance.DoesNotExist:
|
||||
return Response({"detail": "Attendance record not found."}, status=404)
|
||||
|
||||
serializer = AttendanceSerializer(instance=attendance, data=request.data)
|
||||
|
||||
if serializer.is_valid():
|
||||
serializer.save()
|
||||
return Response(serializer.data, status=200)
|
||||
|
||||
# Customize error message for unique constraint
|
||||
serializer_errors = serializer.errors
|
||||
if "non_field_errors" in serializer.errors:
|
||||
unique_error_msg = (
|
||||
"The fields employee_id, attendance_date must make a unique set."
|
||||
)
|
||||
if unique_error_msg in serializer.errors["non_field_errors"]:
|
||||
serializer_errors = {
|
||||
"non_field_errors": [
|
||||
"The employee already has attendance on this date."
|
||||
]
|
||||
}
|
||||
return Response(serializer_errors, status=400)
|
||||
|
||||
@method_decorator(
|
||||
permission_required("attendance.delete_attendance", raise_exception=True)
|
||||
)
|
||||
def delete(self, request, pk):
|
||||
attendance = Attendance.objects.get(id=pk)
|
||||
month = attendance.attendance_date
|
||||
month = month.strftime("%B").lower()
|
||||
overtime = attendance.employee_id.employee_overtime.filter(month=month).last()
|
||||
if overtime is not None:
|
||||
if attendance.attendance_overtime_approve:
|
||||
# Subtract overtime of this attendance
|
||||
total_overtime = strtime_seconds(overtime.overtime)
|
||||
attendance_overtime_seconds = strtime_seconds(
|
||||
attendance.attendance_overtime
|
||||
)
|
||||
if total_overtime > attendance_overtime_seconds:
|
||||
total_overtime = total_overtime - attendance_overtime_seconds
|
||||
else:
|
||||
total_overtime = attendance_overtime_seconds - total_overtime
|
||||
overtime.overtime = format_time(total_overtime)
|
||||
overtime.save()
|
||||
try:
|
||||
attendance.delete()
|
||||
return Response({"status", "deleted"}, status=200)
|
||||
except Exception as error:
|
||||
return Response({"error:", f"{error}"}, status=400)
|
||||
else:
|
||||
try:
|
||||
attendance.delete()
|
||||
return Response({"status", "deleted"}, status=200)
|
||||
except Exception as error:
|
||||
return Response({"error:", f"{error}"}, status=400)
|
||||
|
||||
|
||||
class ValidateAttendanceView(APIView):
|
||||
"""
|
||||
Validates an attendance record and sends a notification to the employee.
|
||||
|
||||
Method:
|
||||
put(request, pk): Marks the attendance as validated and notifies the employee.
|
||||
"""
|
||||
|
||||
def put(self, request, pk):
|
||||
attendance = Attendance.objects.filter(id=pk).update(attendance_validated=True)
|
||||
attendance = Attendance.objects.filter(id=pk).first()
|
||||
try:
|
||||
notify.send(
|
||||
request.user.employee_get,
|
||||
recipient=attendance.employee_id.employee_user_id,
|
||||
verb=f"Your attendance for the date {attendance.attendance_date} is validated",
|
||||
verb_ar=f"تم تحقيق حضورك في تاريخ {attendance.attendance_date}",
|
||||
verb_de=f"Deine Anwesenheit für das Datum {attendance.attendance_date} ist bestätigt.",
|
||||
verb_es=f"Se valida tu asistencia para la fecha {attendance.attendance_date}.",
|
||||
verb_fr=f"Votre présence pour la date {attendance.attendance_date} est validée.",
|
||||
redirect="/attendance/view-my-attendance",
|
||||
icon="checkmark",
|
||||
api_redirect=f"/api/attendance/attendance?employee_id{attendance.employee_id}",
|
||||
)
|
||||
except:
|
||||
pass
|
||||
return Response(status=200)
|
||||
|
||||
|
||||
class OvertimeApproveView(APIView):
|
||||
"""
|
||||
Approves overtime for an attendance record and sends a notification to the employee.
|
||||
|
||||
Method:
|
||||
put(request, pk): Marks the overtime as approved and notifies the employee.
|
||||
"""
|
||||
|
||||
def put(self, request, pk):
|
||||
try:
|
||||
attendance = Attendance.objects.filter(id=pk).update(
|
||||
attendance_overtime_approve=True
|
||||
)
|
||||
except Exception as E:
|
||||
return Response({"error": str(E)}, status=400)
|
||||
|
||||
attendance = Attendance.objects.filter(id=pk).first()
|
||||
try:
|
||||
notify.send(
|
||||
request.user.employee_get,
|
||||
recipient=attendance.employee_id.employee_user_id,
|
||||
verb=f"Your {attendance.attendance_date}'s attendance overtime approved.",
|
||||
verb_ar=f"تمت الموافقة على إضافة ساعات العمل الإضافية لتاريخ {attendance.attendance_date}.",
|
||||
verb_de=f"Die Überstunden für den {attendance.attendance_date} wurden genehmigt.",
|
||||
verb_es=f"Se ha aprobado el tiempo extra de asistencia para el {attendance.attendance_date}.",
|
||||
verb_fr=f"Les heures supplémentaires pour la date {attendance.attendance_date} ont été approuvées.",
|
||||
redirect="/attendance/attendance-overtime-view",
|
||||
icon="checkmark",
|
||||
api_redirect="/api/attendance/attendance-hour-account/",
|
||||
)
|
||||
except:
|
||||
pass
|
||||
return Response(status=200)
|
||||
|
||||
|
||||
class AttendanceRequestView(APIView):
|
||||
"""
|
||||
Handles requests for creating, updating, and viewing attendance records.
|
||||
|
||||
Methods:
|
||||
get(request, pk=None): Retrieves a specific attendance request by `pk` or a filtered list of requests.
|
||||
post(request): Creates a new attendance request.
|
||||
put(request, pk): Updates an existing attendance request.
|
||||
"""
|
||||
|
||||
serializer_class = AttendanceRequestSerializer
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
def get(self, request, pk=None):
|
||||
if pk:
|
||||
attendance = Attendance.objects.get(id=pk)
|
||||
serializer = AttendanceRequestSerializer(instance=attendance)
|
||||
return Response(serializer.data, status=200)
|
||||
|
||||
requests = Attendance.objects.filter(
|
||||
is_validate_request=True,
|
||||
)
|
||||
requests = filtersubordinates(
|
||||
request=request,
|
||||
perm="attendance.view_attendance",
|
||||
queryset=requests,
|
||||
)
|
||||
requests = requests | Attendance.objects.filter(
|
||||
employee_id__employee_user_id=request.user,
|
||||
is_validate_request=True,
|
||||
)
|
||||
request_filtered_queryset = AttendanceFilters(request.GET, requests).qs
|
||||
field_name = request.GET.get("groupby_field", None)
|
||||
if field_name:
|
||||
# groupby workflow
|
||||
url = request.build_absolute_uri()
|
||||
return groupby_queryset(request, url, field_name, request_filtered_queryset)
|
||||
|
||||
pagenation = PageNumberPagination()
|
||||
page = pagenation.paginate_queryset(request_filtered_queryset, request)
|
||||
serializer = self.serializer_class(page, many=True)
|
||||
return pagenation.get_paginated_response(serializer.data)
|
||||
|
||||
def post(self, request):
|
||||
serializer = AttendanceRequestSerializer(data=request.data)
|
||||
if serializer.is_valid():
|
||||
serializer.save()
|
||||
return Response(serializer.data, status=200)
|
||||
return Response(serializer.errors, status=404)
|
||||
|
||||
@manager_permission_required("attendance.update_attendance")
|
||||
def put(self, request, pk):
|
||||
attendance = Attendance.objects.get(id=pk)
|
||||
serializer = AttendanceRequestSerializer(instance=attendance, data=request.data)
|
||||
if serializer.is_valid():
|
||||
instance = serializer.save()
|
||||
instance.employee_id = attendance.employee_id
|
||||
instance.id = attendance.id
|
||||
if attendance.request_type != "create_request":
|
||||
attendance.requested_data = json.dumps(instance.serialize())
|
||||
attendance.request_description = instance.request_description
|
||||
# set the user level validation here
|
||||
attendance.is_validate_request = True
|
||||
attendance.save()
|
||||
else:
|
||||
instance.is_validate_request_approved = False
|
||||
instance.is_validate_request = True
|
||||
instance.save()
|
||||
return Response(serializer.data, status=200)
|
||||
return Response(serializer.errors, status=404)
|
||||
|
||||
|
||||
class AttendanceRequestApproveView(APIView):
|
||||
"""
|
||||
Approves and updates an attendance request.
|
||||
|
||||
Method:
|
||||
put(request, pk): Approves the attendance request, updates attendance records, and handles related activities.
|
||||
"""
|
||||
|
||||
@manager_permission_required("attendance.change_attendance")
|
||||
def put(self, request, pk):
|
||||
try:
|
||||
attendance = Attendance.objects.get(id=pk)
|
||||
prev_attendance_date = attendance.attendance_date
|
||||
prev_attendance_clock_in_date = attendance.attendance_clock_in_date
|
||||
prev_attendance_clock_in = attendance.attendance_clock_in
|
||||
attendance.attendance_validated = True
|
||||
attendance.is_validate_request_approved = True
|
||||
attendance.is_validate_request = False
|
||||
attendance.request_description = None
|
||||
attendance.save()
|
||||
if attendance.requested_data is not None:
|
||||
requested_data = json.loads(attendance.requested_data)
|
||||
requested_data["attendance_clock_out"] = (
|
||||
None
|
||||
if requested_data["attendance_clock_out"] == "None"
|
||||
else requested_data["attendance_clock_out"]
|
||||
)
|
||||
requested_data["attendance_clock_out_date"] = (
|
||||
None
|
||||
if requested_data["attendance_clock_out_date"] == "None"
|
||||
else requested_data["attendance_clock_out_date"]
|
||||
)
|
||||
Attendance.objects.filter(id=pk).update(**requested_data)
|
||||
# DUE TO AFFECT THE OVERTIME CALCULATION ON SAVE METHOD, SAVE THE INSTANCE ONCE MORE
|
||||
attendance = Attendance.objects.get(id=pk)
|
||||
attendance.save()
|
||||
if (
|
||||
attendance.attendance_clock_out is None
|
||||
or attendance.attendance_clock_out_date is None
|
||||
):
|
||||
attendance.attendance_validated = True
|
||||
activity = AttendanceActivity.objects.filter(
|
||||
employee_id=attendance.employee_id,
|
||||
attendance_date=prev_attendance_date,
|
||||
clock_in_date=prev_attendance_clock_in_date,
|
||||
clock_in=prev_attendance_clock_in,
|
||||
)
|
||||
if activity:
|
||||
activity.update(
|
||||
employee_id=attendance.employee_id,
|
||||
attendance_date=attendance.attendance_date,
|
||||
clock_in_date=attendance.attendance_clock_in_date,
|
||||
clock_in=attendance.attendance_clock_in,
|
||||
)
|
||||
|
||||
else:
|
||||
AttendanceActivity.objects.create(
|
||||
employee_id=attendance.employee_id,
|
||||
attendance_date=attendance.attendance_date,
|
||||
clock_in_date=attendance.attendance_clock_in_date,
|
||||
clock_in=attendance.attendance_clock_in,
|
||||
)
|
||||
except Exception as E:
|
||||
return Response({"error": str(E)}, status=400)
|
||||
return Response({"status": "approved"}, status=200)
|
||||
|
||||
|
||||
class AttendanceRequestCancelView(APIView):
|
||||
"""
|
||||
Cancels an attendance request.
|
||||
|
||||
Method:
|
||||
put(request, pk): Cancels the attendance request, resetting its status and data, and deletes the request if it was a create request.
|
||||
"""
|
||||
|
||||
def put(self, request, pk):
|
||||
try:
|
||||
attendance = Attendance.objects.get(id=pk)
|
||||
if (
|
||||
attendance.employee_id.employee_user_id == request.user
|
||||
or is_reportingmanager(request)
|
||||
or request.user.has_perm("attendance.change_attendance")
|
||||
):
|
||||
attendance.is_validate_request_approved = False
|
||||
attendance.is_validate_request = False
|
||||
attendance.request_description = None
|
||||
attendance.requested_data = None
|
||||
attendance.request_type = None
|
||||
|
||||
attendance.save()
|
||||
if attendance.request_type == "create_request":
|
||||
attendance.delete()
|
||||
except Exception as E:
|
||||
return Response({"error": str(E)}, status=400)
|
||||
return Response({"status": "success"}, status=200)
|
||||
|
||||
|
||||
class AttendanceOverTimeView(APIView):
|
||||
"""
|
||||
Manages CRUD operations for attendance overtime records.
|
||||
|
||||
Methods:
|
||||
get(request, pk=None): Retrieves a specific overtime record by `pk` or a list of records with filtering and pagination.
|
||||
post(request): Creates a new overtime record.
|
||||
put(request, pk): Updates an existing overtime record.
|
||||
delete(request, pk): Deletes an overtime record.
|
||||
"""
|
||||
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
def get(self, request, pk=None):
|
||||
if pk:
|
||||
attendance_ot = get_object_or_404(AttendanceOverTime, pk=pk)
|
||||
serializer = AttendanceOverTimeSerializer(attendance_ot)
|
||||
return Response(serializer.data, status=200)
|
||||
|
||||
filterset_class = AttendanceOverTimeFilter(request.GET)
|
||||
queryset = filterset_class.qs
|
||||
self_account = queryset.filter(employee_id__employee_user_id=request.user)
|
||||
permission_based_queryset = filtersubordinates(
|
||||
request, queryset, "attendance.view_attendanceovertime"
|
||||
)
|
||||
queryset = permission_based_queryset | self_account
|
||||
field_name = request.GET.get("groupby_field", None)
|
||||
if field_name:
|
||||
# groupby workflow
|
||||
url = request.build_absolute_uri()
|
||||
return groupby_queryset(request, url, field_name, queryset)
|
||||
|
||||
pagenation = PageNumberPagination()
|
||||
page = pagenation.paginate_queryset(queryset, request)
|
||||
serializer = AttendanceOverTimeSerializer(page, many=True)
|
||||
return pagenation.get_paginated_response(serializer.data)
|
||||
|
||||
@manager_permission_required("attendance.add_attendanceovertime")
|
||||
def post(self, request):
|
||||
serializer = AttendanceOverTimeSerializer(data=request.data)
|
||||
if serializer.is_valid():
|
||||
serializer.save()
|
||||
return Response(serializer.data, status=200)
|
||||
return Response(serializer.errors, status=400)
|
||||
|
||||
@manager_permission_required("attendance.change_attendanceovertime")
|
||||
def put(self, request, pk):
|
||||
attendance_ot = get_object_or_404(AttendanceOverTime, pk=pk)
|
||||
serializer = AttendanceOverTimeSerializer(
|
||||
instance=attendance_ot, data=request.data
|
||||
)
|
||||
if serializer.is_valid():
|
||||
serializer.save()
|
||||
return Response(serializer.data, status=200)
|
||||
return Response(serializer.errors, status=400)
|
||||
|
||||
@method_decorator(
|
||||
permission_required(
|
||||
"attendance.delete_attendanceovertime", raise_exception=True
|
||||
)
|
||||
)
|
||||
def delete(self, request, pk):
|
||||
attendance = get_object_or_404(AttendanceOverTime, pk=pk)
|
||||
attendance.delete()
|
||||
|
||||
return Response({"message": "Overtime deleted successfully"}, status=204)
|
||||
|
||||
|
||||
class LateComeEarlyOutView(APIView):
|
||||
"""
|
||||
Handles retrieval and deletion of late come and early out records.
|
||||
|
||||
Methods:
|
||||
get(request, pk=None): Retrieves a list of late come and early out records with filtering.
|
||||
delete(request, pk=None): Deletes a specific late come or early out record by `pk`.
|
||||
"""
|
||||
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
def get(self, request, pk=None):
|
||||
data = LateComeEarlyOutFilter(request.GET)
|
||||
serializer = AttendanceLateComeEarlyOutSerializer(data.qs, many=True)
|
||||
return Response(serializer.data, status=200)
|
||||
|
||||
def delete(self, request, pk=None):
|
||||
attendance = get_object_or_404(AttendanceLateComeEarlyOut, pk=pk)
|
||||
attendance.delete()
|
||||
return Response({"message": "Attendance deleted successfully"}, status=204)
|
||||
|
||||
|
||||
class AttendanceActivityView(APIView):
|
||||
"""
|
||||
Retrieves attendance activity records.
|
||||
|
||||
Method:
|
||||
get(request, pk=None): Retrieves a list of all attendance activity records.
|
||||
"""
|
||||
|
||||
def get(self, request, pk=None):
|
||||
data = AttendanceActivity.objects.all()
|
||||
serializer = AttendanceActivitySerializer(data, many=True)
|
||||
return Response(serializer.data, status=200)
|
||||
|
||||
|
||||
class TodayAttendance(APIView):
|
||||
"""
|
||||
Provides the ratio of marked attendances to expected attendances for the current day.
|
||||
|
||||
Method:
|
||||
get(request): Calculates and returns the attendance ratio for today.
|
||||
"""
|
||||
|
||||
def get(self, request):
|
||||
|
||||
today = datetime.today()
|
||||
week_day = today.strftime("%A").lower()
|
||||
|
||||
on_time = find_on_time(request, today=today, week_day=week_day)
|
||||
late_come = find_late_come(start_date=today)
|
||||
late_come_obj = len(late_come)
|
||||
|
||||
marked_attendances = late_come_obj + on_time
|
||||
|
||||
expected_attendances = find_expected_attendances(week_day=week_day)
|
||||
marked_attendances_ratio = 0
|
||||
if expected_attendances != 0:
|
||||
marked_attendances_ratio = (
|
||||
f"{(marked_attendances / expected_attendances) * 100:.2f}"
|
||||
)
|
||||
|
||||
return Response(
|
||||
{"marked_attendances_ratio": marked_attendances_ratio}, status=200
|
||||
)
|
||||
|
||||
|
||||
class OfflineEmployeesCountView(APIView):
|
||||
"""
|
||||
Retrieves the count of active employees who have not clocked in today.
|
||||
|
||||
Method:
|
||||
get(request): Returns the number of active employees who are not yet clocked in.
|
||||
"""
|
||||
|
||||
def get(self, request):
|
||||
count = (
|
||||
EmployeeFilter({"not_in_yet": date.today()})
|
||||
.qs.exclude(employee_work_info__isnull=True)
|
||||
.filter(is_active=True)
|
||||
.count()
|
||||
)
|
||||
return Response({"count": count}, status=200)
|
||||
|
||||
|
||||
class OfflineEmployeesListView(APIView):
|
||||
"""
|
||||
Lists active employees who have not clocked in today, including their leave status.
|
||||
|
||||
Method:
|
||||
get(request): Retrieves and paginates a list of employees not clocked in today with their leave status.
|
||||
"""
|
||||
|
||||
def get(self, request):
|
||||
queryset = (
|
||||
EmployeeFilter({"not_in_yet": date.today()})
|
||||
.qs.exclude(employee_work_info__isnull=True)
|
||||
.filter(is_active=True)
|
||||
)
|
||||
leave_status = self.get_leave_status(queryset)
|
||||
pagenation = PageNumberPagination()
|
||||
page = pagenation.paginate_queryset(leave_status, request)
|
||||
return pagenation.get_paginated_response(page)
|
||||
|
||||
def get_leave_status(self, queryset):
|
||||
|
||||
today = date.today()
|
||||
queryset = queryset.distinct()
|
||||
# Annotate each employee with their leave status
|
||||
employees_with_leave_status = queryset.annotate(
|
||||
leave_status=Case(
|
||||
# Define different cases based on leave requests and attendance
|
||||
When(
|
||||
leaverequest__start_date__lte=today,
|
||||
leaverequest__end_date__gte=today,
|
||||
leaverequest__status="approved",
|
||||
then=Value("On Leave"),
|
||||
),
|
||||
When(
|
||||
leaverequest__start_date__lte=today,
|
||||
leaverequest__end_date__gte=today,
|
||||
leaverequest__status="requested",
|
||||
then=Value("Waiting Approval"),
|
||||
),
|
||||
When(
|
||||
leaverequest__start_date__lte=today,
|
||||
leaverequest__end_date__gte=today,
|
||||
then=Value("Canceled / Rejected"),
|
||||
),
|
||||
When(
|
||||
employee_attendances__attendance_date=today, then=Value("Working")
|
||||
),
|
||||
default=Value("Expected working"), # Default status
|
||||
output_field=CharField(),
|
||||
),
|
||||
job_position_id=F("employee_work_info__job_position_id"),
|
||||
).values(
|
||||
"employee_first_name",
|
||||
"employee_last_name",
|
||||
"leave_status",
|
||||
"employee_profile",
|
||||
"id",
|
||||
"job_position_id",
|
||||
)
|
||||
|
||||
for employee in employees_with_leave_status:
|
||||
|
||||
if employee["employee_profile"]:
|
||||
employee["employee_profile"] = (
|
||||
settings.MEDIA_URL + employee["employee_profile"]
|
||||
)
|
||||
return employees_with_leave_status
|
||||
|
||||
|
||||
class CheckingStatus(APIView):
|
||||
"""
|
||||
Checks and provides the current attendance status for the authenticated user.
|
||||
|
||||
Method:
|
||||
get(request): Returns the attendance status, duration at work, and clock-in time if available.
|
||||
"""
|
||||
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
@classmethod
|
||||
def _format_seconds(cls, seconds):
|
||||
hours = seconds // 3600
|
||||
minutes = (seconds % 3600) // 60
|
||||
seconds = seconds % 60
|
||||
return f"{hours:02}:{minutes:02}:{seconds:02}"
|
||||
|
||||
def get(self, request):
|
||||
attendance_activity = (
|
||||
AttendanceActivity.objects.filter(employee_id=request.user.employee_get)
|
||||
.order_by("-id")
|
||||
.first()
|
||||
)
|
||||
duration = None
|
||||
work_seconds = request.user.employee_get.get_forecasted_at_work()[
|
||||
"forecasted_at_work_seconds"
|
||||
]
|
||||
duration = CheckingStatus._format_seconds(int(work_seconds))
|
||||
status = False
|
||||
clock_in_time = None
|
||||
|
||||
today = datetime.now()
|
||||
attendance_activity_first = (
|
||||
AttendanceActivity.objects.filter(
|
||||
employee_id=request.user.employee_get, clock_in_date=today
|
||||
)
|
||||
.order_by("in_datetime")
|
||||
.first()
|
||||
)
|
||||
if attendance_activity:
|
||||
clock_in_time = attendance_activity_first.clock_in.strftime("%I:%M %p")
|
||||
if attendance_activity.clock_out_date:
|
||||
status = False
|
||||
else:
|
||||
status = True
|
||||
return Response(
|
||||
{"status": status, "duration": duration, "clock_in": clock_in_time},
|
||||
status=200,
|
||||
)
|
||||
return Response(
|
||||
{"status": status, "duration": duration, "clock_in_time": clock_in_time},
|
||||
status=200,
|
||||
)
|
||||
|
||||
|
||||
class MailTemplateView(APIView):
|
||||
"""
|
||||
Retrieves a list of recruitment mail templates.
|
||||
|
||||
Method:
|
||||
get(request): Returns all recruitment mail templates.
|
||||
"""
|
||||
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
def get(self, request):
|
||||
instances = RecruitmentMailTemplate.objects.all()
|
||||
serializer = MailTemplateSerializer(instances, many=True)
|
||||
return Response(serializer.data, status=200)
|
||||
|
||||
|
||||
class ConvertedMailTemplateConvert(APIView):
|
||||
"""
|
||||
Renders a recruitment mail template with data from a specified employee.
|
||||
|
||||
Method:
|
||||
put(request): Renders the mail template body with employee and user data and returns the result.
|
||||
"""
|
||||
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
def put(self, request):
|
||||
template_id = request.data.get("template_id", None)
|
||||
employee_id = request.data.get("employee_id", None)
|
||||
employee = Employee.objects.filter(id=employee_id).first()
|
||||
bdy = RecruitmentMailTemplate.objects.filter(id=template_id).first()
|
||||
template_bdy = template.Template(bdy.body)
|
||||
context = template.Context(
|
||||
{"instance": employee, "self": request.user.employee_get}
|
||||
)
|
||||
render_bdy = template_bdy.render(context)
|
||||
return Response(render_bdy)
|
||||
|
||||
|
||||
class OfflineEmployeeMailsend(APIView):
|
||||
"""
|
||||
Sends an email with attachments and rendered templates to a specified employee.
|
||||
|
||||
Method:
|
||||
post(request): Renders email templates with employee and user data, attaches files, and sends the email.
|
||||
"""
|
||||
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
def post(self, request):
|
||||
employee_id = request.POST.get("employee_id")
|
||||
subject = request.POST.get("subject", "")
|
||||
bdy = request.POST.get("body", "")
|
||||
other_attachments = request.FILES.getlist("other_attachments")
|
||||
attachments = [
|
||||
(file.name, file.read(), file.content_type) for file in other_attachments
|
||||
]
|
||||
email_backend = ConfiguredEmailBackend()
|
||||
host = email_backend.dynamic_username
|
||||
employee = Employee.objects.get(id=employee_id)
|
||||
template_attachment_ids = request.POST.getlist("template_attachments")
|
||||
bodys = list(
|
||||
RecruitmentMailTemplate.objects.filter(
|
||||
id__in=template_attachment_ids
|
||||
).values_list("body", flat=True)
|
||||
)
|
||||
for html in bodys:
|
||||
# due to not having solid template we first need to pass the context
|
||||
template_bdy = template.Template(html)
|
||||
context = template.Context(
|
||||
{"instance": employee, "self": request.user.employee_get}
|
||||
)
|
||||
render_bdy = template_bdy.render(context)
|
||||
attachments.append(
|
||||
(
|
||||
"Document",
|
||||
generate_pdf(render_bdy, {}, path=False, title="Document").content,
|
||||
"application/pdf",
|
||||
)
|
||||
)
|
||||
|
||||
template_bdy = template.Template(bdy)
|
||||
context = template.Context(
|
||||
{"instance": employee, "self": request.user.employee_get}
|
||||
)
|
||||
render_bdy = template_bdy.render(context)
|
||||
|
||||
email = EmailMessage(
|
||||
subject,
|
||||
render_bdy,
|
||||
host,
|
||||
[employee.employee_work_info.email],
|
||||
)
|
||||
email.content_subtype = "html"
|
||||
|
||||
email.attachments = attachments
|
||||
try:
|
||||
email.send()
|
||||
if employee.employee_work_info.email:
|
||||
return Response(f"Mail sent to {employee.get_full_name()}")
|
||||
else:
|
||||
return Response(f"Email not set for {employee.get_full_name()}")
|
||||
except Exception as e:
|
||||
return Response("Something went wrong")
|
||||
27
horilla_api/api_views/auth/views.py
Normal file
27
horilla_api/api_views/auth/views.py
Normal file
@@ -0,0 +1,27 @@
|
||||
from rest_framework_simplejwt.tokens import RefreshToken
|
||||
from rest_framework.views import APIView
|
||||
from rest_framework.response import Response
|
||||
from django.contrib.auth import authenticate
|
||||
from ...api_serializers.auth.serializers import GetEmployeeSerializer
|
||||
|
||||
|
||||
|
||||
class LoginAPIView(APIView):
|
||||
def post(self, request):
|
||||
if 'username' and 'password' in request.data.keys():
|
||||
username = request.data.get('username')
|
||||
password = request.data.get('password')
|
||||
user = authenticate(username=username, password=password)
|
||||
if user:
|
||||
refresh = RefreshToken.for_user(user)
|
||||
employee = user.employee_get
|
||||
result = {
|
||||
'employee' : GetEmployeeSerializer(employee).data,
|
||||
'access': str(refresh.access_token),
|
||||
}
|
||||
return Response(result, status=200)
|
||||
else:
|
||||
return Response({'error': 'Invalid credentials'}, status=401)
|
||||
else:
|
||||
return Response({'error':'Please provide Username and Password'})
|
||||
|
||||
1282
horilla_api/api_views/base/views.py
Normal file
1282
horilla_api/api_views/base/views.py
Normal file
File diff suppressed because it is too large
Load Diff
749
horilla_api/api_views/employee/views.py
Normal file
749
horilla_api/api_views/employee/views.py
Normal file
@@ -0,0 +1,749 @@
|
||||
from rest_framework import status
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.views import APIView
|
||||
from rest_framework.pagination import PageNumberPagination
|
||||
from django.http import Http404
|
||||
from ...api_decorators.base.decorators import manager_or_owner_permission_required, manager_permission_required
|
||||
from employee.filters import DisciplinaryActionFilter, DocumentRequestFilter, EmployeeFilter
|
||||
from employee.models import DisciplinaryAction, Employee, EmployeeBankDetails, EmployeeWorkInformation, Policy,EmployeeType
|
||||
from employee.views import work_info_export, work_info_import
|
||||
from ...api_methods.base.methods import groupby_queryset, permission_based_queryset
|
||||
from ...api_decorators.employee.decorators import or_condition
|
||||
from horilla.decorators import owner_can_enter
|
||||
from horilla_documents.models import Document, DocumentRequest
|
||||
from ... api_serializers.employee.serializers import (DisciplinaryActionSerializer, DocumentRequestSerializer, DocumentSerializer,
|
||||
EmployeeBankDetailsSerializer, EmployeeListSerializer, EmployeeSelectorSerializer, EmployeeSerializer, EmployeeTypeSerializer, EmployeeWorkInformationSerializer, PolicySerializer)
|
||||
from django_filters.rest_framework import DjangoFilterBackend
|
||||
from django.contrib.auth.decorators import permission_required
|
||||
from django.utils.decorators import method_decorator
|
||||
from rest_framework.permissions import IsAuthenticated
|
||||
from django.db.models import ProtectedError
|
||||
from notifications.signals import notify
|
||||
from django.db.models import Q
|
||||
|
||||
|
||||
class EmployeeTypeAPIView(APIView):
|
||||
"""
|
||||
Retrieves employee types.
|
||||
|
||||
Methods:
|
||||
get(request, pk=None): Returns a single employee type if pk is provided, otherwise returns all employee types.
|
||||
"""
|
||||
def get(self,request,pk=None):
|
||||
if pk:
|
||||
employee_type = EmployeeType.objects.get(id=pk)
|
||||
serializer = EmployeeTypeSerializer(employee_type)
|
||||
return Response(serializer.data,status=200)
|
||||
employee_type = EmployeeType.objects.all()
|
||||
serializer = EmployeeTypeSerializer(employee_type,many=True)
|
||||
return Response(serializer.data,status=200)
|
||||
|
||||
class EmployeeAPIView(APIView):
|
||||
"""
|
||||
Handles CRUD operations for employees.
|
||||
|
||||
Methods:
|
||||
get(request, pk=None):
|
||||
- Retrieves a single employee by pk if provided.
|
||||
- Retrieves and filters all employees if pk is not provided.
|
||||
|
||||
post(request):
|
||||
- Creates a new employee if the user has the 'employee.change_employee' permission.
|
||||
|
||||
put(request, pk):
|
||||
- Updates an existing employee if the user is the employee, a manager, or has 'employee.change_employee' permission.
|
||||
|
||||
delete(request, pk):
|
||||
- Deletes an employee if the user has the 'employee.delete_employee' permission.
|
||||
"""
|
||||
|
||||
filter_backends = [DjangoFilterBackend]
|
||||
filterset_class = EmployeeFilter
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
def get(self, request, pk=None):
|
||||
|
||||
if pk:
|
||||
try:
|
||||
employee = Employee.objects.get(pk=pk)
|
||||
except Employee.DoesNotExist:
|
||||
return Response({"error": "Employee does not exist"}, status=status.HTTP_404_NOT_FOUND)
|
||||
|
||||
serializer = EmployeeSerializer(employee)
|
||||
return Response(serializer.data)
|
||||
|
||||
paginator = PageNumberPagination()
|
||||
employees_queryset = Employee.objects.all()
|
||||
employees_filter_queryset = self.filterset_class(
|
||||
request.GET, queryset=employees_queryset).qs
|
||||
|
||||
field_name = request.GET.get("groupby_field", None)
|
||||
if field_name:
|
||||
url = request.build_absolute_uri()
|
||||
return groupby_queryset(request, url, field_name, employees_filter_queryset)
|
||||
|
||||
page = paginator.paginate_queryset(employees_filter_queryset, request)
|
||||
serializer = EmployeeSerializer(page, many=True)
|
||||
return paginator.get_paginated_response(serializer.data)
|
||||
|
||||
@manager_permission_required("employee.change_employee")
|
||||
def post(self, request):
|
||||
serializer = EmployeeSerializer(data=request.data)
|
||||
if serializer.is_valid():
|
||||
serializer.save()
|
||||
return Response(serializer.data, status=status.HTTP_201_CREATED)
|
||||
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
def put(self, request, pk):
|
||||
user = request.user
|
||||
employee = Employee.objects.get(pk=pk)
|
||||
is_manager = EmployeeWorkInformation.objects.filter(
|
||||
reporting_manager_id=user.employee_get).first()
|
||||
if employee == user.employee_get or is_manager or user.has_perm("employee.change_employee"):
|
||||
serializer = EmployeeSerializer(
|
||||
employee, data=request.data, partial=True)
|
||||
if serializer.is_valid():
|
||||
serializer.save()
|
||||
return Response(serializer.data)
|
||||
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||
return Response({"error": "You don't have permission"}, status=400)
|
||||
|
||||
@method_decorator(permission_required('employee.delete_employee'))
|
||||
def delete(self, request, pk):
|
||||
try:
|
||||
employee = Employee.objects.get(pk=pk)
|
||||
employee.delete()
|
||||
except Employee.DoesNotExist:
|
||||
return Response({"error": "Employee does not exist"}, status=status.HTTP_404_NOT_FOUND)
|
||||
except ProtectedError as e:
|
||||
return Response({"error": str(e)}, status=status.HTTP_204_NO_CONTENT)
|
||||
return Response(status=status.HTTP_204_NO_CONTENT)
|
||||
|
||||
|
||||
class EmployeeListAPIView(APIView):
|
||||
"""
|
||||
Retrieves a paginated list of employees with optional search functionality.
|
||||
|
||||
Methods:
|
||||
get(request):
|
||||
- Returns a paginated list of employees.
|
||||
- Optionally filters employees based on a search query in the first or last name.
|
||||
"""
|
||||
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
def get(self, request):
|
||||
paginator = PageNumberPagination()
|
||||
paginator.page_size = 13
|
||||
search = request.query_params.get('search',None)
|
||||
if search:
|
||||
employees_queryset = Employee.objects.filter(Q(employee_first_name__icontains = search)|Q(employee_last_name__icontains = search))
|
||||
else:
|
||||
employees_queryset = Employee.objects.all()
|
||||
page = paginator.paginate_queryset(employees_queryset, request)
|
||||
serializer = EmployeeListSerializer(page, many=True)
|
||||
return paginator.get_paginated_response(serializer.data)
|
||||
|
||||
|
||||
class EmployeeBankDetailsAPIView(APIView):
|
||||
"""
|
||||
Manage employee bank details with CRUD operations.
|
||||
|
||||
Methods:
|
||||
get(request, pk=None):
|
||||
- Retrieves bank details for a specific employee if `pk` is provided.
|
||||
- Returns a paginated list of all employee bank details if `pk` is not provided.
|
||||
|
||||
post(request):
|
||||
- Creates a new bank detail entry for an employee.
|
||||
|
||||
put(request, pk):
|
||||
- Updates existing bank details for an employee identified by `pk`.
|
||||
|
||||
delete(request, pk):
|
||||
- Deletes bank details for an employee identified by `pk`.
|
||||
"""
|
||||
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
def get_queryset(self):
|
||||
queryset = EmployeeBankDetails.objects.all()
|
||||
user = self.request.user
|
||||
# checking user level permissions
|
||||
perm = "base.view_employeebankdetails"
|
||||
queryset = permission_based_queryset(user, perm, queryset)
|
||||
return queryset
|
||||
|
||||
def get(self, request, pk=None):
|
||||
if pk:
|
||||
try:
|
||||
bank_detail = EmployeeBankDetails.objects.get(pk=pk)
|
||||
except EmployeeBankDetails.DoesNotExist:
|
||||
return Response({"error": "Bank details do not exist"}, status=status.HTTP_404_NOT_FOUND)
|
||||
|
||||
serializer = EmployeeBankDetailsSerializer(bank_detail)
|
||||
return Response(serializer.data)
|
||||
paginator = PageNumberPagination()
|
||||
employee_bank_details = self.get_queryset(request)
|
||||
page = paginator.paginate_queryset(employee_bank_details, request)
|
||||
serializer = EmployeeBankDetailsSerializer(page, many=True)
|
||||
return paginator.get_paginated_response(serializer.data)
|
||||
|
||||
@manager_or_owner_permission_required(EmployeeBankDetails, "employee.add_employeebankdetails")
|
||||
def post(self, request):
|
||||
serializer = EmployeeBankDetailsSerializer(data=request.data)
|
||||
if serializer.is_valid():
|
||||
serializer.save()
|
||||
return Response(serializer.data, status=status.HTTP_201_CREATED)
|
||||
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
@manager_or_owner_permission_required(EmployeeBankDetails, "employee.add_employeebankdetails")
|
||||
def put(self, request, pk):
|
||||
try:
|
||||
bank_detail = EmployeeBankDetails.objects.get(pk=pk)
|
||||
except EmployeeBankDetails.DoesNotExist:
|
||||
return Response({"error": "Bank details do not exist"}, status=status.HTTP_404_NOT_FOUND)
|
||||
|
||||
serializer = EmployeeBankDetailsSerializer(
|
||||
bank_detail, data=request.data)
|
||||
if serializer.is_valid():
|
||||
serializer.save()
|
||||
return Response(serializer.data)
|
||||
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
@manager_permission_required("employee.change_employeebankdetails")
|
||||
def delete(self, request, pk):
|
||||
try:
|
||||
bank_detail = EmployeeBankDetails.objects.get(pk=pk)
|
||||
bank_detail.delete()
|
||||
except EmployeeBankDetails.DoesNotExist:
|
||||
return Response({"error": "Bank details do not exist"}, status=status.HTTP_404_NOT_FOUND)
|
||||
except Exception as E:
|
||||
return Response({"error": str(E)}, status=400)
|
||||
|
||||
return Response(status=status.HTTP_204_NO_CONTENT)
|
||||
|
||||
|
||||
|
||||
class EmployeeWorkInformationAPIView(APIView):
|
||||
"""
|
||||
Manage employee work information with CRUD operations.
|
||||
|
||||
Methods:
|
||||
get(request, pk):
|
||||
- Retrieves work information for a specific employee identified by `pk`.
|
||||
|
||||
post(request):
|
||||
- Creates a new work information entry for an employee.
|
||||
|
||||
put(request, pk):
|
||||
- Updates existing work information for an employee identified by `pk`.
|
||||
|
||||
delete(request, pk):
|
||||
- Deletes work information for an employee identified by `pk`.
|
||||
"""
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
def get(self, request, pk):
|
||||
work_info = EmployeeWorkInformation.objects.get(pk=pk)
|
||||
serializer = EmployeeWorkInformationSerializer(work_info)
|
||||
return Response(serializer.data)
|
||||
|
||||
@manager_permission_required("employee.add_employeeworkinformation")
|
||||
def post(self, request):
|
||||
serializer = EmployeeWorkInformationSerializer(data=request.data)
|
||||
if serializer.is_valid():
|
||||
serializer.save()
|
||||
return Response(serializer.data, status=status.HTTP_201_CREATED)
|
||||
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
@manager_permission_required("employee.change_employeeworkinformation")
|
||||
def put(self, request, pk):
|
||||
try:
|
||||
work_info = EmployeeWorkInformation.objects.get(pk=pk)
|
||||
except EmployeeWorkInformation.DoesNotExist:
|
||||
raise Http404
|
||||
serializer = EmployeeWorkInformationSerializer(
|
||||
work_info, data=request.data, partial=True)
|
||||
if serializer.is_valid():
|
||||
serializer.save()
|
||||
return Response(serializer.data)
|
||||
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
|
||||
|
||||
@method_decorator(permission_required("employee.delete_employeeworkinformation"), name='dispatch')
|
||||
def delete(self, request, pk):
|
||||
try:
|
||||
work_info = EmployeeWorkInformation.objects.get(pk=pk)
|
||||
except EmployeeWorkInformation.DoesNotExist:
|
||||
raise Http404
|
||||
work_info.delete()
|
||||
return Response(status=status.HTTP_204_NO_CONTENT)
|
||||
|
||||
|
||||
|
||||
class EmployeeWorkInfoExportView(APIView):
|
||||
"""
|
||||
Endpoint for exporting employee work information.
|
||||
|
||||
Methods:
|
||||
get(request):
|
||||
- Exports work information data based on user permissions.
|
||||
"""
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
@manager_permission_required("employee.add_employeeworkinformation")
|
||||
def get(self, request):
|
||||
return work_info_export(request)
|
||||
|
||||
class EmployeeWorkInfoImportView(APIView):
|
||||
"""
|
||||
Endpoint for importing employee work information.
|
||||
|
||||
Methods:
|
||||
get(request):
|
||||
- Handles the importing of work information data based on user permissions.
|
||||
"""
|
||||
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
@manager_permission_required("employee.add_employeeworkinformation")
|
||||
def get(self, request):
|
||||
return work_info_import(request)
|
||||
|
||||
|
||||
class EmployeeBulkUpdateView(APIView):
|
||||
"""
|
||||
Endpoint for bulk updating employee and work information.
|
||||
|
||||
Permissions:
|
||||
- Requires authentication and "change_employee" permission.
|
||||
0
|
||||
Methods:
|
||||
put(request):
|
||||
- Updates multiple employees and their work information.
|
||||
"""
|
||||
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
@method_decorator(permission_required("employee.change_employee"), name='dispatch')
|
||||
def put(self, request):
|
||||
employee_ids = request.data.get('ids', [])
|
||||
employees = Employee.objects.filter(id__in=employee_ids)
|
||||
employee_work_info = EmployeeWorkInformation.objects.filter(
|
||||
employee_id__in=employees)
|
||||
employee_data = request.data.get('employee_data', {})
|
||||
work_info_data = request.data.get("employee_work_info", {})
|
||||
fields_to_remove = [
|
||||
"badge_id",
|
||||
"employee_first_name",
|
||||
"employee_last_name",
|
||||
"is_active",
|
||||
"email",
|
||||
"phone",
|
||||
"employee_bank_details__account_number",
|
||||
]
|
||||
for field in fields_to_remove:
|
||||
employee_data.pop(field, None)
|
||||
work_info_data.pop(field, None)
|
||||
|
||||
try:
|
||||
employees.update(**employee_data)
|
||||
employee_work_info.update(**work_info_data)
|
||||
except Exception as e:
|
||||
return Response({"error": str(e)}, status=400)
|
||||
return Response({"status": "success"}, status=200)
|
||||
|
||||
|
||||
class DisciplinaryActionAPIView(APIView):
|
||||
"""
|
||||
Endpoint for managing disciplinary actions.
|
||||
|
||||
Permissions:
|
||||
- Requires authentication.
|
||||
|
||||
Methods:
|
||||
get(request, pk=None):
|
||||
- Retrieves a specific disciplinary action by `pk` or lists all disciplinary actions with optional filtering.
|
||||
|
||||
post(request):
|
||||
- Creates a new disciplinary action.
|
||||
|
||||
put(request, pk):
|
||||
- Updates an existing disciplinary action by `pk`.
|
||||
|
||||
delete(request, pk):
|
||||
- Deletes a specific disciplinary action by `pk`.
|
||||
"""
|
||||
filterset_class = DisciplinaryActionFilter
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
def get_object(self, pk):
|
||||
try:
|
||||
return DisciplinaryAction.objects.get(pk=pk)
|
||||
except DisciplinaryAction.DoesNotExist:
|
||||
raise Http404
|
||||
|
||||
def get(self, request, pk=None):
|
||||
if pk:
|
||||
disciplinary_action = self.get_object(pk)
|
||||
serializer = DisciplinaryActionSerializer(disciplinary_action)
|
||||
return Response(serializer.data, status=200)
|
||||
else:
|
||||
paginator = PageNumberPagination()
|
||||
disciplinary_actions = DisciplinaryAction.objects.all()
|
||||
disciplinary_action_filter_queryset = self.filterset_class(
|
||||
request.GET, queryset=disciplinary_actions).qs
|
||||
page = paginator.paginate_queryset(
|
||||
disciplinary_action_filter_queryset, request)
|
||||
serializer = DisciplinaryActionSerializer(page, many=True)
|
||||
return paginator.get_paginated_response(serializer.data)
|
||||
|
||||
def post(self, request):
|
||||
serializer = DisciplinaryActionSerializer(data=request.data)
|
||||
if serializer.is_valid():
|
||||
serializer.save()
|
||||
return Response(serializer.data, status=status.HTTP_201_CREATED)
|
||||
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
def put(self, request, pk):
|
||||
disciplinary_action = self.get_object(pk)
|
||||
serializer = DisciplinaryActionSerializer(
|
||||
disciplinary_action, data=request.data)
|
||||
if serializer.is_valid():
|
||||
serializer.save()
|
||||
return Response(serializer.data)
|
||||
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
def delete(self, request, pk):
|
||||
disciplinary_action = self.get_object(pk)
|
||||
disciplinary_action.delete()
|
||||
return Response(status=status.HTTP_204_NO_CONTENT)
|
||||
|
||||
|
||||
class PolicyAPIView(APIView):
|
||||
"""
|
||||
Endpoint for managing policies.
|
||||
|
||||
Permissions:
|
||||
- Requires authentication.
|
||||
|
||||
Methods:
|
||||
get(request, pk=None):
|
||||
- Retrieves a specific policy by `pk` or lists all policies with optional search functionality.
|
||||
|
||||
post(request):
|
||||
- Creates a new policy.
|
||||
|
||||
put(request, pk):
|
||||
- Updates an existing policy by `pk`.
|
||||
|
||||
delete(request, pk):
|
||||
- Deletes a specific policy by `pk`.
|
||||
"""
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
def get_object(self, pk):
|
||||
try:
|
||||
return Policy.objects.get(pk=pk)
|
||||
except Policy.DoesNotExist:
|
||||
raise Http404
|
||||
|
||||
def get(self, request, pk=None):
|
||||
if pk:
|
||||
policy = self.get_object(pk)
|
||||
serializer = PolicySerializer(policy)
|
||||
return Response(serializer.data)
|
||||
else:
|
||||
search = request.GET.get("search", None)
|
||||
if search:
|
||||
policies = Policy.objects.filter(title__icontains=search)
|
||||
else:
|
||||
policies = Policy.objects.all()
|
||||
serializer = PolicySerializer(policies, many=True)
|
||||
paginator = PageNumberPagination()
|
||||
page = paginator.paginate_queryset(
|
||||
policies, request)
|
||||
serializer = PolicySerializer(page, many=True)
|
||||
return paginator.get_paginated_response(serializer.data)
|
||||
|
||||
def post(self, request):
|
||||
serializer = PolicySerializer(data=request.data)
|
||||
if serializer.is_valid():
|
||||
serializer.save()
|
||||
return Response(serializer.data, status=201)
|
||||
return Response(serializer.errors, status=400)
|
||||
|
||||
def put(self, request, pk):
|
||||
policy = self.get_object(pk)
|
||||
serializer = PolicySerializer(policy, data=request.data)
|
||||
if serializer.is_valid():
|
||||
serializer.save()
|
||||
return Response(serializer.data)
|
||||
return Response(serializer.errors, status=400)
|
||||
|
||||
def delete(self, request, pk):
|
||||
policy = self.get_object(pk)
|
||||
policy.delete()
|
||||
return Response(status=204)
|
||||
|
||||
|
||||
class DocumentRequestAPIView(APIView):
|
||||
"""
|
||||
Endpoint for managing document requests.
|
||||
|
||||
Permissions:
|
||||
- Requires authentication.
|
||||
- Specific actions require manager-level permissions.
|
||||
|
||||
Methods:
|
||||
get(request, pk=None):
|
||||
- Retrieves a specific document request by `pk` or lists all document requests with pagination.
|
||||
|
||||
post(request):
|
||||
- Creates a new document request and notifies relevant employees.
|
||||
|
||||
put(request, pk):
|
||||
- Updates an existing document request by `pk`.
|
||||
|
||||
delete(request, pk):
|
||||
- Deletes a specific document request by `pk`.
|
||||
"""
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
def get_object(self, pk):
|
||||
try:
|
||||
return DocumentRequest.objects.get(pk=pk)
|
||||
except DocumentRequest.DoesNotExist:
|
||||
raise Http404
|
||||
|
||||
def get(self, request, pk=None):
|
||||
if pk:
|
||||
document_request = self.get_object(pk)
|
||||
serializer = DocumentRequestSerializer(document_request)
|
||||
return Response(serializer.data)
|
||||
else:
|
||||
document_requests = DocumentRequest.objects.all()
|
||||
pagination = PageNumberPagination()
|
||||
page = pagination.paginate_queryset(
|
||||
document_requests, request)
|
||||
serializer = DocumentRequestSerializer(
|
||||
page, many=True)
|
||||
return pagination.get_paginated_response(serializer.data)
|
||||
|
||||
@manager_permission_required("horilla_documents.add_documentrequests")
|
||||
def post(self, request):
|
||||
serializer = DocumentRequestSerializer(data=request.data)
|
||||
if serializer.is_valid():
|
||||
obj = serializer.save()
|
||||
try:
|
||||
employees = [
|
||||
user.employee_user_id for user in obj.employee_id.all()]
|
||||
|
||||
notify.send(
|
||||
request.user.employee_get,
|
||||
recipient=employees,
|
||||
verb=f"{request.user.employee_get} requested a document.",
|
||||
verb_ar=f"طلب {request.user.employee_get} مستنداً.",
|
||||
verb_de=f"{request.user.employee_get} hat ein Dokument angefordert.",
|
||||
verb_es=f"{request.user.employee_get} solicitó un documento.",
|
||||
verb_fr=f"{request.user.employee_get} a demandé un document.",
|
||||
redirect="/employee/employee-profile",
|
||||
icon="chatbox-ellipses",
|
||||
api_redirect=f"/api/employee/document-request/{obj.id}"
|
||||
)
|
||||
except:
|
||||
pass
|
||||
return Response(serializer.data, status=status.HTTP_201_CREATED)
|
||||
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
@manager_permission_required("horilla_documents.change_documentrequests")
|
||||
def put(self, request, pk):
|
||||
document_request = self.get_object(pk)
|
||||
serializer = DocumentRequestSerializer(
|
||||
document_request, data=request.data)
|
||||
if serializer.is_valid():
|
||||
serializer.save()
|
||||
return Response(serializer.data)
|
||||
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
@method_decorator(permission_required("employee.delete_employee", raise_exception=True))
|
||||
def delete(self, request, pk):
|
||||
document_request = self.get_object(pk)
|
||||
document_request.delete()
|
||||
return Response(status=status.HTTP_204_NO_CONTENT)
|
||||
|
||||
|
||||
class DocumentAPIView(APIView):
|
||||
filterset_class = DocumentRequestFilter
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
def get_object(self, pk):
|
||||
try:
|
||||
return Document.objects.get(pk=pk)
|
||||
except Document.DoesNotExist:
|
||||
raise Http404
|
||||
|
||||
def get(self, request, pk=None):
|
||||
if pk:
|
||||
document = self.get_object(pk)
|
||||
serializer = DocumentSerializer(document)
|
||||
return Response(serializer.data)
|
||||
else:
|
||||
documents = Document.objects.all()
|
||||
document_requests_filtered = self.filterset_class(
|
||||
request.GET, queryset=documents).qs
|
||||
paginator = PageNumberPagination()
|
||||
page = paginator.paginate_queryset(
|
||||
document_requests_filtered, request)
|
||||
serializer = DocumentSerializer(page, many=True)
|
||||
return paginator.get_paginated_response(serializer.data)
|
||||
|
||||
@manager_or_owner_permission_required(DocumentRequest, "horilla_documents.add_document")
|
||||
def post(self, request):
|
||||
serializer = DocumentSerializer(data=request.data)
|
||||
if serializer.is_valid():
|
||||
serializer.save()
|
||||
try:
|
||||
notify.send(
|
||||
request.user.employee_get,
|
||||
recipient=request.user.employee_get.get_reporting_manager().employee_user_id,
|
||||
verb=f"{request.user.employee_get} uploaded a document",
|
||||
verb_ar=f"قام {request.user.employee_get} بتحميل مستند",
|
||||
verb_de=f"{request.user.employee_get} hat ein Dokument hochgeladen",
|
||||
verb_es=f"{request.user.employee_get} subió un documento",
|
||||
verb_fr=f"{request.user.employee_get} a téléchargé un document",
|
||||
redirect=f"/employee/employee-view/{request.user.employee_get.id}/",
|
||||
icon="chatbox-ellipses",
|
||||
api_redirect=f"/api/employee/documents/"
|
||||
)
|
||||
except:
|
||||
pass
|
||||
return Response(serializer.data, status=status.HTTP_201_CREATED)
|
||||
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
@method_decorator(owner_can_enter("horilla_documents.change_document", Employee))
|
||||
def put(self, request, pk):
|
||||
document = self.get_object(pk)
|
||||
serializer = DocumentSerializer(document, data=request.data)
|
||||
if serializer.is_valid():
|
||||
serializer.save()
|
||||
return Response(serializer.data)
|
||||
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
@method_decorator(owner_can_enter("horilla_documents.delete_document", Employee))
|
||||
def delete(self, request, pk):
|
||||
document = self.get_object(pk)
|
||||
document.delete()
|
||||
return Response(status=status.HTTP_204_NO_CONTENT)
|
||||
|
||||
|
||||
class DocumentRequestApproveRejectView(APIView):
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
@manager_permission_required("horilla_documents.add_document")
|
||||
def post(self, request, id, status):
|
||||
document = Document.objects.filter(id=id).first()
|
||||
document.status = status
|
||||
document.save()
|
||||
return Response({"status": "success"}, status=200)
|
||||
|
||||
|
||||
class DocumentBulkApproveRejectAPIView(APIView):
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
@manager_permission_required("horilla_documents.add_document")
|
||||
def put(self, request):
|
||||
ids = request.data.get("ids", None)
|
||||
status = request.data.get("status", None)
|
||||
status_code = 200
|
||||
|
||||
if ids:
|
||||
documents = Document.objects.filter(id__in=ids)
|
||||
response = []
|
||||
for document in documents:
|
||||
if not document.document:
|
||||
status_code = 400
|
||||
response.append(
|
||||
{"id": document.id, "error": "No documents"})
|
||||
continue
|
||||
response.append({"id": document.id, "status": "success"})
|
||||
document.status = status
|
||||
document.save()
|
||||
return Response(response, status=status_code)
|
||||
|
||||
|
||||
class EmployeeBulkArchiveView(APIView):
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
@method_decorator(permission_required("employee.delete_employee", raise_exception=True))
|
||||
def post(self, request, is_active):
|
||||
ids = request.data.get("ids")
|
||||
error = []
|
||||
for employee_id in ids:
|
||||
employee = Employee.objects.get(id=employee_id)
|
||||
employee.is_active = is_active
|
||||
employee.employee_user_id.is_active = is_active
|
||||
if employee.get_archive_condition() is False:
|
||||
employee.save()
|
||||
error.append({"employee": str(employee),
|
||||
"error": "Related model found for this employee. "})
|
||||
return Response(error, status=200)
|
||||
|
||||
|
||||
class EmployeeArchiveView(APIView):
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
@method_decorator(permission_required("employee.delete_employee", raise_exception=True))
|
||||
def post(self, request, id, is_active):
|
||||
employee = Employee.objects.get(id=id)
|
||||
employee.is_active = is_active
|
||||
employee.employee_user_id.is_active = is_active
|
||||
response = None
|
||||
if employee.get_archive_condition() is False:
|
||||
employee.save()
|
||||
else:
|
||||
response = {"employee": str(
|
||||
employee), "error": employee.get_archive_condition()}
|
||||
return Response(response, status=200)
|
||||
|
||||
|
||||
class EmployeeSelectorView(APIView):
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
def get(self, request):
|
||||
employee = request.user.employee_get
|
||||
employees = Employee.objects.filter(employee_user_id=request.user)
|
||||
|
||||
|
||||
is_manager = EmployeeWorkInformation.objects.filter(
|
||||
reporting_manager_id=employee
|
||||
).exists()
|
||||
|
||||
if is_manager:
|
||||
employees = Employee.objects.filter(
|
||||
Q(pk=employee.pk) | Q(
|
||||
employee_work_info__reporting_manager_id=employee)
|
||||
)
|
||||
if request.user.has_perm("employee.view_employee"):
|
||||
employees = Employee.objects.all()
|
||||
|
||||
paginator = PageNumberPagination()
|
||||
page = paginator.paginate_queryset(
|
||||
employees, request)
|
||||
serializer = EmployeeSelectorSerializer(page, many=True)
|
||||
return paginator.get_paginated_response(serializer.data)
|
||||
|
||||
|
||||
|
||||
class ReportingManagerCheck(APIView):
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
def get(self,request):
|
||||
if Employee.objects.filter(employee_work_info__reporting_manager_id =request.user.employee_get):
|
||||
return Response(status=200)
|
||||
return Response(status=404)
|
||||
|
||||
|
||||
|
||||
1102
horilla_api/api_views/leave/views.py
Normal file
1102
horilla_api/api_views/leave/views.py
Normal file
File diff suppressed because it is too large
Load Diff
65
horilla_api/api_views/notifications/views.py
Normal file
65
horilla_api/api_views/notifications/views.py
Normal file
@@ -0,0 +1,65 @@
|
||||
from rest_framework.views import APIView
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.permissions import IsAuthenticated
|
||||
|
||||
from ...api_serializers.notifications.serializers import NotificationSerializer
|
||||
from rest_framework.pagination import PageNumberPagination
|
||||
|
||||
# Create your views here.
|
||||
|
||||
|
||||
|
||||
class NotificationView(APIView):
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
def get(self, request, type):
|
||||
if type == 'all':
|
||||
queryset = request.user.notifications.all()
|
||||
elif type == 'unread':
|
||||
queryset = request.user.notifications.unread()
|
||||
|
||||
pagination = PageNumberPagination()
|
||||
page = pagination.paginate_queryset(queryset, request)
|
||||
serializer = NotificationSerializer(page, many=True)
|
||||
return pagination.get_paginated_response(serializer.data)
|
||||
|
||||
|
||||
class NotificationReadDelView(APIView):
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
def post(self, request, id):
|
||||
obj = request.user.notifications.filter(id=id).first()
|
||||
obj.mark_as_read()
|
||||
serializer = NotificationSerializer(obj)
|
||||
return Response(serializer.data, status=200)
|
||||
|
||||
def delete(self, request, id):
|
||||
obj = request.user.notifications.filter(id=id).first()
|
||||
obj.deleted = True
|
||||
obj.save()
|
||||
return Response({"status": "deleted"}, status=200)
|
||||
|
||||
|
||||
class NotificationBulkReadDelView(APIView):
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
def post(self, request):
|
||||
obj = request.user.notifications.all()
|
||||
obj.mark_all_as_read()
|
||||
return Response({"status": "marked as read"}, status=200)
|
||||
|
||||
def delete(self, request):
|
||||
obj = request.user.notifications.all()
|
||||
obj.mark_all_as_deleted()
|
||||
return Response({"status": "deleted"}, status=200)
|
||||
|
||||
|
||||
|
||||
class NotificationBulkDelUnreadMessageView(APIView):
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
def delete(self, request):
|
||||
obj = request.user.notifications.unread()
|
||||
obj.mark_all_as_deleted()
|
||||
return Response({"status": "deleted"}, status=200)
|
||||
|
||||
348
horilla_api/api_views/payroll/views.py
Normal file
348
horilla_api/api_views/payroll/views.py
Normal file
@@ -0,0 +1,348 @@
|
||||
from collections import defaultdict
|
||||
import gettext
|
||||
from django.shortcuts import render
|
||||
from rest_framework.views import APIView
|
||||
|
||||
from base.backends import ConfiguredEmailBackend
|
||||
from payroll.models.tax_models import TaxBracket
|
||||
from payroll.threadings.mail import MailSendThread
|
||||
from payroll.views.views import payslip_pdf
|
||||
from ... api_serializers.payroll.serializers import AllowanceSerializer, ContractSerializer, DeductionSerializer, LoanAccountSerializer, PayslipSerializer, ReimbursementSerializer, TaxBracketSerializer
|
||||
from ...api_methods.base.methods import groupby_queryset
|
||||
from payroll.filters import AllowanceFilter, ContractFilter, DeductionFilter, PayslipFilter
|
||||
from payroll.models.models import Allowance, Contract, Deduction, LoanAccount, Payslip, Reimbursement
|
||||
from rest_framework.pagination import PageNumberPagination
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.permissions import IsAuthenticated
|
||||
from django.contrib.auth.decorators import permission_required
|
||||
from django.utils.decorators import method_decorator
|
||||
|
||||
|
||||
class PayslipView(APIView):
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
def get(self, request,id=None):
|
||||
if id:
|
||||
payslip = Payslip.objects.filter(id=id).first()
|
||||
if request.user.has_perm("payroll.view_payslip") or payslip.employee_id == request.user.employee_get:
|
||||
serializer = PayslipSerializer(payslip)
|
||||
return Response(serializer.data,status=200)
|
||||
if request.user.has_perm("payroll.view_payslip"):
|
||||
payslips = Payslip.objects.all()
|
||||
else:
|
||||
payslips = Payslip.objects.filter(
|
||||
employee_id__employee_user_id=request.user
|
||||
)
|
||||
|
||||
payslip_filter_queryset = PayslipFilter(request.GET, payslips).qs
|
||||
# groupby workflow
|
||||
field_name = request.GET.get("groupby_field", None)
|
||||
if field_name:
|
||||
url = request.build_absolute_uri()
|
||||
return groupby_queryset(request, url, field_name, payslip_filter_queryset)
|
||||
pagination = PageNumberPagination()
|
||||
page = pagination.paginate_queryset(payslip_filter_queryset, request)
|
||||
serializer = PayslipSerializer(page, many=True)
|
||||
return pagination.get_paginated_response(serializer.data)
|
||||
|
||||
class PayslipDownloadView(APIView):
|
||||
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
def get(self, request, id):
|
||||
if request.user.has_perm("payroll.view_payslip"):
|
||||
return payslip_pdf(request, id)
|
||||
|
||||
if Payslip.objects.filter(id=id, employee_id=request.user.employee_get):
|
||||
return payslip_pdf(request, id)
|
||||
else:
|
||||
raise Response({"error":"You don't have permission"})
|
||||
|
||||
|
||||
class PayslipSendMailView(APIView):
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
@method_decorator(permission_required("payroll.add_payslip", raise_exception=True))
|
||||
def post(self, request):
|
||||
email_backend = ConfiguredEmailBackend()
|
||||
if not getattr(
|
||||
email_backend, "dynamic_username_with_display_name", None
|
||||
) or not len(email_backend.dynamic_username_with_display_name):
|
||||
return Response({"error": "Email server is not configured"}, status=400)
|
||||
|
||||
payslip_ids = request.data.get("id", [])
|
||||
payslips = Payslip.objects.filter(id__in=payslip_ids)
|
||||
result_dict = defaultdict(
|
||||
lambda: {"employee_id": None, "instances": [], "count": 0}
|
||||
)
|
||||
|
||||
for payslip in payslips:
|
||||
employee_id = payslip.employee_id
|
||||
result_dict[employee_id]["employee_id"] = employee_id
|
||||
result_dict[employee_id]["instances"].append(payslip)
|
||||
result_dict[employee_id]["count"] += 1
|
||||
mail_thread = MailSendThread(
|
||||
request, result_dict=result_dict, ids=payslip_ids)
|
||||
mail_thread.start()
|
||||
return Response({"status": "success"}, status=200)
|
||||
|
||||
|
||||
class ContractView(APIView):
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
def get(self, request,id=None):
|
||||
if id :
|
||||
contract = Contract.objects.filter(id=id).first()
|
||||
serializer = ContractSerializer(contract)
|
||||
return Response(serializer.data,status=200)
|
||||
if request.user.has_perm("payroll.view_contract"):
|
||||
contracts = Contract.objects.all()
|
||||
else:
|
||||
contracts = Contract.objects.filter(
|
||||
employee_id=request.user.employee_get)
|
||||
filter_queryset = ContractFilter(request.GET, contracts).qs
|
||||
# groupby workflow
|
||||
field_name = request.GET.get("groupby_field", None)
|
||||
if field_name:
|
||||
url = request.build_absolute_uri()
|
||||
return groupby_queryset(request, url, field_name, filter_queryset)
|
||||
pagination = PageNumberPagination()
|
||||
page = pagination.paginate_queryset(filter_queryset, request)
|
||||
serializer = ContractSerializer(page, many=True)
|
||||
return pagination.get_paginated_response(serializer.data)
|
||||
|
||||
@method_decorator(permission_required("payroll.add_contract", raise_exception=True))
|
||||
def post(self, request):
|
||||
serializer = ContractSerializer(data=request.data)
|
||||
if serializer.is_valid():
|
||||
serializer.save()
|
||||
return Response(serializer.data, status=200)
|
||||
return Response(serializer.errors, status=400)
|
||||
|
||||
@method_decorator(permission_required("payroll.change_contract", raise_exception=True))
|
||||
def put(self, request, pk):
|
||||
contract = Contract.objects.get(id=pk)
|
||||
serializer = ContractSerializer(instance=contract, data=request.data)
|
||||
if serializer.is_valid():
|
||||
serializer.save()
|
||||
return Response(serializer.data, status=200)
|
||||
return Response(serializer.errors, status=400)
|
||||
|
||||
@method_decorator(permission_required("payroll.delete_contract", raise_exception=True))
|
||||
def delete(self, request, pk):
|
||||
contract = Contract.objects.get(id=pk)
|
||||
contract.delete()
|
||||
return Response({"status": "deleted"}, status=200)
|
||||
|
||||
|
||||
class AllowanceView(APIView):
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
@method_decorator(permission_required("payroll.view_allowance", raise_exception=True))
|
||||
def get(self, request,pk=None):
|
||||
if pk:
|
||||
allowance = Allowance.objects.get(id=pk)
|
||||
serializer = AllowanceSerializer(instance=allowance)
|
||||
return Response(serializer.data,status=200)
|
||||
allowance = Allowance.objects.all()
|
||||
filter_queryset = AllowanceFilter(request.GET, allowance).qs
|
||||
pagination = PageNumberPagination()
|
||||
page = pagination.paginate_queryset(filter_queryset, request)
|
||||
serializer = AllowanceSerializer(page, many=True)
|
||||
return pagination.get_paginated_response(serializer.data)
|
||||
|
||||
@method_decorator(permission_required("payroll.add_allowance", raise_exception=True))
|
||||
def post(self, request):
|
||||
serializer = AllowanceSerializer(data=request.data)
|
||||
if serializer.is_valid():
|
||||
serializer.save()
|
||||
return Response(serializer.data, status=200)
|
||||
return Response(serializer.errors, status=400)
|
||||
|
||||
@method_decorator(permission_required("payroll.change_allowance", raise_exception=True))
|
||||
def put(self, request, pk):
|
||||
contract = Allowance.objects.get(id=pk)
|
||||
serializer = AllowanceSerializer(instance=contract, data=request.data)
|
||||
if serializer.is_valid():
|
||||
serializer.save()
|
||||
return Response(serializer.data, status=200)
|
||||
return Response(serializer.errors, status=400)
|
||||
|
||||
@method_decorator(permission_required("payroll.delete_allowance", raise_exception=True))
|
||||
def delete(self, request, pk):
|
||||
contract = Allowance.objects.get(id=pk)
|
||||
contract.delete()
|
||||
return Response({"status": "deleted"}, status=200)
|
||||
|
||||
|
||||
class DeductionView(APIView):
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
@method_decorator(permission_required("payroll.view_deduction", raise_exception=True))
|
||||
def get(self, request,pk=None):
|
||||
if pk:
|
||||
deduction = Deduction.objects.get(id=pk)
|
||||
serializer = DeductionSerializer(instance=deduction)
|
||||
return Response(serializer.data,status=200)
|
||||
deduction = Deduction.objects.all()
|
||||
filter_queryset = DeductionFilter(request.GET, deduction).qs
|
||||
pagination = PageNumberPagination()
|
||||
page = pagination.paginate_queryset(filter_queryset, request)
|
||||
serializer = DeductionSerializer(page, many=True)
|
||||
return pagination.get_paginated_response(serializer.data)
|
||||
|
||||
@method_decorator(permission_required("payroll.add_deduction", raise_exception=True))
|
||||
def post(self, request):
|
||||
serializer = DeductionSerializer(data=request.data)
|
||||
if serializer.is_valid():
|
||||
serializer.save()
|
||||
return Response(serializer.data, status=200)
|
||||
return Response(serializer.errors, status=400)
|
||||
|
||||
@method_decorator(permission_required("payroll.change_deduction", raise_exception=True))
|
||||
def put(self, request, pk):
|
||||
contract = Deduction.objects.get(id=pk)
|
||||
serializer = DeductionSerializer(instance=contract, data=request.data)
|
||||
if serializer.is_valid():
|
||||
serializer.save()
|
||||
return Response(serializer.data, status=200)
|
||||
return Response(serializer.errors, status=400)
|
||||
|
||||
@method_decorator(permission_required("payroll.delete_deduction", raise_exception=True))
|
||||
def delete(self, request, pk):
|
||||
contract = Deduction.objects.get(id=pk)
|
||||
contract.delete()
|
||||
return Response({"status": "deleted"}, status=200)
|
||||
|
||||
|
||||
class LoanAccountView(APIView):
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
@method_decorator(permission_required("payroll.add_loanaccount", raise_exception=True))
|
||||
def post(self, request):
|
||||
serializer = LoanAccountSerializer(data=request.data)
|
||||
if serializer.is_valid():
|
||||
serializer.save()
|
||||
return Response(serializer.data, status=200)
|
||||
return Response(serializer.errors, status=400)
|
||||
|
||||
@method_decorator(permission_required("payroll.view_loanaccount", raise_exception=True))
|
||||
def get(self, request, pk=None):
|
||||
if pk:
|
||||
loan_account = LoanAccount.objects.get(id=pk)
|
||||
serializer = LoanAccountSerializer(instance=loan_account)
|
||||
return Response(serializer.data, status=200)
|
||||
loan_accounts = LoanAccount.objects.all()
|
||||
pagination = PageNumberPagination()
|
||||
page = pagination.paginate_queryset(loan_accounts, request)
|
||||
serializer = LoanAccountSerializer(page, many=True)
|
||||
return pagination.get_paginated_response(serializer.data)
|
||||
|
||||
@method_decorator(permission_required("payroll.change_loanaccount", raise_exception=True))
|
||||
def put(self, request, pk):
|
||||
loan_account = LoanAccount.objects.get(id=pk)
|
||||
serializer = LoanAccountSerializer(loan_account, data=request.data)
|
||||
if serializer.is_valid():
|
||||
serializer.save()
|
||||
return Response(serializer.data, status=200)
|
||||
return Response(serializer.errors, status=400)
|
||||
|
||||
@method_decorator(permission_required("payroll.delete_loanaccount", raise_exception=True))
|
||||
def delete(self, request, pk):
|
||||
loan_account = LoanAccount.objects.get(id=pk)
|
||||
loan_account.delete()
|
||||
return Response(status=200)
|
||||
|
||||
|
||||
class ReimbursementView(APIView):
|
||||
serializer_class = ReimbursementSerializer
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
def get(self, request, pk=None):
|
||||
if pk:
|
||||
reimbursement = Reimbursement.objects.get(id=pk)
|
||||
serializer = self.serializer_class(reimbursement)
|
||||
return Response(serializer.data, status=200)
|
||||
reimbursements = Reimbursement.objects.all()
|
||||
|
||||
if request.user.has_perm("payroll.view_reimbursement"):
|
||||
reimbursements = Reimbursement.objects.all()
|
||||
else:
|
||||
reimbursements = Reimbursement.objects.filter(
|
||||
employee_id=request.user.employee_get)
|
||||
pagination = PageNumberPagination()
|
||||
page = pagination.paginate_queryset(reimbursements, request)
|
||||
serializer = self.serializer_class(page, many=True)
|
||||
return pagination.get_paginated_response(serializer.data)
|
||||
|
||||
def post(self, request):
|
||||
serializer = self.serializer_class(
|
||||
data=request.data, context={'request': request})
|
||||
if serializer.is_valid():
|
||||
serializer.save()
|
||||
return Response(serializer.data, status=200)
|
||||
return Response(serializer.errors, status=400)
|
||||
|
||||
@method_decorator(permission_required("payroll.change_reimbursement", raise_exception=True))
|
||||
def put(self, request, pk):
|
||||
reimbursement = Reimbursement.objects.get(id=pk)
|
||||
serializer = self.serializer_class(
|
||||
instance=reimbursement, data=request.data)
|
||||
if serializer.is_valid():
|
||||
serializer.save()
|
||||
return Response(serializer.data, status=200)
|
||||
return Response(serializer.errors, status=400)
|
||||
|
||||
@method_decorator(permission_required("payroll.delete_reimbursement", raise_exception=True))
|
||||
def delete(self, request, pk):
|
||||
reimbursement = Reimbursement.objects.get(id=pk)
|
||||
reimbursement.delete()
|
||||
return Response(status=200)
|
||||
|
||||
class ReimbusementApproveRejectView(APIView):
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
def post(self, request, pk):
|
||||
status = request.data.get('status', None)
|
||||
amount = request.data.get('amount', None)
|
||||
amount = eval(request.data.get('amount')
|
||||
) if request.data.get('amount') else 0
|
||||
amount = max(0, amount)
|
||||
reimbursement = Reimbursement.objects.filter(id=pk)
|
||||
if amount:
|
||||
reimbursement.update(amount=amount)
|
||||
reimbursement.update(status=status)
|
||||
return Response({"status": reimbursement.first().status}, status=200)
|
||||
|
||||
class TaxBracketView(APIView):
|
||||
|
||||
def get(self, request, pk=None):
|
||||
if pk:
|
||||
tax_bracket = TaxBracket.objects.get(id=pk)
|
||||
serializer = TaxBracketSerializer(tax_bracket)
|
||||
return Response(serializer.data, status=200)
|
||||
tax_brackets = TaxBracket.objects.all()
|
||||
serializer = TaxBracketSerializer(instance=tax_brackets, many=True)
|
||||
return Response(serializer.data, status=200)
|
||||
|
||||
def post(self, request):
|
||||
serializer = TaxBracketSerializer(data=request.data)
|
||||
if serializer.is_valid():
|
||||
serializer.save()
|
||||
return Response(serializer.data, status=200)
|
||||
return Response(serializer.errors, status=400)
|
||||
|
||||
def put(self, request, pk):
|
||||
tax_bracket = TaxBracket.objects.get(id=pk)
|
||||
serializer = TaxBracketSerializer(
|
||||
instance=tax_bracket, data=request.data, partial=True)
|
||||
if serializer.save():
|
||||
serializer.save()
|
||||
return Response(serializer.data, status=200)
|
||||
return Response(serializer.errors, status=400)
|
||||
|
||||
def delete(self, request, pk):
|
||||
tax_bracket = TaxBracket.objects.get(id=pk)
|
||||
tax_bracket.delete()
|
||||
return Response(status=200)
|
||||
|
||||
Reference in New Issue
Block a user