From e38e99374acc1d4ac45b8a73d22c5974ef59b107 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=94=D0=B0=D0=BB=D0=B5=D1=80?= <101361201+DarkSteelD@users.noreply.github.com> Date: Thu, 9 Jan 2025 12:48:36 +0300 Subject: [PATCH] kek --- hr/migrations/0001_initial.py | 69 +++++++++++++++++++++++++++++++++++ hr/migrations/__init__.py | 0 hr/urls.py | 5 ++- hr/views.py | 46 ++++++++++++++++++++++- logs.log | 2 + 5 files changed, 120 insertions(+), 2 deletions(-) create mode 100644 hr/migrations/0001_initial.py create mode 100644 hr/migrations/__init__.py diff --git a/hr/migrations/0001_initial.py b/hr/migrations/0001_initial.py new file mode 100644 index 0000000..8f35336 --- /dev/null +++ b/hr/migrations/0001_initial.py @@ -0,0 +1,69 @@ +# Generated by Django 5.1.4 on 2025-01-09 09:45 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='Employee', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('first_name', models.CharField(max_length=50)), + ('last_name', models.CharField(max_length=50)), + ('position', models.CharField(max_length=100)), + ('email', models.EmailField(max_length=254, unique=True)), + ('hired_date', models.DateField()), + ('work_schedule', models.JSONField(default=dict)), + ], + ), + migrations.CreateModel( + name='Leave', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('leave_type', models.CharField(choices=[('vacation', 'Vacation'), ('sick', 'Sick Leave')], max_length=10)), + ('start_date', models.DateField()), + ('end_date', models.DateField()), + ('reason', models.TextField(blank=True)), + ('employee', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='hr.employee')), + ], + ), + migrations.CreateModel( + name='OvertimeReport', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('date', models.DateField()), + ('worked_hours', models.FloatField()), + ('required_hours', models.FloatField(default=8.0)), + ('overtime', models.FloatField()), + ('comment', models.TextField(blank=True)), + ('employee', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='hr.employee')), + ], + ), + migrations.CreateModel( + name='Report', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('report_date', models.DateField(auto_now_add=True)), + ('employee', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='hr.employee')), + ], + ), + migrations.CreateModel( + name='WorkTimeLog', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('date', models.DateField()), + ('check_in', models.TimeField(blank=True, null=True)), + ('check_out', models.TimeField(blank=True, null=True)), + ('worked_hours', models.FloatField(blank=True, null=True)), + ('employee', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='hr.employee')), + ], + ), + ] diff --git a/hr/migrations/__init__.py b/hr/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/hr/urls.py b/hr/urls.py index 6d88889..5eed527 100644 --- a/hr/urls.py +++ b/hr/urls.py @@ -7,14 +7,16 @@ from .views import ( EmployeeViewSet, WorkTimeLogViewSet, LeaveViewSet, OvertimeReportViewSet, ReportViewSet ) +from .views import generate_employee_report # Create the router for HR-related views router_hr = DefaultRouter() router_hr.register(r'employees', EmployeeViewSet) router_hr.register(r'work-time-logs', WorkTimeLogViewSet) -router_hr.register(r'leaves', LeaveViewSet) router_hr.register(r'overtime-reports', OvertimeReportViewSet) router_hr.register(r'reports', ReportViewSet) +router_hr.register(r'work-time-logs', WorkTimeLogViewSet, basename='work-time-log') +router_hr.register(r'leaves', LeaveViewSet, basename='leave') # Swagger schema view for HR schema_view_hr = get_schema_view( @@ -34,4 +36,5 @@ urlpatterns = [ path('', include(router_hr.urls)), path('swagger/', schema_view_hr.with_ui('swagger', cache_timeout=0), name='schema-swagger-ui-hr'), path('redoc/', schema_view_hr.with_ui('redoc', cache_timeout=0), name='schema-redoc-hr'), + path('generate-report//', generate_employee_report, name='generate_employee_report'), ] diff --git a/hr/views.py b/hr/views.py index f958047..14c2a4d 100644 --- a/hr/views.py +++ b/hr/views.py @@ -5,7 +5,51 @@ from .serializers import ( OvertimeReportSerializer, ReportSerializer ) -# ViewSet для модели Employee +from django.http import FileResponse +from django.shortcuts import get_object_or_404 +from rest_framework import viewsets +from rest_framework.filters import OrderingFilter +from django_filters.rest_framework import DjangoFilterBackend + +class WorkTimeLogViewSet(viewsets.ModelViewSet): + queryset = WorkTimeLog.objects.all() + serializer_class = WorkTimeLogSerializer + filter_backends = [DjangoFilterBackend, OrderingFilter] + filterset_fields = { + 'employee__id': ['exact'], + 'date': ['gte', 'lte'], + } + ordering_fields = ['date'] + +class LeaveViewSet(viewsets.ModelViewSet): + queryset = Leave.objects.all() + serializer_class = LeaveSerializer + filter_backends = [DjangoFilterBackend, OrderingFilter] + filterset_fields = { + 'employee__id': ['exact'], + 'start_date': ['gte', 'lte'], + 'end_date': ['gte', 'lte'], + } + ordering_fields = ['start_date', 'end_date'] + +class OvertimeReportViewSet(viewsets.ModelViewSet): + queryset = OvertimeReport.objects.all() + serializer_class = OvertimeReportSerializer + filter_backends = [DjangoFilterBackend, OrderingFilter] + filterset_fields = { + 'employee__id': ['exact'], + 'date': ['gte', 'lte'], + } + ordering_fields = ['date'] + +def generate_employee_report(request, report_id): + """ + Генерация отчета с фильтрацией по диапазону дат. + """ + report = get_object_or_404(Report, id=report_id) + pdf_buffer = report.generate_pdf() + return FileResponse(pdf_buffer, as_attachment=True, filename=f"отчет_{report.employee.last_name}.pdf") + class EmployeeViewSet(viewsets.ModelViewSet): queryset = Employee.objects.all() serializer_class = EmployeeSerializer diff --git a/logs.log b/logs.log index 6051cdf..dbc9113 100644 --- a/logs.log +++ b/logs.log @@ -951,3 +951,5 @@ RuntimeError: You called this URL via POST, but the URL doesn't end in a slash a "POST /api/hq/api/employees/upload/ HTTP/1.1" 201 45 "POST /api/hq/api/contractors/upload/ HTTP/1.1" 201 47 "POST /api/hq/api/contractor-contacts/upload/ HTTP/1.1" 201 55 +Watching for file changes with StatReloader +"GET /api/hr/ HTTP/1.1" 200 10827